Integrating Concepts

Thanks to John Esak for providing this general overview.

In [rd]clerk: When filePro retrieves a record, whether you get it by pressing the down arrow in dclerk, or going through scan or an index, ... whether you are coming off the browse screen into the full screen mode or already in full screen mode ... _before_ you see the record on the screen, the automatic processing is run against the data in that record. Then, after the first encountered "end" on the automatic table, the @entsel processing is run. In other words just before the cursor is put at the "Enter Selection
" prompt, the @entsel processing is run.

Now, let's say you are sitting at the Enter Selection prompt and looking at this record which has just been run through those two processes and everything looks fine. You press "U" to update the record and filePro will immediately retrieve the record again and run and run the automatic processing again before it puts your cursor into the first field on the cursor path. It does this because the record may have been altered during the time you've been sitting there perusing it at the Enter Selection prompt. Good idea... now you have the latest copy of the data, properly adjusted and bashed about by your automatic processing, your cursor should go into the first field on the cursor path... but no, first it has to run through any @wefxxx that exists for that field!  So, just retrieving the record and pressing "U" to update it, you've run it through automatic twice and @entsel twice... and now @wefxxx. No problem, both AUTOMATIC and @ENTSEL processing should have NOTHING on them that alters real fields. This will be "noted" and "ignored" by any @entsel processing that tries to alter a real field... but you must be smart enough not to do it on the AUTOMATIC yourself... filePro _will__ actually _let_ you alter a real field on AUTOMATIC, but _don't_ do it! It is an EXTREMELY, HORRIBLY bad thing to do.


Why? Simple... the record is not "locked" by AUTOMATIC processing, so you can't be sure someone else doesn't also have a copy of that record, changing it at the same time you are....  Meanwhile, back to the flow of processing in [dr]clerk. You will note, that after retrieving a record, pressing "U" to update it, at no time have we yet run _any_ INPUT processing. The INPUT table processing pointer is still firmly clamped at line 1 or loosely called the TOP of the INPUT processing table. It _has_ moved some other processing pointers around, the one for the AUTOMATIC table, the one for the @entsel processing, even the one for the @wefxxx processing have all been moved through their little processing snips, but the main INPUT processing pointer has not moved at all. It is at "the top" or line 1. The  main INPUT processing gets run only when the program or the user say it's time to "store" the record. This situation happens 99% of the time when the user presses the key designated for this purpose, in Unix usually
ESCAPE/ESCAPE, in Windows just ESCAPE. (This key can be changed...) The other 1% of the time, the running of the INPUT table can be forced by actually issuing the "SAVE" command.  (I do actually use this command, but it is only in very, very, rare and usually special circumstances.) In general, the INPUT table is left waiting, never to run, until the user presses the key himself to do it.

Why explain all this? Because, in that 99% of the time, filePro is going to store the record and run the INPUT processing table for you "automatically", you don't have to engineer it with the "SAVE" command.  Even if your
cursor is in various fields when the ESCAPE/ESCAPE is pressed... filePro will still run the @wlfxxx snip as usual, then just after the ending command of that @wlfxxx is encountered, the INPUT table picks up from wherever its pointer is positioned... usually the "top" of the table. The times you may NOT want to run the @wlfxxx code _again_ before running the INPUT table are some of the times you might actually want to put the "SAVE" command on the very first line of the @wlfxxx and act on it before the other stuff. Like in your example.

@wlfxxx    if: @sn eq "something"
    then: SAVE
if: 'other stuff that happens if they are
         then: 'not on this screen.
           if:
       then: end

Now, you mentioned setting them back to the beginning of the INPUT table with the "RESTART" command. Of course it will do this, but there is a not so subtle difference. The RESTART command would put there cursor _back on the screen at the beginning of the cursor path and move the INPUT processing pointer to the "top", i.e., line 1. BUT, the ball would be back in the user's court. The SAVE command would not give the ball back, but simply start running the INPUT table.

Why is all this important? Because, there is one more thing which must be added to the mix to get to the reason for the behavior you saw in the debugger. AFTER the user has pressed the SAVE key (escape/escape), the INPUT table is run, yes, but immediately after it encounters its first "end" statement the AUTOMATIC table is run one more time... why? Because you may have changed some data on the record and you want to massage it again in the same way you did when you first retrieved it but now with the newly updated data.  Hey! pretty good, so now we finally get to see everything...nope... there's that pesky Enter Selection prompt... and what runs just before the cursor is placed there? Yup! @entsel processing.  Now, you've got the whole picture, or a lot of it. The flow of processing is very important, because it is one thing you can count on working the same way, every time, all the time.

Now, how is it you saw the AUTOMATIC table running first. All I can guess is you had possibly forgotten that first "end" on the INPUT table. Then when the user pressed ESCAPE/ESCAPE you saw the @wlfxxx processing label come
up and thought it was running because they were leaving that field... well, yes, it was, but it was running because filePro first ran your @wlfxxx snippet as it should, which you saw... then it ran the INPUT table from the top because you had put an explicit "SAVE" command as the first thing to do... in which case it would now be looking just the same in the debugger... my guess is you had to press ENTER one extra time before you saw the AUTOMATIC table running in the debugger and you just ignored this. I do this all the time while in the debugger. You press the ENTER and think you somehow didn't really press it because you are seeing the same thing twice... in this really strange case you've bumped into, that is exactly what it would do. You're right very confusing. Putting an "end" as the first
> line in the INPUT table would prevent this.  Unless, of course, there actually IS some INPUT processing that needs to be run... then be sure there is an "end" somewhere along the way, just so the processing doesn't "fall" into the @wlfxxx processing snippets by accident.


Okay, all clear as mud?  good. :-)  The reason's I've gone all through this stuff (which I realize you and most people may know) is this... To reiterate, just once more, I promise... :-) The @entsel processing and any other trigger processing (@wefxxx, @wlfxxx, etc.) in clerk have to be put on a processing table somewhere. filePro mandates that this trigger processing has to be on the INPUT table.  So, where does it all go??? It must come after an "end" statement. The way filePro differentiates "what" is the INPUT processing part of the INPUT table and what are the other trigger parts of it like @wlfxxx, @wefxxx, @wukxxx, @whlpxxx, etc.) is to set aside all the lines from line 1 until the first encountered "end" statement for it. (This is really a fantastic thing and sets up a very useful symbiotic relationship between the two types of processing... even though they are NOT connected at all in any specified way, unless _you_ arrange it. More about this later.) You can badly obviate and break all this wonderful schema by not remembering to put an "end" statement to delineate the END of INPUT processing. :-) A troubling "statement" in itself. Yes. But the simplest demonstration is this. If you had the following as the entire INPUT table:

@keyZ   


1      then: show "@I am @keyZ processing."
         if:
2      then: end

It would only work badly, in that it would work twice... which is sort of a screw-up all around. It would work if they press Z, but it would also work when they press "U" and then ESCAPE/ESCAPE.... which you probably do NOT want.

Whereas, doing the way we all know it should be done:

1      then: end
@keyZ    if:
2      then: show "@I am @keyZ processing."
          if:
        then: end

The above is perfectly fine INPUT table (with NO input processing at all, but just some trigger processing.)  It doesn't mean there is actually no INPUT processing, because INPUT processing _still_ gets run, it is just that the only thing INPUT processing is telling filePro to do is "end". That step actually does get executed, it just obviously does nothing. If it weren't there, filePro would run the stuff you only wanted to be run when the keyZ was pressed. It would run because INPUT processing starts from line 1 regardless of what the label says. So pressing key Z would make it show
" I am at the @keyZ processing." and also pressing "U" and ESCAPE/ESCAPE would do the same thing... probably not what you meant by the code. filePro is often knocked for the fact that the first line of the INPUT processing table is
often END. :-) Everyone knows that this simply means there is NOTHING to be done when the record is saved and written out.

Now, let me write some ABSOLUTELY terrible, really BAD code to demonstrate that symbiotic thing between the INPUT table processing and trigger snippets. You might actually do something like this... but don't. It's just an example of why having all these things on the same table can be VERY confusing as you said.


       then: show "@hello, I'm in INPUT processing now."
totals   if:
       then: 14=7+8+9+10+11
         if:
       then: display
         if:
       then: end
@wlf12 if: 12 eq "Y"
       then: goto totals
         if:
       then: end

The programmer here (who shall remain nameless) is doing something that filePro will allow him/her to do, but it only works because filePro does what it does without flinching... and you are just lucky if you write code like this and can figure out later when things get more complicated what's going on. Sure, you are ending the @wlfxxx processing with an "end" statement, one of the 5 commands that will properly end the @wlfxxx snippet, but you've done it sort of sneakily by co-opting the end of the INPUT processing table. This would all be so much better written by doing something like this:

         if:
       then: show "@hello, I'm in INPUT processing now."
         if:
       then: gosub totals
         if:
       then: display
         if:
       then: end
totals  if:
       then: 14=7+8+9+10+11
         if:
       then: return
@wlf12 if: 12 eq "Y"
       then: gosub totals
         if:
       then: end

Now, you still get to use stuff that may be shared with the INPUT processing, but you are doing it much more clearly and explicitly... i.e., in a way that will be much easier to read as the processing gets more and more complex.

Which brings us to the next level.

top      if: @sn eq "4"
        then: form "something";  screen 5;  goto top
          if:
        then: screen 9
          if:
        then: end
@wlf12   if: 12 eq "Y"
        then: screen 4
          if:
        then: end

Let's say the user starts out on Screen 1 and field 12 is on screen 1. Different things will happen based on whether he puts an X in this field or not. The relationship between the INPUT processing and the trigger processing can be non-existent, or it can be very tightly integrated and interdependent as shown above. It's all in what you arrange... knowing the flow of which processing runs when... what *ends* an @wlfxxx snippet.


There are 5 things which do this, END, SKIP, SCREEN, RESTART and, EXIT. Remember the not-so-subtle between RESTART and "goto top" being that RESTART gives control back to the user, goto top doesn't. There are zillions of variations to all this, but here is one important one. If you are using @key processing, the flow is this... first the AUTOMATIC table is run, and _then_ the @key processing is run until an "end" is encountered. INPUT processing is not considered at all. You could, of course, invoke INPUT processing from @key processing by using the RESTART command.

@keyT    if:
        then: do some stuff
           if:
        then: restart

This would END the @key processing snippet, and deposit the user into the first field on the cursor path. The next time they press ESCAPE/ESCAPE, the INPUT table would run from the top. Interesting, huh? (Remember also, that after this, the AUTOMATIC table and the @entsel snip would run as well... :-)

Okay, hope all of that helped and you aren't more hopelessly confused. If I've messed something up in my description, forgive me, it is late after a long day.  Oh yeah, just one last thing... what I was going for at first to help describe another reason why the AUTOMATIC processing appeared to be running first.  If you have already run _part_ of the INPUT processing.... that is where the INPUT processing pointer will be, and where processing will begin again when ESCAPE/ESCAPE is pressed (or you hit that "SAVE" you had put in the @wlfxxx snip.) Consider you've done something like this:

1      then: do a lot of stuff; do more stuff
           if: something equals something
2      then: some more stuff
          if:
3      then: screen 7
          if:
4     then: end
@wlfxxx  if: @sn eq "7"
5      then: form "blah";  SAVE

If the user has pressed ESCAPE/ESCAPE once already before ever entering field "xxx", then the INPUT processing table has "already" started running and has stopped at line 3, the screen 7 command. Assuming field "xxx" is on Screen 7 and the cursor goes there, when the user presses ESCAPE/ESCAPE this time, the INPUT processing will start up where it left off, which would be the next command immediately after the screen 7 command in this case just
ending the INPUT processing. You would only see the end command in the debugger and then the AUTOMATIC processing would appear.

Obviously, we can't tell exactly why you saw AUTOMATIC processing running first, but I can assure you it was because you were somehow telling filePro to do this.... In other words, it actually did run its normal flow of
things and it just appeared to not be running the INPUT table... (again, I think there might have been a doubling of the @wlfxxx because of no "end" statement above it... and things just appeared messed up.

Good luck. Regardless of what it was. It seems you've fixed it with a RESTART, I hope this helped a little anyway.