2

我第一次写一个stackOverflow问题,所以如果我做错了什么请告诉我。

我现在已经搜索了几个小时,但无法找到解决问题的方法(通常我会找到答案,因此为什么这是我作为潜伏者使用 stackoverflow 几年后的第一个问题)。

基本上,我正在尝试编写一个修改后的 VLOOKUP 函数,该函数的功能类似于 VLOOKUP,除了它返回“下一个较小的较大”值而不是默认的“前一个最大较小”值。不幸的是,我知道索引/匹配方法,我需要手动仔细替换已经存在于我目前正在工作中清理的工作簿中的数千个 VLOOKUP。因此,我求助于编写一个 VLOOKUPnew 函数,这样我就可以用 VLOOKUPnew“查找/替换”所有 VLOOKUP。

Function VLOOKUPnew(lookup_value As Variant, table_array As Range, _
        col_index_num As Integer, Optional exactMatch As Boolean) As Variant
    Dim row As Integer

    Debug.Print table_array.Address

    With Application
        On Error GoTo NO_ROW
        row = .Match(lookup_value, table_array.Columns(1), 0)
        On Error GoTo 0

        If row = -1 And Not exactMatch Then
            row = .Match(lookup_value, table_array.Columns(1), 1)
            row = row + 1
        End If

        VLOOKUPnew = .index(table_array.Columns(col_index_num), row, 0)
    End With

Exit Function

NO_ROW:
    row = -1
    Resume Next
End Function

我成功地编写了这个函数,但遇到了障碍。因为我将“table_array”声明为范围,所以 vba 无法识别对其他工作簿的范围引用

例如 "=VLOOKUPnew($A432,'reallyLongFilepath/[filename.xlsx]tablename'!$B$6:$N$35,columnNumber,0),FALSE)" 解析为 #VALUE 错误

真正奇怪的是,如果我打开文件,则文件路径会从公式中删除(变成只是 "=VLOOKUPnew($A432,'[filename.xlsx]tablename'!$B$6:$N$35,columnNumber,0 ),FALSE)") 然后我的自定义函数可以正常工作,返回正确的值。

所以我的问题是如何解决不必打开其他文件来使用此工作簿的问题。我什至不确定 Excel 如何将地址或范围传递给自定义公式,所以我怀疑当文件路径包含在范围引用中时它会中断。有没有办法拆分文件路径、文件名、工作表和地址(在传入之后)?或者可能将它作为字符串传递然后轻松拆分它?还是将其作为可以正确识别不同工作簿中范围的内容传入?

请记住,我试图避免更改函数的参数,因为我想执行查找/替换技巧,并且这是为了工作,因此对数据布局的过多更改有限制。此外,该工作簿供其他员工使用,我只是将其设置为使用。

提前致谢!

安德鲁

4

1 回答 1

3

你在这里面临着相当的困境!

根本问题是,虽然VLOOKUP可以查看已关闭的工作簿,但不能查看Range参数UDF。范围引用解析为错误,因此函数调用因类型不匹配而失败。如果您将table_array参数类型更改为Variant并在函数头上放置一个断点,您将看到参数值为Error 2036.

虽然有一些方法可以查看已关闭的工作簿,但所有这些(AFAIK)都很慢。既然你提到... I would need to carefully replace literally thousands of VLOOKUPs ...我怀疑这些方面的任何解决方案都会慢得令人无法接受。

我的建议是走这INDEX/MATCH条路,写一个VBA宏来为你更新公式。

于 2012-09-21T06:04:02.787 回答