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.