Search code examples
vbaexcel-2013

Nested If - Possible better solution?


I am hoping to get some advice on a better solution to a massive nested If statement in VBA. Becasue of the amount of conditions that would be possible the If statement is becoming extremely large. I was thinking of using a For loop, but that seems like it would still require a significant amount of If conditions, and I also thought of a Select Case, but that doesnt really work either.

The code below shows how I have the variables set for the If statements and most of the conditions. Any help in streamlining this code would be greatly appreciated.

    If wsCalc.Range("LenderComplete") <> vbNullString Then f = 1
If wsCalc.Range("ProcessorComplete") <> vbNullString Then g = 1
If wsCalc.Range("KeyerComplete") <> vbNullString Then h = 1
If wsCalc.Range("CheckerComplete") <> vbNullString Then i = 1

If f <> 1 And g <> 1 And h <> 1 And i <> 1 Then
    ContLoanFile.ContinueLP.BackColor = vbYellow
    With ContLoanFile.Label7
        .Caption = "Lender items NOT complete." & vbNewLine & "Processor items NOT complete." & vbNewLine & "Keyer items NOT complete." & vbNewLine & "Checker items NOT complete."
        .Font.Size = 9
    End With
    If f = 1 And g <> 1 And h <> 1 And i <> 1 Then
        ContLoanFile.ContinueLP.BackColor = vbYellow
        With ContLoanFile.Label7
            .Caption = "Lender items COMPLETE." & vbNewLine & "Processor items COMPLETE." & vbNewLine & "Keyer items NOT complete." & vbNewLine & "Checker items NOT complete."
            .Font.Size = 9
        End With
        If f = 1 And g = 1 And h <> 1 And i <> 1 Then
            ContLoanFile.ContinueLP.BackColor = vbYellow
            With ContLoanFile.Label7
                .Caption = "Lender items COMPLETE." & vbNewLine & "Processor items COMPLETE." & vbNewLine & "Keyer items NOT complete." & vbNewLine & "Checker items NOT complete."
                .Font.Size = 9
            End With
            If f = 1 And g = 1 And h = 1 And i <> 1 Then
                ContLoanFile.ContinueLP.BackColor = vbYellow
                With ContLoanFile.Label7
                    .Caption = "Lender items COMPLETE." & vbNewLine & "Processor items COMPLETE." & vbNewLine & "Keyer items COMPLETE." & vbNewLine & "Checker items NOT complete."
                    .Font.Size = 9
                End With
                If f = 1 And g = 1 And h = 1 And i = 1 Then
                    ContLoanFile.ContinueLP.BackColor = vbYellow
                    With ContLoanFile.Label7
                        .Caption = "Lender items COMPLETE." & vbNewLine & "Processor items COMPLETE." & vbNewLine & "Keyer items COMPLETE." & vbNewLine & "Checker items COMPLETE."
                        .Font.Size = 9
                    End With
                    If f <> 1 And g = 1 And h = 1 And i = 1 Then
                        ContLoanFile.ContinueLP.BackColor = vbYellow
                        With ContLoanFile.Label7
                            .Caption = "Lender items NOT complete." & vbNewLine & "Processor items COMPLETE." & vbNewLine & "Keyer items COMPLETE." & vbNewLine & "Checker items COMPLETE."
                            .Font.Size = 9
                        End With
                        If f = 1 And g <> 1 And h = 1 And i = 1 Then
                            ContLoanFile.ContinueLP.BackColor = vbYellow
                            With ContLoanFile.Label7
                                .Caption = "Lender items COMPLETE." & vbNewLine & "Processor items NOT complete." & vbNewLine & "Keyer items COMPLETE." & vbNewLine & "Checker items COMPLETE."
                                .Font.Size = 9
                            End With

Solution

  • Firstly, they don't need to be nested because they all have conflicting logic and will never "cascade" down like a nested If is intended to do.

    If f <> 1 And g <> 1 And h <> 1 And i <> 1 Then '// If this is true
        '...
        If f = 1 And g <> 1 And h <> 1 And i <> 1 Then '// Then this can never be true
    

    If you were going to keep this design then it should really be If...ElseIf... logic in place.


    Secondly, you have a lot of common logic so something like this should work because you don't have to repeat the same outcome for every condition:

    Dim caption As String
    
    caption = "Lender items " & IIf(wsCalc.Range("LenderComplete").Value <> vbNullString, "COMPLETE", "NOT complete") & vbNewLine & _
              "Processor items " & IIf(wsCalc.Range("ProcessorComplete").Value <> vbNullString, "COMPLETE", "NOT complete") & vbNewLine & _
              "Keyer items " & IIf(wsCalc.Range("KeyerComplete").Value <> vbNullString, "COMPLETE", "NOT complete") & vbNewLine & _
              "Checker items " & IIf(wsCalc.Range("CheckerComplete").Value <> vbNullString, "COMPLETE", "NOT complete")
    
    
    With ContLoanFile
        .ContinueLP.BackColor = vbYellow
        With .Label7
            .Caption = caption
            .Font.Size = 9
        End With
    End With
    

    No need for a loop and no need to test the same values multiple times.