我正在编写一些VBA函数用于工作并遇到了一个应该很容易解决的问题,但不管怎么说我都无法解决,尽管我在Google和Google上找到答案的最佳尝试。我写了一个函数,它应该给我一列中两个字符串之间的范围:
Function FindRng(StartRng As String, EndRng As String) As Variant
Dim TopOfRange As Single
Dim BottomOfRange As Single
TopOfRange = WorksheetFunction.Match(StartRng, Sheets("InfCom").Range("B:B"), 0)
BottomOfRange = WorksheetFunction.Match(EndRng, Sheets("InfCom").Range("B:B"), 0)
FindRng = Range(Sheets("InfCom").Cells(TopOfRange, 2), Sheets("InfCom").Cells(BottomOfRange, 2))
End Function
因此,如果输入A和B在行100和105上,则应返回B100:B105。当我通过调整代码来读取FindRng = Range(...)。地址来测试时,我确实得到$ B $ 100:$ B $ 105。
然而,当我将FindRng的结果输入到自定义的索引匹配函数中时,我收到错误。功能如下:
Function subsetPBPC(rngReturn As Range, LookupValueH As Variant, TopOfRange As String, BottomOfRange As String, LookupValueV As Variant) As Variant
subsetPBPC = sPBPC(rngReturn, LookupValueH, FindRng(TopOfRange, BottomOfRange), LookupValueV)
End Function
问题在于它似乎不是将FindRng的输出读作范围,而是作为该范围的内容:当我在另一个公式中嵌入的FindRng上使用Evaluate Formula工具时,它将FindRng的输出显示为{ A,B,C,D,E}而不是$ B $ 100:$ B $ 105,其中A到E是范围内单元格的内容。我觉得解决方案非常简单,但我没有看到它。自定义索引匹配功能的基础功能已经过测试,所有功能都像魅力一样。
答案 0 :(得分:2)
设置而不是let。让我们将表达式的值赋给变量。 Set为变量分配对象引用。您希望返回对范围对象的引用,而不是返回范围对象的默认属性生成的值。
在VBA写作中
FindRng = Range(...)
隐含着写
Let FindRng = Range(...)
但是你想要
Set FindRng = Range(...)
编辑1:
理解对象引用和VBA中的值之间的区别非常重要。这与通过值或引用传递参数的概念类似。希望这两个链接有所帮助:
The Let statement on MSDN
The Set statement on MSDN
编辑2:
哦,我想我应该触摸默认属性!像range这样的对象具有默认属性。如果将范围视为值而不是对象,则它使用默认属性而不是抛出错误,因为它是对象而不是值。在范围的情况下,默认属性为Value
。因此,如果您说A = Range("A1")
Let A = Range("A1").Value
,那么您所说的Set A = Range("A1")
就是{{1}}。因此,您将获得单元格A1中包含的值,而不是表示该单元格的范围对象。
答案 1 :(得分:1)
拿起你当前的代码应该
Set
SetRng
作为范围而不是变体 您可以如下简化您的功能(如果您重复调用它可以节省时间)
此外,您可以测试此范围是Nothing
(如果找不到您的两个字符串),而如果缺少任何一个字符串,您当前的代码将会出错。
Function SetRng(str1 As String, str2 As String) As Range
With Sheets("infCom").Columns(2)
Set SetRng = Range(.Find(str1, , xlValues, xlWhole), .Find(str2, , xlValues, xlWhole))
End With
End Function