Vba 检查值是否为列表的成员 我必须对照项目列表检查一段用户输入;如果输入在项目列表中,则将流程定向为单向。如果没有,则将流引导到另一个 此列表在工作表本身上不可见;必须在代码下对其进行模糊处理
我想到了两种策略:Vba 检查值是否为列表的成员 我必须对照项目列表检查一段用户输入;如果输入在项目列表中,则将流程定向为单向。如果没有,则将流引导到另一个 此列表在工作表本身上不可见;必须在代码下对其进行模糊处理,vba,excel,Vba,Excel,我想到了两种策略: 声明为enum并检查输入是否是该enum的一部分,尽管我不确定其语法-是否每次使用该enum时都需要初始化它 声明为数组并检查输入是否是该数组的一部分 我想知道VBA在效率和可读性方面哪个更好?与.NET语言不同,VBA不将枚举公开为文本。严格来说,它是一个数字,并且没有任何.ToString()方法会公开枚举的名称。可以创建自己的ToString()方法并返回枚举的字符串表示形式。也有可能。尽管一切都是可以实现的,但我不建议这样做,因为对于这样一项任务来说,事情过于复杂了
enum
并检查输入是否是该enum
的一部分,尽管我不确定其语法-是否每次使用该enum
时都需要初始化它我想知道VBA在效率和可读性方面哪个更好?与.NET语言不同,VBA不将枚举公开为文本。严格来说,它是一个数字,并且没有任何
.ToString()
方法会公开枚举的名称。可以创建自己的ToString()
方法并返回枚举的字符串表示形式。也有可能。尽管一切都是可以实现的,但我不建议这样做,因为对于这样一项任务来说,事情过于复杂了
您可以创建一个项目的字典集合,然后简单地使用Exist
方法和某种错误处理(或简单的if/else语句)来检查列表中是否存在输入框中的任何用户输入
例如:
Sub Main()
Dim myList As Object
Set myList = CreateObject("Scripting.Dictionary")
myList.Add "item1", 1
myList.Add "item2", 2
myList.Add "item3", 3
Dim userInput As String
userInput = InputBox("Type something:")
If myList.Exists(userInput) Then
MsgBox userInput & " exists in the list"
Else
MsgBox userInput & " does not exist in the list"
End If
End Sub
注意:如果您添加对Microsoft脚本运行时
库的引用,则您将能够使用intelli sense和myList
对象,因为它将在早期绑定
Dim myList As Object
Set myList = CreateObject("Scripting.Dictionary")
与
这取决于你想走哪条路,什么更方便。请注意,如果使用后期绑定,则不需要添加引用,而如果希望使用intelli sense进行早期绑定,则需要添加引用
为了让读者能够可视化使用Enum的版本,让我演示一下这个机制是如何工作的
Enum EList
item1
item2
item3
[_Min] = item1
[_Max] = item3
End Enum
Function ToString(eItem As EList) As String
Select Case eItem
Case EList.item1
ToString = "item1"
Case EList.item2
ToString = "item2"
Case EList.item3
ToString = "item3"
End Select
End Function
Function Exists(userInput As String) As Boolean
Dim i As EList
For i = EList.[_Min] To EList.[_Max]
If userInput = ToString(i) Then
Exists = True
Exit Function
End If
Next
Exists = False
End Function
Sub Main()
Dim userInput As String
userInput = InputBox("type something:")
MsgBox Exists(userInput)
End Sub
首先,将您的列表声明为Enum。为了使示例尽可能简单,我只添加了3项[\u Min]
和[\u Max]
指示枚举的最小值和最大值(可以对此进行调整,但现在让我们保持简单)。您声明它们都可以在EList
上迭代
ToString()
方法返回枚举的字符串表示形式。任何VBA开发人员都会在某个时候意识到,VBA缺少这一内置功能太糟糕了。不管怎样,您现在已经有了自己的实现
Exists
获取userInput
存储的任何内容,并在枚举中迭代EList
以匹配枚举的字符串表示形式。这太过分了,因为您需要调用许多方法并在枚举上循环,以便能够一次性实现简单的字典存在的方法。这就是为什么我不建议针对您的特定问题使用枚举的主要原因
最后是Main
sub,它简单地收集用户的输入并调用Exists
方法。它显示一个带有true
或false
的消息框,指示字符串是否以枚举类型存在。您可以运行一个简单的数组测试,如下所示,将单词添加到单个列表中:
Sub Main1()
arrList = Array("cat", "dog", "dogfish", "mouse")
Debug.Print "dog", Test("dog") 'True
Debug.Print "horse", Test("horse") 'False
End Sub
Function Test(strIn As String) As Boolean
Test = Not (IsError(Application.Match(strIn, arrList, 0)))
End Function
或者,如果您想进行更详细的搜索并返回子字符串匹配列表以供进一步工作,请使用过滤器。如果查找dog
狗,狗鱼
在这种特殊情况下,代码会检查是否与狗
完全匹配
Sub Main2()
arrList = Array("cat", "dog", "dogfish", "mouse")
Debug.Print "dog", Test1("dog")
Debug.Print "horse", Test1("horse")
End Sub
Function Test1(strIn As String) As Boolean
Dim vFilter
Dim lngCnt As Long
vFilter = Filter(arrList, strIn, True)
For lngCnt = 0 To UBound(vFilter)
If vFilter(lngCnt) = strIn Then
Test1 = True
Exit For
End If
Next
End Function
只需在列表中使用选择案例
:
Select Case entry
Case item1,item2, ite3,item4 ' add up to limit for Case, add more Case if limit exceeded
do stuff for being in the list
Case Else
do stuff for not being in list
End Select
我怎么了,是我错过了什么,还是你的医生:
很奇怪?如果字典中不存在用户输入,myList.Exists(userInput)
只返回false
,并且没有错误触发geredyoure right@simoco发布之前我没有测试代码,忽略了这一点。已经用更简单的答案更新了答案approach@mehowOn似乎表明枚举可以是字符串,否?@SchwitJanwityanujit您正在查看的是Visual Basic引用,而不是VBA,这两种引用不同。@SchwitJanwityanujit我想您已经有了txt文件或Excel中可用的列表了?-我将直接将其作为数组使用。像我这样一行一行地编一本字典是不现实的。不,清单就在一张纸上!好吧,这是一个惊喜:)然后我仍然会用数组将它们添加到一个代码行中,而不是为每个新项目添加一行新代码。很好的答案,但为时已晚——我已经在字典中手动添加了大约100个项目:(.当然,除了所有的手工工作之外,解决方案没有任何问题。将它们存储在数组中是个好主意。稍微修改一下代码,将列表存储在一个带有分隔符的变量中,然后使用Split
创建您的数组用于恢复这篇旧文章,但我想知道我是谁thod(在字典和数组之间)将是最有效、更快的方法。同样在数组中,使用应用程序。Match
比在数组中循环快吗?感谢回答我自己的问题,我发现使用Match()
函数实际上比仅仅迭代(循环)慢得多通过数组。我使用大小为2000的数组进行了测试。在数组中循环的最坏情况是查找最后一项(在索引2000处)。调用Match()
函数和循环5000次后,Match()的总时间
was3.746094
但仅1.667969
用于在数组中循环。这不提供问题的答案。对
Select Case entry
Case item1,item2, ite3,item4 ' add up to limit for Case, add more Case if limit exceeded
do stuff for being in the list
Case Else
do stuff for not being in list
End Select