MOVE TBL01-KEY            TO TWA-KEY-VALUE.   MOVE REDKY            TO TWA-DB-CMD.   MOVE 'TBLK1'            TO TWA-DB-FILE-NAME.   MOVE 'TBL01'            TO TWA-ELT-LIST.   CALL 'MAGECSET' USING      TWA-DB-AREA-A               TBL01-ELEMENT.   PERFORM AA840-CALL-MAGEC-IO THRU AA899-EXIT.   IF ( REC-FOUND )   MOVE TBL01-DESC      TO some-work-field   ELSE     there is no ERROR-HIGHLIGHT specified (default will apply).   Remember to check in the "Insertion Points" chapter of your *Programmer's Reference Guide* to determine whether it is (cont.) necessary to save and restore the I/O request area when doing I/O in the insertion point you choose. In %EDIT or %JOIN (cont.) it is not necessary, for some others it may be. # Appendix U -- List-type Update Screens ## Multi-Record Updates You might frequently find it useful to develop screens on which the operator maintains multiple records from a single (cont.) transaction. Such a screen typically lists records much like the browses do, but allows the operator to modify the (cont.) listed records on the screen. The program senses which records were modified on the screen and updates, adds, or (cont.) deletes accordingly. An example of a function which might work this way is an Accounts Payable screen which shows the vendor information at (cont.) the top and lists open invoices below. The operator might be allowed to modify the Release-to-Pay date on one or more (cont.) of the invoices. He or she might also be allowed to delete invoices by typing a code into a designated field on that (cont.) invoice's line, or to add new invoices by typing them into blank lines shown below the last open invoice on the screen. (cont.) Such a program would read (and likely update) the vendor master record as well as one or more invoice (cont.) records. While this process might seem very different from the standard MAGEC-generated functions, it is not difficult to (cont.) create. It requires surprisingly little customization to do so. Here is one technique which many MAGEC customers have (cont.) used to develop hundreds of list-update MMP's. You may wish to modify this technique to accommodate some special (cont.) requirement of your own. Once you have developed your first list-update program you will likely use it as a model for (cont.) many other similar programs. ## General Premises Before we discuss the technique it is helpful to review a few of the standards employed in the generated MMP's. (cont.) Regardless what type function is being processed, the generated MMP's are designed to build a "logical record" or (cont.) "view", then to do the desired process against the data within that logical record. In other words, the program reads (cont.) one or more files or tables, calculates derived values, and places all of the resulting data into predictable locations (cont.) (usually that means in the appropriate element copybooks in %DATADEF) early in the processing cycle. Thereafter, the (cont.) logic is unconcerned about from whence the data came; all data is available to use however (cont.) necessary. An example of that is the Vacation MMP (MMP600) which you developed in these tutorials. It gathers data from two files (cont.) (VAC and SIF) plus derived values (the calculated days due). The %JOIN insertion point is used to build the logical (cont.) record. If you have reviewed the Screen Painting section of your Programmer's Reference manual, you should have noticed that (cont.) MAGEC allows you to easily define "repeating fields" on a screen. These repeating fields constitute an array, or table (cont.) which is accessed using a Cobol subscript or index. You can have more than one such array on your screen. You can (cont.) specify as the Source/Target database field for these repeating screen fields any valid Cobol dataname which OCCURS. It (cont.) is perfectly legitimate for the Source/Target field to be a "Working-Storage" field, rather than an actual database (cont.) field. You specify a relative subscript using an asterisk " (*) " to denote that the corresponding occurrence of each (cont.) screen field and its Source/Target field will be MOVE'd to one another at the appropriate times. All of the routines which do I/O in the MMP can be modified by you using customization in insertion points such as (cont.) %REDKY, %RDUKY, %UPDAT, et cetera. When you add customization logic into these insertion points, MAGEC presents a (cont.) proforma on the screen which strongly resembles the default I/O logic. This facilitates your making modifications to (cont.) the I/O logic without having to re-type the default code. ## One Technique While there are probably many ways to skin a cat, professional developers usually find one good way to do something, (cont.) then adopt it as a standard and use it many times over. Below is a technique which was developed by some accomplished (cont.) MAGEC users and has been shared with many others. Specifications** For this example we will assume the vendor/invoice problem referenced earlier. The screen is to show vendor data at the (cont.) top and is to list ten (10) invoices below. To the left of each invoice there is to be a one-byte action code into (cont.) which the operator will type "A", "C", or "D" to cause an add, change or delete of that invoice. The standard MAGEC PF7 (cont.) and PF8 keys will bump to the previous or next vendor, the PF4 and PF5 keys will scroll backward or forward through (cont.) this vendor's invoices. The vendor file is keyed by vendor number, the invoice file is keyed by vendor number plus invoice number concatenated. (cont.) The vendor number must already exist on the vendor file, thus this program will have only SEE and CHG maintenance (cont.) functions. To add or delete vendors the operator will have a different vendor maintenance screen. **Auto-Join** To begin, you define the screen and MMP headers just as you would for any other new application. You specify the vendor (cont.) file as your primary data class. Using the fully-automated development process to create the screen, you select the (cont.) invoice file for MAGEC to join to. *Note, this presumes that the vendor number is the high-order portion of the invoice (cont.) file key and that it belongs to the same domain as the vendor number in the vendor file.* MAGEC will generate a (cont.) partial-key join ("left Join") to the invoice file; that is, it will generate (in %JOIN) a LOCKY, REDLE to read the (cont.) first invoice for this vendor. You will be able to customize this join to then do REDNX to get subsequent invoices. If (cont.) you are not familiar with these database I/O commands, refer to the Database Administration section of your (cont.) Programmer's Reference manual. **Screen Painting** After you have selected the fields (Data Items) you wish to present on your screen from both the vendor and invoice (cont.) record elements, MAGEC will generate a screen containing fields to display one vendor's data and one invoice's data. (cont.) Using the manual screen painter, arrange the vendor data at the top of the screen and arrange the invoice data across (cont.) one line. Delete the screen prompts which were generated to the left of each invoice field, you will be drawing a (cont.) column heading above the invoice fields to replace these prompts. Leave one blank line (optional) below the vendor (cont.) data, plus one line for the column headings. Place the invoice fields on the next line below the column headings line. (cont.) Manually draw one column heading field with appropriate literals in the line immediately above the invoice data (cont.) line. Modify each invoice field by cursor-selecting it using PF18. Change the Occurrence to "*10", this will cause MAGEC to (cont.) repeat that field ten times vertically. Of course, if you wished to have other than ten occurrences, you would modify (cont.) the entry into Occurrence. Also modify the Source/Target to be an arrayed Working-Storage field, rather than the (cont.) database field name which was generated for you. For ease of understanding, you should use a similar name with only the (cont.) prefix altered. For instance: if the database name was IVC01-AMOUNT, you might alter it to WS-AMOUNT (*). The asterisk (cont.) in the subscript tells MAGEC to generate MOVE's back and forth between the arrayed screen fields and their (cont.) corresponding occurrences of "WS-" fields. Do not forget to add a one-byte Action-Code field which OCCURS just like the (cont.) invoice fields. Its Source/Target might be WS-ACTION (*). **%DATADEF** Define a table of Working-Storage Source/Target fields. Use Cobol level 03 for the group item defining the entire (cont.) table. Use Cobol level 05 (or as desired) for the entry below the group item. This 05 item should contain the OCCURS 10 (cont.) TIMES clause. Define each "WS-" field using Cobol level 07 below it. Also define an index or subscript [PIC S9(4) COMP (cont.) SYNC is recommended]. MAGEC will generate MOVE's from the fields in this table to the screen for displays and from the screen fields to this (cont.) table for updates. For all intents and purposes, MAGEC now "thinks" this table is the database record which was read or (cont.) will be updated. Do not forget the action code which also occurs. Be sure to include all the primary key fields necessary to read each invoice record. If some of the key fields will not (cont.) be displayed on the screen, include them in the table anyhow--you will need the complete primary key to add, delete, or (cont.) update these records. Also, add a field in %DATADEF to store the "beginning invoice number". This field will be used to start the browse looking for invoices for this vendor. **%REDKY** The default logic here does an exact key read of the vendor record, then it performs the join logic. Add one line of (cont.) code before performing JA100-LOGICAL-JOIN to set the beginning invoice number to zero. **%JOIN** In %JOIN you will find generated logic to read the first invoice for the vendor being processed. That means that at the (cont.) bottom of this generated join logic you will have the vendor data and one invoice's data in their appropriate element (cont.) copybook areas. First, alter the logic which builds the generic key for the invoice records. The generated logic fills in the (cont.) high-order portion of the key using the vendor number and sets the low-order portion (the invoice number) to zeros. You (cont.) must move the beginning invoice number from your %DATADEF holding field into the invoice number portion (low-order (cont.) portion) of the key. This results in positioning to the first invoice for this vendor having an invoice number equal to (cont.) or greater than the beginning invoice number. 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.) Next: https://magec.com/DOC/markdown/cstm20.md.txt