What's wrong with using GOTO ?????

  • Thread starter trevorC via AccessMonster.com
  • Start date
T

trevorC via AccessMonster.com

As a tool to move within code whats wrong with using goto to - as an example -
3 buttons on a form, 1st button is clicked and the code sets a textbox value
to say 1, then exit sub. Clicking one of the other buttons calls the button 1
code to run and at the start of the is a case to determine wich button was
pressed and then using GOTO go to a portion of the code related to that
action, and so on for each button.
 
S

Stuart McCall

trevorC via AccessMonster.com said:
As a tool to move within code whats wrong with using goto to - as an
example -
3 buttons on a form, 1st button is clicked and the code sets a textbox
value
to say 1, then exit sub. Clicking one of the other buttons calls the
button 1
code to run and at the start of the is a case to determine wich button was
pressed and then using GOTO go to a portion of the code related to that
action, and so on for each button.

Some folks will tell you that using GoTo is a Bad Thing. But then they'll
tell you you must have error handlers, where you have no choice other than
using GoTo. I say if it's good enough for error handling then it's good
enough to use elsewhere. However you must remember to use it sparingly or
code soon becomes an ugly mess (jumping here and there like a flea).

So go ahead and use it, but bear that in mind when you do.
 
D

Dirk Goldgar

Stuart McCall said:
Some folks will tell you that using GoTo is a Bad Thing. But then they'll
tell you you must have error handlers, where you have no choice other than
using GoTo. I say if it's good enough for error handling then it's good
enough to use elsewhere. However you must remember to use it sparingly or
code soon becomes an ugly mess (jumping here and there like a flea).

So go ahead and use it, but bear that in mind when you do.


"On Error Go To" is not really the same as a standalone Go To statement, and
I think it's misleading to use error-handling as a justification for
non-error Go To statements. However, error-trapping does share one
*negative* aspect with normal Go To statements: when code is executing
anywhere after a target label, you can't tell how the program got there:
normal sequential execution, or Go To.

I won't say *never* use a Go To statement, but I will say that good
old-fashioned structured code using "If ... Then ... Else ... End If",
"Select Case", "Do ... Loop", and "While ... Wend" will almost always do the
job better, make the procedure logic clearer, and be easier to maintain.

I have found a very few cases where a Go To was the only practical way to
make an odd logic structure work. In those cases, you had better believe I
documented the hell out of what I was doing and why!
 
T

tbs

There's absolutely nothing wrong with using goto. i use that alot. however, I
do know of ppl who got lost in their codes after using goto. so unless you're
logically strong, i would advise you to avoid using goto.
 
D

Dirk Goldgar

trevorC via AccessMonster.com said:
As a tool to move within code whats wrong with using goto to - as an
example -
3 buttons on a form, 1st button is clicked and the code sets a textbox
value
to say 1, then exit sub. Clicking one of the other buttons calls the
button 1
code to run and at the start of the is a case to determine wich button was
pressed and then using GOTO go to a portion of the code related to that
action, and so on for each button.


I can't imagine how the type of logic you describe wouldn't be better
handled by a Select Case structure. Maybe you could give some sample code
to demonstrate how you would use Go To, and I -- or someone -- could suggest
a better structure. If not, then a Go To is probably justified.
 
T

trevorC via AccessMonster.com

Here ya go, try and sort this out,
the basics of it are that I wanted this to be a touch screen interface for
time tracking, thus i had to create my own messages with large buttons, the
code hides/ not hides the buttons and depending on what stage of the entry
they are up to the first case will direct them to the next correct place to
continue after there previous selection.
I know there is lots of ways to do this but i wanted to try and see if this
works, and it does.


Private Sub Command17_Click() '
start work day
Me.msg_title.Caption = "Entry Update Notification - START SHIFT"
Select Case Me.msg_no.Tag
Case Is = "msg_return1"
GoTo msg_return1
Case Is = "msg_return2"
GoTo msg_return2
Case Is = "msg_return3"
GoTo msg_return3
Case Else
End Select
Select Case Me.msg_yes.Tag
Case Is = "msg_return1"
GoTo msg_return1
Case Is = "msg_return2"
GoTo msg_return2
Case Is = "msg_return3"
GoTo msg_return3
Case Else
End Select
Dim Msg_Box1, Late_Reason, a, b, aa, bb, Normal_Start_Time
Normal_Start_Time = Format(DLookup("[normal start time]", "[Employees]", "
[barcode] = " & Me.[scan input]), "hh:mm")
aa = Format(Me.Scan_Date, "short date") '
scan date
a = Emp_ID '
lookup using barcode
b = Me.Employee_ID '
stored value
loop1:
bb = Format(Me.[Scan Date In], "short date")
If b = 0 Or IsNull(b) Then GoTo add_new
If a = b Then '
check for correct employee id
If Format(aa, "short date") = Format(bb, "short date") Then '
check if scan date = recorded scan date
PlaySound ("\\Tran1\database\Fail.wav")
Me.msg_yes.Tag = "msg_return1"
Me.msg_no.Tag = "msg_return1"
Me.msg_header.Caption = "An entry already exists for the Start of
your shift for Today"
Me.msg_text.Caption = "Existing Entry, Date - " & Me.
Scan_Date_In & " Time - " & Format(Me.Scan_Time_In, "hh:mm") & vbCrLf &
"Your Comments - " & Me.[Comments Scan In]
Me.msg_footer.Caption = "Select Yes to update to the new entry or
No to cancel"
Call Message_Box_Yes_No
Me.msg_yes.SetFocus
Me.msg_input.Visible = False
Exit Sub
msg_return1:
Select Case Me.msgbutton.Tag
Case Is = "yes"
GoTo Update_entry
Case Is = "no"
PlaySound ("\\Tran1\database\alert.wav")
Me.msg_header.Caption = "Entry was canceled"
Me.msg_text.Caption = vbCrLf & " Your
previous entry has not been changed"
Call Message_Box_Ok 'and exit
Exit Sub
End Select
Else
DoCmd.GoToRecord , , acNext
b = Me.Employee_ID '
stored value
GoTo loop1
End If
Else
DoCmd.GoToRecord , , acNext
b = Me.Employee_ID '
stored value
GoTo loop1
End If
Exit Sub
Exit_Point:
Me.msg_header.Caption = "Entry Updated to - "
Me.msg_text.Caption = " Shift Start Date - " & Me.Scan_Date & " Shift
Start Time - " & Me.Scan_Time & vbCrLf & "Comments - " & vbCrLf & Me.
[Comments Scan In]
Me.msg_footer.Caption = "Select Project Update or OK to return to the Main
Menu"
Call Message_Box_Ok
DoCmd.OpenQuery "update attendance to In"
Forms![main menu]![employees at work].Form.Requery
Exit Sub '
exit here
' loopentry points
add_new:
DoCmd.GoToRecord , , acNewRec
Update_entry:
If Format(Normal_Start_Time, "hh:mm") < Format(Me.Scan_Time, "hh:mm") Then
Me.msg_yes.Caption = "Ok"
Me.msg_no.Caption = "Cancel"
Me.msg_yes.Tag = "msg_return2"
Me.msg_no.Tag = "msg_return2"
Me.msg_header.Caption = "An entry is required to continue"
Me.msg_text.Caption = "A reason is required for scanning In After your
normal Start time."
Me.msg_footer.Caption = "Select Ok to continue or Cancel to exit"
Me.msg_yes.Enabled = False
Call Message_Box_Input
Exit Sub
msg_return2:
Select Case Me.msgbutton.Tag
Case Is = "yes"
Me.In_late_reason = Me.msg_input
Case Is = "no"
PlaySound ("\\Tran1\database\alert.wav")
Me.msg_header.Caption = "Entry was canceled"
Me.msg_text.Caption = vbCrLf & " Your previous
entry has not been changed"
Call Message_Box_Ok
Exit Sub
End Select
End If
Me.yesterdays_date = IIf(Weekday(Date) = 2, Date - 3, Date - 1)
ttt = DMax("[scan date out]", "[time tracking]", "[Employee id]= " & Me.
Emp_ID)
If IsNull(ttt) Then GoTo not_in
If ttt <> Me.yesterdays_date Then
not_in:
Me.msg_yes.Caption = "Ok"
Me.msg_no.Caption = "Cancel"
Me.msg_yes.Tag = "msg_return3"
Me.msg_no.Tag = "msg_return3"
Me.msg_header.Caption = "An entry is required to continue"
Me.msg_text.Caption = "Please enter a reason for Not Scanning Out
Yesterday."
Me.msg_footer.Caption = "Select Ok to continue or Cancel to exit"
Me.msg_yes.Enabled = False
Call Message_Box_Input
Exit Sub
msg_return3:
Select Case Me.msgbutton.Tag
Case Is = "yes"
Me.not_scanned_out = Me.msg_input
Case Is = "no"
PlaySound ("\\Tran1\database\alert.wav")
Me.msg_header.Caption = "Entry was canceled"
Me.msg_text.Caption = vbCrLf & " Your previous
entry has not been changed"
Call Message_Box_Ok
Exit Sub
End Select
End If
Me.Reason_Not_Scanned_Out = Me.not_scanned_out
Me.Late_Reason_In = Me.In_late_reason ' copy text from form to table
Me.[Scan Time In] = Format(Me.Scan_Time, "hh:mm")
Me.[Scan Date In] = Me.Scan_Date
Me.[Comments Scan In] = Me.Notes
Me.Employee_ID = Me.Emp_ID
PlaySound ("\\Tran1\database\success.wav")
GoTo Exit_Point
End Sub
 
B

Banana

trevorC said:
Here ya go, try and sort this out,

Personally, I'd break it up into smaller procedures. A set of
simple-minded functions that does one thing very well is much easier to
pipe than changing logic of a large procedure.

Basically:

Private Sub cmdMyButton_Click()
On Error GoTo Error_Handler

If IsValid(Me.MyTextBox) Then
FillInDefaults
Else
Msgbox "The data in MyTextbox is not valid."
End If

Exit_Procedure:
Exit Sub
Error_Handler
Msgbox Err.Number & " " & Err.Description
Resume Exit_Procedure
End Sub

Private Function IsValid(vInput As Variant) As Boolean

'Do some voodoo to validate

End Function

Private Sub FillInDefaults()

'Fill in defaults. Should be called just prior to saving
'the record as opposed to using the builtin Default Value
'property.

End Sub


Basically, by having several simple procedures and leaving it up to the
event handlers to pipe it together, it's now very easy to maintain the
code and you only have one place to define a certain thing... In a
sense, it's no different from "normalizing" the data. I like to think of
this as "normalizing" the VBA code (though I'm using the term quite fast
and loose). As soon as I find two pieces of code that does similar
thing, then I'm thinking I'm doing it wrongâ„¢.

So, I've yet to find a piece of code where GoTo was the only way forward.

Just my two bits.
 
D

Dirk Goldgar

trevorC via AccessMonster.com said:
Here ya go, try and sort this out,
the basics of it are that I wanted this to be a touch screen interface for
time tracking, thus i had to create my own messages with large buttons,
the
code hides/ not hides the buttons and depending on what stage of the entry
they are up to the first case will direct them to the next correct place
to
continue after there previous selection.
I know there is lots of ways to do this but i wanted to try and see if
this
works, and it does.


Private Sub Command17_Click()
'
start work day
Me.msg_title.Caption = "Entry Update Notification - START SHIFT"
Select Case Me.msg_no.Tag
Case Is = "msg_return1"
GoTo msg_return1
Case Is = "msg_return2"
GoTo msg_return2
Case Is = "msg_return3"
GoTo msg_return3
Case Else
End Select
Select Case Me.msg_yes.Tag
Case Is = "msg_return1"
GoTo msg_return1
Case Is = "msg_return2"
GoTo msg_return2
Case Is = "msg_return3"
GoTo msg_return3
Case Else
End Select
Dim Msg_Box1, Late_Reason, a, b, aa, bb, Normal_Start_Time
Normal_Start_Time = Format(DLookup("[normal start time]", "[Employees]", "
[barcode] = " & Me.[scan input]), "hh:mm")
aa = Format(Me.Scan_Date, "short date")
'
scan date
a = Emp_ID
'
lookup using barcode
b = Me.Employee_ID
'
stored value
loop1:
bb = Format(Me.[Scan Date In], "short date")
If b = 0 Or IsNull(b) Then GoTo add_new
If a = b Then
'
check for correct employee id
If Format(aa, "short date") = Format(bb, "short date") Then '
check if scan date = recorded scan date
PlaySound ("\\Tran1\database\Fail.wav")
Me.msg_yes.Tag = "msg_return1"
Me.msg_no.Tag = "msg_return1"
Me.msg_header.Caption = "An entry already exists for the Start
of
your shift for Today"
Me.msg_text.Caption = "Existing Entry, Date - " & Me.
Scan_Date_In & " Time - " & Format(Me.Scan_Time_In, "hh:mm") & vbCrLf &
"Your Comments - " & Me.[Comments Scan In]
Me.msg_footer.Caption = "Select Yes to update to the new entry
or
No to cancel"
Call Message_Box_Yes_No
Me.msg_yes.SetFocus
Me.msg_input.Visible = False
Exit Sub
msg_return1:
Select Case Me.msgbutton.Tag
Case Is = "yes"
GoTo Update_entry
Case Is = "no"
PlaySound ("\\Tran1\database\alert.wav")
Me.msg_header.Caption = "Entry was canceled"
Me.msg_text.Caption = vbCrLf & " Your
previous entry has not been changed"
Call Message_Box_Ok 'and exit
Exit Sub
End Select
Else
DoCmd.GoToRecord , , acNext
b = Me.Employee_ID '
stored value
GoTo loop1
End If
Else
DoCmd.GoToRecord , , acNext
b = Me.Employee_ID '
stored value
GoTo loop1
End If
Exit Sub
Exit_Point:
Me.msg_header.Caption = "Entry Updated to - "
Me.msg_text.Caption = " Shift Start Date - " & Me.Scan_Date & "
Shift
Start Time - " & Me.Scan_Time & vbCrLf & "Comments - " & vbCrLf & Me.
[Comments Scan In]
Me.msg_footer.Caption = "Select Project Update or OK to return to the Main
Menu"
Call Message_Box_Ok
DoCmd.OpenQuery "update attendance to In"
Forms![main menu]![employees at work].Form.Requery
Exit Sub
'
exit here
' loopentry points
add_new:
DoCmd.GoToRecord , , acNewRec
Update_entry:
If Format(Normal_Start_Time, "hh:mm") < Format(Me.Scan_Time, "hh:mm") Then
Me.msg_yes.Caption = "Ok"
Me.msg_no.Caption = "Cancel"
Me.msg_yes.Tag = "msg_return2"
Me.msg_no.Tag = "msg_return2"
Me.msg_header.Caption = "An entry is required to continue"
Me.msg_text.Caption = "A reason is required for scanning In After
your
normal Start time."
Me.msg_footer.Caption = "Select Ok to continue or Cancel to exit"
Me.msg_yes.Enabled = False
Call Message_Box_Input
Exit Sub
msg_return2:
Select Case Me.msgbutton.Tag
Case Is = "yes"
Me.In_late_reason = Me.msg_input
Case Is = "no"
PlaySound ("\\Tran1\database\alert.wav")
Me.msg_header.Caption = "Entry was canceled"
Me.msg_text.Caption = vbCrLf & " Your previous
entry has not been changed"
Call Message_Box_Ok
Exit Sub
End Select
End If
Me.yesterdays_date = IIf(Weekday(Date) = 2, Date - 3, Date - 1)
ttt = DMax("[scan date out]", "[time tracking]", "[Employee id]= " & Me.
Emp_ID)
If IsNull(ttt) Then GoTo not_in
If ttt <> Me.yesterdays_date Then
not_in:
Me.msg_yes.Caption = "Ok"
Me.msg_no.Caption = "Cancel"
Me.msg_yes.Tag = "msg_return3"
Me.msg_no.Tag = "msg_return3"
Me.msg_header.Caption = "An entry is required to continue"
Me.msg_text.Caption = "Please enter a reason for Not Scanning Out
Yesterday."
Me.msg_footer.Caption = "Select Ok to continue or Cancel to exit"
Me.msg_yes.Enabled = False
Call Message_Box_Input
Exit Sub
msg_return3:
Select Case Me.msgbutton.Tag
Case Is = "yes"
Me.not_scanned_out = Me.msg_input
Case Is = "no"
PlaySound ("\\Tran1\database\alert.wav")
Me.msg_header.Caption = "Entry was canceled"
Me.msg_text.Caption = vbCrLf & " Your previous
entry has not been changed"
Call Message_Box_Ok
Exit Sub
End Select
End If
Me.Reason_Not_Scanned_Out = Me.not_scanned_out
Me.Late_Reason_In = Me.In_late_reason ' copy text from form to table
Me.[Scan Time In] = Format(Me.Scan_Time, "hh:mm")
Me.[Scan Date In] = Me.Scan_Date
Me.[Comments Scan In] = Me.Notes
Me.Employee_ID = Me.Emp_ID
PlaySound ("\\Tran1\database\success.wav")
GoTo Exit_Point
End Sub


Good grief! You're jumping into the middle of an If block inside a loop,
which is itself implemented with GoTo? That *is* spaghetti code. It's
going to take me a llittle while to analyze this.
 
S

Stuart McCall

Inline:

Dirk Goldgar said:
"On Error Go To" is not really the same as a standalone Go To statement,
and

Why isn't it the same? It's still a jump to a label.
I think it's misleading to use error-handling as a justification for
non-error Go To statements. However, error-trapping does share one

Why must I justify using a command that's built into VBA? One could argue
that the only reason it's still part of the language is for error handling,
but then GoSub is still there also (which I use sparingly too). Both
commands provide branching within the scope of a procedure without the
overhead of building a stack frame with (sometimes loads of) parameters and
calling external code. This can in some cases improve execution time.
*negative* aspect with normal Go To statements: when code is executing
anywhere after a target label, you can't tell how the program got there:
normal sequential execution, or Go To.

Er.. before the handler is reached there should definitely be an Exit
Sub/Function statement, which means that error handling code should never
execute from normal sequential means. But I do agree that not being able to
use the call stack will sometimes be a disadvantage. That's one of the
reasons I advised to use with caution (but neglected to mention).
 
B

Banana

Stuart said:
Why isn't it the same? It's still a jump to a label.

A jump may be involved, but GoTo is unconditional, while On Error Goto
is conditional. So at least in case of an On Error GoTo, we know that a
error occurred. With GoTo, it can be for any reasons and we'd have to go
back to find where the GoTo came from. If it came from multiple points,
then that's more time figuring which/when we reach this label from which
GoTo.
Why must I justify using a command that's built into VBA? One could argue
that the only reason it's still part of the language is for error handling,
but then GoSub is still there also (which I use sparingly too). Both
commands provide branching within the scope of a procedure without the
overhead of building a stack frame with (sometimes loads of) parameters and
calling external code. This can in some cases improve execution time.

I'm a big fan of "Just because you can, doesn't mean you should." VBA
has many constructs built in for different reason, and I would bet that
it has GoSub...Return and GoTo as a backward compatibility for old
projects that had no choice but to use those. But that's not an argument
for using them right now, I would think.

With regards to code efficiency, this subject was much more important
when we were working with a handful of hertz cycles, few bytes of memory
but I don't think this is the case anymore. It used to be that
tweaking a code to overflow and thus save on a conditional check or
turning to assembly language would make a material difference, but
nowadays most modern programming languages would trade in efficiency for
reliability by enforcing type-safety, and typing strongly as well doing
more checks. I don't imagine that those would run slower in comparison
to C language. But that meant programmers could deliever a better
quality program with less effort and time. In fact, that's exactly the
premise VB/VBA was based on. It never was meant to be the most efficient
language, just practical.

Not to say that efficiency is now totally irrelevant; there are time
where a piece of code must be optimized, definitely. But I don't think
I've had a case where big performance gains was achieved by using a
GoSub...Return instead of a separate procedure call.

And efficiency isn't always measured in one way (e.g. numbers of
instruction required to execute this piece of code). It can be also
measured in how easy it is to maintain or enhance a program. I would say
that constructs such as GoTo and GoSub...Return actually harm the
efficiency because the procedure is not modular that I can't just stick
in a new feature without undesirable side effects or optimize the code
without changing the output to something undesirable.

So for those reasons, I don't think I would want to use such constructs.
Er.. before the handler is reached there should definitely be an Exit
Sub/Function statement, which means that error handling code should never
execute from normal sequential means. But I do agree that not being able to
use the call stack will sometimes be a disadvantage. That's one of the
reasons I advised to use with caution (but neglected to mention).

Actually, I think Dirk wasn't talking about error handling anymore but
rather the unconditional GoTo, like this:

If something Then
...
GoTo A
Else
...
End If

If anotherthing Then
A:
...
End If

....

How did we get to A? Was it because we passed the anotherthing test or
because we got there from the GoTo in the something test? That's one
guess I'd rather not make.
 
M

Marshall Barton

Stuart said:
Why isn't it the same? It's still a jump to a label.


The difference in my mind is that error handling is a lot
like an event for dealing with invalid operations. On Error
GoTo is just setting the event destination, it does not
actually do a procedural jump to another section in the
logical flow of the code.

Not having a built-in way to get the source of the error is
a serious pain, but that's a different question with little
or nothing to do with the similarities/differences between
GoTo and error handlers.
 
D

David W. Fenton

"On Error Go To" is not really the same as a standalone Go To
statement, and I think it's misleading to use error-handling as a
justification for non-error Go To statements. However,
error-trapping does share one *negative* aspect with normal Go To
statements: when code is executing anywhere after a target label,
you can't tell how the program got there: normal sequential
execution, or Go To.

Well, you can write your code such that you *can* tell how it got
there:

On Error GoTo errHandler

[code that will inevitably produce an error someday]
GoTo exitRoutine

exitRoutine:
Exit Sub

errHandler:
Resume exitRoutine


In that framework, there are two ways to get into the exitRoutine,
via the error handler or because the code completed successfully. If
it got there from the error handler, everything that needs to be
done for a normal exit from the subroutine has already been done (in
the error handler), so I see no issues here.

With code like this, you can't get into the code block that
corresponds to one of the labels without knowing that it got there
appropriately.

Now, without line numbers, it's true that you can't know how you got
into the error handler, but you know *why* you got there. And line
numbers provide the solution if you're bothered by that (I'm not).
I won't say *never* use a Go To statement, but I will say that
good old-fashioned structured code using "If ... Then ... Else ...
End If", "Select Case", "Do ... Loop", and "While ... Wend" will
almost always do the job better, make the procedure logic clearer,
and be easier to maintain.

I think it all depends on exactly what using standard logic
structures does to your code. It can be worse than a GoTo in some
situations (though that usually indicates that you should be
creating separate subroutines for parts of your main sub).
I have found a very few cases where a Go To was the only practical
way to make an odd logic structure work. In those cases, you had
better believe I documented the hell out of what I was doing and
why!

There are a number of retry contexts where a loop is inappropriate
and a GoTo is the appropriate method to loop. However, if your label
is inside one of the logical branching structures, you shouldn't
have the GoTo change to a different level -- it should only happen
inside the same level. For example, this is bad:

If ... Then
Retry:
Else
End If
If ... Then GoTo Retry

This is OK:

If ... Then
Retry:
Code:
If ... Then GoTo Retry
Else
End If

As long as your GoTo jump stays inside a single indentation level of
your control structure, you're fine.

But, again, it is often the case that a loop is more appropriate
(though not always).
 
D

David W. Fenton

Banana said:
Actually, I think Dirk wasn't talking about error handling anymore
but rather the unconditional GoTo, like this:

If something Then
...
GoTo A
Else
...
End If

If anotherthing Then
A:
...
End If

...

How did we get to A? Was it because we passed the anotherthing
test or because we got there from the GoTo in the something test?
That's one guess I'd rather not make.

That violates my principle that GoTo should only ever operate inside
the same level of a control structure, or pass control out of the
lower-level structure into a higher level (something I didn't
actually say explicitly in my followup to Dirk).

All that said, I hardly ever use GoTo for anything other than error
handlers. I can think of maybe a dozen times I've done it in 14
years of full-time Access programming.
 
D

David W. Fenton

Good grief! You're jumping into the middle of an If block inside
a loop, which is itself implemented with GoTo? That *is*
spaghetti code. It's going to take me a llittle while to analyze
this.

I couldn't be bothered. This is a case where we're being asked to
fix a problem in an ill-chosen solution, instead of being asked to
solve the original problem. If the OP would explain what this
massive hunk of spaghetti is designed to accomplish, then it would
be a lot easier to provide a solution.

What was posted is an attempt at a solution, but it's a bad
solution.

It looks to me like an attempt to do in one block of code something
that ought to be done sequentially, like in a wizard interface, with
<<Previous and Next>> buttons. Then the branching can be handled
quite easily in small blocks, such that you don't have to check the
same condition multiple times at different levels within the same
code block.

But that's only a guess from looking at the mass of interwined and
badly-formatted code. It would be a lot easier to evaluate that code
if it were properly indented, for one.

Until there's an explanation of the task the code is supposed to be
accomplishing, I'm going to spend my time on something else.
 
M

Marshall Barton

David said:
Marshall Barton wrote


Line numbers?

You got me? I haven't used line numbers in at least 30
years so I usually forget about that feature(?). Could you
explain (or point me to a reference about) how using line
number helps identify the source of an error?
 
B

Banana

Marshall said:
You got me? I haven't used line numbers in at least 30
years so I usually forget about that feature(?). Could you
explain (or point me to a reference about) how using line
number helps identify the source of an error?

I do believe David is referring to the Erl function. It should be
documented in the Access help files, but basically if there's a line
number, you can do something like this:

<Procedure Statement>
On Error GoTo Error_Handler

10 ...
20 ...
30 ...
40 Msgbox 1/0
50 ...
60 ...
70 ...

Exit_Procedure:
Exit <Procedure>
Error_Handler:
Msgbox Err.Number & " " Err.Description & _
vbCrLf & "occurred on line: " & Erl
Resume Exit_Procedure
End <Procedure>

If there are no line numbers, Erl will return 0. You can use tool like
MZ-Tools or FMS Inc. to add in line numbers for you.

http://www.fmsinc.com/free/NewTips/VBA/errorhandling/linenumber.html

HTH.
 
M

Marshall Barton

Banana said:
I do believe David is referring to the Erl function. It should be
documented in the Access help files, but basically if there's a line
number, you can do something like this:

Thanks for pointing me to the Erl function. I seem to have
a vague memory of seeing that somewhere before. BUT it is
NOT in A2003 VBA Help. I did find it in the Object Browser,
but it was a hidden member and clicking the ? button brought
up the topic for the Err object. Did I miss where Erl was
deprecated?
 
D

David W. Fenton

Thanks for pointing me to the Erl function. I seem to have
a vague memory of seeing that somewhere before. BUT it is
NOT in A2003 VBA Help. I did find it in the Object Browser,
but it was a hidden member and clicking the ? button brought
up the topic for the Err object. Did I miss where Erl was
deprecated?

I don't know that a member being hidden indicates that it's
deprecated. I would expect there are a lot of reasons why members
are implemented as hidden.
 
M

Marshall Barton

David said:
Marshall Barton wrote


I don't know that a member being hidden indicates that it's
deprecated. I would expect there are a lot of reasons why members
are implemented as hidden.


IME, the primary reason to remove a Help topic and hide it
in Object Browser is so people don't use it and MS won't
have to worry about testing it. And, if they don't test it,
they can break it.

OTOH, SaveAsText and LoadFromText have always been hidden.
But then, that's only because they only intended it for
their own use, not general use.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top