Next, you must initialize the "WS-" table which you have defined in %DATADEF. In Cobol II you may use the INITIALIZE verb, or you may move appropriate spaces or zeros in older Cobol implementations. Next, you must move the appropriate fields from the first invoice record into the first entry of the table (occurrence (cont.) 1). Be sure to move the key fields into the table entry. Set the subscript or index to 1. Then, you must do the REDNX I/O command to get the next invoice, increment the subscript, and move its data to the (cont.) table entry using that subscript. You loop back through this REDNX processing. Of course, you will test for your (cont.) subscript reaching the end of the table or your REDNX getting a NOT-FOUND, or reaching an invoice for the next vendor (cont.) to know when to stop looping. At the end of this, your table will be loaded with invoices. Any unused entries at the bottom of the table will contain (cont.) the initial values you set earlier. The action codes will all be set to their initial value, normally (cont.) spaces. **%RDUKY** In this insertion point the defailt logic reads the primary record (vendor record) for update, getting exclusive (cont.) control of it; then performs the join logic. Reading for update is a prerequisite for updating or deleting a record. If (cont.) you will be updating the vendor record, leave the RDUKY for it alone, but remove the perform of JA100-LOGICAL-JOIN. If (cont.) you will not be updating the primary record, also remove the perform of AA840-CALL-MAGEC-IO. The reason you do not want (cont.) to re-do the join logic is because 1) it is unnecessary since the data is preserved in your table in %DATADEF, and 2) (cont.) you do not yet know which, if any, of the invoice records will be updated, deleted, or added--that will be determined (cont.) later in %UPDAT. If you remove the call to AA840-CALL-MAGEC-IO you should replace it with MOVE SPACES TO (cont.) TWA-DB-RETURN-CODE, or SET REC-FOUND TO TRUE. **%UPDAT** In this insertion point the defaiult logic updates the primary record (vendor record, in this example). If you do not (cont.) want to update the primary record, remove the call to AA840-CALL-MAGEC-IO and move spaces to TWA-DB-RETURN-CODE (or SET (cont.) REC-FOUND TO TRUE). Next, you will code a routine to loop through your table interrogating the action codes to (cont.) determine whether to add, update, delete, or ignore each invoice. For each invoice to be added, you must do the ADDIT I/O command after moving the fields from the appropriate occurrence (cont.) in the table to the invoice element copybook. Be sure to fill in all key fields completely--in some designs this would (cont.) involve reading a control record to assign the next available invoice number. For each invoice to be deleted, you must do the RDUKY I/O command followed by the DELET I/O command. For each invoice to be updated, you must do the RDUKY I/O command, then move the fields from the table to the invoice element copybook fields, then do the UPDAT I/O command. It is important to save the TWA-DB-REQUEST area into TWA-DB-REQ-SAV after the primary file's I/O and before your (cont.) routine to update the joined file (even if you have removed the call to update the primary file), and then to restore (cont.) it to TWA-DB-REQUEST after you have finished looping through your table. The standard logic of the MMP expects the (cont.) TWA-DB-REQUEST area to reflect the status resulting from the update of the primary file after exiting from this point (cont.) in the program. As you are updating, adding, or deleting records based upon the action code on the screen you should also be setting (cont.) the action code off (by moving space to it) for each item. You may prefer to move something to the screen indicating (cont.) which lines were processed, as well. **%GOODCHG** The default logic in this insertion points will set a message into SCOMPL indicating successful completion and will (cont.) fetch to the SEE function to display the results of the changes. You may not wish to execute the SEE function, but (cont.) rather just send the screen as is with any messages or statuses you have inserted into the array to show what was (cont.) added, changed, or deleted. To accomplish that you should merely remove the line of code which says: MOVE FTH-FUNCT TO (cont.) TWA-NONTP-REQUEST. The program will still change the function code in SFUNCT to the SEE function, but will not execute (cont.) the SEE function. It will just send the screen as is. **%PFKEYM** The default logic for handling PF7 (page back to prior vendor) and PF8 (page forward to next vendor) will remain (cont.) intact. It works just as we want it to. We will, however, add logic to handle PF4 (scroll up the list of invoices) and (cont.) PF5 (scroll down the list of invoices). The scrolling operations will limit themselves to only those invoices which (cont.) belong to this vendor. The invoice scrolling depends upon the fact that you have the table in %DATADEF which contains (cont.) data for each invoice listed on the screen, including the invoice numbers. For PF5, move the invoice number from the last invoice listed on the screen into the %DATADEF field used to hold the (cont.) beginning invoice number, add one to it, then perform JA100-LOGICAL-JOIN THRU JA199-EXIT, perform BB200-FILL-SCREEN (cont.) thru BB299-EXIT and GO TO AA800-SEND-SCREEN. For PF4, you do a similar process, except that you must use the invoice number from the first invoice listed on the (cont.) screen, then do the REDPR I/O command to "back up" ten invoices (or until you reach the Beginning-of-File or an invoice (cont.) for another vendor) to obtain the appropriate beginning invoice number to start listing from. It may also be prudent, prior to accepting a PF4 or PF5 or PF7 or PF8 key) to add a check of the screens action codes (cont.) for each invoice listed on the screen to see if any were marked for database action. If any were marked, you might wish (cont.) to ignore the scrolling or paging by resetting the key to ENTER, as: SET TWA-MSK-ENTER-HIT TO TRUE, or MOVE QUOTE TO (cont.) TWA-MSK-AID. This must be done before the processing for PF4 or PF5, obviously. ## Other Techniques The technique discussed above has been successfully used many times. You may wish to modify it with your own (cont.) refinements. One common modification is to eliminate the action code on each detail line of the screen and compare the (cont.) screen data to the data in the "WS-" table to determine if anything has been altered. You might retain the action codes (cont.) in the "WS-" table and set them to "A", "C", or "D" internally. A delete might be indicated by finding a zero invoice (cont.) number on the screen corresponding to an occurrence in the table which is non-zero. An addition might be indicated by (cont.) finding a non-zero invoice number on the screen corresponding to a zero entry in the table, and so forth, a change (cont.) might be indicated by finding the same invoice number on the screen for its corresponding table entry, but with other (cont.) values on that line altered from what was in the table. ## Beware - Avoid a Deadly Embrace A potential problem in any multi-tasking systen you should be aware of is called "Deadly Embrace". Here is what it (cont.) means: a task is waiting for a resource that is held with exclusive control (i.e. read for update) by another task that (cont.) is waiting for a resource that the first task is holding, As a result both tasks are in an endless wait status. Both (cont.) tasks may even be the same program. MAGEC generates MMP's With a keen awareness of this classic danger and a problem (cont.) like this may never, or very rarely, occur among MAGEC applications. But, your ability to do virtually unlimited (cont.) customization--including calling non-MAGEC programs--makes it impossible to eliminate every possibility for (cont.) error. The tasks may be MAGEC-generated MMP(s), other programs, or any combination. The resource being held may be a file, a record, an element, or any other resource. The best way to make it as unlikely as possible for the problem to occur is some simple standards.Obtain exclusive (cont.) condtrol (i.e. read for update) as late as possible in your procedureRelease it as early as pssible after no longer (cont.) neededAlways do either an implicit (i.e. UPDAT) or explicit (i.e. RELES) Process in a predictable order (i.e. key (cont.) sequence) in all tasks Of course, a task can get exclusive control over other types of resources (i.e. main memory storage) that you might (cont.) have little ability to control, but file or database I/O is the type you will most likely be involved with and these (cont.) simple standards might afford you the luxury of *never* being involved at all.