检查一个值是否是一个列表的成员
- 我必须根据项目列表检查一段用户input; 如果input在项目列表中,则单向指导stream程。 如果不是,将stream量引导到另一个。
- 该列表在工作表本身上不可见; 它必须在代码下被混淆。
我曾想过两个策略来做到这一点:
- 声明为一个
enum
并检查input是否是这个enum
一部分,虽然我不确定在这个语法 – 我需要初始化enum
每次我想要使用它? - 声明为一个数组,并检查input是否是这个数组的一部分。
我想知道VBA在效率和可读性方面更好吗?
与.NET语言不同,VBA不会将Enum作为文本公开。 它严格来说是一个数字,并没有.ToString()
方法,将公开名称的枚举。 可以创build自己的ToString()
方法并返回一个枚举的string表示forms。 枚举Enumtypes也是可能的。 虽然一切都是可以实现的,但是我不会推荐这样做,因为事情太复杂了。
你如何创build一个项目的Dictionary集合,并简单地使用Exist
方法和某种error handling( 或简单的if / else语句 )来检查input框中的任何用户input是否存在于列表中。
例如:
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 Scripting Runtime
库的引用,那么您将能够使用myList
对象的智能感,因为它已经被早期绑定replace
Dim myList As Object Set myList = CreateObject("Scripting.Dictionary")
同
Dim myList as Dictionary Set myList = new Dictionary
这取决于你想要什么方式,什么是更方便。 请注意,如果使用Late Binding,则不需要添加引用,而需要引用的情况下,如果要使用智能检测的Early Binding。
只是为了读者能够使用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个项目,尽可能简单。 [_Min]
和[_Max]
表示枚举的最小值和最大值( 可以调整,但是现在让我们保持简单 )。 你声明它们都能够迭代你的EList
。
ToString()
方法返回Enum的string表示forms。 任何VBA开发人员在某种程度上意识到这是糟糕的VBA缺less这个内置function。 无论如何,你现在已经有了自己的实现。
Exists
获取任何userInput
存储,同时迭代Enum EList
与Enum的String表示EList
匹配。 这是一个矫枉过正,因为你需要调用许多方法,并遍历枚举,以便能够实现一个简单的Dictionary
的Exists
方法一次完成。 这主要是为什么我不会推荐使用枚举为您的具体问题。
然后最后你有Main
子,它简单地收集用户的input并调用Exists
方法。 它显示一个消息框,其中包含true
或false
,表示string是否作为Enumtypes存在。
您可以像下面那样运行一个简单的数组testing,将单词添加到单个列表中:
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
或者,如果您想进行更详细的search,并返回子string匹配列表以供进一步工作,请使用“ Filter
。 如果查找dog
此代码将通过vFilter
返回以下内容
狗,angular鲨
在这个特定的情况下,代码然后检查一个完全匹配的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
与一个列表:
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