trouble with the error expected "end" - vbscript

what am I doing wrong in this script?
Randomize
value=int((150 * Rnd + 1) * Rnd + lowerbound)
guess+inputbox("guess the number","guess","guess here")
if guess=value then
msgbox("correct"),0+64+4096,("guess")
wscript.quit
else
if guess < value then
msgbox("too low"),0+32+4096,("guess")
once=1
end if
else
msgbox("too high"),0+32+4096,("guess")
end if
once=1
do
guess=inputbox("try again","guess","guess here")
if guess=value then
msgbox("correct"),0+64+4096,("guess")
else
if guess < value then
msgbox("too low"),0+32+4096,("guess")
end if
else
msgbox("too high"),0+32+4096,("guess")
end if
loop
If you can figure out what is going wrong that would be great.
It has been saying
expected "end"
and when I do what it says I will run it and it still won't work.

Have edited the code to properly indent it which should help highlight the issue. The error is because an If statement can only have one Else condition, the basic structure of an If statement is;
If <boolean condition> Then
<true outcome>
Else
<false outcome>
End If
At the moment you have multiple instances of
If <boolean condition> Then
<true outcome>
Else
<false outcome>
Else
<unknown condition>
End If
which is invalid syntax because a basic If statement can only return True or False.
However there is also ElseIf which allows multiple boolean conditions to be specified and return different outcomes.
Which looks like this;
If <boolean condition> Then
<true outcome>
ElseIf <boolean condition> Then
<true outcome>
ElseIf <boolean condition> Then
<true outcome>
Else
<false outcome>
End If
Based on how you are nesting the If statements the code in question could be re-written like this;
Randomize
value = Int((150 * Rnd + 1) * Rnd + lowerbound)
guess = InputBox("guess the number", "guess", "guess here")
If guess = value Then
Call MsgBox("correct", vbOKOnly + vbInformation + vbSystemModal, "guess")
WScript.Quit
ElseIf guess < value Then
Call MsgBox("too low", vbOKOnly + vbQuestion + vbSystemModal, "guess")
once = 1
Else
Call MsgBox("too high", vbOKOnly + vbQuestion + vbSystemModal, "guess")
End if
once = 1
Do
guess = InputBox("try again", "guess", "guess here")
If guess = value Then
Call MsgBox("correct", vbOKOnly + vbInformation + vbSystemModal, "guess")
ElseIf guess < value then
Call MsgBox("too low", vbOKOnly + vbQuestion + vbSystemModal, "guess")
Else
Call MsgBox("too high", vbOKOnly + vbQuestion + vbSystemModal, "guess")
End If
Loop
Couple of things to note about the example above
Replaced the + with = in the line
guess+inputbox("guess the number","guess","guess here")
as it won't assign the result of InputBox() to guess which is what I'm assuming you are doing. If you were trying to concatenate the result of InputBox() to guess that still wouldn't work you would have to use
guess = guess + InputBox("guess the number", "guess", "guess here")
If that was the case though personally I prefer to use & over + for string concatenation.
The brackets in MsgBox() appear to be a bit odd, usually you would call MsgBox() without brackets if not returning the result to a variable, like this;
MsgBox "correct", vbOKOnly + vbInformation + vbSystemModal, "guess"
but if you did want to include the brackets (as I prefer to do) you can just use Call like this
Call MsgBox("correct", vbOKOnly + vbInformation + vbSystemModal, "guess")
which avoids the dreaded
Microsoft VBScript compilation error: Cannot use parentheses when calling a Sub
but still allows the function to be surrounded with brackets when no value is being returned.
You may also noticed that I replaced the hardcoded numeric values in MsgBox() with the Named Constants which is easier for others to read and interpret their meaning. They are also hard-boiled into VBScript so there is no excuse for not using them.
Thinking about what you trying to do thought I could re-factor the code a little bit to hopefully make it work as you expected
Dim value, guess, msg, once
Randomize
value = Int((150 * Rnd + 1) * Rnd + lowerbound)
Do
If once = 0 Then
msg = "guess the number"
Else
msg = "try again"
End If
guess = CInt(InputBox(msg, "guess", "guess here"))
If guess = value Then
Call MsgBox("correct", vbOKOnly + vbInformation + vbSystemModal, "guess")
WScript.Quit
ElseIf guess < value then
Call MsgBox("too low", vbOKOnly + vbQuestion + vbSystemModal, "guess")
once = 1
Else
Call MsgBox("too high", vbOKOnly + vbQuestion + vbSystemModal, "guess")
once = 1
End If
Loop
Things to take from this;
We only need the one InputBox() inside the loop to handle both the first initial guess and the subsequent "try again" attempts. This means we are not duplicating the same piece of code again, see DRY Principle.
InputBox() returns a string so at first the code was trying to compare a string value with a integer value which will give all sorts of weird results. By casting to integer using CInt() the comparison starts to work as expected.

Related

Dir function error "wrong number of arguments or invalid property assignment"

I have made a control panel within vb6, and in one of the forms, I want the user of the program to change the name of the existing text file or rewrite it. I am using the Dir function as shown below:
If Check3.Value = 1 Then
If Dir(File.Path + " \ " + Form2.filetext.Text, vbNormal) <> 0 Then
intfile = MsgBox("File existing. Do you want to delete the existing file?", vbYesNo, "WARNING")
If intfile = 6 Then
Open File.Path + "\" + Form2.filetext.Text For Output As #3
Else
Open File.Path + "\" + Form2.filetext.Text For Append As #3
End If
Else
Open File.Path + "\" + Form2.filetext.Text For Output As #3
End If
Else
Close #3
End If
End Sub
But when I chose my file or changing the name, the Dir function gives me this error
wrong number of arguments or invalid property assignment
I would appreciate it if you could help me.
Change Line
If Dir(File.Path + " \ " + Form2.filetext.Text, vbNormal) <> 0 Then
to
If Dir(File.Path + "\" + Form2.filetext.Text, vbNormal) <> "" Then
Add "Option Explicit" without Quotes on top of code of form and check for undeclared variable

vb 2010 conditional statements inside listview

I put three items in a listview and checkboxes to choose one of them at time. The code works if I check the items from the first to the last but it doesn't when and go backwards. I mean, after choosing the last item if I choose again the second the message shown is wrong. How can fix it?
Cheers.
For Each Me.item In lsv_school.Items
If Not item.Index = e.Index Then
item.Checked = False
If e.Index = lsv_school.Items(0).Checked Then
lbl_err.Hide()
lbl_feed.Text = "Your school tuition will be " + "$" & dipAcc + " per term."
ElseIf e.Index = lsv_school.Items(1).Checked Then
lbl_err.Hide()
lbl_feed.Text = "Your school tuition will be " + "$" & dipBus + " per term."
ElseIf e.NewValue = lsv_school.Items(2).Checked Then
lbl_err.Hide()
lbl_feed.Text = "Your school tuition will be " + "$" & dipMar + " per term."
End If
End If
Next
End Sub
I solved the mess by myself, thanks for your suggestions but I had to use those components and could not do otherwise. I will post the code I used.
The first sub class is a loop to check one checkbox at time.
Private Sub lsv_school_ItemCheck(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles lsv_school.ItemCheck
'Loop to check one checkbox at time.
For Each Me.item In lsv_school.Items
If Not item.Index = e.Index Then
item.Checked = False
End If
Next
End Sub
The second sub class solve the problem, the conditional statements now check each case properly.
Private Sub lsv_school_ItemChecked(ByVal sender As Object, ByVal e As ItemCheckedEventArgs) Handles lsv_school.ItemChecked
'Conditional statements to select one course at time.
If lsv_school.Items(0).Checked = True Then
item.Selected = CBool(dipAcc)
lbl_err.Hide()
lbl_feed.Show()
lbl_feed.Text = "Your school tuition will be " + "$" & dipAcc
ElseIf lsv_school.Items(1).Checked = True Then
item.Selected = CBool(dipBus)
lbl_err.Hide()
lbl_feed.Show()
lbl_feed.Text = "Your school tuition will be " + "$" & dipBus
ElseIf lsv_school.Items(2).Checked = True Then
item.Selected = CBool(dipMar)
lbl_err.Hide()
lbl_feed.Show()
lbl_feed.Text = "Your school tuition will be " + "$" & dipMar
Else
If item.Checked = False Then
lbl_feed.Text = ""
lbl_feed.Hide()
lbl_err.Show()
lbl_err.Text = "Select a course from the list."
End If
End If
End Sub
In this way I managed to let checkboxes work as radiobuttons inside a listview.

QTP: Checking If an array of strings contains a value

I am having trouble getting my test case to run correctly.
The problem is in the code below, the first if statement to be exact. QTP complains that an object is required
For j=Lbound(options) to Ubound(options)
If options(j).Contains(choice) Then
MsgBox("Found " & FindThisString & " at index " & _
options.IndexOf(choice))
Else
MsgBox "String not found!"
End If
Next
When I check the array I can see that it is populated correctly and 'j' is also the correct string.
Any help with this issue would be greatly appreciated.
Strings in VBScript are not objects, in that they do not have member functions. Searching for a substring should be done by using the InStr function.
For j=Lbound(options) to Ubound(options)
If InStr(options(j), choice) <> 0 Then
MsgBox("Found " & choice & " at index " & j
Else
MsgBox "String not found!"
End If
Next
A concise way to check if an array of strings contains a value would be to combine the Filter and UBound functions:
If Ubound(Filter(options, choice)) > -1 Then
MsgBox "Found"
Else
MsgBox "Not found!"
End If
Cons: you don't get the indexes where the elements are found
Pros: it's simple and you have the usual include and compare parameters to specify the matching criteria.
Function CompareStrings ( arrayItems , choice )
For i=Lbound(arrayItems) to Ubound(arrayItems)
' 0 - for binary comparison "Case sensitive
' 1 - for text compare not case sensitive
If StrComp(arrayItems(i), choice , 0) = 0 Then
MsgBox("Found " & choice & " at index " & i
Else
MsgBox "String not found!"
End If
Next
End Function
Hi if you check exact String not sub-String in the array use StrComb because if use InStr then if array = "apple1" , "apple2" , "apple3" , "apple" and choice = "apple" then all will return pass for every array item.
Function CompareStrings ( arrayItems , choice )
For i=Lbound(arrayItems) to Ubound(arrayItems)
' 1 - for binary comparison "Case sensitive
' 0 - not case sensitive
If StrComp(arrayItems(i), choice , 1) = 0 Then
CompareStrings = True
MsgBox("Found " & choice & " at index " & i
Else
CompareStrings = False
MsgBox "String not found!"
End If
Next
End Function

Help Continue VBS String?

I'm VERY new to VBScript and general computer programing in general.
IF I were to do this:
a=inputbox("Password:")
if a="Drop Zero" then
msgbox"Loging On"
else
msgbox"Invalid"
end if
a=inputbox("Hello, what would you like to know:")
I can't continue with the if and else after the second input box. Any help would be highly appreciated for a nOOb such as myself.!!
I'm in trouble understanding your question.
Anyway, if you need to quit when password is wrong, you can try this:
a=inputbox("Password:")
if a="Drop Zero" then
msgbox"Logging On"
else
msgbox"Invalid"
WScript.Quit
end if
a=inputbox("Hello, what would you like to know:")
UPDATE:
Look at this code taken from here:
Function ValidInteger(sNumber,iMin,iMax)
If IsNumeric(sNumber) = 0 Then
If InStr(sNumber,".") Then
If CLng(sNumber)>= iMin And CLng(sNumber)<= iMax Then
ValidInteger=""
Else
ValidInteger = "You must enter a number between " & iMin & " and " & iMax
End If
Else
ValidInteger = "You must enter a whole number"
End If
Else
ValidInteger = "You must enter a number value"
End If
End Function

VB6: Runtime Error '13': Type Mismatch when setting and int with an int

I'm not new to VB6 programming, but I'm not a master at it either. Hopefully someone can help me out with a question that I have concerning a Type Mismatch error that I'm receiving from trying to set an int variable with a int returned from a function.
The integer that I'm trying to set is defined as:
Global AICROSSDOCKStatus As Integer
Now when I try to make this call I get the Runtime Error 13
AICROSSDOCKStatus = ProcessQuery(iocode, pb, AICROSSDOCBOLFN, "")
I've stepped through debugging the program line for line. The ProcessQuery function gets and returns the expected integer, but when the assignment is to be made to the AICROSSDOCKStatus it fails.
On a side note, I've also tried doing a CInt() to the ProcessQuery with the same result.
Does anyone have any suggestions for what I may be able to try?
Edit:
Here is the definition of ProcessQuery
Function ProcessQuery(icode As Integer, pb As ADODB.Recordset, TableName As String, sql$) As Integer
Edit 2: I couldn't tell you why this was done in this manner. I inherited the code base. Yikes...
Function ProcessQuery(icode As Integer, pb As ADODB.Recordset, TableName As String, sql$) As Integer
ProcessQuery = ProcessQuery1(icode, pb, TableName, sql$)
End Function
Function ProcessQuery1(icode As Integer, pb As ADODB.Recordset, TableName As String, sql$) As Integer
''THIS IS THE ORIGINAL SQL CALL ROUTINE!
Dim STATUS As Integer
On Error GoTo ProcessSQLError
STATUS = 0
Select Case icode
Case BCLOSE
If pb.State 0 Then
pb.Close
End If
Set pb = Nothing
STATUS = 3
Case BOPEN
STATUS = 9
Set pb = New ADODB.Recordset
Case BOPENRO
STATUS = 9
Set pb = New ADODB.Recordset
Case BGETEQUAL, BGETEQUAL + S_NOWAIT_LOCK, BGETGREATEROREQUAL, BGETGREATEROREQUAL + S_NOWAIT_LOCK
If pb.State 0 Then
pb.Close
''Set pb = Nothing
''Set pb = New ADODB.Recordset
End If
pb.Open sql$, MISCO_SQL_DB, adOpenDynamic, adLockOptimistic
If Not pb.EOF Then
pb.MoveFirst
Else
STATUS = 9
End If
Case BGET_LE, BGET_LE + S_NOWAIT_LOCK
If pb.State 0 Then
pb.Close
End If
pb.Open sql$, MISCO_SQL_DB, adOpenDynamic, adLockOptimistic
If Not pb.BOF Then
pb.MoveLast
Else
STATUS = 9
End If
Case BGETFIRST, BGETFIRST + S_NOWAIT_LOCK
If pb.State 0 Then pb.Close
sql = "select * from " + TableName
If InStr(1, gblOrderBy, "ORDER BY") > 0 Then
sql = sql + gblOrderBy
Else
sql = sql + " ORDER BY " + gblOrderBy
End If
gblOrderBy = ""
pb.Open sql$, MISCO_SQL_DB, adOpenDynamic, adLockOptimistic
If Not pb.EOF Then
pb.MoveFirst
End If
Case BGETLAST, BGETLAST + S_NOWAIT_LOCK
If pb.State 0 Then
pb.Close
End If
sql = "select * from " + TableName
If InStr(1, gblOrderBy, "ORDER BY") > 0 Then
sql = sql + gblOrderBy
Else
sql = sql + " ORDER BY " + gblOrderBy
End If
gblOrderBy = ""
pb.Open sql$, MISCO_SQL_DB, adOpenDynamic, adLockOptimistic
If Not pb.EOF Then
pb.MoveFirst
pb.MoveLast
End If
Case BGETNEXT, BGETNEXT + S_NOWAIT_LOCK: pb.MoveNext
Case BGETPREVIOUS, BGETPREVIOUS + S_NOWAIT_LOCK: pb.MovePrevious
Case B_UNLOCK
''need to add code here
Case BINSERT
If pb.State = 0 Then
pb.Open TableName, MISCO_SQL_DB, adOpenDynamic, adLockOptimistic
End If
Case BDELETE
STATUS = 8
pb.Delete
Case Else
STATUS = 1
MsgBox "STOP: UNDEFINDED PROCEDURE" + Str$(icode)
End Select
If STATUS = 0 Then
If pb.EOF Or pb.BOF Then STATUS = 9
End If
ProcessQuery1 = STATUS
Exit Function
ProcessSQLError:
MsgBox TableName + ": " + Error(Err), vbCritical, "Error "
ProcessQuery1 = 9
End Function
Well, I can't say I know what's breaking, but here's a possible debugging step: Assign a locally defined integer first, then assign AICROSSDOCKStatus to the local int. If the run-time err 13 happens at the first assignment, something REALLY weird is going on - if it happens at the second, then you might want to see if any of your global variables are arrays that you might be overrunning bounds on.
Good luck!
Try using an intermediate Variant which should take any kind of type from your function. It should at least allow you to investigate the real type of the return value.
This will tell you the name of the type your function is actually returning:
MsgBox TypeName(ProcessQuery(...))
Confining the ProcessQuery() function to int might be helpful in any case, to prevent such errors right from the start:
Function ProcessQuery(whatever arguments) As Integer
''// ...
End Function
It's a little unusual for an API to return a VB6 Integer, which is a 16-bit quantity. Fairly often, someone translating a C function prototype will confuse a c "int" with a VB6 Integer, when the equivalent is really a Long in VB6.
The problem was not in the fact that it was having trouble with the returns from a function but the parameters that were being passed by reference. I needed a Recordset(pb) to pass by reference, but I had declared (pb) as a Record.
Try the following and see if the value turns out to be an int,
msgbox ProcessQuery(iocode, pb, AICROSSDOCBOLFN, "")
I am sure it won't be an int & that is the result it is failing. My guess is that, it will have come characters which makes it a non-numeric value.
You can try IsNumeric() function on the results to check, if it is a numeric value.

Resources