Excel / VBA – 使用dynamic范围的索引匹配function

如何在VBA中有效地使用Index/Match公式?

背景:我有一个工作表,在很大程度上依赖于使用一个公式检索输出的基础上,匹配一个特定的名字到它的名字范围以及一个特定的date到它的date范围。

 =INDEX(OutputRange,MATCH(1,(Name=NameRange)*(Date=DateRange),FALSE),1) 

此外,有一个硬编码的VBA子产生相同的输出

 Sub ExampleHardCode() Dim Result As Variant Result = Evaluate("INDEX($C$4:$C$13,MATCH(1,($G$6=$A$4:$A$13)*($G8=$B$4:$B$13),FALSE),1)") ActiveCell.Value = Result End Sub 

问题:我想生成一个函数,返回与上述选项相同的输出,但允许用户(i)通过引用相应单元格select名称和date值,并(ii)select每个范围(名称范围,date范围和输出范围)。 基本上在excel中使用= examplefunction(名称值,名称范围,date值,date范围,输出范围)。

我尝试了一些不同的解决scheme,但没有成功。 下面是我到目前为止所尝试的一个例子,我认为即使在我尝试设置范围(使用硬编码范围)时,也会出现匹配部分的问题,但返回错误。

 Function TestIndexMatch1(NameVal As Variant, DateVal As Date) Dim NameRng As Range Dim DateRng As Range Dim OutputRng As Range Dim Var1 As Variant 'should this be a range or integer? Dim Result As Variant Set NameRng = Range("$A$4:$A$13") Set DateRng = Range("$B$4:$B$13") Set OutputRng = Range("$C$4:$D$13") With Application.WorksheetFunction Var1 = .Match(1, (NameVal = NameRng) * (DateVal = DateRng), False) Result = .Index(OutputRng, Var1, 1) End With End Function 

如果有帮助我可以分享,我有一个示例工作簿。 我不确定这是否可行,但如果是这样的话,它确实可以帮助许多对Excel不熟悉的用户正确使用index / match excel公式。 不幸的是对我来说,我的excel技能远远超过了我的VBA技能。

要使用VBA代码中的数组公式, 将Application对象的ReferenceStyle设置为xlR1C1 (暂时只在您的函数执行期间) 。 最后调用Evaluate来获得公式的结果。

 Private Const TEMPLATE As String = "=INDEX({0},MATCH(1,({1}={2})*({3}={4}),{5}))" Private Const MATCH_TYPE = 0 Public Function TestIndexMatch1(ByRef outputRange As Range, _ ByRef nameCriteria As Range, _ ByRef dateCriteria As Range, _ ByRef nameRange As Range, _ ByRef dateRange As Range) On Error GoTo Err_Handler Err.Number = 0 Dim originalReferenceStyle originalReferenceStyle = Application.ReferenceStyle Application.ReferenceStyle = xlR1C1 Dim myFormula As String myFormula = Replace(TEMPLATE, "{0}", outputRange.Address()) myFormula = Replace(myFormula, "{1}", nameCriteria.Address()) myFormula = Replace(myFormula, "{2}", nameRange.Address()) myFormula = Replace(myFormula, "{3}", dateCriteria.Address()) myFormula = Replace(myFormula, "{4}", dateRange.Address()) myFormula = Replace(myFormula, "{5}", MATCH_TYPE) TestIndexMatch1 = Application.Evaluate(myFormula) Err_Handler: If (Err.Number <> 0) Then MsgBox Err.Description Application.ReferenceStyle = originalReferenceStyle End Function 

所以它看起来在表上:

在这里输入图像说明

在这里输入图像说明