6

有没有一种正确的方法来计算 VBA 中枚举的元素?目前,我留下一个枚举值,KeepThisOneHere如下例所示

Enum TestEnum
   ValueA
   ValueB
   ValueC
   KeepThisOneHere
End Enum

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

4

5 回答 5

5

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

只有在您的计算机上安装了 TypeLibInfo DLL 时,您才能执行此操作。在 VBA 中,转到 Tools 菜单,选择 References,然后向下滚动到“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

如果为 EnumGroupName 定义了值,则此函数返回 True,如果未定义,则返回 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

诚挚的,Chip Pearson Microsoft MVP 1998 - 2010 Pearson Software Consulting, LLC www.cpearson.com [网站上的电子邮件]

于 2013-04-24T14:16:04.567 回答
2

这是我的解决方法的一个示例,非常简单:

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 值定义,具体取决于您使用它的方式。此外,对于从零开始的枚举,_End 值与其项目数不同。而且,如果您在最后添加项目,则必须相应地更新 _End 值的定义。最后,如果你的枚举是一个不连续的值范围,那么所有的赌注都是用这种方法!

于 2016-06-08T19:35:16.593 回答
1

没有办法得到计数。

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

Chip Pearson 对枚举常量有一些很好的提示:Chip Pearson: Enum Variable Type

于 2013-04-24T13:58:38.107 回答
0

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

于 2019-06-18T09:56:45.033 回答
-1
Sub count()
    Dim n, c

    For n = headers.frstItem To headers.lastItem
        c = c + 1
    Next
    Debug.Print c
End Sub
于 2021-02-05T19:27:56.607 回答