2013-12-02 7 views
2

Я пытаюсь написать пользовательскую функцию, которая будет проверять 2 критерия в диапазоне, а затем средневзвешенное значение любых совпадений, которые оно находит. Мой код ниже, и он не правильно интерпретирует мои критерии. Он отображает #Value для моих критериев. Любая помощь будет принята с благодарностью! Спасибо: DExcel VBA Средневзвешенное значение Если пользовательская функция

https://drive.google.com/file/d/0B6aefGNRPaHiRlR4a3Vvc3RNamM/edit?usp=sharing

Function WeightedAverageIf(Range As Range, Citeria1 As String, Column1 As Integer, Criteria2 As String, Column2 As Integer, Column3 As Integer, Column4 As Integer) 
    lr = Range.Cells(Rows.Count, 1).End(xlUp).Row 
    Dim num1 As Integer, per1 As Integer, num2 As Integer, per2 As Integer, counter As Integer 
    coutner = 0 
    For x = 1 To lr 
     If counter = 0 Then 
      If Range.Cells(x, Column1) = Criteria1 And Range.Cells(x, Column2) = Criteria2 Then num1 = Cells(x, Column3) And per1 = Range.Cells(x, Column4) And counter = counter + 1 
      End If 
     If counter > 0 Then 
      If Range.Cells(x, Column1) = Criteria1 And Cells(x, Column2) = Criteria2 Then num2 = Range.Cells(x, Column3) And per2 = Range.Cells(x, Column4) And counter = counter + 1 
      per1 = (((per1 * num1) + (per2 * num2))/(num1 + num2)) 
      num1 = (num1 + num2) 
     End If 
    Next x 
    WeightedAverageIf = per1 
End Function 
+2

Это не поможет решить вашу проблему, но вы не должны использовать Range в качестве имени переменной для своего диапазона, так как Range является ключевым словом VBA. Поэтому он будет путать VBA, если вы используете Range, когда вы действительно имеете в виду Range ... понимаете, что я имею в виду? Измените его на R или Rng или что-то другое, кроме Range, чтобы сделать код более легким для чтения. – sous2817

ответ

1

Благодарим вас за вашу помощь вы указали мне в правильном направлении! Я должен был добавить некоторые проверки и переместить оператор 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 («Диапазон ваших данных», «Что вам нужно, чтобы соответствовать в диапазоне», «В каком столбце в диапазоне находятся искомые данные в», «Столбец с взвешиванием» «Столбец с усредненными числами»)

Смежные вопросы