J
JE McGimpsey
John McGhie said:Forgive my failing memory, but I thought "On Error Resume Next" had global
scope within a module? So wherever you put it, it's going to have effect
within the module?
No - nearly the opposite. On Error Resume Next only applies until
another sub or function is called, the procedure exits, or another On
Error instruction is executed.
From Help:
An On Error Resume Next statement becomes inactive when
another procedure is called, so you should execute an
On Error Resume Next statement in each called routine
if you want inline error handling within that routine.
Should we be writing modules that "Exit" from the middle of the code.? Or
using a function named "Resume" that in fact "Exits"?
It's perhaps something of a style issue, but the principle I use is a
common one that there should be a single entry and exit point from a
procedure. Using Resume ResumeHere allows a graceful exit at that single
point.
In my commercial code, I'd call this as a Function, and have a
success/fail value assigned to the function's return value at the
ResumeHere: label. In fact, I'd probably write it as two functions - one
for Paste unformatted, and one for Paste, the latter being called from
the error handler.
Using a single exit point also allows for easier logging and tracing,
though I've not included any code for that here.
So the Exit Sub is really the last statement of the procedure, coming
just before the error handler, not in "the middle of the code".
Note that Resume *doesn't* Exit, it returns to the instruction that
threw the error.
So yes, I think the code is extensible, maintainable and
self-documenting (though somewhat weak on the latter). This is a very
simple error handling routine, though. I'd certainly entertain a more
thorough effort.
BTW - Exit Sub is far more appropriate than End, IMO, which is very
unfriendly to other code. From Help:
When executed, the End statement resets all module-level
variables and all static local variables in all modules.
...The End statement stops code execution abruptly, without
invoking the Unload, QueryUnload, or Terminate event, or
any other Visual Basic code.