Multiple IF statements within each other (1 Viewer)

tmyers

Well-known member
Local time
Today, 08:08
Joined
Sep 8, 2020
Messages
1,090
I want to make sure I am "nesting" IF statements correctly before I get too crazy with this

Code:
If Me.QuoteComplete = True Then
    
    Call LockForm
    Me.LockQuoteBtn.Caption = "Unlock Quote"
        
        ElseIf Me.QuoteComplete = False Then
        
            Msg = "Is the quote done/complete?"
            Style = vbYesNo + vbCritical + vbDefaultButton2
            Title = "Lock Quote"
            Response = MsgBox(Msg, Style, Title)
                'user confirmed quote is complete and lock, else exit sub
                ElseIf Response = vbYes Then

I am unsure if that last one needs to be an ElseIf, or just a plain if to handle the response of the msgbox. I think it just needs to be a plain IF statement. Could someone assist?
 

plog

Banishment Pending
Local time
Today, 07:08
Joined
May 11, 2011
Messages
11,613
Just a plain Else. Only 2 mutual exclusive conditions--if it ain't True, then its False.

Also, that's not nesting. Nesting is an if within the scope of another If; not just an Else and ElseIf are technically not nested. This would be nested If statements:

Code:
If Color=Blue Then
  var1=7
   If Age>19 Then
    var2=10
    End If
End If

It does a test within a test that already passed. If Color is not blue, it doesn't even test the age.
 

tmyers

Well-known member
Local time
Today, 08:08
Joined
Sep 8, 2020
Messages
1,090
Just a plain Else. Only 2 mutual exclusive conditions--if it ain't True, then its False.
So:

Code:
If Me.QuoteComplete = True Then
   
    Call LockForm
    Me.LockQuoteBtn.Caption = "Unlock Quote"
       
        ElseIf Me.QuoteComplete = False Then
       
            Msg = "Is the quote done/complete?"
            Style = vbYesNo + vbCritical + vbDefaultButton2
            Title = "Lock Quote"
            Response = MsgBox(Msg, Style, Title)
                'user confirmed quote is complete, else exit sub
                Else: Response = vbYes
                    Call LockForm
                    Me.LockQuoteBtn.Caption = "Unlock Quote"
                Else
                    Exit Sub
                End If
 

plog

Banishment Pending
Local time
Today, 07:08
Joined
May 11, 2011
Messages
11,613
Your indentation is messy. The first ElseIf should be on the same line as your first If

Code:
If Me.QuoteComplete = True Then
   
    Call LockForm
    Me.LockQuoteBtn.Caption = "Unlock Quote"
ElseIf Me.QuoteComplete = False Then

However, because if something isn't true it must be false you do not need to test anything and can simply use an Else instead of that ElseIf.

The other 2 Elses in your code exist without an If so they make no sense.
 

Isaac

Lifelong Learner
Local time
Today, 05:08
Joined
Mar 14, 2017
Messages
8,738
Here's a tip. I see a lot of people use the 'ResponseVariable = msgbox' method, but I think this is easier...and will result in a slightly simpler IF situation. Usually I am all about variables, but if you're struggling with being able to eyeball the IF stuff, this results in fewer noise:

If msgbox("Some question?",vbyesno," ")=vbno then

Just to let you know you can also do that, it's the way I do it.

PS. Your indentation on everything, just about, should always (when complete), look like a caret with its pointy side facing right.

Code:
If this Then
    If this Then
        If this Then
            'something
        End If
    End If
End If
 

tmyers

Well-known member
Local time
Today, 08:08
Joined
Sep 8, 2020
Messages
1,090
Here's a tip. I see a lot of people use the 'ResponseVariable = msgbox' method, but I think this is easier...and will result in a slightly simpler IF situation. Usually I am all about variables, but if you're struggling with being able to eyeball the IF stuff, this results in fewer noise:

If msgbox("Some question?",vbyesno," ")=vbno then

Just to let you know you can also do that, it's the way I do it.
That is how I typically do it because of the If block mess.
I wanted to give this one a try since it is a little easier to read.

Your indentation is messy. The first ElseIf should be on the same line as your first If

Code:
If Me.QuoteComplete = True Then
  
    Call LockForm
    Me.LockQuoteBtn.Caption = "Unlock Quote"
ElseIf Me.QuoteComplete = False Then

However, because if something isn't true it must be false you do not need to test anything and can simply use an Else instead of that ElseIf.

The other 2 Elses in your code exist without an If so they make no sense.
It is a mess of me trying to do the msgbox in a way I typically dont. I will just remove it all together and user the other way that Isaac mentioned.
 

tmyers

Well-known member
Local time
Today, 08:08
Joined
Sep 8, 2020
Messages
1,090
Isaac, switching back to the other method, I would have to change that else to an elseif correct?
 

Isaac

Lifelong Learner
Local time
Today, 05:08
Joined
Mar 14, 2017
Messages
8,738
That is how I typically do it because of the If block mess.
I wanted to give this one a try since it is a little easier to read.


It is a mess of me trying to do the msgbox in a way I typically dont. I will just remove it all together and user the other way that Isaac mentioned.
One thing I do when I am typing (might be weird, but!), I close up my IF statements immediately - before typing other content inside.
Just makes it easier to remember what to close up and where.
 

Isaac

Lifelong Learner
Local time
Today, 05:08
Joined
Mar 14, 2017
Messages
8,738
I think

Code:
If Me.QuoteComplete = True Then
    Call LockForm
    Me.LockQuoteBtn.Caption = "Unlock Quote"
Else
    If MsgBox("Is the quote done/complete?", vbYesNo, "Lock Quote") = vbYes Then
        'something
    End If
End If

But, sorry, I am unable to be sure from your original code
 

tmyers

Well-known member
Local time
Today, 08:08
Joined
Sep 8, 2020
Messages
1,090
Handling multiple Ifs within each other is quite a headache. I typically can avoid it.
 

theDBguy

I’m here to help
Staff member
Local time
Today, 05:08
Joined
Oct 29, 2018
Messages
21,358
Handling multiple Ifs within each other is quite a headache. I typically can avoid it.
Hi. I could be wrong, but there may also be a limit on the number of levels within a nested If/Then block.

Just thinking out loud...
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 08:08
Joined
May 21, 2018
Messages
8,463
One thing to save some typing and make clearer. In real life we do not say If True = True, we just say if true.

If Me.QuoteComplete = True then
can simply be
If me.quotecomplete then
Same as for the false side
if not me.quotecomplete then
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 08:08
Joined
May 21, 2018
Messages
8,463
Two other things that can simplify
1. You can simplify using a switch for certain things that are true and false.

If something = true then
me. somecontrol.visible = true
else
me.someControl.visible = false
end if

this can be written as one line to handle both true and false
me.somecontrol.visible = (something = true)

2. Learn the Select Case. This can make things much easier and clearer.
 

Isaac

Lifelong Learner
Local time
Today, 05:08
Joined
Mar 14, 2017
Messages
8,738
I'm an odd one out, I guess - I personally like the style of:

If Me.Controlname = True

I do realize it's unnecessary, but (maybe it's just me), I find it much quicker and easier to eyeball/read through.
Then again, I'm always more in favor of readability rather than shortness. Anyone can see this who has seen my variable names! 😆
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 08:08
Joined
May 21, 2018
Messages
8,463
I use long descriptive variable and function names so in my case it would be clear.

If Completed or not Included then
I would not do with non descriptive variables
If X = True or Y = False then
 

Isaac

Lifelong Learner
Local time
Today, 05:08
Joined
Mar 14, 2017
Messages
8,738
I use long descriptive variable and function names so in my case it would be clear.

If Completed or not Included then
I would not do with non descriptive variables
If X = True or Y = False then
Gotcha - That's a good point. If the variable name is already in such and such a way, the = True/False is less 'needed', or whatever the word is, mentally
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 08:08
Joined
Feb 19, 2002
Messages
42,981
1. When nesting If's, ALWAYS indent appropriately.
2. If's and Else's must be matched although If's don't need else's if there is no alternative code you want to execute.
3. Each If ends with an End If

ElseIf just confuses the formatting and keeps you from actually aligning the clauses so I never use it. Isaac showed you the correct format in #5 and he gave you a cleaner version of your If in #9.

Here are some more complex examples.
An If where the true option doesn't do anything. I frequently code these because people have more trouble understanding a negative question than a positive one so I do the positive test and don't include any code after it. Sometimes I might include a comment
Code:
If something Then
Else
    'do something'
End If
Here's a sample that goes in and out and even stacks If's within an If. Something2 is not dependent on either path of Something1.
Code:
If Something Then
    'do something'
    If Something1 Then
    Else
        'do something1'
        If Something2 Then
            'do something2'
        End If
    End IF
    If Something3 Then
        'so something3'
        If Something4 Then
            do something4
        end If
    End If
Else
    'do something else'
End If

The thing to remember is If-then-else is not the only tool in your toolbox. Many people use it when they should be using Select Case. Select Case is used when you want to test several values for the same variable and do something different for each value
Code:
Select Case Me.SomeField
    Case "Blue"
        'do something blue'
    Case "Red"
        'do something red'
    Case Else
        'do the same thing for all the other colors'
End Select

Handling multiple Ifs within each other is quite a headache. I typically can avoid it.
Logic is logic. Avoiding the correct structure just leads to errors. You will be much less inclined to make a mistake if you are religious about indentation.
 
Last edited:

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 07:08
Joined
Feb 28, 2001
Messages
27,001
Here is a reference for IF statements that might help.


Note that Excel has limits on IF but that is because they have space limits for formulas within a cell. VBA has different limits. Let's think about what it means to have a bunch of nested IF/THEN/ELSE/ENDIF cases (and note that I have omitted ELSEIF entirely for this discussion.

If you have a Yes/No condition, you use IF (yes) THEN do something ELSE do another thing ENDIF. This is not a big deal. One variable, two possible outcomes.

Suppose you have to nest something else based on a second variable and each case of the first variable needs to test the second variable. That is two variables, FOUR possible outcomes.

If you reach 6 variables, that is 64 different outcomes. That is one helluva decision tree. Even if some of the combinations can't happen, you are in essence building a decision tree with up to 64 nodes. Now add one more variable and you hit 128 nodes. The maintenance of such a tree (which, when full, has 127 branches - because you have to count the lower-level branches too...) becomes nightmarish. You hit the limit when you realize that a module is limited to (I think) 64K lines. But that would imply a tree of fourteen variables, 16K choices.

A method I have sometimes used is to build a binary decision tree on paper (to help me organize it) then use the yes/no value of each individual test to generate a 1 or 0 in a particular bitmask. Then I use a SELECT CASE statement on the synthesized number. The number of executed tests remains the same but the nesting can be minimal and can be much easier to read.
 

Users who are viewing this thread

Top Bottom