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 Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Any way to break a process in FoxPro?

Status
Not open for further replies.

foxprox558

Programmer
Oct 19, 2013
53
US
Hi, me again.
Just wondering if there is any way to break a function in foxpro, for example I have an If statement that looks to see if an order has already been deleted, and If it has, I need the whole process to end here's the code
Code:
nOrd=INPUTBOX("Enter The Order Number To Delete.", "Individual Deletion")
USE orders SHARED
LOCATE FOR (orders.invoiceno)=VAL(nOrd)
IF FOUND()
IF DELETED()
MESSAGEBOX("This Record Has Already Been Marked For Deletion.", 48, "Record Already Deleted")
&& Something needs to go here to tell the program to stop this process
endif
nConf=MESSAGEBOX("Are you sure you want to delete order # "+nOrd+" ?", 4, "Confirm Deletion")
DO CASE
CASE nConf=6
DELETE
MESSAGEBOX("Order # "+nOrd+" Has successfully been deleted.", 64, "Order "+nOrd+" Deleted")
CASE nConf=7
ENDCASE
ELSE
MESSAGEBOX("Order Not Found In Database.", 48, "Order Not Located")
endif
Thanks!
 
First it helps to beautify code, to indent it, to better read it. All you need in this case is to put some of the further code after your comment "something needs to go here" in a further ELSE. In both OOP or structured programming you should always find a solution in control flow like CASE, IF ELSE, etc. to solve the problem of not executing code which does not need to execute in some case purely by putting it in the right code branch. I show another way to keep your code flat and make many nests of IFs unnecessary. But in this case a further ELSE is okay:

Code:
Local nOrd, nConf, llDeleted
nOrd=Inputbox("Enter The Order Number To Delete.", "Individual Deletion")
* Check, if Orders is already used, or
Use orders In Select("orders") Shared
Select Orders
* Locate in all records, including deleted ones
Set Deleted Off
Locate For (orders.invoiceno)=Val(nOrd)
If Found()
   llDeleted = Deleted()
   Set Deleted On
   If llDeleted 
      Messagebox("This Record Has Already Been Marked For Deletion.", 48, "Record Already Deleted")
      * further code does not exectute, anything else is in other IF/ELSE branches
   Else
      nConf=Messagebox("Are you sure you want to delete order # "+nOrd+" ?", 4, "Confirm Deletion")
      If nConf=6
         Delete
         Messagebox("Order # "+nOrd+" Has successfully been deleted.", 64, "Order "+nOrd+" Deleted")
      Endif
   Endif
Else
   Messagebox("Order Not Found In Database.", 48, "Order Not Located")
Endif

In this case, it's best solved this way.

I also double check, if the record pointer didn't move or another station already changed the orders table. VFP is single threaded and the message box is modal, still plenty of waiting time has past after the LOCATE has been done, waiting for the user confirming the deletion. Also something can happen to the table from another session, another station, another user. That's the consequence of shared access.

One more thing: If you SET DELETED ON, you'll never locate a record marked for deletion. If you SET DELETED OFF, all records marked for deletion will be seen in grids etc. all the time, so you won't want this. If you SET DELETED ON your code will always just be saying "Order not found", if a user enters an already deleted order number, you'll never get into the branch If Deleted(). If you want that, you need to temporarily SET DELETED OFF, but only temporarily.

I changed this and some other stuff. In the end I would do all that much different, for example embed deletion of orders in a form, where users also may enter or process orders, but that would lead way off.

Last not least: In the general case you want to exit code, you can exit a loop with EXIT, you can exit a PRG or a function/procedure within a PRG or a method with RETURN. It's good practice not to do so in the middle of code, though, because it makes code less maintainable and harder to understand, if there are several places of exits. One way of coping with an early exit is to put code in this way:

Code:
Local llContinue
llContinue = .T.

* step 1
* do some code, set llContinue = .F., if you want to stop
If llContinue
   * step 2, some more code, also setting llContinue = .F. if further code should not execute
Endif

If llContinue
   * step 3, some more code, also setting llContinue = .F. if further code should not execute
Endif

* etc. etc.
* in the end eventually (in a function)
Return someresult

This whole code often is used as an entry method or function doing the control flow for a more complicated process with many branch offs and conditions. This entry and control flow code then calls other methods, classes, etc. within the steps. The way to control this by a variable llContinue helps keeping code flat, while you would need many nested IFs to get the same code flow with just the normal nesting of IFs.

Bye, Olaf.
 
Sorry, I changed your code further to what I posted within a VFP edit window and then forgot to copy that back, too.

Here's what I also already described in my previous post. Think of it as the first code block of the previous post:

Code:
Local lcOrd, lnConf, llDeleted, llFound
lcOrd=Inputbox("Enter The Order Number To Delete.", "Individual Deletion")
* Check, if Orders is already used, or reopen it in it's current workarea
Use orders In Select("orders") Shared
* Select("orders") is 0 in case it's not open, so this also works in that case, 
* but after (re)openeing orders, that workarea needs to be selected:
Select orders
* Locate in all records, including deleted ones
Set Deleted Off
Locate For (orders.invoiceno)=Val(lcOrd)
llFound = Found()
llDeleted = Deleted()
Set Deleted On
If llFound
   If llDeleted
      Messagebox("This Record has already been marked for deletion.", 48, "Record Already Deleted")
   Else
      lnConf=Messagebox("Are you sure you want to delete order # "+lcOrd+" ?", 4, "Confirm Deletion")
      If lnConf=6 and orders.invoiceno = Val(lcOrd)
         Delete Next 1
         Messagebox("Order # "+lcOrd+" Has successfully been deleted.", 64, "Order "+lcOrd+" Deleted")
      Else
         Messagebox("Someone else has removed the order now.")
      Endif
   Endif
Else
   Messagebox("Order Not Found In Database.", 48, "Order Not Located")
Endif
I straightened some variable declarations and added the SET DELETED ON even before going into the nested IFs. The code above would not go back to SET DELETED ON in case an order isn't found.

Bye, Olaf.
 
Still another flaw in my code change:
Code:
lnConf=Messagebox("Are you sure you want to delete order # "+lcOrd+" ?", 4, "Confirm Deletion")
If lnConf=6 And orders.invoiceno = Val(lcOrd)
   Delete Next 1
   Messagebox("Order # "+lcOrd+" Has successfully been deleted.", 64, "Order "+lcOrd+" Deleted")
Else
   Messagebox("Someone else has removed the order now.")
Endif

This would also blame "someone else" to have removed the order, if the user just answers No to the messagebox.

I put this back to a CASE:

Code:
lnConf=Messagebox("Are you sure you want to delete order # "+lcOrd+" ?", 4, "Confirm Deletion")
Do Case
   Case lnConf=6 And orders.invoiceno = Val(lcOrd)
      Delete Next 1
      Messagebox("Order # "+lcOrd+" Has successfully been deleted.", 64, "Order "+lcOrd+" Deleted")
   Case lnConf=6 And orders.invoiceno <> Val(lcOrd)
      Messagebox("It seems someone else has removed the order already.")
   Otherwise
      * Messagebox("OK, the order is kept.")
Endcase

Bye, Olaf.
 
Olaf has given you some very helpful advice, and I can't add much to what he said.

But to go back to your original question, you say you want to "break" the process. I understood that to mean you want to cause it to fail in some way. But I think you mean that you want it to exit from somewhere in the middle of the code, rather than at the end. Is that right?

In other words, you've got something like this:

Code:
* Do something here

IF ... some condition ...
   * exit the function here
ENDIF

* Do more stuff here

If that's what you want to achieve, you simply need to execute a RETURN at the point where you want to exit:

Code:
* Do something here

IF ... some condition ...
  [b] RETURN[/b]
ENDIF

* Do more stuff here

I'm sorry if I'm stating the obvious here, but that's my intepretation of your question.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top