如何为多变量索引匹配公式创建 UDF
Posted
技术标签:
【中文标题】如何为多变量索引匹配公式创建 UDF【英文标题】:How to create UDF for multi-variable Index Match formula 【发布时间】:2019-09-06 18:25:48 【问题描述】:我想为以下 Excel 索引匹配公式创建一个 UDF:
=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))
enter image description here
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:对应的索引匹配结果
【问题讨论】:
总是"$A$1:$J$7"
还是您也需要用户设置范围的能力?
@ScottCraner 最终我将为表格/范围选择创建另一个参数,但现在只是为了让公式正常工作,“$A$1:$J$7”很好。
【参考方案1】:
起初我误读了您的帖子,并认为使用标准公式会更好,但是您专门寻找 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
只要选择变量的范围,表格的位置或大小都没有关系。您也可以从另一个工作表中调用它。
【讨论】:
谢谢@JvdV 这效果很好,我唯一改变的是 Dim SearchRng4 As String 而不是 Double。 是的,那是我的错,应该是字符串 当从工作簿中的不同工作表中选择 RNG 时,您是否有任何建议可以使此 UDF 工作? @SteveC,请参阅我在编辑后的答案中使用Parent.Name
属性的建议。
感谢您的帮助。出于某种原因,您的代码对我不起作用,但我对其进行了一些更新,现在它可以按照我的意愿完美运行。谢谢!【参考方案2】:
您可以将数据保存在变量数组中并对其进行迭代:
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
【讨论】:
我希望有一种方法可以在不遍历数组的情况下做到这一点,但这很好用,非常感谢。 @ScottCraner 不要忘记将其设为 Volatile - 它引用不属于参数的数据以上是关于如何为多变量索引匹配公式创建 UDF的主要内容,如果未能解决你的问题,请参考以下文章
Excel 技术篇 - 利用Match公式返回匹配的最后一个数据的索引