Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

on error is not working?? 2

Status
Not open for further replies.

ron9999

Programmer
Feb 14, 2003
89
AT
I use this code to check if the table is in use:

local llerror
llerror=.f.
lcStlFileName="02155.stk" (it's a dbf)
ON ERROR llerror = .T.
lcStkl= SYS(5)+CURDIR()+'BELEGE\'+ lcStlFileName
SELECT 0
USE &lcStkl EXCLUSIVE ALIAS 'ITEMLIST'
IF llerror
thisform.Caption = "file is in use !!!"
ENDIF

when I step it through
I can see the file was not opend (is not there)
but the error don't trigger llerror
llerror is still .f.

if I make the same procedure in command-window it works

tia
ron
 
Try this

Code:
Local llerror
llerror=.F.
lcStlFileName="02155.stk"
On Error myError()
lcStkl= Sys(5)+Curdir()+'BELEGE\'+ lcStlFileName
Select 0
Use &lcStkl Exclusive Alias 'ITEMLIST'
Procedure myError
    Thisform.Caption = "file is in use !!!"
Endproc



Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
no is not working
on error does not fire even a error happend
ron
 
Hi Ron,

Try this. It works for me.
Code:
On ERROR DO myError
lcStkl= "c:\att\ccust" && Real filename is cust.dbf
Select 0
Use &lcStkl Exclusive Alias ITEMLIST
Procedure myError
   MESSAGEBOX("File is in use !!!")
   ON ERROR 
Endproc
Regards,

Mike
 

All the proposed solutions are viable solutions. I can only assume something else is at play here.


Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
I believe the problem is due to the scope of llerror.

If you make llerror private your problem should be solved.

i.e.

Code:
private llerror
llerror=.f.

lcStlFileName="02155.stk"

on error llerror = .t.

lcStkl= sys(5)+curdir()+'BELEGE\'+ lcStlFileName

select 0

use &lcStkl exclusive alias 'ITEMLIST'

if llerror
  thisform.caption = "file is in use !!!"
endif
 
thank you all,
I find out all procedures and all your advices are working, if I run it in a single my.prg.
I guess the problem is in my environment or settings, that's what I have to find out.
on error does'nt fire - I don't know why -
I try to set safty on - it was'nt
if I find the solution I post it
ron
 
now I guess I have the reason but no solution.
in my thread184-1052156 I had a problem with parm because the method is called from a toolbar.
This code now runs at the same method
may be I also have to use the DoDefault???
ron
 
on error is not launching
even if I try: do database xyz
llError is not changeing
it must have something with

toolbar.prior() && lnResult = _screen.ActiveForm.Prior()
|
|
V
activeform.prior() && mybasfrm::prior()
|
|
v
mybasfrm.prior() && change the rec
|
|
v
activeform.prior() && here I try on Error
|
|
v
toolbar.prior()


ron
 
If you have code in mybsfrm.Error() this has priority to code running by ON ERROR. A Space in mybsfrm.Error() may be enough to have this affect. Might also be in the derived class that the activeform is based on.

In VFP8 or there is TRY .. CATCH ... FINALLY errorhandling, which has even higher priority than Error Event and ON ERROR handling.

Bye, Olaf.
 
that's it Olaf. I have code in mybasefrm.error() and I need it in other forms derived from mybasefrm. I use vfp7. How can I change the priority that on error is launching.
it does'nt work if I make a '*' in the error() method of the form.
ron
 
No, if you have code in Error of mybasefrm and you set the error method of a dervied class to default, that'll of course trigger the Error-Event of mybasefrm and if you put a * inside or NODEFAULT an error would nevertheless trigger that method, that does nothing, but doesn't trigger what's defined with ON ERROR. It's a bit of a no escape situation.

But if you made llError a private variable, like Darell suggested, then the line llError = .t. insode the Error method of your derived form class would work, you wouldn't need to set the ON ERROR behaviour, and you can't set it to be of higher priority.

This might also answer Geoff Franklin's question. As the Error is handled outside the scope of the method USEing the table, you have to have at least a PRIVATE variable, which's scope is in both that method and the Error event.

If that doesn't work, make llError a PUBLIC variable.

You could also do this in the error event, which would be more general:

Code:
* ERROR-Event:
* Any handling of Errors especially connected 
* to the form class. If no such error occurs
* call the 'normal' errorhandler:
local lcOnError
lcOnError = ON("ERROR")
if !empty(lcOnError)
   &lcOnError
else 
   Error nError
endif

Bye, Olaf.
 
thank you Olaf - now I got it
it works
thank to you all
 
This might also answer Geoff Franklin's question.

Thank's Olaf but I'm still puzzled.

If llError is local then it'll be set .T. by the ON ERROR and the form error handler won't be able to see or alter it's value. llError will still be .T. whenever execution gets back from the form error handler.

If llError is made Private then the form error handler will be able to see its value and there might be a conflict with an undeclared llError in the handler.

I think I need to write an example for myself and single-step through it. Not today though. It's an interesting problem but it's May Day holiday today and wife and daughter will lynch me if I sit indoors at the keyboard<g>.

Geoff Franklin
 
Hi Geoff,

A LOCAL variable (as llError was originally) can ONLY be seen from within the method/function/procedure that defines it LOCAL. Any ON ERROR, ON KEY, ON *anything* that launches from within that method/functoin/procedure CANNOT see it because they are essentially a sub-routine call (they show up in the call stack, for instance).

Making llError PRIVATE is a workable solution: If the Error method were to use llError locally, it Should declare it LOCAL or PRIVATE... in either case, this new declaration would hide any llError that existed outside the .Error method.

If llError is made Private then the form error handler will be able to see its value and there might be a conflict with an undeclared llError in the handler.
The whole reason that Olaf suggested making llError PRIVATE IS so that the .error method CAN change it, instead of an ON ERROR (which ON ERROR simply won't fire if there is an .error method). There won't be a conflict with an undeclared llError in .error because .Error is now designed to access an external llError variable.

(BTW: Personally, I'd rename llError something else, like plError, since is is no longer a Local Logical, but now a Private Logical)

- Bill

Get the best answers to your questions -- See FAQ481-4875.
 
Hi Bill,

correct. In general one would expect, that even an error occuring inside the function/method where llError was defined LOCAL could not set llError, as ON ERROR calls something, that would always be out of scope of the current method.

But it works, if the error occurs local, you don't need llError to be defined PRIVATE.

Geoff: Just try to understand the concept of a PRIVATE var vs a LOCAL one and you'd see that thereby errors occuring in called procs/functions/methods (eg in another form) could affect a PRIVATE var, and therefore it's always a good idea to make it that way:

Code:
LOCAL lcOldOnError
PRIVATE plError
plError = .F.
lcOldOnError = ON("ERROR")
ON ERROR plError = .T.
* do something, which might trigger a foreseeable error.
* could be on command or even a call of a method or
* something else out of the scope of this code.

* check if an error occured with IF plError ...
* and display a message or whatever needed.
IF EMPTY(lcOldOnError)
   ON ERROR
ELSE
   ON ERROR &lcOldOnError
ENDIF
RELEASE plError

Since VFP8 all that is much easier done as structured error hanlding with TRY ... CATCH ... FINALLY. But that has that same problems with errors that occur outside of the local scope. Eg TRY DO myprg.prg CATCH ... ENDTRY isn't a good idea, as you don't CATCH errors occuring in myprg that way.

Bye, Olaf.
 
errors occuring in called procs/functions/methods (eg in another form) could affect a PRIVATE var

This was what was confusing me because I could only see the one scope in the sample code we started with. So I took the trouble to single-step through it and I've found the true cause of the problem - the form's error method has nothing to do with it.

The problem occurs because the action of an On Error statement does not occur in the same scope as the parent code. I pasted ron's code into Command1.Click and watched the scope of the Locals window as it ran. This started off as "form1.command1.click" but switched to "On Error" as soon as an error occurred.

This was news to me but the separate scope explains the peculiar behaviour.

There's nothing in the error processing code to define llError within that scope. When it sets llError equal to .T., Fox creates a new variable which is Private to the scope of On Error. When we return to the Click method we are back to the original local llError which is still .F..

Defining llError as Private within the original code means that this llError will also exist in the On Error scope. Fox does not have to create a new variable named llError but sets the existing llError to .T. and this stays at .T. when we return to the original scope.

Defining llError as Private or Public solves the problem but declaring Privates and Publics is a bad way of passing parameters. Olaf's suggestion of a Try...Catch...Finally structure would sidestep the problem altogether because there would be no call to the separate On Error scope and the local variable would remain in scope. If we must use On Error then I'd suggest something like this which removes the need for llError completely:
Code:
  On Error Do FileError
  lcStlFileName="02155.stk"  && (it's a dbf)
  lcStkl= SYS(5)+CURDIR()+'BELEGE\'+ lcStlFileName
  SELECT 0
  USE &lcStkl EXCLUSIVE ALIAS 'ITEMLIST'
Return

Procedure FileError
  thisform.Caption = "file is in use !!!"
Return

Geoff Franklin
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top