VBS error: "Expected end of statement" - vbscript

I must be overlooking something painfully obvious. The following code fails on the Next line with the error message "Expected end of statement":
Option Explicit
GetB
Sub GetB()
Dim i
For i = 1 to 2
Msgbox i
Next i
End Sub

Found it. The repetition of the loop variable ("i") in the Next statement, which is legal and optional in every other BASIC-like (B*SIC?) language, is illegal in VBS.
The code should read:
Option Explicit
GetB
Sub GetB()
Dim i
For i = 1 to 2
Msgbox i
Next
End Sub

Related

How to get an HTA application to accept command line arguments?

Sub Window_onLoad
arrCommands = Split(ITTool.commandLine, chr(34))
For i = 3 to (Ubound(arrCommands) - 1) Step 2
MsgBox arrCommands(i)
Next
End Sub
When I run my HTA application, I get:
arrCommands is undefined
I am trying to make an HTA app that accepts command line arguments (optional).
Your script section contains an Option Explicit statement. That makes defining variables before you can use them mandatory. Add a line Dim arrCommands, i to your procedure:
Sub Window_onLoad
Dim arrCommands, i
arrCommands = Split(ITTool.commandLine, chr(34))
For i = 3 to (Ubound(arrCommands) - 1) Step 2
MsgBox arrCommands(i)
Next
End Sub

How to pass error back to calling function?

What is the best way in VB6 to pass an error back to the calling function?
1 On Error Resume Next
2 ' do something
3 If Err.Number <> 3026 Or Err <> 0 Then ?????????
How would you send the error in Line 3 back to the calling function? Is the following the only way to achieve this?
errNum = Err.Number
On Error Goto 0
Err.Raise errNum
Use On Error GoTo and re-raise the error in the handler with Err.Raise.
Private Function DoSomething(ByVal Arg as String)
On Error GoTo Handler
Dim ThisVar as String
Dim ThatVar as Long
' Code here to implement DoSomething...
Exit Function
Handler:
Err.Raise Err.Number, , "MiscFunctions.DoSomething: " & Err.Description
End Function
You'll then be able to get the error number and description in the caller via Err.Number and Err.Description.
If the caller is also using On Error GoTo, you'll see them in the handler there.
If the caller is using On Error Resume Next, then you can still use those same variables inline.
I prefer the first option, using On Error Goto in all functions and subs, because it seems like the natural way to use VB6's built-in error raising features. You can also update the description in the called function's handler, like the example above, and get a pseudo call stack you can eventually log or display to yourself during debugging.
More VB6 error handling thoughts here:
Is it possible to retrieve the call stack programmatically in VB6?
How to clean up error handling in a function?
Why not add ByRef errorCode as Long to the called function's args and set it equal to Err.Number after ' do something
Or you could have a public field called ErrorCode as Long that you could set after ' do something
I have worked with a lot of industrial control APIs and both of these methods have been used.
You can easily send the error to the upper (calling) sub/function as long as the function that raises the error does not have (ON ERROR RESUME ---), that way, error handling is left in the upper level only. Otherwise you will have to handle the error inside the called function
Private Sub Command1_Click()
Dim test As Integer
On Error Resume Next
test = myFunction 'Calling a function that is known to have an error
If Err <> 0 Then
MsgBox "MyFunction failed because:" & Err.Description 'Error is passed
End If
End Sub
'--------------------------
Function myFunction() As Integer
Dim i As Integer
i = 1
i = 4 / 0 'This will raise an Error, and control returns to the calling sub
i = 2 'This will never get executed
myFunction = i
End Function
If you simply want to pass the error back to the original caller without handling it, then you want to remove any ON ERROR in the child function:
Public Sub ParentSub()
On Error GoTo ErrorHandler
' do something
Call ChildSub()
' do something
Exit Sub
ErrorHandler:
' handle the error here
End Sub
Public Sub ChildSub()
' do something
' if there is an error here, the error will be handled in ErrorHandler of ParentSub
End Sub
or if you want to handle it in both subs:
Public Sub ParentSub()
On Error GoTo ErrorHandler
' do something
Call ChildSub()
' do something
Exit Sub
ErrorHandler:
' handle the error here
End Sub
Public Sub ChildSub()
On Error GoTo ErrorHandler
' do something
Exit Sub
ErrorHandler:
' handle the error here and pass it back to the ParentSub to handle it as well
Err.Raise Err.Number
End Sub

VB6 Exception Handling within the calling procedure

I have two procedures procA and procB. procA is calling procB. An exception occurs within procB. I can handle the exception within procB, but i like to handle it within procA and this is what i did not get to work. I'm not very familiar with VB6 but i think this should be possible because MSDN says:
If an error occurs while an error handler is active (between the occurrence of the error and a Resume, Exit Sub, Exit Function, or Exit Property statement), the current procedure's error handler can't handle the error. Control returns to the calling procedure. If the calling procedure has an enabled error handler, it is activated to handle the error.
What i'm doing wrong?
Now the code fragments:
Private Sub procA()
On Error GoTo ErrHnd
...
procB obj
Exit Sub
ErrHnd:
MsgBox Err.Description, vbInformation, Me.caption
End Sub
Public Sub procB(ByRef rec As Object)
On Error GoTo ErrHnd
... Exception occurs within DAO Recordset Operation
Exit Sub
ErrHnd:
Select Case Err.Number
Case 3022
Err.Raise vbObjectError + 9999, Err.Source, "Error Text"
Case Else
...
End Select
End Sub
I also tried to turn off exception handling within procB (On Error Goto 0) but it seems that procA never gets the Exception.
Thanks for your help.
Edit: Additional information:
Exception Raised from DAO.Recordset Object.
I also tried to completele remove exception handling within procB with no effect.
procA exists in another file then procB (data.cls, frmListArtikel.frm).
Solution: I didn't know that it makes a difference how the programm is executed. If i start it from the IDE, the Exception does not get handled by procA. If i start the EXE (previously making it from the IDE) from the Explorer, the Exception gets handled as desired by procA.
You can only have one active error handler at a time. If you activate in procb, procb will handle.
you may also need to check your editor settings. choose the option "Tools > Options > General tab" "break in class module"
Code sample 1. you will receive error 6 in procA:
Private Sub Form_Load()
Call procA
End Sub
Private Sub procA()
On Error GoTo errhan
procB
Exit Sub
errhan:
Debug.Print "proca handle"
End Sub
Private Sub procB()
Err.Raise 6
End Sub
Code sample 2. You will receive error 7 in procA:
Private Sub Form_Load()
Call procA
End Sub
Private Sub procA()
On Error GoTo errhan
procB
Exit Sub
errhan:
Debug.Print "proca handle"
End Sub
Private Sub procB()
On Error GoTo errhan
Err.Raise 6
errhan:
Err.Raise 7
End Sub
Check your editor settings and choose the option "Tools > Options > General tab" "Break on Unhandled Errors"
check this link: http://www.fmsinc.com/tpapers/vbacode/debug.asp

Does anyone remember what the statement/command "WaitOn" meant in VB3?

In the Form_Load event of this ultralegacy app I need to transliterate over to a web app is this command/statement "WaitOn" that occurs right after the On Error GoTo...
Does anyone remember what WaitOn means?
Here's the code snippet:
Dim sCmd As String
Dim iFileHandle As Integer
Dim sFileName As String
Dim i As Integer
Dim sKeyWord As String
Dim sWindowPosition As String
Dim iWindowState As Integer
Dim sSystemId As String
Dim sMetrics() As String
On Error GoTo MainFormLoadErr
WaitOn
ReDim gsFundsUsed(0 To 0)
ReDim gsObjectsUsed(0 To 0)
Set gsActiveSpread = Nothing
.
.
.
MainFormLoadExit:
WaitOff
Close
Exit Sub
MainFormLoadErr:
MsgBox Error$(Err) & " in MainForm Load"
Resume MainFormLoadExit
There is a corresponding WaitOff down there I just found. I don't think WaitOn is part of a line label.
As #C-Pound Guru suggested, WaitOn and WaitOff were methods in one of the (many) modules of the program. Not clear from the the names of the subroutines was the fact that their task was to set the mouse pointer to the Wait Cursor, and then return to the default, later.
Sub WaitOn ()
On Error Resume Next
Screen.MousePointer = 11
End Sub
Sub WaitOff ()
On Error Resume Next
Screen.MousePointer = 0
End Sub
I've never come across a 'WaitOn' or 'WaitOff' command in VB. You might want to double-check the code to see if there's a WaitOn method written (and a WaitOff method as well). It's not a label as VB labels end with a colon (:).
What happens if you right-click and Go To Definition? And does the code currently run?
Check the references - maybe it's something from a non-standard dll.

Word macro error messages

I am changing document template macros. The one thing I can't find out how to do is to customize error messages. For example an error message in a document is
"Error! No table of figures entries found"
I would like to change this to display something else. Is it possible to do this with Word VBA or VBScript?
Is it possible to put this in some
kind of global error handler? – Craig
It is possible. Here is a very rough example.
In a standard module:
Sub HandleErr(ErrNo As Long)
Select Case ErrNo
Case vbObjectError + 1024
MsgBox "No table of figures entries found.", vbOKOnly + vbCritical
Case vbObjectError + 1034 To vbObjectError + 4999
MsgBox "Still no table of figures entries found.", vbOKOnly + vbCritical
Case Else
MsgBox "I give up.", vbOKOnly + vbCritical, _
"Application Error"
End Select
End Sub
Some code:
Sub ShowError()
Dim i As Integer
On Error GoTo Proc_Err
'VBA Error
i = "a"
'Custom error
If Dir("C:\Docs\TableFigs.txt") = "" Then
Err.Raise vbObjectError + 1024
End If
Exit_Here:
Exit Sub
Proc_Err:
If Err.Number > vbObjectError And Err.Number < vbObjectError + 9999 Then
HandleErr Err.Number
Else
MsgBox Err.Description
End If
End Sub
If you want to trap a specific error type in VBA, one method is to use On Error Resume Next then test for an error message on the line following the action to trap, e.g.:
On Error Resume Next
' try action
If Err.Number <> 0 Then
' handle w/ custom message
Err.Clear
End If
If you know the exact error number (If Err.Number = N Then), that would be better of course.
Well if you are talking about having a custom message box - that's easy.
Look up 'msgbox' in VBA help for better info.
Msgbox("Error! No table of figures entries found",16,"Error")
The 16 makes it a 'criticial' message.
If you're talking about error trapping then you'll need code like this:
On Error Resume Next
n = 1 / 0 ' this causes an error
If Err.Number <> 0 Then
n = 1
if Err.Number = 1 Then MsgBox Err.Description
End If
When an error is thrown, a number and description are given to the Err object.

Resources