0

我试图在 VBA 中实现索引匹配组合,以在给定 2 个条件的范围内找到一个数字。下面似乎是一个很好的方法,但是,我的输入不是来自 excel,而是来自代码本身发生变化的变量。对于我的生活,我无法弄清楚,但我是一个新手。

Excel / VBA - 使用动态范围的索引匹配功能

如果您的姓名和日期是贷款编号(1、2、3 等)和日期(2013 年 6 月 30 日),并且不在电子表格中,而是在 VBA 代码中生成,那么代码可以运行会发生什么情况到一个范围并在该日期查找该贷款的余额并将其存储到变量中

-----------------范围定义-------------------------------------------- ------------------------------------------

关于代码: Cantidad、ID 和 Fecha 是动态范围,定义如下:

With Worksheets("CFs")
Set ID = Range("offset($a$3,4,0,counta($A:$A)-4,1)")
Set Fecha = Range("offset($b$3,4,0,counta($B:$B)-4,1)")
Set Cantidad = Range("offset($f$3,4,0,counta($F:$F)-4,1)")
End With

------------------功能代码------------------------------ ---------------------------------------- 关于函数:dia1 和 ID 是一个日期每月更改一次,贷款编号每次循环一次,直到达到贷款总数。

Public Function TestIndexMatch1(ByRef Cantidad As Range, _
                                                    ByRef Prestamo As Integer, _
                                                    ByRef Dia1 As Date, _
                                                    ByRef ID As Range, _
                                                    ByRef Fecha As Range)

                    Const Template As String = "=INDEX({0},MATCH(1,({1}={2})*({3}={4},{5}))"

                    Const MATCH_TYPE = 0
                    On Error GoTo Err_Handler
                    Err.Number = 0

                    Dim originalReferenceStyle
                    originalReferenceStyle = Application.ReferenceStyle
                    Application.ReferenceStyle = xlR1C1

                    Dim myFormula As String
                    myFormula = Replace(Template, "{0}", Cantidad.Address())
                    myFormula = Replace(Template, "{1}", Prestamo.Address())
                    myFormula = Replace(Template, "{2}", Dia1.Address())
                    myFormula = Replace(Template, "{3}", ID.Address())
                    myFormula = Replace(Template, "{4}", Fecha.Address())

                    TestIndexMatch1 = Application.Evaluate(myFormula)

Err_Handler:
                        If (Err.Number <> 0) Then MsgBox Err.Description
                        Application.ReferenceStyle = originalReferenceStyle


End Function
4

1 回答 1

0

首先,您似乎缺少一些东西:

  1. 公式字符串中的右括号 ...{4} ) ,{5}...
  2. 名称定义中范围前的一个点(设置 ID = .Range)

但我认为你可能想要做一些不同的事情。如果您在 VBA 中定义要在工作表上的工作表函数中使用的变量,则需要小心定义依赖关系。VBA 函数中使用的每个范围都应该是函数的输入参数,因此 Excel 将在该值更改时重新计算。在代码中评估公式的另一个问题是缺少中间调试信息,并且函数并不总是像在工作表上那样评估。

对于第一部分,我认为您想要设置工作表名称,这可以通过对上面的代码进行以下调整来完成:

Sub SetUpNames()
With Worksheets("CFs").Names
    .Add "ID", "=offset($a$3,4,0,counta($A:$A)-4,1)"
    .Add "Fecha", "=offset($b$3,4,0,counta($B:$B)-4,1)"
    .Add "Cantidad", "=offset($f$3,4,0,counta($F:$F)-4,1)"
End With
End Sub

这也可以通过定义名称对话框来完成。然后可以将这些名称插入到链接帖子中的函数中。

对于第二部分代码,这里是链接帖子中函数的替代方法,它也使用工作表函数方法:

Public Function TestIndexMatch2(ByRef outputRange As Range, _
                            ByRef nameCriteria As Range, _
                            ByRef dateCriteria As Range, _
                            ByRef nameRange As Range, _
                            ByRef dateRange As Range)

Dim v as Variant
With Application
    v = .CountIfs(nameCriteria, nameRange, dateCriteria, dateRange)
    TestIndexMatch2 = .Index(outputRange, .Match(1, v, 0))
End With

End Function

(如果需要,现在至少可以使用观察窗口来评估中间结果)。

注意:在没有 .WorksheetFunction 的情况下使用 Application 返回一个变体,该变体允许在参数和结果中使用数组。但是,VBA 不会公开所有工作表函数或 Excel 运算符,因此您需要更加灵活地使用这种方法,例如缺少Exact函数,但有诸如 len(substitute(a,b,""))=0 之类的变通方法。

于 2013-08-17T16:12:14.583 回答