VBA中的指数匹配范围(根据贷款编号和日期查找贷款余额)

时间:2013-08-16 21:21:11

标签: excel vba indexing match named-ranges

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

Excel / VBA - Index Match function using Dynamic Ranges

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

----------------- RANGE DEFINITIONS ---------------------------- ---------------------------------------------

关于代码:Cantidad,ID和Fecha是以下列方式定义的dymanic范围:

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

1 个答案:

答案 0 :(得分:0)

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

  1. 公式字符串中的右括号... {4} ,{5} ......
  2. 您的名称定义中的一个点前面的点(Set ID = .Range)
  3. 但我认为你可能想要对事情略有不同。如果要在工作表函数中定义要在工作表函数中使用的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 函数缺失,但有一些变通办法(替换(a,b, “”))= 0。