Как создать UDF для мульти-переменной формулы индекса соответствия - PullRequest
1 голос
/ 16 апреля 2019

Я хочу создать UDF для следующей формулы совпадения индекса Excel:

{=INDEX($A$1:$J$7,MATCH(B9,$A$1:$A$7,0),MATCH(1,($A$1:$J$1=B10)*($A$2:$J$2=B11),0))}

введите описание изображения здесь

    AA  AA  AA  BB  BB  BB  CC  CC  CC
    a   b   c   a   b   c   a   b   c
1   10  55  24  48  95  19  5   28  65
2   16  48  3   62  46  50  59  80  17
3   63  47  19  23  67  26  14  16  9
4   55  91  4   55  72  79  27  39  50
5   75  53  7   42  45  19  58  41  12

Condition1  3                               
Condition2  AA                              
Condition3  c                               

index-Match 19  =INDEX($A$1:$J$7,MATCH(B9,$A$1:$A$7,0),MATCH(1,($A$1:$J$1=B10)*($A$2:$J$2=B11),0))}                         

ПРИМЕЧАНИЕ: CTRL + SHIFT + ENTER для возврата результата массива в excel

Это работает на листе Excel, но когда я пытаюсь преобразовать его в VBA, я получаю сообщение об ошибке.

Я полагаю, что мне нужно применить FormulaArray где-то в следующих кодах, любая помощь очень ценится.

Я пробовал использовать следующие коды, но получил #VALUE!

Public Function UDF_IndexMatch(Condition1, Condition2, COndition3)
    UDF_IndexMatch = Application.WorksheetFunction.Index(Range("$A$1:$J$7"), _
                                                  Application.WorksheetFunction.Match(Condition1, Range("$A$1:$A$7"), 0), _ 
                                                 Application.WorksheetFunction.Match(1, (Range("$A$1:$J$1") = Condition2) * (Range("$A$2:$J$2") = COndition3), 0))

End Function

конечный результат должен выглядеть примерно так:

= UDF_IndexMatch(Condition1, Condition2, COndition3) 

return: соответствующий индексный результат совпадения

Ответы [ 2 ]

2 голосов
/ 16 апреля 2019

Сначала я неправильно прочитал ваш пост и подумал, что вам лучше использовать стандартную формулу, однако вы специально ищете UDF.Просто для того, чтобы дать другие варианты, вот один:

Public Function ReturnVal(RNG As Range, Con1, Con2, Con3) As String
Dim SearchRng1 As String, SearchRng2 As String, SearchRng3 As String, SearchRng4 As String

With ActiveWorkbook.Sheets(RNG.Parent.Name)
    SearchRng1 = RNG.Parent.Name & "!" & RNG.Range(.Cells(3, 2), .Cells(RNG.Rows.Count, RNG.Columns.Count)).Address(False, False)
    SearchRng2 = RNG.Parent.Name & "!" & RNG.Range(.Cells(3, 1), .Cells(RNG.Rows.Count, 1)).Address(False, False)
    SearchRng3 = RNG.Parent.Name & "!" & RNG.Range(.Cells(1, 2), .Cells(1, RNG.Columns.Count)).Address(False, False)
    SearchRng4 = RNG.Parent.Name & "!" & RNG.Range(.Cells(2, 2), .Cells(2, RNG.Columns.Count)).Address(False, False)
End With
ReturnVal = Evaluate("=INDEX(" & SearchRng1 & ",MATCH(" & Con1 & "," & SearchRng2 & ",0),MATCH(""" & Con2 & """&""" & Con3 & """," & SearchRng3 & "&" & SearchRng4 & ",0))")

End Function

Пока вы выбираете диапазон в переменных, не имеет значения, где расположена ваша таблица или насколько она велика.Вы также можете позвонить с другого листа.

enter image description here

2 голосов
/ 16 апреля 2019

Вы можете просто сохранить данные в массиве вариантов и повторить это:

Public Function UDF_IndexMatch(Condition1, Condition2, COndition3)
    Application.Volatile

    Dim rngarr As Variant
    rngarr = Application.Caller.Parent.Range("A1:J7").Value

    Dim irow As Long
    irow = 0

    Dim i As Long
    For i = LBound(rngarr, 1) To UBound(rngarr, 1)
        If rngarr(i, 1) = Condition1 Then
            irow = i
            Exit For
        End If
    Next i

    Dim jcolumn As Long
    jcolumn = 0

    If irow > 0 Then
        Dim j As Long
        For j = LBound(rngarr, 2) To UBound(rngarr, 2)
            If rngarr(1, j) = Condition2 And rngarr(2, j) = COndition3 Then
                jcolumn = j
            End If
        Next j
    End If

    If j > 0 Then

        UDF_IndexMatch = rngarr(irow, jcolumn)
    End If
End Function

enter image description here

...