在Excel VBA中,如何在MATCH函数中替换局部变量来代替硬编码值?

问题描述 投票:1回答:2

我写了一些VBA代码,循环遍历开放式Excel数据表的行,执行Evaluate(Index(Match))语句,我在网上找到,在第二个Excel工作簿中搜索2个值(LastName和LabCat)。结果(FirstName)从第二个Excel工作簿返回并存储在本地变量中。我通过以下语句成功返回了我正在寻找的值:

strFirstName = Evaluate("INDEX('[MyMatrix.xlsm]MySheet'!$C$2:$C$1000,MATCH(""Cain""&""ABO1"",'[MyMatrix.xlsm]MySheet'!$B$2:$B$1000&'[MyMatrix.xlsm]MySheet'!$H$2:$H$1000,0))")

但我无法解决的是如何用局部变量替换硬编码值,例如这句话(我用变量strLastName替换字符串“cain”,并用变量替换字符串“ABO1”) strLabCat):

strFirstName = Evaluate("INDEX('[MyMatrix.xlsm]MySheet'!$C$2:$C$1000,MATCH(""strLastName""&""strLabCat"",'[MyMatrix.xlsm]MySheet'!$B$2:$B$1000&'[MyMatrix.xlsm]MySheet'!$H$2:$H$1000,0))")

此语句将“Error 2042”返回到strFirstName。

excel-vba match vba excel
2个回答
0
投票

你几乎拥有它,但很容易混淆你在字符串中需要的所有“”双“”引号,以便为字符串的值赋予“双引号”。

根据您的具体示例,如果成功:

strFirstName = Evaluate("INDEX('[MyMatrix.xlsm]MySheet'!$C$2:$C$1000,MATCH(""Cain""&""ABO1"",'[MyMatrix.xlsm]MySheet'!$B$2:$B$1000&'[MyMatrix.xlsm]MySheet'!$H$2:$H$1000,0))")

...但是,您想要从问题中所述的字符串变量中获取值,而不是硬编码CainAB01,将行更改为:

strFirstName = Evaluate("INDEX('[MyMatrix.xlsm]MySheet'!$C$2:$C$1000,MATCH(""" & strLastName & """&""" & strLabCat & """,'[MyMatrix.xlsm]MySheet'!$B$2:$B$1000&'[MyMatrix.xlsm]MySheet'!$H$2:$H$1000,0))")

备份一下,考虑以下简单的字符串示例分配给变量:

Option Explicit

Sub varTest1()
    Dim myGreeting As String
    myGreeting = "Hello, My name is Juan and I live in Mexico"
    MsgBox myGreeting
End Sub

运行此子例程会弹出一条消息,其中包含来自Juan的问候语。非常基本,但请注意:

  • 该变量是显式声明的。它可以在没有As String部分的情况下工作,但总是指定数据类型是很好的编码实践。
  • 我使用了可选语句Option Explicit。如果使用,它必须是模块中的第一行,并且每个模块只出现一次。通过在编译期间或代码执行之前生成“pickier”错误,强制您通过生成“pickier”错误来强制您声明所有变量并正确处理对象。为什么你想要更多的错误?现在比[意外]更好,并且强烈建议新编码员和/或进行故障排除。

接下来,让我们用另一个变量替换Juan的硬编码名称。

还是很简单,像这样:

Sub varTest2()
    Dim myGreeting As String, myName As String
    myName = "Juan"
    myGreeting = "Hello, My name is " & myName & " and I live in Mexico"
    MsgBox myGreeting
End Sub

基本上你只是concatenating a string。加号符号+用于将字符串或数字加在一起,但同样,最佳做法是坚持使用专门用于字符串的字符串,即&符号&

让我们再次添加另一个变量:

Sub varTest3()
    Dim myGreeting As String, myName As String, myCountry As String
    myName = "Juan"
    myCountry = "Mexico"
    myGreeting = "Hello, My name is " & myName & " and I live in " & myCountry
    MsgBox myGreeting
End Sub

与#2相同的想法;我添加示例#2的原因是为了证明如果变量位于字符串的末尾,则不需要额外的"引用。

但是,如果我们想在句子结尾处有​​一段句子,那么该行看起来像:

    myGreeting = "Hello, My name is " & myName & " and I live in " & myCountry & "."

请注意,所有上述示例都具有相同的结果。


在字符串中添加双引号:

这是"双引号可能会有点混乱的地方,因为它们需要围绕您分配给字符串的文本,但我们如何将它们放在字符串中呢?那么有几种方法。

再次备份,我们可以在名称周围添加单引号',如下所示:

    myGreeting = "Hello, My name is 'Juan' and I live in Mexico."

...而字符串将包含:

您好,我的名字是'Juan',我住在墨西哥。

...但是如果我们想要使用双引号"在字符串中出于美观的原因(例如这些示例),或者出于强制性原因(如公式中的要求)(我的示例),我们可以执行以下两项操作之一:

  • 使用"字符代码34添加ASCII符号.VBA中的函数将是Chr(34)和工作表函数CHAR(34)
  • 或者,每次我们想要一个"双引号,我们一起使用两个双引号""(或我称之为四引号。)

例如,硬编码:

Sub varTest4()
    Dim myGreeting As String
    myGreeting = "Hello, My name is ""Juan"" and I live in Mexico."
    MsgBox myGreeting
End Sub

这将显示一个弹出消息框,显示:

您好,我的名字是“胡安”,我住在墨西哥

或者,我们可以再次使用带有名称的变量和围绕它的双引号:

Sub varTest5()
    Dim myGreeting As String, myName As String
    myName = """Juan"""
    myGreeting = "Hello, My name is " & myName & " and I live in Mexico"
    MsgBox myGreeting
End Sub

...将产生与前一个例子相同的结果(#4)。

或者我们可以添加双引号到myGreeting而不是通过myName:\

Sub varTest6()
    Dim myGreeting As String, myName As String
    myName = "Juan"
    myGreeting = "Hello, My name is """ & myName & """ and I live in Mexico"
    MsgBox myGreeting
End Sub

......我们将再次获得与上述完全相同的结果。

并且,为了演示如果我们想要名称和国家/地区的双引号会是什么样子(因此在字符串的最末端出现双引号):

Sub varTest7()
    Dim myGreeting As String, myName As String, myCountry As String
    myName = "Juan"
    myCountry = "Mexico"
    myGreeting = "Hello, My name is """ & myName & """ and I live in """ & myCountry & """"
    MsgBox myGreeting
End Sub

至少有几种方法可以在字符串中添加双引号:

  • 使用上面的""“quad-quote”,或者,
  • 使用ASCII字符代码(双引号为34)。

...因为有时所有这些过多的引用都会让人感到困惑。

例如,要显示三个双引号,如下所示:

"""

我需要使用:

MsgBox """"""""

...这是八个双引号:一个用于开始字符串,一个用于结束字符串,另外三个用于显示每个字符串。 (这会被称为Octo-quote?!)

我们可以显示这个:

"Juan"

有:

MsgBox """Juan"""

...或完全相同的结果(但在我的脑海里有点清洁):

MsgBox Chr(34) & "Juan" & Chr(34)

...因此改变示例#7中的行,这:

myGreeting = "Hello, My name is " & Chr(34) & myName & Chr(34) & _
    " and I live in " & Chr(34) &  myCountry & Chr(34)

......会产生与例子#7相同的结果:

您好,我的名字是“胡安”,我住在“墨西哥”


最后,还有一个想法来自你的问题的例子,关于清晰与混乱的字符串。您可以使用下划线_作为“行继续符号”将多行代码分解为多行,使其更易于在VBA编辑器(VBE)中读取,以及其他人读取或复制/在这样的网站上发布代码时粘贴!

例如,我对您的代码行的“更正”是:

strFirstName = Evaluate("INDEX('[MyMatrix.xlsm]MySheet'!$C$2:$C$1000,MATCH(""" & strLastName & """&""" & strLabCat & """,'[MyMatrix.xlsm]MySheet'!$B$2:$B$1000&'[MyMatrix.xlsm]MySheet'!$H$2:$H$1000,0))")

......一条loooong线(他们可以得到much loooonger!)

在我解释引号之前,我不想让我的原始响应更加混乱我添加额外的符号,但是编写冗长行的“更干净”是在下一行的任何地方添加下划线,如下所示:

 strFirstName = Evaluate("INDEX('[MyMatrix.xlsm]MySheet'!$C$2:$C$1000, " & _
    "MATCH(""" & strLastName & """&""" & strLabCat & """,'[MyMatrix.xlsm]" & _
    "MySheet'!$B$2:$B$1000'[MyMatrix.xlsm]MySheet'!$H$2:$H$1000,0))")

您不必在VBE中向右滚动以查看代码,并注意Stack Overflow如何不必添加水平滚动条。

像泥一样清楚? :-)

祝好运! (而且你的问题也是很好的问题。欢迎,顺便说一下!)

Further info on:


1
投票

有时使用令牌替换方法比尝试进行多串连接更容易。

Ef。:

Dim sht As Worksheet, f, strFirstName

Set sht = Workbooks("MyMatrix.xlsm").Worksheets("MySheet")

f = "INDEX($C$2:$C$1000,MATCH(""{LastName}""&""{LabCat}"",$B$2:$B$1000&$H$2:$H$1000,0))"
f = Replace(f, "{LastName}", "Cain")
f = Replace(f, "{LabCat}", "AB01")

strFirstName = sht.Evaluate(f) '<< note using the Worksheet.Evaluate form here
© www.soinside.com 2019 - 2024. All rights reserved.