VBA: 传递多个值给 Instr
VBA: Passing multiple values to Instr
现在我有一长串 "Industry" 用户通过表单提交的值。我编写了一个宏,它将在这些值中搜索特定术语并粘贴符合我的"acceptable" 行业值列表的值。重点是将用户提交的所有当前行业价值重新分类到我现有的分类法中。这是我的 If-Then 语句现在的样子:
If InStr(1, Cells(i, "A").Value, "Energy") > 0 Or InStr(1, Cells(i, "A").Value, "Electricity") > 0 Or InStr(1, Cells(i, "A").Value, "Gas") > 0 Or InStr(1, Cells(i, "A").Value, "Utilit") > 0 Then
Cells(i, "B").Value = "Energy & Utilities"
End If
真难看。工作得很好,但读起来很费劲。我的宏中充斥着这些难以理解的 If-Then 语句,很难通读一遍。有没有办法将多个值传递给 Instr
的 "String2" 参数?
无法将多个参数传递给 InStr,但您可以创建自己的子程序来处理它。我会创建一个 sub,它接受要查找的字符串和要搜索的字符串数组。然后它可以遍历数组并为每个字符串调用 InStr。让它 return 得到它是否找到所有这些的最终结果,然后用对你的 sub 的一次调用替换你所有丑陋的条件语句。
If Instr(1, Cells(i, "A").Value, "EnergyElectricityGasUtilit") > 0 Then
Cells(i, "B").Value = "Energy & Utilities"
[On Edit:我修改了函数,如果最后一个参数是整数,它就扮演 Instr
中的 compareMode
参数的角色(0 表示区分大小写搜索,这是默认值,1 表示不区分大小写)。作为最后的调整,您还可以为可选的最终参数传递布尔值而不是整数,其中 True
对应于不区分大小写,False
对应于默认的区分大小写]
如果你经常做这类事情,那么编写一个类似于 inStr
但可以处理多种模式的函数是有意义的。 ParamArray
是一个自然而然的工具:
Function Contains(str As String, ParamArray args()) As Boolean
Dim i As Long, n As Long, mode As Integer
n = UBound(args)
If TypeName(args(n)) <> "String" Then
mode = args(n)
mode = Abs(mode) 'So True => -1 => 1 for case-insensitive search
n = n - 1
End If
For i = 0 To n
If InStr(1, str, args(i), mode) > 0 Then
Contains = True
Exit Function
End If
Next i
Contains = False
End Function
测试如下:
Sub Test()
Debug.Print Contains("General Electric", "Gas", "Electric", "Oil")
Debug.Print Contains("General electric", "Gas", "Electric", "Oil")
Debug.Print Contains("General electric", "Gas", "Electric", "Oil", False)
Debug.Print Contains("General electric", "Gas", "Electric", "Oil", True)
Debug.Print Contains("General electric", "Gas", "Electric", "Oil", 1)
Debug.Print Contains("General Motors", "Gas", "Electric", "Oil")
End Sub
输出:
True
False
False
True
True
False
现在我有一长串 "Industry" 用户通过表单提交的值。我编写了一个宏,它将在这些值中搜索特定术语并粘贴符合我的"acceptable" 行业值列表的值。重点是将用户提交的所有当前行业价值重新分类到我现有的分类法中。这是我的 If-Then 语句现在的样子:
If InStr(1, Cells(i, "A").Value, "Energy") > 0 Or InStr(1, Cells(i, "A").Value, "Electricity") > 0 Or InStr(1, Cells(i, "A").Value, "Gas") > 0 Or InStr(1, Cells(i, "A").Value, "Utilit") > 0 Then
Cells(i, "B").Value = "Energy & Utilities"
End If
真难看。工作得很好,但读起来很费劲。我的宏中充斥着这些难以理解的 If-Then 语句,很难通读一遍。有没有办法将多个值传递给 Instr
的 "String2" 参数?
无法将多个参数传递给 InStr,但您可以创建自己的子程序来处理它。我会创建一个 sub,它接受要查找的字符串和要搜索的字符串数组。然后它可以遍历数组并为每个字符串调用 InStr。让它 return 得到它是否找到所有这些的最终结果,然后用对你的 sub 的一次调用替换你所有丑陋的条件语句。
If Instr(1, Cells(i, "A").Value, "EnergyElectricityGasUtilit") > 0 Then
Cells(i, "B").Value = "Energy & Utilities"
[On Edit:我修改了函数,如果最后一个参数是整数,它就扮演 Instr
中的 compareMode
参数的角色(0 表示区分大小写搜索,这是默认值,1 表示不区分大小写)。作为最后的调整,您还可以为可选的最终参数传递布尔值而不是整数,其中 True
对应于不区分大小写,False
对应于默认的区分大小写]
如果你经常做这类事情,那么编写一个类似于 inStr
但可以处理多种模式的函数是有意义的。 ParamArray
是一个自然而然的工具:
Function Contains(str As String, ParamArray args()) As Boolean
Dim i As Long, n As Long, mode As Integer
n = UBound(args)
If TypeName(args(n)) <> "String" Then
mode = args(n)
mode = Abs(mode) 'So True => -1 => 1 for case-insensitive search
n = n - 1
End If
For i = 0 To n
If InStr(1, str, args(i), mode) > 0 Then
Contains = True
Exit Function
End If
Next i
Contains = False
End Function
测试如下:
Sub Test()
Debug.Print Contains("General Electric", "Gas", "Electric", "Oil")
Debug.Print Contains("General electric", "Gas", "Electric", "Oil")
Debug.Print Contains("General electric", "Gas", "Electric", "Oil", False)
Debug.Print Contains("General electric", "Gas", "Electric", "Oil", True)
Debug.Print Contains("General electric", "Gas", "Electric", "Oil", 1)
Debug.Print Contains("General Motors", "Gas", "Electric", "Oil")
End Sub
输出:
True
False
False
True
True
False