Search code examples
excelms-accessvbaselect-case

return value from select case


How can I get the value from the expression in my Select Case statement?

When we write select case statements, we are told that good practice is to have a case else at the end. I understand the purpose of this to be if we don't think of all possible cases, there is a way to inform us instead of just moving on. Usually I just use debug.assert in that case, which works great for personal debugging and is sometimes sufficient for some end users after delivery.

That doesn't work well when I am writing to the VBE, as breaking is not supported anytime after the VBE has been called. I realize that I could probably unload the VBE object and then debug.assert, but that kind of defeats the purpose of pausing my code, if the case has to do with what I am reading/writing to the VBE.

To my mind, the easiest solution would be to msgbox TheUnexpectedResultFromMyExpression, but I have no idea how to call that. The second easiest solution appears to be to have full and complete prescience of what my users may or may not do, as well as when and how they may do it. I have been working on that too, so if you don't know how to return the value, then maybe you have some tips on omniscience.

I know that I, in the vase majority of cases, could simply copy the expression itself to a msgbox ... inside case else, but I happen to be working with a case of a decision tree based upon the return to setting an object, and I am not interested in doing that twice. Another option might be to just myVariable=<expression> and select case myVariable instead of select case <expression>, and then always debug.print myVariable before every select case, but my log is already so busy, doing that in a larger project would mean I have to buy another monitor, and I am struggling with groceries right now.

Asking here seems easier. Thanks.

EDIT:

For those that seemed to have a hard time understanding what I am trying to ask, I boiled the code down as simply as I could. Obviously the below isn't super useful, but you get the idea.

Select Case Forms("Form1").Module.CreateEventProc("Click", Forms("Form1").Controls("label0").Name)
Case 1
    Debug.Print "line1"
Case 2
    Debug.Print "line2"
Case Else
    Debug.Print Forms("Form1").Module.CreateEventProc("Click", Forms("Form1").Controls("label0").Name)
End Select

When my Case Else statement runs, it may print the value of the expression (the workaround I mentioned) in the immediate window, and I know I could do the same with a msgbox or variant or whatever, but it runs the code again. And yes, as I mentioned above already, I could (in this case) just assign the value to a long and then run the Select Case on the long, but that option doesn't solve the problem in my application. And lest this become a conversation where we debate the merits of using VBE objects, or tries to get me to ask a different question of why I get unexpected values (I am not, I am trying to plan for clean debugging during runtime), or someone asking me why I can't just make the code simpler and easier to use instead of tens of thousands of lines of code that write another thousand+ lines of code, it is because I have a client. And they pay for what they want.

So, back to original question, all I want is to know how to return the value from the select case expression. If you are a superhero, and can get code to pause after the VBE is called, then by all means answer that question instead or in addition to.


Solution

  • The answer is: you can't.

    Sorry, no source, except multiple descriptions of Select Case, e.g. MSDN, which would mention it, if this functionality existed.

    It is a rather unusual question, that's one reason for the confusion in the comments. You are looking for a "meta" variable or method, like @@IDENTITY in T-SQL. But this doesn't exist for the VBA Select Case.

    And the reason why it isn't needed: you have complete control over the testexpression in the Select part. The usual way, and I actually consider this good programming practice, is to always assign any sort of complex expression or method call (like CreateEventProc) to a variable, and then use this variable for Select Case.

    So

    LineNr = Forms("Form1").Module.CreateEventProc("Click", Forms("Form1").Controls("label0").Name)
    
    Select Case LineNr 
        Case <expected values>
            ' do something useful
        Case Else
            Debug.Print "Whoa, unexpected LineNr: " & LineNr
    End Select
    

    is really the and the only solution.