I have a piece of vb.net code that I wrote. It's a for loop with two embedded if statements, and the compiler is telling me that each elseif and endif must be preceded by a matching if.
This is my second day of working with vb.net ever, and the only programming experience I have is writing .bat files, so this could be something really stupid. But I cannot figure out why I'm getting these errors, and if you all would be willing to help me out, I would greatly appreciate it!
For Each computer In compArray
If compArray(I) <> Computers.GetKey(I) Then notpresentList.Add(Computers.GetKey(I))
Else
If Computers.GetByIndex(I) = 0 Then disabledList.Add(Computers.GetKey(I))
Elseif Computers.GetByIndex(I)=1 Then enabledList.Add(Computers.GetKey(I))
Elseif Computers.GetByIndex(I)=2 Then unknownList.Add(Computers.GetKey(I))
End if
End if
I += 1
Next
The context for this: I am trying to write a piece of code that will confirm the presence of bitlocker. I wrote in VBScript something that will check whether bitlocker is enabled and then send an email. This piece of code is a part of a program which would retrieve those emails, compare them to a list of computers, and then produce a digest email which states which computers are absent, have bitlocker enabled, disabled, or in an unknown state.
I'm sure there's another and better way to do this, but as I said, I'm fairly new at this, and we need to have this done for legal reasons.
Thanks again!
EDIT: If you need more info, please ask me!
I would use the inline syntax in VB.NETonly with short and simple conditions. Otherwise it makes the code less readable and more error-prone.
Try this:
For Each computer In compArray
If compArray(i) <> Computers.GetKey(i) Then
notpresentList.Add(Computers.GetKey(i))
Else
Dim comp = Computers.GetByIndex(i)
If comp = 0 Then
disabledList.Add(Computers.GetKey(i))
ElseIf comp = 1 Then
enabledList.Add(Computers.GetKey(i))
ElseIf comp = 2 Then
unknownList.Add(Computers.GetKey(i))
Else ' added this to show you that this case is not covered yet
Throw New NotSupportedException
End If
End If
i += 1
Next
Your If…Then lines need to be broken up. Move everything after Then to the next lines and you should be good.
If compArray(I) <> Computers.GetKey(I) Then notpresentList.Add(Computers.GetKey(I))
If…Then statements on one line are self-contained, are not followed with a terminating End If, and may not use ElseIf.
Your confusion is in the VB.NET syntax for If statements. VB.NET allows two different formats which each have different syntax rules: Single-line If statements, and Multi-line If blocks.
A single-line If statement looks like this (notice that there is no End If):
If x Then y = 1
A multi-line If block looks like this:
If x Then
y = 1
End If
When you put code on the same line, after the Then, it assumes that you intend it to be a single-line If statement. Single-line If statements cannot include ElseIf, nor Else conditions. They can only be used for simple conditions. Therefore, to make your code work properly, you need to format it as a multi-line If block by putting the conditional code on the following line, like this:
For Each computer In compArray
If compArray(I) <> Computers.GetKey(I) Then
notpresentList.Add(Computers.GetKey(I))
Else
If Computers.GetByIndex(I) = 0 Then
disabledList.Add(Computers.GetKey(I))
Elseif Computers.GetByIndex(I)=1 Then
enabledList.Add(Computers.GetKey(I))
Elseif Computers.GetByIndex(I)=2 Then
unknownList.Add(Computers.GetKey(I))
End if
End if
I += 1
Next
For more information on the syntax, take a look at the MSDN page on the If statement.
Single line If's should all start with just If:
i.e.
If Computers.GetByIndex(I) = 0 Then disabledList.Add(Computers.GetKey(I))
If Computers.GetByIndex(I) = 1 Then enabledList.Add(Computers.GetKey(I))
If Computers.GetByIndex(I) = 2 Then unknownList.Add(Computers.GetKey(I))
You can also use Select Case to make it more readable, i.e.
Select Case Computers.GetByIndex(I)
Case 0
disabledList.Add(Computers.GetKey(I))
Case 1
enabledList.Add(Computers.GetKey(I))
Case 2
unknownList.Add(Computers.GetKey(I))
Case Else
' Some sort of default action can go here, useful for error catching/prevention
End Select
Related
This question already has answers here:
Using multiple else if statements
(3 answers)
Closed 5 months ago.
I am working on a basic yes no game right now as my first vbscript app and I am worried that there is a more efficient way to write this. My main concern is accounting for lowercase answers and at the end I have to write end end end end end etc, my current solution for multiple answers is writing more if statements but that makes my code longer and require a lot of ends at the final line of code
if a ="No" Then
p = MsgBox("Bye")
Else
if a ="no" Then
p1 = MsgBox("Bye")
Else
b = InputBox("What is your name?")
c = InputBox("Isn't that a good name?(Yes/No)")
if c ="No" Then
d = MsgBox("That's not nice.")
Else
if c ="no" Then
d1 = MsgBox("That's not nice.")
Else
l = MsgBox("It's good that you like it, afterall you are stuck with that name.")end if end if end if end if```
To make it so that it isn't non-CaSe SeNsItIvE you can use the LCase or UCase function to make the inputted string either all upper case with UCase or fully lower case with LCase.
For your case you could do:
c = InputBox("Isn't that a good name?(Yes/No)")
if LCase(c) = "no" Then
MsgBox("That's not nice.")
End If
No matter how the user capitalizes the input this will work.
To better visualize refer to this table:
Input
LCase(input)
nO
no
No
no
no
no
(Make sure that your = "WHATEVER" is either all in lowercase or uppercase depending if you use LCase or UCase as using the wrong case sensitivity from your function will not make it work)
Also, side note you don't need to make your MsgBox a variable.
second 'If' can come only after the first statement so there will not be run time error- due to the fact that "el_rule" can be sometimes nothing..
so i can't put both in same statement with AND.
but after both 'if statement' i want same lines of code will run if one of the if statement will not happens(else)... is my only option is too just write it twice?
like on following code? thanks for any help!
If el_rule.Length > 0 Then
If LCase(ActiveCell.Offset(0, el_rule.Item(0).Attributes.getNamedItem("column_number").Text).Value) = LCase(el_rule.Item(0).Attributes.getNamedItem("value").Text) Then
Set el = xDoc.SelectNodes("/simulator")
Else
Set el =....... -code first time
End If
else
Set el =....... -code second time
End If
you could use a helper Boolean variable
Dim doIt As Boolean
If el_rule.Length > 0 Then doIt = LCase(ActiveCell.Offset(0, el_rule.item(0).Attributes.getNamedItem("column_number").Text).Value) = LCase(el_rule.item(0).Attributes.getNamedItem("value").Text)
If doIt Then
Set el = xDoc.SelectNodes("/simulator")
Else
Set el =....... -code only time
End If
I don't quite follow (since I don't know what el_rule is), but VBA doesn't have short-circuiting of its Boolean operators such as And. As a consequence, nested If statements are more common in VBA than in other languages. If el_rule is sometimes nothing then you would need to have code like:
If Not el_rule Is Nothing Then
If el_rule.Length > 0 Then
'Code in which el_rule is something And with Length > 0
End If
Else
'code to handle the case when el_rule is nothing
End If
As an alternative, if it is genuinely an exceptional situation for el_rule to be nothing, you could simply write code that assumes it isn't and use error handling to catch the times when it is.
I'm writing code and there is a null reference exception. I can see where it is, but I can't work out how to fix it. I'm honestly not sure why, I've been reading and re-reading my code, trying different things. I think I'm being dense or possibly have a mental block on it somehow.
The two bits of code are :
For looper = 0 To 3
Sandpit.Controls.Add(Me.QueueMembers(looper).VisRep)
Me.QueueMembers(looper).VisRep.ForeColor = Me.QueueMembers(looper).GetBackgroundColour
Select Case (Me.Direction)
Case "R"
TempPoint.X += 32
TempPoint.Y = 260
Case "U"
TempPoint.Y += 32
Case "L"
TempPoint.X -= 32
End Select
Which works for creating a queue and everything. When I try to remove anything from the queue, though, using the following code:
Public Sub RemoveDiner()
Dim TempDiner As Diner
For looper = 0 To Me.EndPointer - 1
TempDiner = QueueMembers(looper)
QueueMembers(looper) = QueueMembers(looper + 1)
Next
DrawQueue()
End Sub
It's the looper causing the problem, I think because once the item is deleted, there aren't three items in the QueueMembers array.
If someone could just give me advice on how to fix this because I'm being completely dense about it, please, I would be very grateful.
Thanks!
I have always written my For-loops like this:
For foo = 1 to 10
' do something
Next
However, when I read code snippets online, people always do this:
For foo = 1 to 10
' do something
Next foo
I have not noticed any difference between the two, and I can't find any documentation on next statement is more desirable. What is the difference between those two (if any)?
The counter after the Next statement is optional. It used to be required in BASIC-derived languages, but this is no longer the case in VBA.
You can check the VBA reference:
If you omit counter in a Next statement, execution continues as if counter is included. If a Next statement is encountered before its corresponding For statement, an error occurs.
The reason people still add the counter it to increase readability.
It's for when you have multiple for loops.
For example,
For i to j
For k to l
next k
next i
Otherwise, the next is ambiguous. It's not absolutely necessary, as the loop will still work without it, but it's just good practice to have it marked for the sake of anyone else reading your code.
i have this line of code to catch an exception if a letter is inputed, or if it is out of rang as a number, but I have added WHEN to avoid catching numberical data. Now how can I use an exception error to use it before my case statement in order to avoid running the code twice, cause once the case codes has been through it will run a clear txtbox which is already taken care by the try catch, don`t if thats clear for you but i understand it. here is the code in parts...
Try
'Integer Levels: intLvls is egual to the assigned text box, the first one from
'the top, this line of code allow the user input to be captured into a variable.
intLvls = txtBoxLvl.Text
Catch ex As Exception When IsNumeric(intLvls)
ErrTypeLetterFeild1()
Finally
analysingvalues1()
End Try
WHAT I WOULD LIKE TO DO: Use loop until refencing the exception error to avoid running this following part of the code:
Private Sub analysingvalues1()
Do Until IsNumeric (ex As Exception)<------how do i do this???
Loop
the case part of the code:
Select Case intLvls
'User is prompt with the following label: lblLvl "Level of salespersons 1 - 4"
'to make a choice from 1 to 4 as available values.
Case 1 To 4
'This line regulates the range of acceptable values, first textbox: must be egual
'or higher than 1 and lower or egual to 4. Upon such rules a validation becomes
'correct and is directed to the isValidCalculation sub.
isValidCalculation()
Case Is < 1
ErrType1NumberRangeFeild()
Case Is > 4
ErrType1NumberRangeFeild()
Case Else
If txtBoxLvl.Text = "" Then
ErrTypeClear1()
Else
If Not IsNumeric(txtBoxLvl.Text) Then
ErrType1NumberRangeFeild()
Else
ErrTypeLetterFeild1()
ErrTypeClear1()
End If
End If
End Select 'Ending choices.
End Sub
Tks for your help!
If you turn on Option Strict this:
intLvls = txtBoxLvl.Text
Will no longer compile. This should tell you that your doing something smelly.
Turn on Option Strict
The correct solution is not to blindly allow the runtime to cast string to int for you, and catch the exceptions.
When you are converting string user input to an integer, bad input is not an exceptional condition, it is something you should expect and code defensively for.
I would rewrite it to something like this:
'Integer Levels: intLvls is egual to the assigned text box, the first one from
'the top, this line of code allow the user input to be captured into a variable.
if integer.TryParse( txtBoxLvl.Text, intLvls )
analysingvalues1()
else
ErrTypeLetterFeild1()
Edit - As pointed out by Chris below, I meant Option Strict. I recommend using but Explicit and Strict, and Infer if available.