Link to home
Start Free TrialLog in
Avatar of deathman5
deathman5

asked on

Select Case

IF you have a better answer plz tell me.
SELECT CASE QUESTION

I have more than 25 IF...THEN statments and I want to make then Select Case but the problem is the statments are

If Left$(text1.text, 3) = "msg" then
msgbox "message!"
end if
if left$(text1.text,4)="help" then
msgbox "help"
end if
...

so Select case isnt working :(

I thought of something similar to this:

x = Len(CASES)
Select Case Left$(Text1.Text, x)
Case "msg"
MsgBox "MESSAGE!"
Case "help"
MsgBox "HELP!"
End Select

but there is nothing called Len(CASES)

any help?
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

deathman5,

Here is one way to simplify the code.  Create a project and add a textbox.  In the Form_Load() sub, add all the commands you need into the cmds string as shown.  Type a test string into the textbox and hit Enter.

Enjoy,

Idle_Mind

' Code Follows
Private cmdArray As Variant

Private Sub Form_Load()
    Dim cmds As String
   
    cmds = "msg;help;send;squelch;beep"
    cmdArray = Split(UCase(cmds), ";")
End Sub

Private Sub Text1_KeyPress(KeyAscii As Integer)
    Dim a As Integer
   
    If KeyAscii = 13 Then
        For a = LBound(cmdArray) To UBound(cmdArray)
            If Left(UCase(Text1.Text), Len(cmdArray(a))) = cmdArray(a) Then
                runCommand a
                Exit For
            End If
        Next a
   
        KeyAscii = 0
    End If
End Sub

Private Sub runCommand(cmd As Integer)
    Select Case cmd
        Case 0 ' msg
            MsgBox cmdArray(cmd)
            ' add custom code here...
             
        Case 1 ' help
            MsgBox cmdArray(cmd)
            ' add custom code here...
       
        Case 2 ' send
            MsgBox cmdArray(cmd)
            ' add custom code here...
       
        Case 3 ' squelch
            MsgBox cmdArray(cmd)
            ' add custom code here...
       
        Case 4 ' beep
            MsgBox cmdArray(cmd)
            ' add custom code here...
       
        Case Default ' oops
            MsgBox "Oops"
            ' add Oops code here =)
    End Select
End Sub
The case statement was not designed to handle multiple comparisons, but I've seen another method that makes the code simpler (though not necessarily easier to decipher:

Select Case True

  Case Left$(text1.text, 3) = "msg"
    msgbox "message!"

  Case left$(text1.text,4)="help"
    msgbox "help"

...  

End Select

Essentially, you compare everything against "true" and if it's true then it handles the case.
Avatar of prasitlee
prasitlee

Dear deathman5,
     Why don't you try the following code ?

Select case Left$(text1.text, 3)
     case "msg"
     'Your code here

end select

Select case Left$(text1.text, 4)
     case "help"
     'Your code here

end select

    It also give you the simply way to do and easy to read and modify further in the future.

    In your case, I don't know what the variable "CASES" is. I think it is the main reason which give you the result of nothing. Let 's try to define the value of "CASES" first and you could give almost the same result as I posted the code.

Dear rspahitz,
    Your code seems does not work because it executed only the first case and the other cases were never executed.
 
                                                                                  Meng
Meng,

That's how the case statement works:  After a valid condition is found, the remainder of the case structure is ignored.

However, after reviewing the orignal question, it was not clear if deathman wanted to use the Case statement properly, or as a simplified IF structure, in which case your above example would be correct.
I prompted deathman5 to post this question because it had been ignored in an earlier posting titled "Three questions". I suggested that he post the question again on its own with an appropriate title because I had a solution which I thought worth sharing.

However the weekend has intervened. rspahitz's solution was the one I was thinking about.

As rspahitz and Meng (prasitlee) comments suggest, you may have to consider the order of the Case statements.

If you wanted to treat "help" differently from "held" and "hello", this would not do it.
Select Case True
  Case Left$(text1.text, 3) = "hel"
    msgbox "message!"
  Case left$(text1.text,4)="help"
    msgbox "help"
End Select

But this would:
Select Case True
  Case Left$(text1.text, 4) = "help"
    msgbox "help"
  Case left$(text1.text,3)="hel"
    msgbox "message!"
End Select

"....The case statement was not designed to handle multiple comparisons......"
Hummm....
how about this:

'NOTE: example not related to question

Sub test(s As String)
Select Case s
Case "a", "b", "c"
     MsgBox "you have been selecting " & s
Case Else
     MsgBox "you have been selecting something else"
End Select

End Sub
Dear GrahamSkan,
   The sample you posted is the same as  rspahitz. If the first condition is true then it would execute only the code which is corresponding it only.
    For example, if your string is "help", you would never see the message box "help". On the other hand, you would only see the message box "hel".
                                                                          Meng
Yes Meng - that was the point I was trying to make. I seem to have failed to make it clear, but it's not for the first time.
Graham
Nobody likes my solution eh?....

or is it being ignored since the true spirit of this question was to see how convuluted a way we could use the Select Case structure?  

;-)

Idle_Mind
Richie,

>>not designed to handle multiple comparisons
>how about this

OK--I mis-worded this.

CASE statement was not designed to handle multiple comparisons of multiple parts such as a=b and c>d.

Your example is multiple comparisons of common parts such as a=b and a>c and a<d
--------------

Idle_Mind, you solution seems viable, but certainly seems to require extra work on the computer's part (which is not a big deal these days.)   My biggest complaint is that it is more obfuscated than the straight-forward IF-THEN or CASE statements.

Honestly, I've learned over the years that it's more important to be clear with VB code than to be efficient (mainly because most VB code is not doing anything "important" enough to demand memory-efficient, high-speed processing.  It's not that it can't but; just that it rarely is so there's no need these days to sacrifice readability for efficiency or speed.)
I agree that it may be harder to read at first, but it is easy to add another command.

Just tack another command onto the end of the string and add another easy to read Case x statement.

cmds = "msg;help;send;squelch;beep;anotherCommand"

Less room for error since the conditional checking code does not change.

Idle_Mind
Good point!

However, because each entry still requires another entry in another part of the program, it still suffers from obfuscation that could lead to "dis-synchronization" of parts.

Maybe a better way is to build a class module (very similar to your code) to better handle the parts and include an enumeration that handles some of those pieces.  I'd offer code, but don't want to waste my time unless deathman returns.
I agree, but there is always the possibility of "dis-synchronization" of parts since programs are written by people.

It all just boils down to what style of code you like...and that in itself is enough to spark a very, very long flaming thread.

Where are you deathman5?

There is a heated debate going on without you....

;-)

Idle_Mind
Avatar of deathman5

ASKER

@Idle_Mind
I am here, reading everthing (Email Notification :P )
anyway until now the only two ways are
as I said

Select Case Left(strData,3)
Case "hel"
'bla
Case "hea"
'bla
End Select

or as Idle_Mind said

 Code Follows
Private cmdArray As Variant

Private Sub Form_Load()
    Dim cmds As String
   
    cmds = "msg;help;send;squelch;beep"
    cmdArray = Split(UCase(cmds), ";")
End Sub

Private Sub Text1_KeyPress(KeyAscii As Integer)
    Dim a As Integer
   
    If KeyAscii = 13 Then
        For a = LBound(cmdArray) To UBound(cmdArray)
            If Left(UCase(Text1.Text), Len(cmdArray(a))) = cmdArray(a) Then
                runCommand a
                Exit For
            End If
        Next a
   
        KeyAscii = 0
    End If
End Sub

Private Sub runCommand(cmd As Integer)
    Select Case cmd
        Case 0 ' msg
            MsgBox cmdArray(cmd)
            ' add custom code here...
             
        Case 1 ' help
            MsgBox cmdArray(cmd)
            ' add custom code here...
       
        Case 2 ' send
            MsgBox cmdArray(cmd)
            ' add custom code here...
       
        Case 3 ' squelch
            MsgBox cmdArray(cmd)
            ' add custom code here...
       
        Case 4 ' beep
            MsgBox cmdArray(cmd)
            ' add custom code here...
       
        Case Default ' oops
            MsgBox "Oops"
            ' add Oops code here =)
    End Select
End Sub

these are the answers only till now, the
Select Case True 'didnt work (I didnt try it, but u said it didnt work)
so I am going to wait a little bit to see your 'heated debate' and then accept :)
Dear deathman5,
    How about my comment ?
                                                            Meng
Just a variation on what I had before but I think it is easier to read:

Private Sub Form_Load()
    Dim cmds As String
   
    cmds = "msg;help;send;squelch;beep"
    cmdArray = Split(UCase(cmds), ";")
End Sub

Private Sub Text1_KeyPress(KeyAscii As Integer)
    If KeyAscii = 13 Then
        Select Case getCommand(Text1.Text)
            Case "MSG"
                MsgBox "MSG"
                ' add custom code here...
             
            Case "HELP"
                MsgBox "HELP"
                ' add custom code here...
       
            Case "SEND"
                MsgBox "SEND"
                ' add custom code here...
           
            Case "SQUELCH"
                MsgBox "SQUELCH"
                ' add custom code here...
       
            Case "BEEP"
                MsgBox "BEEP"
                ' add custom code here...
           
            Case "UNKNOWN"
                MsgBox "Unknown Command"
                ' add Oops code here =)
        End Select

        KeyAscii = 0
    End If
End Sub

Private Function getCommand(inputString As String) As String
    getCommand = "UNKNOWN"
    For a = LBound(cmdArray) To UBound(cmdArray)
        If Left(UCase(Text1.Text), Len(cmdArray(a))) = cmdArray(a) Then
            getCommand = cmdArray(a)
            Exit Function
        End If
    Next a
End Function

Regards,

Idle_Mind
The Select Case True actually works fine, but may not give you what you want, which we are still awaiting an answer.

Do you need to check ALL conditions, or only the first condition that matches?

If you only need to find the first answer, the Case True method works fine.

If you need to check all conditions, the Case True will work but is overkill since you'll have to create a case statement for each condition.  In this situation, any CASE statement is really overkill.

--
Have you considered a different approach so that you can more easily use the Idle variation?

Based on what you're doing, it seems that you want to parse some input and do something based on the first word.  This will handle it:

Select Case lcase$(split(Text1.Text, " ")(0))
  case "help"
    msgbox "Help requested"
  case "msg"
    msgbox "Message requested"
  case else
    msgbox "Something other than help or msg entered"
end select

I dont know if they said this answer before (they probebly did) I cant read all the replies, so I will say what I know:

Select Case Left (whatever, 3)
case "333"
'...
case "222"
'...
End select

I dont know any other way.

PS:
can u guys check this question
https://www.experts-exchange.com/questions/20815081/Connected-to-the-net.html

thx

ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
deathman also said, "the Select Case True 'didnt work (I didnt try it, but u said it didnt work)"

Since I confirmed that it DOES work, I would recommend a 50-50 split between us because (as I said) "we are still awaiting an answer"

Our two solutions seemed to be the closest solutions, but for slightly different needs.

Now, since there are only 20 points, I really don't care who gets them.