Excel 有没有办法对VBA枚举中的元素进行计数?
在VBA中是否有正确的方法来计算枚举的元素数? 目前,我在下面的示例中留下了一个枚举值,例如Excel 有没有办法对VBA枚举中的元素进行计数?,excel,vba,enums,Excel,Vba,Enums,在VBA中是否有正确的方法来计算枚举的元素数? 目前,我在下面的示例中留下了一个枚举值,例如KeepThisOneHere Enum TestEnum ValueA ValueB ValueC KeepThisOneHere End Enum 我使用最后一个值来知道大小。。。我不喜欢这个解决方案,因为我不确定我是否能保证值总是以相同的方式索引,并且代码可能会被第三方更改,第三方可能会在最后一个特殊的值之后添加值,悄悄地破坏代码的其余部分。无法获得计数 您需要做的是循环遍
KeepThisOneHere
Enum TestEnum
ValueA
ValueB
ValueC
KeepThisOneHere
End Enum
我使用最后一个值来知道大小。。。我不喜欢这个解决方案,因为我不确定我是否能保证值总是以相同的方式索引,并且代码可能会被第三方更改,第三方可能会在最后一个特殊的值之后添加值,悄悄地破坏代码的其余部分。无法获得计数 您需要做的是循环遍历枚举的元素,直到找到最后一个元素
Chip Pearson有一些关于枚举常量的好建议:这里的礼仪不太清楚,所以我会发布它,如果有人建议,我会回来删除它。Chip Pearson在代码框架论坛()上发布了此代码。我的机器上没有TypeLinfo DLL,所以我无法测试它(我相信谷歌会找到下载TLBINF32.DLL的地方)。尽管如此,以下是他的全部帖子,以避免其他人注册论坛: 只有在计算机上安装了TypeLibInfo DLL时,才能执行此操作 电脑。在VBA中,转到“工具”菜单,选择“参照”,然后滚动 下至“类型库信息”。如果此项存在,请检查它。如果没有 存在,然后停止阅读,因为你不能做你想做的事。这个 所需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
利用这些知识,您可以创建两个有用的函数。枚举名称
返回一个字符串数组,其中包含
枚举:
您可以使用以下代码调用此函数:
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
您还可以创建一个函数来测试是否为
枚举:
如果为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
诚恳地,
奇普·皮尔森
微软MVP 1998-2010
皮尔逊软件咨询有限责任公司
www.cpearson.com
[网站上的电子邮件]以下是我的解决方案示例,非常简单:
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
'...
但请注意,如果您使用的是基于一的枚举,则可能需要调整_结束值定义,具体取决于您使用它的方式。此外,对于基于零的枚举,_结束值与其项计数不同。而且,如果在末尾添加项,则必须相应地更新_end值的定义。最后,如果您的枚举是一个非连续的值范围,则使用此方法将取消所有赌注 如果您知道设计时的枚举类型,则可以将它们转换为
静态属性Get MyEnumColl()as Collection…
(无需类,在第一次访问时静态初始化)这样就可以很容易地循环它们或像图中所示那样计算它们在我看来,这是为了从Excel类型信息中提取数据而设计的,它适用于Excel类型,但不适用于用户定义的类型。tlbinf32.dll不是TLI.tliaapplication的唯一来源。如果您有Visual Studio,它附带了vstlbinf.dll,但需要手动注册。我在64位windows 8.1上运行VS 2012,通过从管理员启动的cmd提示符运行这些命令来实现这一点:cd C:\Program Files(x86)\Microsoft Visual Studio 10.0\Common7\IDE regsvr32 vstlbinf.dll即使在那时脚本对我来说也不是“本机”运行的,但如果我从32位cmd窗口运行cscript命令,它就可以正常运行,您可以使用C:\Windows\SysWOW64\cmd.exe启动此行:Set-TLILibInfo=New-TLI.TypeLibInfo
是多余的。每次使用它时,您都会在下一行中指定一个全新的对象。有一个建议-我会做与您相同的事情,但实际上我会命名第一个和最后一个枚举[\u first]
和[\u last]
。VBA在intellisense下拉列表中隐藏以下划线开头的枚举,因此您不必正常查看它们,但仍然可以通过FileSpecFields引用它们。[[u First]
<代码>headers.lastItem-headers.frstItem+1。仅当枚举值连续且顺序递增时,此选项才有效。
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
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
'...
Sub count()
Dim n, c
For n = headers.frstItem To headers.lastItem
c = c + 1
Next
Debug.Print c
End Sub