Limit to ElseIf Conditions? - vba

So I have some VBA code designed to go through a few things based on a value in a cell. The value in the cell is read and the code runs accordingly. This works without issue with.
If Target.Value = "something" Then
End If
ElseIf Target.Value = "something2" Then
End If
ElseIf Target.Value = "something3" Then
End If
ElseIf Target.Value = "something4" Then
End If
That works perfectly, however if I add an additional ElseIf condition I get the compiler error of "Else without If". Changing ElseIf to Else on the fifth condition doesn't fix the issue. My question is that is there a limit to the amount of ElseIf conditions I can run? I literally only need this fifth one to be entirely done with what I am trying to do. I am positive the code within the condition has no errors.

The End If goes at the end only:
If Target.Value = "something" Then
'Do something
ElseIf Target.Value = "something2" Then
'Do something
ElseIf Target.Value = "something3" Then
'Do something
ElseIf Target.Value = "something4" Then
'Do something
End If

Definitely you should "upgrade" your multiple ElseIf and go with Select Case.
This will let you implement more scenarios in the future easier.
Select Case Target.Value
Case "something"
' code 1 here
Case "something2"
' code 2 here
Case "something3"
' code 3 here
Case "something4"
' code 4 here
Case "something5", "something6" ' <-- replaces using another If with And
' code 5 here
' Case ....
End Select

Related

VBA If Statement within For (Else Running even when If condition is met)

I'm pretty new to VBA and having issues with a Else statements running even when If conditions are met.
Pretty sure this is due to the If statement being within a For & Next
For iCnt = 1 To Len(Firstname)
If IsNumeric(Mid(Firstname, iCnt, 1)) Then
MsgBox "The Firstname cannot contain Numeric values"
ElseIf Len(Firstname) > 100 Then
MsgBox "The Firstname exceeds the character limit (100)"
Else
Sheet3.Cells(lRow, 2).Value = Me.Firstname.Value
End If
Next iCnt
Please any suggestions how to fix this?
Really you only want the first condition to exist in that FOR loop. The rest of it should be tested afterwards and only if that first condition never trips.
Consider instead:
Dim nameHasNumbers as boolean: nameHasNumbers = False
For iCnt = 1 To Len(Firstname)
If IsNumeric(Mid(Firstname, iCnt, 1)) Then
'number found toggle flag and exit the loop
nameHasNumbers = True
exit For
End If
Next iCnt
'Now alert the user or update the name cell
If nameHasNumbers Then
MsgBox "The Firstname cannot contain Numeric values"
ElseIf Len(Firstname) > 100 Then
MsgBox "The Firstname exceeds the character limit (100)"
Else
Sheet3.Cells(lRow, 2).Value = Me.Firstname.Value
End If
For each letter in the name you are going to get the Else to happen. Need to restructure the whole thing. I would put the checking into a function and then based on that result do your other work. If you need a message to inform the user of the reason for the name being invalid add that to the function. Your function can then do other testing on other conditions without affecting your calling code.
Private Function IsValidName(ByVal value As String) As Boolean
If Len(value) > 100 Then
IsValidName = False
Exit Function
Else
Dim charCounter As Long
For charCounter = 1 To Len(value)
If IsNumeric(Mid(value, charconter, 1)) Then
IsValidName = False
Exit Function
End If
Next
IsValidName = True
End If
End Function
When you want to check whether a string includes a digit, you can compare it to a Like pattern which matches a digit: FirstName Like "*[0-9]*"
That approach is simpler than looping through the string checking whether each character is a digit. And since it does not require the For loop, it should be easier to avoid the logic error in your code sample. (As long as the string length did not exceed 100 characters, it wrote a value to Sheet3.Cells(lRow, 2).Value again for each and every non-numeric character contained in FirstName.)
If FirstName Like "*[0-9]*" Then
MsgBox "The Firstname cannot contain Numeric values"
ElseIf Len(FirstName) > 100 Then
MsgBox "The Firstname exceeds the character limit (100)"
Else
Sheet3.Cells(lRow, 2).Value = Me.FirstName.Value
End If

Two If statements inside each other in VBA

I tried to write two If statements inside each other in VBA, but it gives me wrong answer. When I debug it, it shows that the program doesn't go through the ElseIf and keeps going with the else of the first If.
How can I have two If statements working properly inside each other?
Code:
If ConfigBox.Value <> ... Then
If ListBox1.Value = ... Then
DO SOMETHING
Else
DO SOMETHING
End If
ElseIf ListBox1.Value = ... Or ListBox1.Value = ... Then
DO SOMETHING
Else
DO SOMETHING
End If
Your nesting is a bit off. You would want to do something like this:
If ConfigBox.Value <> ... Then
If ListBox1.Value = ... Then
Code
ElseIF ListBox1.Value = ... Or ListBox1.Value = ... Then
Code
Else
Code 'if ListBox1.Value doesn't meet above criteria
End If
Else
Code 'if ConfigBox criteria is not met. You could start another nested If for the ListBox1 here too.
End If
try with below
If ((ConfigBox.Value <> "1") And (ListBox1.Value = "2")) Then
'Do Something
ElseIf ((ConfigBox.Value <> "1") And (ListBox1.Value <> "2")) Then
'Do Something
ElseIf ListBox1.Value = "3" Or ListBox1.Value = "4" Then
'Do Something
Else
'Do Something
End If

How can I use two conditions for my `IF` block?

I have a problem to create double conditions with If, so this is what I have for hiding a line:
If Target.Address = "$D$35" Then
If (Target.Value = "No") Then
ActiveSheet.Range("37:40").Rows.Hidden = False
End If
If (Target.Value = "Yes") Then
ActiveSheet.Range("37:40").Rows.Hidden = True
End If
End If
Now, I want to add another condition for this formula, let's say that that cell $D$35 need to be "No" and Cell $D$36 need to be "done" in order for the Hide function to work.
How do I insert this to my existing formula ?
1. You can use And for multiple conditions (cf #jonrsharpe comment). Actually take a look at other logical operators like Or etc ... Logical and Bitwise Operators
2. Why don't you use If\ElseIf\Else ? It's quite obvious that if Target.Value = "No" is true you do not have to test if Target.Value = "Yes" ...
So just do something like that:
If cond1 And cond2 Then
' Some code
ElseIf cond3 And cond4 Then '<--editted
' Some code
Else
' Some code
End If
Example: Let's say you want to do a condition on the values of cell D35 ($D$35) and D36 you can just do:
If Range("D35")= "No" And Range("D36")= "No" Then
ActiveSheet.Range("37:40").Rows.Hidden = False
ElseIf Range("D35")= "Yes" And Range("D36")= "done" Then
ActiveSheet.Range("37:40").Rows.Hidden = True
End If
Instead of
If Target.Address = "$D$35" Then
If (Target.Value = "No") Then
ActiveSheet.Range("37:40").Rows.Hidden = False
End If
If (Target.Value = "Yes") Then
ActiveSheet.Range("37:40").Rows.Hidden = True
End If
End If
Note 1: this assumes you are working on the right sheet
Note 2: this isn't especially the best way to do ...
First, it's not a formula, it's a subroutine. Second, you don't have to have multiple IF blocks. Just one should suffice.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("D35:D36")) Is Nothing Then
ActiveSheet.Range("37:40").Rows.Hidden = (Range("D35").Value = "No" And Range("D36").Value = "Done")
End If
End Sub
A little explanation is in order:
If Not Intersect(Target, Range("D35:D36")) Is Nothing returns TRUE if the change is detected in either D35 or D36. If you want the condition to check in non-contiguous ranges, use Union on the ranges you want to check.
(Range("D35").Value = "No" And Range("D36").Value = "Done") evaluates to TRUE if both conditions are met, FALSE if else. We then use this as the boolean trigger for the Hidden property of the given range.
Hope this helps.

Type Mismatch Run Time Error '13'

I have searched everywhere for an answer to this issue and I am fairly new to VBA so I hope you can help. Below is the code.
If [e19].Value + [g19].Value = [c19].Value Then
[l19].Value = "Yes"
ElseIf [e19].Value = "N/A" Then
[l19].Value = "N/A"
**ElseIf Range("i18:i21, l18").Value = "{a}" Then**
l19.Value = "{b}"
The code wrapped in ** is where I am having my issue. Any ideas?
Thank you
You can't compare a range with a specific value.. You could take each cell inside a 'For Each xxx In Range.Cells...Next' statement to proceed to the comparison for each value inside the range, but note that each cell is compared individually, in turn. This code should work this way:
Sub zo()
If [e19].Value + [g19].Value = [c19].Value Then
[l19].Value = "Yes"
ElseIf [e19].Value = "N/A" Then
[l19].Value = "N/A"
Else
For Each cell In Range("i18:i21, l18")
If cell.Value = "{a}" Then
[l19].Value = "{b}"
End If
Next
End If
End Sub

Remove repetition from if-else statement

I have written an if...else statement which uses an array myArr and a string myStr as follows:
If myArr.Length > 0 AndAlso myArr(0) = "-1" Then
'Do stuff 1
ElseIf myStr= "xyz" Then
'Do stuff 2
ElseIf myArr.Length > 0 Then
'Do Stuff 3
Else
'Do Nothing
End If
It works exactly as I need. But It looks really confusing, mostly because the array length is checked twice. There must be a clearer way to write it, but I can't think of one.
Just to clarify.... the order that each statement is executed is crucial. i.e. Stuff 1 has priority over stuff 2, which has priority over stuff 3.
I don't think you'll be able to get exactly the same flow in a simpler way.
Either you're going to end up doing things different things, or doing duplicate things. eg:
If myArr.Length > 0 Then
If myArr(0) = "-1" Then
'Do stuff
Else
'Do stuff
End If
ElseIf myStr= "xyz" Then
'Do stuff
Else
'Do Nothing
End If
This will cause mystr="xyz" not to happen whenn myArr(0) <> -1 whereas it may have before.
You might be able to get rid of multiple checks against myArr.Length by using nested If statements, but this makes the code less clear.
A clear approach (i.e. one that can be understood easily) is one that allows you to read a code fragment without having to remember the context in which the code is executed. By nesting If statements, more information must be kept in the readers working memory (or short term memory) to deduce the meaning of he code.
I guess this would do the trick:
If myArr.Length > 0 Then
If myArr(0) = "-1" Then
'Do stuff
Else
'Do stuff
End If
ElseIf myStr= "xyz" Then
'Do stuff
Else
'Do Nothing
End If
What you need is nested if
If myArr.Length > 0 Then
'Do stuff for non zero length
If myArr(0) = "-1" Then
'Do stuff for -1 and you already have checked for array length
End If
End If
If myArr.Length > 0 Then
If myArr(0) = "-1" Then
' Stuff 1
Else
' Stuff 3
End If
ElseIf myStr = "xyz"
' Stuff 2
End If
... no further else needed
You can decompose the statements like this:
If myArr.Length > 0 Then
If myArr(0) = "-1" Then
'Do stuff
Else
'Do sstuff
End If
Else
If myyStr= "xyz" Then
'Do stuff
End If
End If