Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Enum Question

Status
Not open for further replies.

victoryhighway2

Programmer
Jul 18, 2005
42
US
Hello,

Is there anything that I can use in a conditional statement to refer to ANY member of an enum? Such as:

Code:
Select Case xyzvar

    Case MyEnum.All

End Select

What I'm looking for is to test to see if the value of xyzvar matches any of the member values of the enum MyEnum, without having to explicitly type out all of the member names.

Regards,
Geoffrey
 

It is possible, if I understand you right. Is the enum in tlb?
I am pressed for time so will have to get back tomorrow
 
SBerthod,

No, the enum is in my own code, in a BAS module.

Regards,
Geoffrey
 
This might be helpful to you:
Code:
Enum myEnum
    Red = 0
    Blue = 1
    Green = 2
    Yellow = 3
End Enum

Private Sub Command2_Click()
Dim x As myEnum
Dim i As Integer
x = Green
For i = 0 To 4
    If x = i Then
        MsgBox x
    End If
Next i
End Sub

Bob
 
I'm curious.

The whole point of Enums is to not use "magic numbers", so if the variable xyzvar was not declared as an MyEnum, you have already defeated the purpose.

Is there any reason not to declare xyzvar as MyEnum? It would eliminate the need to check if it is one of the permissable values.



 
>> Is there any reason not to declare xyzvar as MyEnum? It would eliminate the need to check if it is one of the permissable values.

It does not eliminate the need to check it's value. Enums (in my opinon) exist to eliminate "magic numbers". However, a variable declare as an enum is actually a long and can be set to any value that a long allows. For example....

Code:
Option Explicit

Enum myEnum
    Red = 0
    Blue = 1
    Green = 2
    Yellow = 3
End Enum

Private Sub Form_Load()
    
    Dim Blah As myEnum
    
    Blah = Blue
    Blah = 20000
    Blah = 1000000
    
    MsgBox TypeName(Blah)
    
End Sub

When you run this code, you don't get any errors. The message box displays 'long'.



-George

"The great things about standards is that there are so many to choose from." - Fortune Cookie Wisdom
 
Enums are mnemonics, nothing more. An example of a couple of enums that we often use without thinking of them as such (assuming we didn't begin with VB 3) is the MsgBoxStyle and MsgBoxResult enums. The code
Code:
If MsgBox "Hello World", 305 = 2 Then
is exactly the same as
Code:
If MsgBox "Hello World", vbOkCancel + vbExclamation = vbCancel Then
The simple point is that they are easier to remember--mnemonics. The computer evaluates the mnemonic as whatever value it is set to, not having any need of mnemonics. So you can always substitute the numeric value.

Now, George points out that you can set the value of the Enum to any valid long value. So, there may be a need to ensure that the enum is properly set. On the other hand, enums are for programmers, not users. Getting in the habit of using the mnemonic rather than the long value should make it unnecessary to determine whether the value has been set to an allowable number. However, if you need a piece of code that checks this, you can take mine as an example, with some modification:

Code:
Enum myEnum
    Red = 0
    Blue = 1
    Green = 2
    Yellow = 3
End Enum

Private Function CheckValidmyEnum(someMyEnum as myEnum) as Boolean 
Dim i As Integer
For i = 0 To 4
    If someMyEnum = i Then
        CheckValidmyEnum = True
        Exit Function
    End If
Next i
CheckValidmyEnum = False
End Function

Bob
 
Still doesn't help. Enums don't need to be sequentially contiguous. eg

Enum FlagOptions
Opt1 = 1
Opt2 = 2
Opt3 = 4
Opt4 = 8
Opt5 = 16
End Enum
 
I was mistaken, I thought the following would cause an error when the cmdInvalid button would get clicked, but it didn't:

Code:
Private Enum MyStatus
    Ready = 1
    NotReady = 2
End Enum

Private AmIReady As MyStatus

Private Sub cmdInvalid_Click()
    SetStatus 100
End Sub

Private Sub SetStatus(Readiness As MyStatus)
    AmIReady = Readiness
End Sub

So I guess there is code required to catch an invalid value after all.


 

>No, the enum is in my own code, in a BAS module.

If you would consider very simply putting the enums in a activex dll class (globalmultiuse is easiest for this) then we can use the TLIApplication to retrieve the enum names.
 
<Enums don't need to be sequentially contiguous.

Yes, that's true, but I don't believe the OP is asking for code that will evaluate any enum passed to it, rather all the values in a single enum that he gets to define as he wishes. That given, he can simply put his values in sequence. With your layout (which is probably a more common layout--the MsgBox function being an example), I would of course have to come up with a more abstruse solution, along the lines of a bitwise parsing operation.

So, given my understanding of the problem described by the OP, I'm going to continue to assert that my code is a simple solution to it.
 
There are "hidden" Enum values that can be used for validation purposes. Normally one would see these used within a Class to validate Property assignments and such, but this works too:
Code:
Option Explicit

Private Enum Monotonic
    mtnBottom = 0
    mtnLow
    mtnMed
    mtnHigh
    mtnTop
    [_first] = mtnBottom
    [_last] = mtnTop
End Enum

Private Sub Main()
    Dim strInp As String
    Dim strMsg As String
    Dim monValue As Monotonic
    
    Do
        strInp = InputBox(strMsg _
                        & "Enter a monotonic value (Cancel to end)")
        If StrPtr(strInp) <> 0 Then
            If IsNumeric(strInp) Then
                monValue = CLng(strInp)
                If Monotonic.[_first] <= monValue And _
                        monValue <= Monotonic.[_last] Then
                    strMsg = "Eureka!  That's acceptable." _
                           & vbNewLine
                Else
                    strMsg = "Sorry, that value is out of range." _
                           & vbNewLine
                End If
            Else
                strMsg = "Sorry, we want numeric values." & vbNewLine
            End If
        End If
    Loop Until StrPtr(strInp) = 0
End Sub
 
>If you would consider very simply putting the enums in a activex dll class (globalmultiuse is easiest for this) then we can use the TLIApplication to retrieve the enum names.

victoryhighway2,
I mis-spoke.
You can do what I said and retrieve the names.

But of course, you can also use the same method and validate if a certain exact Value is held by one of the enum members or not, as you wish to do.

It is just a block of code, (and one reference), which could be used for all of the public enums and enum members stored in that dll.
 
Indeed. And it's the route I'd go if I really needed to do this for some reason. And, indeed, I have done in the past: thread222-832722
 
That certainly has broader application than the solution I proposed. Which is not to say that I would change my proposal for this particular post--I wouldn't. :)
 
>I wouldn't

Ah - but "given my understanding of the problem described by the OP" surely you'd at least consider dilettante's variant solution, which boils down to simply checking if the value to be tested lies between the max and min values of the enum. Whilst your solution requires a loop ...
 

Actually I was just waiting for the OP to say if they were willing to put the enums in a dll, prior to me posting code for doing this, when maybe the OP wouldn't want to go the dll route at all, thus going a different route.
Guess I now don't need to stay around any longer.
 
<surely you'd at least consider

Yes, in fact it's a better solution than mine, now that I'm on vacation and have some time to kill. (I didn't know you could put hidden values in an enum like this! Something new every day...) However, I'm not sure the OP would get it. Gradus ad Parnassum, you know. Perhaps Geoffrey will enlighten us once the aliens are finished with him.
 
I stumbled over those hidden values myself just a year or so ago. There is so much buried in VB6 I've forgotten or don't even know about yet!

At the time I was fumbling with the use of []'ed identifiers in the hope of creating Class methods named the same as otherwise-reserved VB keywords. For example there are places where a Close or Write method would be nice.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top