Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to get the enums in VBA?

Is there a way to get the enums in VBA? Something like this example for C#, but for VBA?

using System;

class EnumsExampleZ
{
    private enum SiteNames
    {
        SomeSample = 1,
        SomeOtherSample = 2,
        SomeThirdSample = 3
    }

    static void Main()
    {
        Type enumType = typeof(SiteNames);
        string[] enumName = enumType.GetEnumNames();

        for (int i = 0; i < enumName.Length; i++)
        {
            Console.WriteLine(enumName[i]);
        }
    }
}

Lets say we have the following:

Enum FruitType
    Apple = 1
    Orange = 2
    Plum = 3
End Enum

How can we display on the immediate window these:

Apple
Orange
Plum
like image 898
Vityata Avatar asked Jan 10 '17 21:01

Vityata


People also ask

How to use VBA enum in Visual Basic?

Follow the below steps to use VBA Enum: Step 1: In the developer’s tab click on Visual Basic to open VB Editor. Step 2: Insert a new module from the insert tab in the VB Editor. Step 3: Declare the Enum function with an enum name. Step 4: Declare the enum values as follows, Step 5: Now declare a sub-function below the enum function to use the enum.

What is enum in programming language?

ENUM is a short form for enumerations, almost in every programming language we have enumerations some are pre-defined and some are user-defined enumerations, like in VBA Vbnewline is an enumeration and we can make our own enumerations using ENUM statement. We usually declare variables and assign data types to them.

What are enumerations in VBA?

Enumerations create a list of items and make them in a group. For example type of mobiles: “Redmi, Samsung, Apple, Vivo, Oppo”. Using enumerations we can group together all them under a single value. Enum can be used as variables in VBA and it is a numeric variable data type of LONG.

How do you find the value of an enum member?

If an Enum member is not explicitly assigned a value then its value will be inferred by incrementing by 1 from the previous Enum value. The default value for a Long integer is 0, so if 0 is used as an Enum value, the default value for a variable of the Enum type will be that Enum member.


2 Answers

There is no built-in function, though it is easy enough to roll your own in a concrete case:

Enum FruitType
    Apple = 1
    Orange = 2
    Plum = 3
End Enum

Function EnumName(i As Long) As String
    EnumName = Array("Apple","Orange","Plum")(i-1)
End Function

If you have several different enums, you could add a parameter which is the string name of the enum and Select Case on it.

Having said all this, it might possible to do something with scripting the VBA editor, though it is unlikely to be worth it (IMHO).

like image 161
John Coleman Avatar answered Nov 05 '22 03:11

John Coleman


Parsing the VBA code yourself with the VBIDE Extensibility library is going to appear nice & simple at first, and then you're going to hit edge cases and soon realize that you need to actually implement that part of the VBA spec in order to properly and successfully parse every possible way to define an enum in VBA.

I'd go with the simple solution.

That said Rubberduck is doing pretty much exactly that, and exposes an experimental COM API that allows you to enumerate all declarations (and their references) in the VBE, effectively empowering your VBA code with reflection-like capabilities; as of 2.0.11 (the latest release), the code would look something like this:

Public Enum TestEnum
    Foo
    Bar
End Enum

Public Sub ListEnums()
    With New Rubberduck.ParserState
        .Initialize Application.VBE
        .Parse
        Dim item As Variant
        For Each item In .UserDeclarations
            Dim decl As Rubberduck.Declaration
            Set decl = item
            If decl.DeclarationType = DeclarationType_EnumerationMember Then
                Debug.Print decl.ParentDeclaration.Name & "." & decl.Name
            End If
        Next
    End With
End Sub

And in theory would output this:

TestEnum.Foo
TestEnum.Bar

However we (ok, I did) broke something around the 2.0.9 release, so if you try that in 2.0.11 you'll get a runtime error complaining about an invalid cast:

broken experimental API

That should be is an easy fix that we'll patch up by 2.0.12, but note that at that point the API is still experimental and very much subject to change (feature requests are welcome!), so I wouldn't recommend using it for anything other than toy projects.

like image 39
Mathieu Guindon Avatar answered Nov 05 '22 03:11

Mathieu Guindon