Благодарим вас за вашу помощь вы указали мне в правильном направлении! Я должен был добавить некоторые проверки и переместить оператор if, но у меня есть конечный продукт, который должен работать для всех, поэтому я решил опубликовать готовый код.
Вот код с одного критерия.
Function WeightedAverageIf(Rng As Range, Find1 As String, Find1Column As Integer, WeightColumn As Integer, AVGColumn As Integer)
lr = Rng.Rows.Count
Dim num1 As Double, per1 As Double, num2 As Double, per2 As Double, counter As Integer
coutner = 0
For x = 1 To lr
If counter > 0 Then
If Rng.Cells(x, WeightColumn) = 0 Or Rng.Cells(x, WeightColumn) = "" Or IsNumeric(Rng.Cells(x, AVGColumn)) = False Or IsNumeric(Rng.Cells(x, WeightColumn)) = False Then GoTo skipif
If Rng.Cells(x, Find1Column) = Find1 Then
num2 = Rng.Cells(x, WeightColumn)
per2 = Rng.Cells(x, AVGColumn)
counter = counter + 1
End If
per1 = (((per1 * num1) + (per2 * num2))/(num1 + num2))
num1 = (num1 + num2)
End If
If counter = 0 Then
If Rng.Cells(x, WeightColumn) = 0 Or Rng.Cells(x, WeightColumn) = "" Or IsNumeric(Rng.Cells(x, AVGColumn)) = False Or IsNumeric(Rng.Cells(x, WeightColumn)) = False Then GoTo skipif
If Rng.Cells(x, Find1Column) = Find1 Then
num1 = Rng.Cells(x, WeightColumn)
per1 = Rng.Cells(x, AVGColumn)
counter = counter + 1
End If
End If
skipif:
Next x
If counter = 1 Then
WeightedAverageIf = per1
ElseIf counter = 0 Then
WeightedAverageIf = 0
Else
WeightedAverageIf = per1
End If
End Function
И вот код с 2-мя критериями.
Function WeightedAverageIfs(Rng As Range, Find1 As String, Find1Column As Integer, Find2 As String, FindColumn2 As Integer, WeightColumn As Integer, AVGColumn As Integer)
lr = Rng.Cells(Rows.Count, 1).End(xlUp).Row
Dim num1 As Double, per1 As Double, num2 As Double, per2 As Double, counter As Integer
coutner = 0
For x = 1 To lr
If counter > 0 Then
If Rng.Cells(x, WeightColumn) = 0 Or Rng.Cells(x, WeightColumn) = "" Or IsNumeric(Rng.Cells(x, AVGColumn)) = False Or IsNumeric(Rng.Cells(x, WeightColumn)) = False Then GoTo skipif
If Rng.Cells(x, Find1Column) = Find1 And Rng.Cells(x, FindColumn2) = Find2 Then
num2 = Rng.Cells(x, WeightColumn)
per2 = Rng.Cells(x, AVGColumn)
counter = counter + 1
End If
per1 = (((per1 * num1) + (per2 * num2))/(num1 + num2))
num1 = (num1 + num2)
End If
If counter = 0 Then
If Rng.Cells(x, WeightColumn) = 0 Or Rng.Cells(x, WeightColumn) = "" Or IsNumeric(Rng.Cells(x, AVGColumn)) = False Or IsNumeric(Rng.Cells(x, WeightColumn)) = False Then GoTo skipif
If Rng.Cells(x, Find1Column) = Find1 And Rng.Cells(x, FindColumn2) = Find2 Then
num1 = Rng.Cells(x, WeightColumn)
per1 = Rng.Cells(x, AVGColumn)
counter = counter + 1
End If
End If
skipif:
Next x
If counter = 1 Then
WeightedAverageIfs = per1
ElseIf counter = 0 Then
WeightedAverageIfs = 0
Else
WeightedAverageIfs = per1
End If
End Function
Я надеюсь, что это поможет людям в будущем. Для тех, кто не знаком с Excel и VBA, вам нужно будет открыть консоль разработчика. Вставьте новый модуль и вставьте один из сегментов кода выше. После этого вы можете просто ввести функцию с аргументами = WeightedAverageIf («Диапазон ваших данных», «Что вам нужно, чтобы соответствовать в диапазоне», «В каком столбце в диапазоне находятся искомые данные в», «Столбец с взвешиванием» «Столбец с усредненными числами»)
Это не поможет решить вашу проблему, но вы не должны использовать Range в качестве имени переменной для своего диапазона, так как Range является ключевым словом VBA. Поэтому он будет путать VBA, если вы используете Range, когда вы действительно имеете в виду Range ... понимаете, что я имею в виду? Измените его на R или Rng или что-то другое, кроме Range, чтобы сделать код более легким для чтения. – sous2817