是否有一种方法来计算VBA枚举中的元素



是否有正确的方法来计算VBA中枚举的元素?现在,我在下面的示例

中留下一个枚举值,如KeepThisOneHere
Enum TestEnum
   ValueA
   ValueB
   ValueC
   KeepThisOneHere
End Enum

我使用最后一个值来知道大小…我不喜欢这个解决方案,因为我不确定我能保证值总是以相同的方式索引,代码可能会被第三方更改,他们可能会在最后一个特殊的值之后添加值,默默地破坏其余的代码。

我不确定这里的礼仪,所以我把它贴出来,如果有人建议,我会回来删除它。Chip Pearson在code Cage论坛(http://www.thecodecage.com/forumz/microsoft-excel-forum/170961-loop-enumeration-constants.html)上发布了这个代码。我的机器上没有TypeLinInfo DLL,所以我无法测试它(我相信谷歌会找到下载TLBINF32.dll的地方)。尽管如此,这里是他的整个帖子,以避免其他人注册论坛:

你可以这样做只有当你有TypeLibInfo DLL安装在你的电脑。在VBA中,转到工具菜单,选择参考,然后滚动到"TypeLib Info"。如果存在,请检查。如果没有存在,然后停止阅读,因为你不能做你想做的事。的您需要的DLL文件名为TLBINF32.dll.

下面的代码展示了如何获取控件中的名称和值XLYesNoGuess枚举:

Sub AAA()
    Dim TLIApp As TLI.TLIApplication
    Dim TLILibInfo As TLI.TypeLibInfo
    Dim MemInfo As TLI.MemberInfo
    Dim N As Long
    Dim S As String
    Dim ConstName As String
    Set TLIApp = New TLI.TLIApplication
    Set TLILibInfo = New TLI.TypeLibInfo
    Set TLILibInfo = TLIApp.TypeLibInfoFromFile( _
        ThisWorkbook.VBProject.References("EXCEL").FullPath)
    ConstName = "XLYesNoGuess"
    For Each MemInfo In _
        TLILibInfo.Constants.NamedItem(ConstName).Members
        S = MemInfo.Name
        N = MemInfo.Value
        Debug.Print S, CStr(N)
    Next MemInfo
End Sub
使用这些知识,您可以创建两个有用的函数。EnumNames对象中值的名称的字符串数组枚举:
Function EnumNames(EnumGroupName As String) As String()
    Dim TLIApp As TLI.TLIApplication
    Dim TLILibInfo As TLI.TypeLibInfo
    Dim MemInfo As TLI.MemberInfo
    Dim Arr() As String
    Dim Ndx As Long
    Set TLIApp = New TLI.TLIApplication
    Set TLILibInfo = New TLI.TypeLibInfo
    Set TLILibInfo = TLIApp.TypeLibInfoFromFile( _
        ThisWorkbook.VBProject.References("EXCEL").FullPath)
    On Error Resume Next
    With TLILibInfo.Constants.NamedItem(EnumGroupName)
        ReDim Arr(1 To .Members.Count)
        For Each MemInfo In .Members
            Ndx = Ndx + 1
            Arr(Ndx) = MemInfo.Name
        Next MemInfo
    End With
    EnumNames = Arr
End Function

你可以用下面的代码来调用这个函数:

Sub ZZZ()
    Dim Arr() As String
    Dim N As Long
    Arr = EnumNames("XLYesNoGuess")
    For N = LBound(Arr) To UBound(Arr)
        Debug.Print Arr(N)
    Next N
End Sub

还可以创建一个函数来测试是否为对象定义了一个值枚举:

Function IsValidValue(EnumGroupName As String, Value As Long) As
    Boolean
    Dim TLIApp As TLI.TLIApplication
    Dim TLILibInfo As TLI.TypeLibInfo
    Dim MemInfo As TLI.MemberInfo
    Dim Ndx As Long
    Set TLIApp = New TLI.TLIApplication
    Set TLILibInfo = New TLI.TypeLibInfo
    Set TLILibInfo = TLIApp.TypeLibInfoFromFile( _
        ThisWorkbook.VBProject.References("EXCEL").FullPath)
    On Error Resume Next
    With TLILibInfo.Constants.NamedItem(EnumGroupName)
        For Ndx = 1 To .Members.Count
            If .Members(Ndx).Value = Value Then
                IsValidValue = True
                Exit Function
            End If
        Next Ndx
    End With
    IsValidValue = False
End Function

如果Value定义为EnumGroupName或如果没有定义,则为False。您可以用代码调用这个函数例如:

Sub ABC()
    Dim B As Boolean
    B = IsValidValue("XLYesNoGuess", xlYes)
    Debug.Print B ' True for xlYes
    B = IsValidValue("XLYesNoGuess", 12345)
    Debug.Print B ' False for 12345
End Sub

热忱,芯片皮尔森微软MVP 1998 - 2010皮尔森软件咨询有限责任公司www.cpearson.com[email on web site]

这是我的变通方法的一个例子,非常简单:

Enum FileSpecFields
    FileSpecFields_Start                    '(zero-based)
        FileNameIdx = FileSpecFields_Start
        FolderNameIdx
        BasePathIdx
        FullPathIdx
        CopyStatus
    FileSpecFields_End = CopyStatus
End Enum
'...
ReDim FileSpecList(1 To MaxFiles, FileSpecFields_Start To FileSpecFields_End) As String
'...

但是请注意,如果您使用的是基于1的Enum,则可能必须调整_End值定义,这取决于您如何使用它。此外,对于从零开始的enum, _End值与它的项目计数不相同。而且,如果在末尾添加项,则必须相应地更新_End值的定义。最后,如果枚举是一个不连续的值范围,那么使用这种方法所有的赌注都是无效的!

没有办法获得计数。

你要做的就是循环遍历Enum的元素,直到到达最后一个。

Chip Pearson有一些关于枚举常量的好技巧:Chip Pearson: Enum变量类型

如果您在设计时知道枚举类型,您可以将它们转换为 Static Property Get MyEnumColl() as Collection ... (不需要类,在第一次访问时静态初始化),从而轻松地遍历它们或计数,如下所示

Sub count()
    Dim n, c
    For n = headers.frstItem To headers.lastItem
        c = c + 1
    Next
    Debug.Print c
End Sub

最新更新