RPG Video Series Contents EXER0101 – “Hello World”, Your First RPG Program. ............................................................................................. 2 EXER0102 – Adding Two Numbers .......................................................................................................................... 4 EXER0201 – This program and print file produces a list of customers in arrive sequence. .................................... 5 EXER0301 – This program accepts a character variable and displays it. ................................................................ 7 EXER0302 – This program allows a user to maintain a customer master file......................................................... 9 EXER0401 – Customer Listing using arrays and Data Structures .......................................................................... 13 EXER0402 - Redo CRUD application with data structures for file I/O ................................................................... 16 EXER0501 – This program allows a user to maintain a customer master file....................................................... 21 EXER0502 – Customer Master Listing with Control-Break Logic .......................................................................... 27 EXER0601 & EXER0602– Customer Master Updates using Service Program ....................................................... 29 EXER0701 – No Documentation ............................................................................................................................ 36 EXER0801 – This program demonstrates using RPG Built-In Functions................................................................ 37 EXER0902 – Subfile program for Order Entry and Maintenance application ....................................................... 42 EXER1001 – This program accepts two parameters and displays a list of items ................................................. 51 EXER1002 & EXER1003 – Displays a list of open orders, allows an order to be deleted, changed or viewed. .... 59 RPGVideo_AttendeeWorkbook.docx 1 of 79 EXER0101 – “Hello World”, Your First RPG Program. The program demonstrates the following concepts: • • • • • • • • • Entering RPG program source Declaring a program as free format Declaring a character variable in RPG Assigning a value to a variable Displaying data with the DSPLY operation code Ending an RPG program Saving source code Creating an RPG program Running an RPG program You Will Need a Library to Work In A library is a cross between a “schema” that you might find in database software, and a “folder” that you might use on a PC. It is used to store database tables like a schema, but is also used to store source code, programs, and many other things. On other platforms, the things you store in a folder are often referred to as “files”, but on IBM i the term “file” is only used for data files. Instead, we use the term “object” to refer to the various things that can be placed in a library. Program, file, and other things are “object types.” You should check with your system administrator to find out if you already have a library that you can use to create programs while you are learning. If you don’t already have one, you can create one from the IBM i command line with the following command (replace EXAMPLE with the name of your library): CRTLIB LIB(EXAMPLE) In your library you will need a file for storing RPG source code. If you don’t already have one, you can create one from the command line with the following command (replace EXAMPLE with the name of your library): CRTSRCPF FILE(EXAMPLE/QRPGLESRC) RCDLEN(112) The name QRPGLESRC is the traditional name of a source file for storing RPG source code. A source file is not limited to only one program’s source, it can contain as many as you like. Each program’s source is called a “source member”. Libraries, objects, files and members will be discussed further in the next video. Program Source for EXER0101 **FREE // ************************************************************* // Written - Scott Klement * // ************************************************************* dcl-s Hello char(12); dcl-s keypress char(1); Hello = 'Hello World'; DSPLY Hello '' keypress; *INLR = *ON; RETURN; RPGVideo_AttendeeWorkbook.docx 2 of 79 Tell RDi Where to Put Your Program New program objects are put into your “current library.” To set the current library in RDi, follow these steps: • • • • In RDi’s “Remote Systems” view, expand your IBM i connection Expand “Objects” Right-click “Library List” Use the “Change Current Library” option to set it to your library Compile Your Program • Make sure your source member is selected by clicking on the tab • Click Compile, then the Compile option from the drop-down • Choose CRTBNDRPG Run Your Program • Use the EDTLIBL command to add your library to the library list • Type: CALL EXER0101 RPGVideo_AttendeeWorkbook.docx 3 of 79 EXER0102 – Adding Two Numbers The program demonstrates the following concepts: • • • • • Declaring Integers Using the DSPLY opcode for input Adding numbers Concatenating character data Upper and lowercase work the same Since you’ve already done one example, this one should be easy! Enter the source code into RDi, compile it, and run it. Program Source for EXER0102 **free // ************************************************************* // Written - Scott Klement * // ************************************************************* dcl-s var1 int(10); dcl-s var2 int(10); dcl-s result int(10); dcl-s keypress char(1); dsply ('Enter the first number') '' var1; dsply ('Enter the second number') '' var2; result = var1+var2; dsply ('Result is ' + %char(result)) '' keypress; dsply ('Enter a number') '' var1; *inlr = *on; RETURN; RPGVideo_AttendeeWorkbook.docx 4 of 79 EXER0201 – This program and print file produces a list of customers in arrive sequence. The program demonstrates the following concepts: • • • • • One of the uses of the Ctl-Opt Keyword Opening Print files and data files. A simple example of the Dcl-S keyword The READ keyword for sequentially reading a database file The use of the DOW keyword to loop through a DB2 table The print file EXER0201P used to produce the Customer listing Printer Output from EXER0201 Program Source for EXER0201 RPGVideo_AttendeeWorkbook.docx 5 of 79 // * Control Options Section Ctl-opt Option(*Nodebugio); // ************************************************************* // Creates a listing of CloudServices247 Inc customers * // EXER0201 - COMMON RPG Video Series * // Written Jim Buck 12-01-16 * // ************************************************************* Dcl-F CSCSTP Disk(*Ext) Usage(*input); Dcl-F EXER0201P Printer(*ext) Usage(*Output) Oflind(EndOfPage); // * Declarations Section Dcl-s EndOfPage Ind Inz(*on); // * Main Section Read CSCSTP; // Read the First Record Dow NOT %EOF; RPTMESSAGE = *Blanks; // Check the Balance Due field and assign value to message field Select; When BALDUE < 0; RPTMESSAGE = 'BALDUE is less than Zero'; When BALDUE > 0 and BALDUE < 500; RPTMESSAGE = 'BALDUE is > 0 and < 500'; When BALDUE > 500 and BALDUE < 1000; RPTMESSAGE = 'BALDUE is > 500 and < 1000'; When BALDUE > 1000; RPTMESSAGE = 'BALDUE is > 1000'; Other; RPTMESSAGE = 'Other BALDUE Values!'; ENDSL; // Check for the End of Page If Endofpage; Write Heading; // Write Heading on report Endofpage = *Off; Endif; Write Detail; // Write a detail line on the report READ CSCSTP; EndDo; // Turn on last record indicator and return to caller *INLR = *ON; Return; RPGVideo_AttendeeWorkbook.docx 6 of 79 EXER0301 – This program accepts a character variable and displays it. The program demonstrates the following concepts: • • • • • • Displaying an input screen and then display the information on a second screen The use of the DOW keyword to loop until the user wants to exit the screen Introduction to INDARA keyword & INNDS data structure Use of F3 and F12 function keys (CA keys) Use of keywords COLOR and EDTWRD A simple example of the Dcl-S keyword The Display file EXER0301D used to produce the Customer Update Application Display Customer data from EXER0301 using the EXER0301D Display file RPGVideo_AttendeeWorkbook.docx 7 of 79 Program Source for EXER0301 // ************************************************************* // This program accepts a name and then after the user presses * // the Enter key. The program displays the value entered on the* // previous screen * // Written - Jim Buck - 02-25-2017 * // ************************************************************* Dcl-f Exer0301D WORKSTN INDDS(Indicators); // Indicator Data Structure Dcl-ds Indicators Len(99); Exit ind Pos(3) inz(*off); Cancel ind Pos(12); End-ds; // Stand Alone Variables Dcl-s PgmName char(9) inz('Exer0301'); // ******************************************************* // Loop until user presses the Exit (F3) Key // ******************************************************* DOW NOT Exit; Reset Name; EXFMT InputSrcn; // Display the Enter Name Screen // Figure out what happened in the screen SELECT; WHEN Exit; LEAVE; // Leave loop and Exit the program WHEN Cancel; ITER; // Loop again ENDSL; EXFMT DspScrn; // Display Name Entered ENDDO; *INLR = *ON; RETURN; // ************************************************************ RPGVideo_AttendeeWorkbook.docx 8 of 79 EXER0302 – This program allows a user to maintain a customer master file. The program demonstrates the following concepts: • • • • • • The use of the DOU keyword to loop until the user wants to exit the screen The CHAIN, WRITE, DELETE and UPDATE keywords to manipulate a database file One of the uses of the Ctl-Opt Keyword Opening Display files and data files. An expanded example of the Dcl-ds keyword Additional use of DDS keywords – CHECK, DSPATR, EDTWRD and EDTCDE The Display file EXER0302D used to produce the Customer Update Application Display Customer data from EXER0302 using the EXER0302D Display file RPGVideo_AttendeeWorkbook.docx 9 of 79 Program Source for EXER0302 // ************************************************************* // This program allows users to interactively maintain Cloud- * // Services Customer Mstr file by adding, changing, and dele- * // ing records. For adds, the next customer number is assigned* // by the system. Customer's whose balance is greater than * // zero cannot be deleted. * // Written - Jim Buck - 02-25-2017 * // ************************************************************* Dcl-f CSCSTP DISK(*ext) keyed Usage(*Update:*Delete:*Output); Dcl-f Exer0302D WORKSTN INDDS(Indicators); // Indicator Data Structure Dcl-ds Indicators Len(99); Exit ind Pos(3) inz(*off); FkeyPressed ind Pos(10) Inz(*off); Cancel ind Pos(12); BalDueError ind Pos(30); RecNotFound ind Pos(90); UpdateError ind Pos(91); ProtectField ind Pos(92) inz; End-ds; // Stand Alone Variables Dcl-s PgmName char(9) inz('Exer0302'); Dcl-s Errormsg char(20); // ******************************************************* // Loop until user presses the Exit (F3) Key // ******************************************************* DOU Exit; CustIn = 0; Exsr ClearFields; EXFMT InputScrn; // Display the Enter Custnbr Screen // Figure out what happened in the screen SELECT; WHEN Exit; LEAVE; // Leave loop and Exit the program WHEN Cancel; ITER; // Loop again WHEN Action = 'A'; EXSR AddRecord; WHEN Action = 'C'; EXSR ChangeRecord; WHEN Action = 'D'; EXSR DeleteRecord; Other; ITER; ENDSL; ENDDO; *INLR = *ON; RETURN; RPGVideo_AttendeeWorkbook.docx 10 of 79 // ******************************************************* // * Add A Record // ******************************************************* BEGSR AddRecord; Mode = 'Add'; EXSR AssignNextNbr; // Assign the next Customer Number EXFMT DispScrn; IF NOT FkeyPressed; CustNo = CustIn; WRITE(E) CustRec; // Write a new record UpdateError = %ERROR; ENDIF; ENDSR; // ****************************************************** // * Get Next Customer Number - Not used to be used in production // ****************************************************** BEGSR AssignNextNbr; SETGT 999999 CSCSTP; // Determine last customer number READP CSCSTP; // Read the previous record CustIn = CustNo + 1; // Increment for new customer EXSR ClearFields; // Clear out the fields ENDSR; // ****************************************************** // * Change a Record // ****************************************************** BEGSR ChangeRecord; Mode = 'Change'; IF NOT FkeyPressed; CHAIN CustIn CSCSTP; RecNotFound = NOT %FOUND; SELECT; WHEN FkeyPressed; LEAVESR; WHEN RecNotFound; ErrorMsg = 'Record Not Found'; LEAVESR; WHEN NOT RecNotFound; EXFMT DispScrn; CustNo = CustIn; UPDATE(E) CustRec; // Update the record UpdateError = %ERROR; ENDSL; ENDIF; ENDSR; RPGVideo_AttendeeWorkbook.docx 11 of 79 // *********************************************************** // * Delete a Record if they don't have a Balance // *********************************************************** BEGSR DeleteRecord; Mode = 'Delete'; IF NOT FkeyPressed; CHAIN CustIn CSCSTP; RecNotFound = NOT %FOUND; BalDueError = (BalDue > 0); // Balance is greater than zero; can't delete SELECT; WHEN FkeyPressed; LEAVESR; WHEN RecNotFound; ErrorMsg = 'Record Not Found'; LEAVESR; WHEN BalDueError; ErrorMsg = 'Balance Due > Zero'; LEAVESR; WHEN NOT BalDueError; ProtectField = *on; // Turn on to protect the fields from change EXFMT DispScrn; ProtectField = *off; DELETE(E) CustRec; UpdateError = %ERROR; ENDSL; ENDIF; ENDSR; // ************************************************************ // * Clear out the fields // ************************************************************ BEGSR ClearFields; RESET Custrec; ErrorMsg = *Blank; RESET BalDueError; RESET RecNotFound; RESET UpdateError; ENDSR; // ************************************************************ RPGVideo_AttendeeWorkbook.docx 12 of 79 EXER0401 – Customer Listing using arrays and Data Structures This program splits a phone number area code, looks up the full state name from an array, and prints the report with a defined printer file. The program demonstrates the following concepts: • • • • • • Declares Files (Dcl-F), Stand-alone variables (Dcl-S), and Data Structures (Dcl-DS) Shows *N usage within Data Structures Shows initializing variables Shows overview of a printer file Shows Read, DoW, %EOF, If, and Write keywords. Shows %Subst, %EditC, and %Dec keywords. The Printer file PROG401P used to produce the report for the Area Code Listing. Records Real Time Display Properties of each field RPGVideo_AttendeeWorkbook.docx 13 of 79 // * Control Options Section Ctl-opt Option(*Nodebugio); // ************************************************************* // Splits Phone Number Area Code and Prints on Report * // Array * // PROG401 - COMMON RPG Video Series * // Written Jim Buck 03-15-17 * // Revised Kody Robinson * // ************************************************************* Dcl-F CSCSTP Disk(*Ext) Usage(*input); Dcl-F Prog401P Printer(*ext) Usage(*Output) Oflind(EndOfPage); // * Declarations Section Dcl-S AreaCode Packed(3:0); Dcl-S EndOfPage Ind Inz(*on); Dcl-S Position Packed(5:0); Dcl-S Statename Char(14); Dcl-Ds Abbreviations; *n Char(30) INZ('ALAKAZARCACOCTDEFLGAHIIDILINIA'); *n Char(30) INZ('KSKYLAMEMDMAMIMNMSMOMTNENVNHNJ'); *n Char(30) INZ('NMNYNCNDOHOKORPARISCSDTNTXUTVT'); *n Char(10) INZ('VAWAWVWIWY'); ABBREV Char(2) Pos(1) DIM(50); End-Ds; // Dcl-Ds NAMES; *n Char(14) INZ('Alabama'); *n Char(14) INZ('Alaska'); *n Char(14) INZ('Arizona'); *n Char(14) INZ('Arkansas'); *n Char(14) INZ('California'); *n Char(14) INZ('Colorado'); *n Char(14) INZ('Connecticut'); *n Char(14) INZ('Delaware'); *n Char(14) INZ('Florida'); *n Char(14) INZ('Georgia'); *n Char(14) INZ('Hawaii'); *n Char(14) INZ('Idaho'); *n Char(14) INZ('Illinois'); *n Char(14) INZ('Indiana'); *n Char(14) INZ('Iowa'); *n Char(14) INZ('Kansas'); *n Char(14) INZ('Kentucky'); *n Char(14) INZ('Louisiana'); *n Char(14) INZ('Maine'); *n Char(14) INZ('Maryland'); *n Char(14) INZ('Massachusetts'); *n Char(14) INZ('Michigan'); *n Char(14) INZ('Minnesota'); *n Char(14) INZ('Mississippi'); *n Char(14) INZ('Missouri'); *n Char(14) INZ('Montana'); *n Char(14) INZ('Nebraska'); *n Char(14) INZ('Nevada'); RPGVideo_AttendeeWorkbook.docx 14 of 79 *n Char(14) INZ('New Hampshire'); *n Char(14) INZ('New Jersey'); *n Char(14) INZ('New Mexico'); *n Char(14) INZ('New York'); *n Char(14) INZ('North Carolina'); *n Char(14) INZ('North Dakota'); *n Char(14) INZ('Ohio'); *n Char(14) INZ('Oklahoma'); *n Char(14) INZ('Oregon'); *n Char(14) INZ('Pennsylvania'); *n Char(14) INZ('Rhode Island'); *n Char(14) INZ('South Carolina'); *n Char(14) INZ('South Dakota'); *n Char(14) INZ('Tennessee'); *n Char(14) INZ('Texas'); *n Char(14) INZ('Utah'); *n Char(14) INZ('Vermont'); *n Char(14) INZ('Virginia'); *n Char(14) INZ('Washington'); *n Char(14) INZ('West Virginia'); *n Char(14) INZ('Wisconsin'); *n Char(14) INZ('Wyoming'); STATE Char(14) Pos(1) DIM(50); End-Ds; // //*******************************************************************// // MainLineLogic // //*******************************************************************// // Reset Fields AreaCode = *Zeros; // Read First Record Read CSCSTP; // Loop until End-Of-File Dow NOT %EOF; // Get area code from phone number file (first three numbers) AreaCode = %Dec(%Subst(%EditC(CPHONE:'X'):1:3):3:0); // Get State Name Position = %Lookup(CSTATE:Abbrev); If Position > 0; Statename = State(Position); EndIf; // Check for the End of Page If Endofpage; Write Heading; // Write Heading on report Endofpage = *Off; Endif; Write Detail; // Write a detail line on the report READ CSCSTP; EndDo; // Turn on last record indicator and return to caller *INLR = *ON; Return; RPGVideo_AttendeeWorkbook.docx 15 of 79 EXER0402 - Redo CRUD application with data structures for file I/O This program allows users to interactively maintain the master file by adding, changing, and deleting the records within it. The program demonstrates the following concepts: • • • • Declares Files (Dcl-F), Stand-alone variables (Dcl-S), and Data Structures (Dcl-DS) o Indicator Data Structure o Data Structure as Input/Output o WORKSTN INDDS – pass in DS for indicators DoU, Select(s), Subroutines, When, Embedded functions The Screen PROG402FM is broken down into two screens, or “records.” The first, INPUTSCRN, lets you enter a customer number (CUSTIN) and then the action code (ACTION). Selecting add will let you input from scratch on the next screen. Change, will populate the information currently in the database and then update it. Delete will delete. RPGVideo_AttendeeWorkbook.docx 16 of 79 // * Control Options Section Ctl-opt Option(*Nodebugio); // ************************************************************* // This program allows users to interactively maintain Cloud- * // Services Customer Mstr file by adding, changing, and dele- * // ing records. For adds, the next customer number is assigned* // by the system. Customer's whose balance is greater than * // zero cannot be deleted. * // Written - Kody Robinson - 03/21/17 * // ************************************************************* Dcl-f CSCSTP DISK(*ext) keyed Usage(*Update:*Delete:*Output); Dcl-f Prog402FM WORKSTN INDDS(Indicators); // Data Structure for I/O Dcl-Ds CusData qualified; Dcl-SubF CusDataIn likerec(CustRec:*input); Dcl-SubF CusDataOut likerec(CustRec:*output) overlay(In); End-Ds; // Indicator Data Structure Dcl-ds Indicators Len(99); Exit ind Pos(3) inz(*off); RPGVideo_AttendeeWorkbook.docx 17 of 79 FkeyPressed ind Pos(10) Inz(*off); Cancel ind Pos(12); BalDueError ind Pos(30); RecNotFound ind Pos(90); UpdateError ind Pos(91); ProtectField ind Pos(92) inz; End-ds; // Stand Alone Variables Dcl-s PgmName char(9) inz('Exer0302'); Dcl-s Errormsg char(20); // ******************************************************* // Loop until user presses the Exit (F3) Key // ******************************************************* DOU Exit; CustIn = 0; Exsr ClearFields; EXFMT InputScrn; // Display the Enter Custnbr Screen // Figure out what happened in the screen SELECT; WHEN Exit; LEAVE; // Leave loop and Exit the program WHEN Cancel; ITER; // Loop again WHEN Action = 'A'; EXSR AddRecord; WHEN Action = 'C'; EXSR ChangeRecord; WHEN Action = 'D'; EXSR DeleteRecord; Other; ITER; ENDSL; ENDDO; *INLR = *ON; RETURN; // ******************************************************* // * Add A Record // ******************************************************* BEGSR AddRecord; Mode = 'Add'; EXSR AssignNextNbr; // Assign the next Customer Number EXFMT DispScrn; IF NOT FkeyPressed; CustNo = CustIn; WRITE(E) CustRec CusDataOut; // Write a new record UpdateError = %ERROR; ENDIF; ENDSR; // ****************************************************** // * Get Next Customer Number - Not used to be used in production // ****************************************************** BEGSR AssignNextNbr; SETGT 999999 CSCSTP; // Determine last customer number READP CSCSTP; // Read the previous record RPGVideo_AttendeeWorkbook.docx 18 of 79 CustIn = CustNo + 1; EXSR ClearFields; ENDSR; // Increment for new customer // Clear out the fields // ****************************************************** // * Change a Record // ****************************************************** BEGSR ChangeRecord; Mode = 'Change'; IF NOT FkeyPressed; CHAIN CustIn CustRec CusDataIn; RecNotFound = NOT %FOUND; SELECT; WHEN FkeyPressed; LEAVESR; WHEN RecNotFound; ErrorMsg = 'Record Not Found'; LEAVESR; WHEN NOT RecNotFound; EXFMT DispScrn; CustNo = CustIn; UPDATE(E) CustRec CusDataOut; // Update the record UpdateError = %ERROR; ENDSL; ENDIF; ENDSR; // *********************************************************** // * Delete a Record if they don't have a Balance // *********************************************************** BEGSR DeleteRecord; Mode = 'Delete'; IF NOT FkeyPressed; CHAIN CustIn CustRec CusDataIn; RecNotFound = NOT %FOUND; // Balance is greater than zero; can't delete BalDueError = (BalDue > 0); SELECT; WHEN FkeyPressed; LEAVESR; WHEN RecNotFound; ErrorMsg = 'Record Not Found'; LEAVESR; WHEN BalDueError; ErrorMsg = 'Balance Due > Zero'; LEAVESR; // Turn on to protect the fields from change WHEN NOT BalDueError; ProtectField = *on; EXFMT DispScrn; ProtectField = *off; DELETE(E) CustRec CusDataOut; UpdateError = %ERROR; ENDSL; ENDIF; ENDSR; RPGVideo_AttendeeWorkbook.docx 19 of 79 // ************************************************************ // * Clear out the fields // ************************************************************ BEGSR ClearFields; RESET Custrec; ErrorMsg = *Blank; RESET BalDueError; RESET RecNotFound; RESET UpdateError; ENDSR; // ********************************************************* RPGVideo_AttendeeWorkbook.docx 20 of 79 EXER0501 – This program allows a user to maintain a customer master file. These programs demonstrates the following concepts: Define and use Control Break Logic (not using the cycle) Declare and use Iteration Declare and use DOW, DOU and FOR Operations Declare and use Subprocedures Declaring local variables Parameters & Return values Passing Parameters by Value Calling Programs Prototypes procedure interfaces The Display file EXER0501D used to produce the Customer Update Applicatio Create – a database record Read – a database record Update – a database record Delete – a database record RPGVideo_AttendeeWorkbook.docx 21 of 79 // * Control Options Section Ctl-opt Option(*Nodebugio) DFTACTGRP(*no); // ************************************************************* // This program allows users to interactively maintain Cloud- * // Services Customer Mstr file by adding, changing, and dele- * // ing records. For adds, the next customer number is assigned* // by the system. Customer's whose balance is greater than * // zero cannot be deleted. * // Written - Jim Buck - 03/22/2017 * // ************************************************************* Dcl-f CSCSTP DISK(*ext) keyed Usage(*Update:*Delete:*Output); Dcl-f DisplayScreen WORKSTN Qualified Alias ExtFile(*extdesc) ExtDesc('EXER0501D') indds(indicators); // Copy in the Prototypes /copy BCRPG/QRPGLESRC,EXER0501CP // Indicator Data Structure Dcl-ds Indicators Len(99); Exit ind Pos(3) inz(*off); FkeyPressed ind Pos(10) Inz(*off); Cancel ind Pos(12); BalDueError ind Pos(30); RecNotFound ind Pos(90); UpdateError ind Pos(91); ProtectField ind Pos(92) inz; End-ds; // Data Structure for Screen I/O Dcl-Ds InputScreenDS likerec(DisplayScreen.InputScrn:*all); Dcl-Ds CustDataInDS likerec(DisplayScreen.DispScrn:*All); // Data Structures for Database I/O Dcl-Ds CSCSTPDataIODS Ext ExtName('CSCSTP':*All) Qualified End-DS; // Stand Alone Variables Dcl-s PgmName char(9) inz('Exer0501'); Dcl-s CustInWrk Packed(6:0); // ******************************************************* // Loop until user presses the Exit (F3) Key // ******************************************************* DOU Exit; ClearFields(); // Display the Enter Custnbr Screen EXFMT DisplayScreen.InputScrn InputScreenDS; CustInWrk = InputScreenDS.CustNo; // Reset screen indicators RESET BalDueError; RESET RecNotFound; RESET UpdateError; // Figure out what happened in the screen SELECT; WHEN Exit; LEAVE; // Leave loop and Exit the program WHEN Cancel; ITER; // Loop again WHEN InputScreenDS.Action = 'A'; RPGVideo_AttendeeWorkbook.docx 22 of 79 AddRecord(); WHEN InputScreenDS.Action = 'C'; ChangeRecord(); WHEN InputScreenDS.Action = 'D'; DeleteRecord(); Other; ITER; ENDSL; ENDDO; *INLR = *ON; RETURN; // ******************************************************* // * Add A Record // ******************************************************* Dcl-Proc AddRecord; AssignNextNbr(); // Assign the next Customer Number CustDataInDS.Mode = 'Add'; CustDataInDS.CustNo = CustInWrk; EXFMT DisplayScreen.DispScrn CustDataInDS; IF NOT FkeyPressed; EVAL-CORR CSCSTPDataIODS = CustDataInDS; UpdateError = WriteCSCSTP_Data(CSCSTPDataIODS:CustInWrk); ENDIF; End-Proc; // ****************************************************** // * Get Next Customer Number - Not used to be used in production // ****************************************************** Dcl-Proc AssignNextNbr; SETGT 999999 CSCSTP; // Determine last customer number READP CSCSTP; // Read the previous record CustInWrk = CustNo + 1; // Increment for new customer ClearFields(); // Clear out the fields End-Proc; // ****************************************************** // * Change a Record // ****************************************************** Dcl-Proc ChangeRecord; CustDataInDS.Mode = 'Change'; IF NOT FkeyPressed; RecNotFound = GetCSCSTP_Data(CSCSTPDataIODS:CustInWrk); SELECT; WHEN FkeyPressed; Return; WHEN RecNotFound; // ErrorMsg = 'Record Not Found'; Return; WHEN NOT RecNotFound; EVAL-CORR CustDataInDS = CSCSTPDataIODS; EXFMT DisplayScreen.DispScrn CustDataInDS; IF NOT FkeyPressed; Eval-corr CSCSTPDataIODS = CustDataInDS; UpdateError = UpdateCSCSTP_Data(CSCSTPDataIODS:CustInWrk); RPGVideo_AttendeeWorkbook.docx 23 of 79 Endif; ENDSL; ENDIF; End-Proc; // *********************************************************** // * Delete a Record if they don't have a Balance // *********************************************************** Dcl-Proc DeleteRecord; CustDataInDS.Mode = 'Delete'; IF NOT FkeyPressed; RecNotFound = GetCSCSTP_Data(CSCSTPDataIODS:CustInWrk); Eval-corr CustDataInDS = CSCSTPDataIODS; // Balance is greater than zero; can't delete BalDueError = (CustDataInDS.BalDue > 0); SELECT; WHEN FkeyPressed; Return; WHEN RecNotFound; // ErrorMsg = 'Record Not Found'; Return; WHEN BalDueError; // ErrorMsg = 'Balance Due > Zero'; Return; WHEN NOT BalDueError; // Turn on to protect the fields from change ProtectField = *on; EXFMT DisplayScreen.DispScrn CustDataInDS; ProtectField = *off; IF NOT FkeyPressed; Eval-corr CSCSTPDataIODS = CustDataInDS; UpdateError = DeleteCSCSTP_Data(CSCSTPDataIODS:CustInWrk); EndIf; ENDSL; ENDIF; End-Proc; // ************************************************************ // * Retrieves DB2 Data For CSCSTP // ************************************************************ Dcl-Proc GetCSCSTP_Data; Dcl-Pi *N IND; CSCSTPDataDS LIKEDS(CSCSTPDataIODS); CustNbrWrk Packed(6:0); End-Pi ; Dcl-s RecNotFound Ind; CHAIN(E) CustNbrWrk CustRec CSCSTPDataDS; RecNotFound = NOT %FOUND; return RecNotFound; End-Proc; // ************************************************************ // * Deletes DB2 Data For CSCSTP // ************************************************************ Dcl-Proc DeleteCSCSTP_Data; Dcl-Pi *N IND; RPGVideo_AttendeeWorkbook.docx 24 of 79 CSCSTPDataDS LIKEDS(CSCSTPDataIODS); CustNbrWrk Packed(6:0); End-Pi ; Dcl-s DeleteError Ind; DELETE(E) CustNbrWrk CustRec; DeleteError = %ERROR; return DeleteError; End-Proc; // ************************************************************ // * Updates DB2 Data For CSCSTP // ************************************************************ Dcl-Proc UpDateCSCSTP_Data; Dcl-Pi *N IND; CSCSTPDataDS LIKEDS(CSCSTPDataIODS); CustNbrWrk Packed(6:0); End-Pi ; Dcl-s UpDateError Ind; UPDATE(E) CustRec CSCSTPDataDS; UpDateError = %ERROR; return UpDateError; End-Proc ; // ************************************************************ // * Adds New DB2 Data For CSCSTP // ************************************************************ Dcl-Proc WriteCSCSTP_Data; Dcl-Pi *N IND; CSCSTPDataDS LIKEDS(CSCSTPDataIODS); CustNbrWrk Packed(6:0); End-Pi ; Dcl-s WriteError Ind; WRITE(E) CustRec CSCSTPDataDS; WriteError = %ERROR; return WriteError; End-Proc; // ************************************************************ // * Clear out the fields // ************************************************************ Dcl-Proc ClearFields; RESET Custrec; CLEAR CustDataInDS; CLEAR InputScreenDS; CLEAR CSCSTPDataIODS; CustDataInDs.PgmName = PgmName; InputScreenDS.PgmName = PgmName; End-Proc; RPGVideo_AttendeeWorkbook.docx 25 of 79 // ************************************************************ // Prototypes used for CSCSTP CRUD Application * // Written: Jim Buck 03-20-2017 * // ************************************************************ DCL-PR DeleteCSCSTP_Data IND; CSCSTPDataDS LIKEDS(CSCSTPDataIODS); CustNbrWrk Packed(6:0); END-PR ; DCL-PR GetCSCSTP_Data IND; CSCSTPDataDS LIKEDS(CSCSTPDataIODS); CustNbrWrk Packed(6:0); END-PR ; DCL-PR UpDateCSCSTP_Data IND; CSCSTPDataDS LIKEDS(CSCSTPDataIODS); CustNbrWrk Packed(6:0); END-PR ; DCL-PR WriteCSCSTP_Data IND; CSCSTPDataDS LIKEDS(CSCSTPDataIODS); CustNbrWrk Packed(6:0); END-PR ; RPGVideo_AttendeeWorkbook.docx 26 of 79 EXER0502 – Customer Master Listing with Control-Break Logic // * Control Options Section Ctl-opt Option(*Nodebugio); // ************************************************************* // Creates a listing of CloudServices247 Inc customers * // EXER0502 - COMMON RPG Video Series * // Written Jim Buck - 03-10-17 * // ************************************************************* Dcl-F EXER0502L Disk(*Ext) Usage(*input) Keyed; Dcl-F EXER0502P Printer(*ext) Usage(*Output) Oflind(EndOfPage); // * Declarations Section Dcl-s ZipTotDue Zoned(8:2); // Used in Report Breakline Dcl-s RrtTotBal Zoned(10:2); // Used in Report Total Line Dcl-s EndOfPage Ind Inz(*on); Dcl-s HoldZipCode Char(9); // Used for Break Processing // Convert the alpha zipcode to numeric Dcl-ds CZip; PrtZipCode Zoned(9:0) Pos(1); End-Ds; // * Main Section Read CustRec; // Read the First Record HoldZipCode = CZip; // used to compare current Zip code to last Dow NOT %EOF; RPTMESSAGE = *Blanks; // Check the Balance Due field and assign value to message field Select; When BALDUE < 0; RPTMESSAGE = 'BALDUE is less than Zero'; When BALDUE >= 0 and BALDUE <= 500; RPTMESSAGE = 'BALDUE is >= 0 and <= 500'; When BALDUE > 500 and BALDUE < 1000; RPTMESSAGE = 'BALDUE is > 500 and < 1000'; RPGVideo_AttendeeWorkbook.docx 27 of 79 When BALDUE >= 1000; RPTMESSAGE = 'BALDUE is >= 1000'; Other; RPTMESSAGE = 'Other BALDUE Values!'; ENDSL; // If the zip-code has changed handle the break processing If HoldZipCode <> CZip; Exsr ZipCodeBreak; ZipTotDue += BalDue; Else; ZipTotDue += BalDue; ENDIF; // Count the records RecCount += 1; // Check for the End of Page ExSr CheckOverFlow; Write Detail; // Write a detail line on the report READ CustRec; EndDo; // Handle the total line ExSr ReportTotals; // Turn on last record indicator and return to caller *INLR = *ON; Return; // ************************************************************* // Handle Zipcode Report Break * // ************************************************************* BegSr ZipCodeBreak; RptTotBal += ZipTotDue; // Accumulate the report totals Write Brkline; ZipTotDue = *Zero; // Clear Zip Total HoldZipCode = CZip; // Move to the hold area Zip EndSr; // ************************************************************* // Handle End of Report Total Lines * // ************************************************************* BegSr ReportTotals; ExSr ZipcodeBreak; Write RptTotal; EndSr; // ************************************************************* // Checks and Handles Report Overflow * // ************************************************************* BegSr CheckOverFlow; If Endofpage; Write Heading; // Write Heading on report Endofpage = *Off; Endif; EndSr; // ************************************************************* RPGVideo_AttendeeWorkbook.docx 28 of 79 EXER0601 & EXER0602– Customer Master Updates using Service Program EXER0602 – “Service Program Example” The program demonstrates the following concepts: • • • • • Improving Code To Make it More Reusable Creating Binder Language Source Creating a Service Program Creating a Binding Directory Binding a Program To a Service Program EXER0601 is the same code as exer0501, except that the code used to update the database is moved into a module. EXER0602 compiles the module into a service program. Start With the EXER0601 Example This example builds on the customer maintenance example that was presented earlier in this video. To get started you should: • • • • • • • • • • • • • Copy display file EXER0601D to EXER0602D and compile it Copy EXER0601 to EXER0602, and find/replace “EXER0601” in the code with “EXER0602” Copy EXER0601CP to EXER0602CP Copy EXER0601M to EXER0602M Rename the procedures to use the CUST prefix Remove unnecessary parameters Add the CONST keyword where appropriate Make the database logic stateless Compile Everything Into Modules Create Binder Language Source Compile EXER0602M as a Service Program Create a Binding Directory Create EXER0602 and bind it to EXER0602M by reference The program sources below are the modified copies for your reference, so you can see a working version if you get stuck. Program Source for EXER0602: // * Control Options Section Ctl-opt Option(*Nodebugio: *Srcstmt); // ************************************************************* // This program allows users to interactively maintain Cloud- * // Services Customer Mstr file by adding, changing, and dele- * // ing records. For adds, the next customer number is assigned* // by the system. Customer's whose balance is greater than * // zero cannot be deleted. * // Written - Jim Buck - 03/22/2017 * // Changed to use a service program by Scott Klement * // ************************************************************* // RPGVideo_AttendeeWorkbook.docx 29 of 79 // // // // // // To compile this: - first compile EXER0602D (display file) - second create service EXER0602M - compile this with: CRTRPGMOD - finally: CRTPGM PGM(EXER0602) BNDSRVPGM(EXER0602M) Dcl-f DisplayScreen WORKSTN Qualified Alias ExtFile(*extdesc) ExtDesc('EXER0602D') indds(indicators); // Copy in the Prototypes /copy COMMONVID/QRPGLESRC,EXER0602CP // Indicator Data Structure Dcl-ds Indicators Len(99); Exit ind Pos(3) inz(*off); FkeyPressed ind Pos(10) Inz(*off); Cancel ind Pos(12); BalDueError ind Pos(30); RecNotFound ind Pos(90); UpdateError ind Pos(91); ProtectField ind Pos(92) inz; End-ds; // Data Structure for Screen I/O Dcl-Ds InputScreenDS likerec(DisplayScreen.InputScrn:*all); Dcl-Ds CustDataInDS likerec(DisplayScreen.DispScrn:*All); // Data Structures for Database I/O Dcl-Ds CSCSTPDataInDS Ext ExtName('CSCSTP':*Input) Qualified End-DS; Dcl-Ds CSCSTPDataOutDS Ext ExtName('CSCSTP':*Output) Qualified End-DS; // Stand Alone Variables Dcl-s PgmName char(9) inz('Exer0602'); Dcl-s CustInWrk Packed(6:0); // ******************************************************* // Loop until user presses the Exit (F3) Key // ******************************************************* DOU Exit; ClearFields(); // Display the Enter Custnbr Screen EXFMT DisplayScreen.InputScrn InputScreenDS; CustInWrk = InputScreenDS.CustNo; // Reset screen indicators RESET BalDueError; RESET RecNotFound; RESET UpdateError; // Figure out what happened in the screen SELECT; WHEN Exit; LEAVE; // Leave loop and Exit the program WHEN Cancel; ITER; // Loop again WHEN InputScreenDS.Action = 'A'; AddRecord(); RPGVideo_AttendeeWorkbook.docx 30 of 79 WHEN InputScreenDS.Action = 'C'; ChangeRecord(); WHEN InputScreenDS.Action = 'D'; DeleteRecord(); Other; ITER; ENDSL; ENDDO; *INLR = *ON; RETURN; // ******************************************************* // * Add A Record // ******************************************************* Dcl-Proc AddRecord; AssignNextNbr(); // Assign the next Customer Number CustDataInDS.Mode = 'Add'; CustDataInDS.CustNo = CustInWrk; EXFMT DisplayScreen.DispScrn CustDataInDS; IF NOT FkeyPressed; EVAL-CORR CSCSTPDataOutDS = CustDataInDS; UpdateError = CUST_write(CSCSTPDataOutDS); ENDIF; End-Proc; // ****************************************************** // * Get Next Customer Number - Not used to be used in production // ****************************************************** Dcl-Proc AssignNextNbr; CustInWrk = CUST_getHighest() + 1; ClearFields(); // Clear out the fields End-Proc; // ****************************************************** // * Change a Record // ****************************************************** Dcl-Proc ChangeRecord; CustDataInDS.Mode = 'Change'; IF NOT FkeyPressed; RecNotFound = CUST_get(CSCSTPDataInDS:CustInWrk); SELECT; WHEN FkeyPressed; Return; WHEN RecNotFound; // ErrorMsg = 'Record Not Found'; Return; WHEN NOT RecNotFound; EVAL-CORR CustDataInDS = CSCSTPDataInDS; EXFMT DisplayScreen.DispScrn CustDataInDS; IF NOT FkeyPressed; Eval-corr CSCSTPDataOutDS = CustDataInDS; UpdateError = CUST_update(CSCSTPDataOutDS:CustInWrk); Endif; ENDSL; ENDIF; RPGVideo_AttendeeWorkbook.docx 31 of 79 End-Proc; // *********************************************************** // * Delete a Record if they don't have a Balance // *********************************************************** Dcl-Proc DeleteRecord; CustDataInDS.Mode = 'Delete'; IF NOT FkeyPressed; RecNotFound = CUST_get(CSCSTPDataInDS:CustInWrk); Eval-corr CustDataInDS = CSCSTPDataInDS; BalDueError = (CustDataInDS.BalDue > 0); SELECT; WHEN FkeyPressed; Return; WHEN RecNotFound; // ErrorMsg = 'Record Not Found'; Return; WHEN BalDueError; // ErrorMsg = 'Balance Due > Zero'; Return; WHEN NOT BalDueError; ProtectField = *on; // Turn on to protect the fields from change EXFMT DisplayScreen.DispScrn CustDataInDS; ProtectField = *off; IF NOT FkeyPressed; UpdateError = CUST_delete(CustInWrk); EndIf; ENDSL; ENDIF; End-Proc; // ************************************************************ // * Clear out the fields // ************************************************************ Dcl-Proc ClearFields; CLEAR CustDataInDS; CLEAR InputScreenDS; CLEAR CSCSTPDataInDS; CLEAR CSCSTPDataOutDS; CustDataInDs.PgmName = PgmName; InputScreenDS.PgmName = PgmName; End-Proc; Program Source for EXER0601CP: DCL-PR CUST_delete IND; CustNbrWrk Packed(6:0) const; END-PR ; DCL-PR CUST_get IND; CSCSTPDataDS LIKEDS(CSCSTPDataInDS); CustNbrWrk Packed(6:0) const; END-PR ; DCL-PR CUST_update IND; RPGVideo_AttendeeWorkbook.docx 32 of 79 CSCSTPDataDS LIKEDS(CSCSTPDataOutDS) const; CustNbrWrk Packed(6:0) const; END-PR ; DCL-PR CUST_write IND; CSCSTPDataDS LIKEDS(CSCSTPDataOutDS) const; END-PR ; Dcl-PR CUST_getHighest like(CSCSTPDataInDS.CustNo); END-PR; Program Source for EXER0601M: ctl-opt NOMAIN option(*nodebugio: *srcstmt); // ************************************************************* // This module handles the database logic for the CSCSTP - * // maintenance program. * // Written - Jim Buck - 03/22/2017 * // Changed into a service program by Scott Klement * // ************************************************************* // // To compile this: // - First compile the module with: CRTRPGMOD // - Make a service program with: CRTSRVPGM SRVPGM(EXER0602M) Dcl-f CSCSTP DISK(*ext) keyed Usage(*Update:*Delete:*Output); // Copy in the Prototypes /copy COMMONVID/QRPGLESRC,EXER0602CP // Data Structures for Database I/O Dcl-Ds CSCSTPDataInDS Ext ExtName('CSCSTP':*Input) Qualified End-DS; Dcl-Ds CSCSTPDataOutDS Ext ExtName('CSCSTP':*Output) Qualified End-DS; // ************************************************************ // * Retrieves DB2 Data For CSCSTP // ************************************************************ Dcl-Proc CUST_get EXPORT; Dcl-Pi *N IND; CSCSTPDataDS LIKEDS(CSCSTPDataInDS); CustNbrWrk Packed(6:0) const; End-Pi ; Dcl-s RecNotFound Ind; CHAIN(n) CustNbrWrk CustRec CSCSTPDataDS; RecNotFound = NOT %FOUND; return RecNotFound; End-Proc ; // ************************************************************ RPGVideo_AttendeeWorkbook.docx 33 of 79 // * Updates DB2 Data For CSCSTP // ************************************************************ Dcl-Proc CUST_delete EXPORT; Dcl-Pi *N IND; CustNbrWrk Packed(6:0) const; End-Pi ; Dcl-s DeleteError Ind; DELETE(E) CustNbrWrk CustRec; DeleteError = %ERROR; return DeleteError; End-Proc ; // ************************************************************ // * Updates DB2 Data For CSCSTP // ************************************************************ Dcl-Proc CUST_update EXPORT; Dcl-Pi *N IND; CSCSTPDataDS LIKEDS(CSCSTPDataOutDS) const; CustNbrWrk Packed(6:0) const; End-Pi ; Dcl-s UpDateError Ind; chain(e) CustNbrWrk CSCSTP; if %error or not %found; UpdateError = *ON; else; UPDATE(E) CustRec CSCSTPDataDS; UpdateError = %ERROR; endif; return UpdateError; End-Proc ; // ************************************************************ // * Adds New DB2 Data For CSCSTP // ************************************************************ Dcl-Proc CUST_write EXPORT; Dcl-Pi *N IND; CSCSTPDataDS LIKEDS(CSCSTPDataOutDS) const; End-Pi ; Dcl-s WriteError Ind; WRITE(E) CustRec CSCSTPDataDS; WriteError = %ERROR; return WriteError; End-Proc ; Dcl-Proc CUST_getHighest EXPORT; RPGVideo_AttendeeWorkbook.docx 34 of 79 Dcl-PI *N like(CSCSTPDataInDS.CustNo); END-PI; clear CSCSTPDataInDS; SETGT 999999 CSCSTP; // Determine last customer number READP(N) CSCSTP CSCSTPDataInDS; // Read the previous record return CSCSTPDataInDS.CustNo; End-Proc; Binder Language Source (source file QSRVSRC, member EXER0602M): STRPGMEXP PGMLVL(*CURRENT) export symbol(CUST_delete) export symbol(CUST_get) export symbol(CUST_update) export symbol(CUST_write) export symbol(CUST_getHighest) ENDPGMEXP Compile Your Source As Modules, Then Create the Service Program, Binding Directory and Program CRTDSPF FILE(EXER0602D) SRCFILE(QDDSSRC) CRTRPGMOD MODULE(EXER0602M) SRCFILE(QRPGLESRC) CRTRPGMOD MODULE(EXER0602) SRCFILE(QRPGLESRC) CRTSRVPGM SRVPGM(EXER0602M) SRCFILE(QSRVSRC) CRTBNDDIR BNDDIR(COMMONVID/MYBNDDIR) ADDBNDDIRE BNDDIR(MYBNDDIR) OBJ((EXER0602M *SRVPGM)) CRTPGM PGM(EXER0602) BNDDIR(MYBNDDIR) RPGVideo_AttendeeWorkbook.docx 35 of 79 EXER0701 – No Documentation RPGVideo_AttendeeWorkbook.docx 36 of 79 EXER0801 – This program demonstrates using RPG Built-In Functions. The program is a simple example of reading some records from a file, processing information from the records, and reporting in a simple form of output to a printer device file which is output to a spooled file. Upon reading a record, it passes field values from the record to subprocedures which return values used for output. There are subprocedures to: 1. Convert the input value to the proper case for a person's name. For simplicity for this exercise, the first letter in each separate word of the name would be uppercased, and the remainder of each word would be lowercased. The name values stored in the sample CSCSTP data file appear to be all uppercase to begin with. 2. Check if a date value is within a certain number of days of the current date when the program is run. To see if it is a "recent" date. However, since the sample CSCSTP dat file was created some years ago, the un-altered versoin of the file has all old dates going back a few years. To allow for this and still get some "positive hits", the input parameter supplying the number of days for the range is set to 5 years. Output is kept simple by using program-described file output, assigning a constructed string value to a data structure and then writing the data structure to QGPL/QPRINT, a system supplied printer device file. There is only the one source EXER0801 of type RPGLE to compile and run. To compile and run it, your job library list should contain QGPL (for the QPRINT file) and the library with the CSCSTP data file. The following command parameters avoid spoecifying library names by relying on their being a current library assigned to the library list, into which the program is compiled, and then found for running. (Use CHGCURLIB to set if needed.) Compile command: CRTBNDRPG PGM(EXER0801) This uses all the other command defaults, including the source file QRPGLESRC To run the pgm: (Therre are no program parameters to set) call exer0801 To view the output to the spooled file: WRKSPLF This shows columns for the first and last names which have been set to the proper name case, and declares 'RECENT' when the date range check met the range parameter (5 years), and finally also lists out the date value which was being tested. (The date value is in MMDDYYYY format.) RPGVideo_AttendeeWorkbook.docx 37 of 79 Note: The source program contains DSPLY statements which are commented out to disable them. These can be un-commented to help trace values when running. RPGLE Program source for EXER0801: // * Control Options Section Ctl-opt Option(*Nodebugio: *Srcstmt); CTL-Opt actgrp(*caller); // ************************************************************* // Session 8 Exercise - RPG Built In Functions // ************************************************************* // // To compile this: // - Add the library with the CSCSTP data file to your library list // - CRTBNDRPG PGM(EXER0801) // // To Run: // - Call EXER0801 // Upon completion, it should have created a spooled file in // your output queue. // - WRKSPLF // In a loop, read a record from the data file, using data from the // record to test our procedures against. // Limit the loop to the first 50 records, for the purposes of our test. // Output the list to a spool file using the QGPL/QPRINT device file dcl-f cscstp usage(*input); dcl-f qprint PRINTER(80); RPGVideo_AttendeeWorkbook.docx 38 of 79 dcl-ds prtline len(80) end-ds; dcl-s count int(10) inz(0); dcl-s recent char(6); read custrec; dow ( (not %eof(cscstp)) and (count <50)); count += 1; //dsply ( cfname + ', ' + clname); //dsply ( NameCase(cfname) + ', ' + NameCase(clname)); //dsply ('Date: ' + %char( orddat) ); //dsply ('Near: ' + CheckDateRecent(orddat: 1500) ); // Special Note: Due to the sample data in the data file having // old dates from a few years ago, and nothing very recent, I am using // a date range value of 5 years, in order to get some hits occuring. if CheckDateRecent(orddat: 5 * 365); recent = 'RECENT'; else; recent = *blank; endif; // Write a line out to the printer device file. prtline = NameCase(cfname) + ', ' + NameCase(clname) + ' ' + recent + ' ' + %char( orddat); write qprint prtline; read custrec; ENDDO; *inlr = *on; // ************************************************************* // Procedure NameCase: // Convert the input value ot the proper case for a name and return it. // // There are many considerations for the proper case presentation of a // person's name, but that is beyond the scope of this exercise. // // For simplicity for this exercise, the procedure will determine // the blank-separated parts of the name string, and convert the // first character of each part to uppercase, and the remaining // characters of the part to lowercase. // It will only treat the standard characters A-Z, a-z. It will not try // to treat other characters or accented characters. dcl-proc NameCase; dcl-pi *n char(15); p1 char(15) value; END-PI; dcl-c LOWER 'abcdefghijklmnopqrstuvwxyz'; RPGVideo_AttendeeWorkbook.docx 39 of 79 dcl-c UPPER 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; dcl-s i int(10) inz(1); dcl-s c char(1); // Loop thru the characters of the value to find the parts // separated by blanks. dow (i <= %len(p1)); c = %subst(p1:i:1); if ( *blank = c); i += 1; else; // Convert first letter of a part to uppercase %subst(p1:i:1) = %xlate(LOWER:UPPER: c); i+= 1; // Convert remaining characters of a part to lowercase dow i <= %len(p1); c = %subst(p1:i:1); if ( *blank = c); i += 1; leave; else; %subst(p1:i:1) = %xlate(UPPER:LOWER: c); i+= 1; endif; enddo; endif; enddo; return p1; END-PROC; // ************************************************************* // Procedure CheckDateRecent: // Test the input value to test if the date it represents is // within a certain number of days of the current date, // returning an indicator result. dcl-proc CheckDateRecent; dcl-pi *n ind; pnum packed(8:0); dayRange int(10) value; END-PI; dcl-s pdate date(*iso); dcl-s delta int(10); //dsply (%char(pnum)); // Convert the input packed value (expected to be in a *USA format) // to a DATE data type pdate = %DATE( pnum: *usa); RPGVideo_AttendeeWorkbook.docx 40 of 79 // Calculate the difference in number of days between the current date // and the input value delta = %DIFF( %date: pdate: *days); //dsply (%char(delta)); return ( %ABS(delta) END-PROC; RPGVideo_AttendeeWorkbook.docx <= dayRange); 41 of 79 EXER0902 – Subfile program for Order Entry and Maintenance application and displays a list of open orders. It calls a CRUD EXER0903 to view, change, delete or enter a new order. Users can do the following tasks using the program: - See a list of open orders by paging up and down Filter the list by entering customer numbers and order dates View order details for an order by taking option V Change or add products for an order by using option C Delete existing order by using option D Create a new order by pressing function key 6 All detail (product) related operations are performed by EXER0903 which receives a parameter identifying the action. The program needs a way to access open only orders without reading entire order file, so it uses a logical file CSORDPL01 that selects orders with statuses eligible for maintenance. The program demonstrates the following concepts: - Using logical file to select records Loading subfile using Load All technique Reading user input from subfile using READC opcode Validating user input and responding to errors Calling another program with a parameter Logical File CSORDPL01 selecting only open orders RPGVideo_AttendeeWorkbook.docx 42 of 79 Screen displaying orders open for maintenance Display file source EXER0902D A*%%TS SD 20170304 100830 MVALDMAN REL-V7R1M0 5770-WDS A***************************************************************** A*$ A*$ SYSTEM NAME: ORDER MAINTENANCE - ORDER LIST A*$ FILE NAME: EXER0902D A*$ TYPE OF FILE: DSPF A*$ A*$ AUTHOR: MAX VALDMAN A*$ A*$ DESCRIPTION: A*$ A*$ FILE REVISION LOG: A*$ ----------------A*$ A*$ DATE PROGRAMMER PROJECT# DESCRIPTION OF REVISION A*$ -------- -------------- -------- ----------------------------A*$ A***************************************************************** A*%%EC A DSPSIZ(24 80 *DS3) A PRINT(*LIBL/QSYSPRT) A INDARA A*---------------------------------------------------------------A* A R SCR01 SFL A*%%TS SD 20170303 145942 MVALDMAN REL-V7R1M0 5770-WDS A OPTS 1A B 7 3 RPGVideo_AttendeeWorkbook.docx 43 of 79 A A A A A A A A A A A A A*%%TS A A A A 98 A 98 A A A 30 A 31 A 32 A 99 A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A ORD#S ODATES ORDTOTS PAYMNTS TWGTS TZIPS ORDSTSS 7 8 7 15EDTCDE(Y) 7 26EDTCDE(4 $) 7 38EDTCDE(4 $) 7 50EDTCDE(4) 7 57 7 63 8 10'Customer' COLOR(TRQ) CUSNAMES 26 O 8 19COLOR(TRQ) CUSTNOS 6 0O 8 47COLOR(TRQ) R SCR02 SFLCTL(SCR01) SD 20170304 100830 MVALDMAN REL-V7R1M0 5770-WDS CA03(03 'Exit') CF05(05 'Refresh') CF06(06 'New prospect') ALARM MSGALARM OVERLAY SFLCSRRRN(&SFLRRN) SFLDSP SFLDSPCTL SFLCLR SFLEND(*MORE) SFLSIZ(0045) SFLPAG(0007) SFLDSP 4S 0H SFLRCDNBR SFLRRN 5S 0H 1 2'Oper ID:' 1 11USER 1 32'Order Maintenance' DSPATR(HI) DSPATR(UL) 1 62'SCR02' 1 72DATE EDTCDE(Y) 2 2'EXER0902' 2 34'Order Summary' DSPATR(HI) 2 72TIME 4 3'Filter by:' COLOR(BLU) 4 14'Customer-' CUSTNOF 6Y 0B 4 24EDTCDE(Z) CHANGE(71) 4 32'Order Date From-' ODATEF 6Y 0B 4 49EDTCDE(Y) CHANGE(71) 4 60'Orders Shown:' ORDNUMD 4Y 0O 4 74EDTCDE(Z) 5 2'Options: D=Delete, C=Change, V=View' DSPATR(HI) 6 2'Opt' COLOR(YLW) 6 8'Ord #' COLOR(YLW) 6 15'Ord Date' RPGVideo_AttendeeWorkbook.docx 5S 0O 6Y 0O 7Y 2O 7Y 2O 3Y 0O 3S 0O 10A O 44 of 79 A COLOR(YLW) A 6 26'Ord Tot' A COLOR(YLW) A 6 38'Pay Incl' A COLOR(YLW) A 6 50'Wgt' A COLOR(YLW) A 6 56'Zone' A COLOR(YLW) A 6 63'Status' A COLOR(YLW) A R SCR03 A*%%TS SD 20170303 140708 MVALDMAN REL-V7R1M0 5770-WDS A 23 3'F03=Exit F05=Refresh A rder' A COLOR(BLU) A MSGLINE 70A O 24 3DSPATR(BL) A*%%RS+<record-sequences> A*%%RS+ <sequence name="SCREEN1"> A*%%RS+ <record-write record-format="SCR02" /> A*%%RS+ </sequence> A*%%RS </record-sequences> RPGVideo_AttendeeWorkbook.docx F06=New O- 45 of 79 Display file EXER0902D open in RDi Screen Designer Program Source for EXER0902 ctl-opt datfmt(*iso) datedit(*ymd) timfmt(*iso) truncnbr(*yes) option(*srcstmt : *nodebugio) ; // ************************************************************** // Displays list of open orders to maintain/option to enter new* // EXER0902 - COMMON RPG Video Series * // Written 02-28-17 * // ************************************************************** //?================== Files ================================= dcl-f exer0902d workstn sfile(scr01:rrn1) indds(f_keys); dcl-f csordpl01 keyed; dcl-f cscstp keyed; //?================== Variables ================================= dcl-s rrn1 packed(4); // rrn subfile 1 dcl-s q1 packed(5); dcl-s pMode char(1); dcl-s OdateF8 packed(8:0) ; dcl-s pOpt char(1) ; dcl-s pOrd# packed(5:0) ; dcl-ds ProgramStatus PSDS; SourceLine# char(8) pos(21); // Source List line # ExceptType char(3) pos(40); // Exception type RPGVideo_AttendeeWorkbook.docx 46 of 79 ExceptNumber char(4) pos(43); // Exception Number ExceptData char(80) pos(91); // Exception Data ExceptID char(4) pos(171); // Exception ID Date char(8) pos(191); // Date in *date fmt JobName char(10) pos(244); // Job Name UserID char(10) pos(254); // User JobNumber zoned(6) pos(264); // Job Number end-ds; // ?Display Function Keys indicators dcl-ds F_Keys; ExitRequest ind pos(3); RefreshRequest ind pos(5); NewOrder ind pos(6); SflDisplay ind pos(30); CntrlDisplay ind pos(31); SflClear ind pos(32); filterChanged ind pos(71); Alarm ind pos(98); SflEnd ind pos(99); end-ds; * Prototype for procedure to see, maintain delete dcl-pr orderMaintenance extpgm('EXER0903'); *n packed(5:0); // order number *n char(1) ; // option end-pr; //?================== loadSfl() ; // C-Specs ================================= Load subfile with open orders Dou ExitRequest; // ?Display screen Write scr03; Exfmt scr02; ResetScreen() ; // ?Support Function Keys Select; When ExitRequest ; Leave; When RefreshRequest; ValidateInput(); // validate search on refresh request If msgLine <> *Blanks ; Iter; Endif; loadSfl() ; Iter; When NewOrder; pOrd# = 0 ; pOpt = 'A' ; orderMaintenance(pOrd#:pOpt) ; // Screen to enter new order Iter ; Other ; RPGVideo_AttendeeWorkbook.docx 47 of 79 checkOptions() ; // Enter, read subfile ValidateInput() ; // See if filters changed If msgLine <> *Blanks ; Iter; Endif; If filterChanged ; // if filter fields changed LoadSfl() ; // reload subfile Endif ; Iter; Endsl; Enddo; *INlr = *ON; //------------------------------------------------------------------Dcl-proc LoadSfl; // ?Initialize subfile rrn1 = 0 ; SflDisplay = *off; CntrlDisplay = *off; SflClear = *on; Write scr02; SflClear = *off; optS = ' ' ; // ?Load subfile Setll *Loval OrdrRec ; Dou %eof(csordpl01) ; Read OrdrRec ; If %eof(csordpl01) ; Leave ; Endif ; // Read Order File If CustNoF <> 0 and CustNoF <> Cust# ; Iter ; // Skip customers if use filter Endif; If Odate < OdateF8 ; // can use without check for zero Iter ; // because any valid date will qualify Endif; Ord#S = OrdNbr ; // Load fields OdateS = %dec(%date(Odate:*ISO):*MDY) ; OrdTotS = OrdTot ; PaymntS = Paymnt ; TwgtS = Twgt ; Select ; When Osts = ' ' ; OrdStsS = 'OPEN' ; When Osts = 'BO' ; OrdStsS = 'BACKORDER' ; Other ; OrdStsS = 'UNKNOWN' ; Endsl; CustNoS = Cust# ; Chain Cust# CustRec ; RPGVideo_AttendeeWorkbook.docx 48 of 79 If %found ; CusNameS = %trimr(cFname) + ' ' + %trimr(cLname) ; Else ; CusNameS = 'Customer not found!!' ; Endif; rrn1 += 1 ; Write scr01; // Write subfile record If rrn1 = 9999 ; Leave ; Endif; // Stop if reach subfile limit Enddo ; OrdNumD = RRN1 ; // ?Get ready to display, if there is something CntrlDisplay = *on; SflEnd = *on; If rrn1 > 0; SflDisplay = *on; Else; SflDisplay = *off ; msgLine = 'No records to display' ; Endif; SflDsp = 1 ; End-proc ; //------------------------------------------------------------------------Dcl-proc checkOptions ; If SflDisplay = *off ; Return ; Endif ; // // If we didn't have anything to display there is nothing to read in SFL Dou %eof(exer0902d) ; Readc scr01 ; // Read changed records If %eof(exer0902d) ; Leave ; Endif ; If OptS = ' ' ; // Option could be changed, but blank Iter ; Endif ; If OptS = 'C' or OptS = 'V' or OptS = 'D' ; // valid options only orderMaintenance(Ord#S:OptS) ; // bring up order for appropriate Endif ; // action OptS = ' ' ; // clear option Update scr01 ; SflDsp = RRN1 ; // display subfile at the last action Enddo ; End-proc ; //-----------------------------------------------------------------------Dcl-proc validateInput ; If CustNoF <> 0 ; // need only one customer Chain CustNoF CustRec ; RPGVideo_AttendeeWorkbook.docx 49 of 79 If not %found(cscstp) ; msgLine = 'Filter by Invalid Customer Number' ; Return ; Endif; Endif; If OdateF <> 0 ; Monitor ; // orders from entered date forward OdateF8 = %dec(%date(OdateF:*MDY):*ISO) ; On-Error ; msgLine = 'Invalid From Date' ; OdateF8 = 0 ; Endmon; Else ; OdateF8 = 0 ; Endif ; End-proc; //-----------------------------------------------------------------------Dcl-proc ResetScreen; // ?Reset screen indicators msgLine = *Blanks ; Alarm = *off; End-proc ; RPGVideo_AttendeeWorkbook.docx 50 of 79 EXER1001 – This program accepts two parameters and displays a list of items The program is based upon program EXER0901 but has been modified to use a dynamic embedded SQL statement to retrieve the order details. The program demonstrates the following concepts: - Setting SQL Options (TAG01) Checking the parameter for validity (TAG02) Building a dynamic SQL statement (TAG03) Preparing the SQL Statement (TAG04) Declaring a cursor (TAG05) Opening the cursor (TAG06) Fetching a row from the file (TAG07) Closing the Cursor (TAG08) The parameters passed to the program are both alphanumeric. The first parameter passed is a 5-character order number. The second parameter is a single character that ranges from 1 to 7. The second parameter will control the order in which the records are displayed on the screen. - 1 = Line Number 2 = Product Number 3 = Quantity Ordered 4 = Quantity on Hold 5 = Tracking Number 6 = Status 7 = Line Cost After adding the Bootcamp Library to your library list type the following command: CALL EXER1001 Parm(‘ 11012 ‘ ‘7‘) and press enter. The following display will be shown: Display file source EXER1001D RPGVideo_AttendeeWorkbook.docx 51 of 79 A*%%TS SD 20170416 124612 MVALDMAN REL-V7R1M0 5770-WDS A***************************************************************** A*$ A*$ SYSTEM NAME: ORDER MAINTENANCE - SINGLE ORDER A*$ FILE NAME: EXER1001D A*$ TYPE OF FILE: DSPF A*$ A*$ AUTHOR: MAX VALDMAN A*$ A*$ DESCRIPTION: A*$ A*$ FILE REVISION LOG: A*$ ----------------A*$ A*$ DATE PROGRAMMER PROJECT# DESCRIPTION OF REVISION A*$ -------- -------------- -------- ----------------------------A*$ A***************************************************************** A*%%EC A DSPSIZ(24 80 *DS3) A PRINT(*LIBL/QSYSPRT) A INDARA A*---------------------------------------------------------------A* A R SCR01 SFL A*%%TS SD 20170416 124612 MVALDMAN REL-V7R1M0 5770-WDS A PRODNOS 6S 0O 7 6 A DESCRPS 25A O 7 13 A QTYORDS 4Y 0O 7 40EDTCDE(4) A LINECSTS 12Y 2O 7 46EDTCDE(4 $) A QTYHOLDS 4Y 0O 7 63EDTCDE(4) A TRACKS 7A O 7 69 A STSS 2A O 7 78 A R SCR02 SFLCTL(SCR01) A*%%TS SD 20170416 124612 MVALDMAN REL-V7R1M0 5770-WDS A SFLSIZ(0045) A SFLPAG(0014) A CA03(03 'Exit') A CF05(05 'Refresh') A 98 ALARM A 98 MSGALARM A OVERLAY A SFLCSRRRN(&SFLRRN) A 30 SFLDSP A 31 SFLDSPCTL A 32 SFLCLR A 99 SFLEND(*MORE) A SFLDSP 4S 0H SFLRCDNBR A SFLRRN 5S 0H A 1 2'Oper ID:' A 1 11USER A 1 34'Order Display' A DSPATR(HI) A DSPATR(UL) A 1 62'SCR02' A 1 72DATE A EDTCDE(Y) A 2 2'EXER1001' RPGVideo_AttendeeWorkbook.docx 52 of 79 A 2 72TIME A 4 4'Customer:' A COLOR(BLU) A CUSTNOH 6Y 0O 4 14EDTCDE(4) A CNAME 20 O 4 22 A 4 65'Order #:' A COLOR(BLU) A ORD#H 5S 0O 4 74 A 6 10'Product' A COLOR(YLW) A 6 39'Ord Q' A COLOR(YLW) A 6 48'Line $' A COLOR(YLW) A 6 62'Hld Q' A COLOR(YLW) A 6 69'Track #' A COLOR(YLW) A 6 78'Sts' A COLOR(YLW) A R SCR03 A*%%TS SD 20170416 124612 MVALDMAN REL-V7R1M0 5770-WDS A 23 3'F03=Exit F05=Refresh' A COLOR(BLU) A MSGLINE 70A O 24 3DSPATR(BL) A*%%RS+<record-sequences> A*%%RS+ <sequence name="SCREEN1"> A*%%RS+ <device type="display" width="80" height="24" /> A*%%RS+ <record-write record-format="SCR03" /> A*%%RS+ <record-write record-format="SCR01" /> A*%%RS+ <record-write record-format="SCR02" /> A*%%RS+ </sequence> A*%%RS </record-sequences> **** End Of Source Code **** RPGVideo_AttendeeWorkbook.docx 53 of 79 Display file EXER1001D open in RDi Screen Designer Program Source for EXER0901 ctl-opt datfmt(*iso) datedit(*ymd) timfmt(*iso) dftactgrp(*No) truncnbr(*yes) option(*srcstmt : *nodebugio) ; // ************************************************************** // Displays sigle order and sorts based on parameter * // EXER1001 - COMMON RPG Video Series * // Written 04-16-17 * // ************************************************************** //?================== Files ================================= dcl-f exer1001d workstn sfile(scr01:rrn1) indds(f_keys); dcl-f csordp usage(*input) keyed; // dcl-f csordprp usage(*input) keyed; dcl-f cscstp keyed; dcl-f csinvp keyed; //?================== Variables ================================= dcl-pr orderMaintenance extpgm('EXER1001'); // Declare program parameters *n zoned(5:0); // pOrderNo *n Char(1); end-pr; dcl-pi orderMaintenance; pOrderNo zoned(5:0); pSortOrder Char(1); end-pi; dcl-s rrn1 packed(4); // rrn subfile 1 dcl-s q1 packed(5); dcl-s OdateF8 packed(8:0) ; RPGVideo_AttendeeWorkbook.docx 54 of 79 dcl-s pOpt char(1) ; dcl-s counter packed(4:0) ; dcl-ds ProgramStatus PSDS; SourceLine# char(8) pos(21); // Source List line # ExceptType char(3) pos(40); // Exception type ExceptNumber char(4) pos(43); // Exception Number ExceptData char(80) pos(91); // Exception Data ExceptID char(4) pos(171); // Exception ID Date char(8) pos(191); // Date in *date fmt JobName char(10) pos(244); // Job Name UserID char(10) pos(254); // User JobNumber zoned(6) pos(264); // Job Number end-ds; // ?Display Function Keys indicators dcl-ds F_Keys; ExitRequest ind pos(3); RefreshRequest ind pos(5); SflDisplay ind pos(30); CntrlDisplay ind pos(31); SflClear ind pos(32); Alarm ind pos(98); SflEnd ind pos(99); end-ds; //?================== C-Specs ================================= loadSfl() ; Dou ExitRequest; // ?Display screen Write scr03; Exfmt scr02; ResetScreen() ; // ?Support Function Keys Select; When ExitRequest ; Leave; When RefreshRequest ; loadSfl() ; Endsl; Enddo; *INlr = *ON; //======================================================================= Begsr *INZSR; TAG01 // Commitment control is not being used RPGVideo_AttendeeWorkbook.docx 55 of 79 TAG01 Exec SQL Set Option Commit = *None; TAG02 TAG02 TAG02 TAG02 // Make sure that a valid Sort order was passed If pSortOrder < '1' or pSortOrder > '7'; Eval pSortOrder = '1'; ENDIF; ENDSR; //---------------------------------------------------------------------------Dcl-proc LoadSfl; TAG03 TAG03 TAG03 TAG03 TAG03 Dcl-S Select VarChar(512); Dcl-S From VarChar(512); Dcl-S Where VarChar(512); Dcl-S OrderBy VarChar(512); Dcl-S Statement VarChar(2048); Dcl-DS RecordDS; // Data Structure for Fetch LnItmNo Zoned(3:0); ProdNo Zoned(6:0); QtyOrd Zoned(4:0); QtyHold Zoned(4:0); Track Char(7); STS Char(2); LineCst Zoned(12:2); END-DS; // ?Initialize subfile rrn1 = 0 ; SflDisplay = *off; CntrlDisplay = *off; SflClear = *on; Write scr02; SflClear = *off; Ord#H = pOrderNo ; Chain pOrderNo OrdrRec ; If Not %found(csordp) ; Clear Cust# ; Endif; Chain Cust# CustRec ; If %found(cscstp) ; CustNoH = Cust# ; Cname = %trimr(cFname) + ' ' + %trimr(cLname) ; Else ; CustNoH = 0 ; Clear Cname ; Endif; // ?Load subfile // Setll Ord#H OrderRec ; // // Dou %eof(csordprp) ; // Reade Ord#H OrderRec ; // If %eof(csordprp) ; // Leave ; // Endif ; RPGVideo_AttendeeWorkbook.docx Read Order File 56 of 79 TAG03 TAG03 TAG03 TAG03 TAG03 TAG03 TAG03 // Build SQL Statement Eval Select = 'Select LnItmNo, ' + 'ProdNo, ' + 'QtyOrd, ' + 'QtyHold, ' + 'Track, ' + 'STS, ' + 'LineCst '; TAG03 TAG03 TAG03 TAG03 Eval From = ' From CSORDPRP'; Eval Where = ' Where ord# = ' + %Trim(%Char(Ord#H)); Eval OrderBy = ' Order by ' + pSortOrder; Eval Statement = Select + From + Where + Orderby; TAG04 TAG05 TAG06 Exec SQL Prepare Stmt From :Statement; Exec SQL Declare C1 Cursor For Stmt; Exec SQL Open C1; If SQLSTT > '02000'; // The cursor could not be opened, Don't attempt to fetch Else; TAG07 TAG08 TAG08 DoU SQLstt > '02000'; Exec SQL Fetch from C1 into :RecordDS; If SQLStt < '02000'; ProdNoS = ProdNo ; // Load fields Chain ProdNo InvRec ; If %found ; DescrpS = Descrp ; Else ; DescrpS = 'Product not found!!' ; Endif; QtyOrdS = QtyOrd ; QtyHoldS = QtyHold ; TrackS = Track ; LineCstS = LineCst ; StsS = Sts ; rrn1 += 1 ; Write scr01; // Write them to the subfile record If rrn1 = 9999 ; Leave ; Endif; Else; Leave; EndIf; Enddo ; // Stop if reach subfile limit // Close The Cursor Exec SQL Close C1; EndIf; // ?Get ready to display, if there is something CntrlDisplay = *on; SflEnd = *on; If rrn1 > 0; RPGVideo_AttendeeWorkbook.docx 57 of 79 SflDisplay = *on; Else; SflDisplay = *off ; msgLine = 'No records to display' ; Endif; SflDsp = 1 ; End-proc ; //---------------------------------------------------------------------------Dcl-proc ResetScreen; // ?Reset screen indicators msgLine = *Blanks ; Alarm = *off; End-proc ; **** End Of Source Code **** RPGVideo_AttendeeWorkbook.docx 58 of 79 EXER1002 & EXER1003 – Displays a list of open orders, allows an order to be deleted, changed or viewed. Program EXER1002 calls program EXER1003C. Program EXER1003C calls Program EXER1003. If the F06 key is pressed, a new order may be entered. It is based upon exercise EXER0902 but it has been modified to use commitment control. The program demonstrates the following concepts: - Starting commitment control (TAG01) Ending commitment Control (TAG02) File Declaration keyword for commitment control (TAG03) Using the Commit command (TAG04) Using the Rollback command (TAG05) Calling the Program After adding the Bootcamp Library to the library list, type: CALL EXER1002 and press the enter key. Screen displaying a List of Open Orders Press F06 to enter a new order or place a D, C or V in the option field and press the Enter key. RPGVideo_AttendeeWorkbook.docx 59 of 79 Screen displaying the New Order entry panel Screen displayed when Deleting an order Press the F07 key to delete the order RPGVideo_AttendeeWorkbook.docx 60 of 79 Screen displayed when Changing an order Screen displayed when Viewing an order RPGVideo_AttendeeWorkbook.docx 61 of 79 Display file source EXER1002D A*%%TS SD 20170304 100830 MVALDMAN REL-V7R1M0 5770-WDS A***************************************************************** A*$ A*$ SYSTEM NAME: ORDER MAINTENANCE - ORDER LIST A*$ FILE NAME: EXER1002D A*$ TYPE OF FILE: DSPF A*$ A*$ AUTHOR: MAX VALDMAN A*$ A*$ DESCRIPTION: A*$ A*$ FILE REVISION LOG: A*$ ----------------A*$ A*$ DATE PROGRAMMER PROJECT# DESCRIPTION OF REVISION A*$ -------- -------------- -------- ----------------------------A*$ A***************************************************************** A*%%EC A DSPSIZ(24 80 *DS3) A PRINT(*LIBL/QSYSPRT) A INDARA A*---------------------------------------------------------------A* A R SCR01 SFL A*%%TS SD 20170303 145942 MVALDMAN REL-V7R1M0 5770-WDS A OPTS 1A B 7 3 A ORD#S 5S 0O 7 8 A ODATES 6Y 0O 7 15EDTCDE(Y) A ORDTOTS 7Y 2O 7 26EDTCDE(4 $) A PAYMNTS 7Y 2O 7 38EDTCDE(4 $) A TWGTS 3Y 0O 7 50EDTCDE(4) A TZIPS 3S 0O 7 57 A ORDSTSS 10A O 7 63 A 8 10'Customer' A COLOR(TRQ) A CUSNAMES 26 O 8 19COLOR(TRQ) A CUSTNOS 6 0O 8 47COLOR(TRQ) A R SCR02 SFLCTL(SCR01) A*%%TS SD 20170304 100830 MVALDMAN REL-V7R1M0 5770-WDS A CA03(03 'Exit') A CF05(05 'Refresh') A CF06(06 'New prospect') A 98 ALARM A 98 MSGALARM A OVERLAY A SFLCSRRRN(&SFLRRN) A 30 SFLDSP A 31 SFLDSPCTL A 32 SFLCLR A 99 SFLEND(*MORE) A SFLSIZ(0045) RPGVideo_AttendeeWorkbook.docx 62 of 79 A SFLPAG(0007) A SFLDSP 4S 0H SFLRCDNBR A SFLRRN 5S 0H A 1 2'Oper ID:' A 1 11USER A 1 32'Order Maintenance' A DSPATR(HI) A DSPATR(UL) A 1 62'SCR02' A 1 72DATE A EDTCDE(Y) A 2 2'EXER1002' A 2 34'Order Summary' A DSPATR(HI) A 2 72TIME A 4 3'Filter by:' A COLOR(BLU) A 4 14'Customer-' A CUSTNOF 6Y 0B 4 24EDTCDE(Z) A CHANGE(71) A 4 32'Order Date From-' A ODATEF 6Y 0B 4 49EDTCDE(Y) A CHANGE(71) A 4 60'Orders Shown:' A ORDNUMD 4Y 0O 4 74EDTCDE(Z) A 5 2'Options: D=Delete, C=Change, V=VieA w' A DSPATR(HI) A 6 2'Opt' A COLOR(YLW) A 6 8'Ord #' A COLOR(YLW) A 6 15'Ord Date' A COLOR(YLW) A 6 26'Ord Tot' A COLOR(YLW) A 6 38'Pay Incl' A COLOR(YLW) A 6 50'Wgt' A COLOR(YLW) A 6 56'Zone' A COLOR(YLW) A 6 63'Status' A COLOR(YLW) A R SCR03 A*%%TS SD 20170303 140708 MVALDMAN REL-V7R1M0 5770-WDS A 23 3'F03=Exit F05=Refresh F06=New OA rder' A COLOR(BLU) A MSGLINE 70A O 24 3DSPATR(BL) A*%%RS+<record-sequences> A*%%RS+ <sequence name="SCREEN1"> A*%%RS+ <record-write record-format="SCR02" /> RPGVideo_AttendeeWorkbook.docx 63 of 79 A*%%RS+ </sequence> A*%%RS </record-sequences> **** End of Source **** Program Source for EXER1002 ctl-opt datfmt(*iso) datedit(*ymd) timfmt(*iso) dftactgrp(*No) truncnbr(*yes) option(*srcstmt : *nodebugio) ; // ************************************************************** // Displays list of open orders to maintain/option to enter new* // EXER1002 - COMMON RPG Video Series * // Written 02-28-17 * // ************************************************************** //?================== Files ================================= dcl-f exer1002d workstn sfile(scr01:rrn1) indds(f_keys); dcl-f csordpl01 keyed; dcl-f cscstp keyed; //?================== Variables ================================= dcl-s rrn1 packed(4); // rrn subfile 1 dcl-s q1 packed(5); dcl-s pMode char(1); dcl-s OdateF8 packed(8:0) ; dcl-s pOpt char(1) ; dcl-s pOrd# packed(5:0) ; dcl-ds ProgramStatus PSDS; SourceLine# char(8) pos(21); // Source List line # ExceptType char(3) pos(40); // Exception type ExceptNumber char(4) pos(43); // Exception Number ExceptData char(80) pos(91); // Exception Data ExceptID char(4) pos(171); // Exception ID Date char(8) pos(191); // Date in *date fmt JobName char(10) pos(244); // Job Name UserID char(10) pos(254); // User JobNumber zoned(6) pos(264); // Job Number end-ds; // ?Display Function Keys indicators dcl-ds F_Keys; ExitRequest ind pos(3); RefreshRequest ind pos(5); NewOrder ind pos(6); SflDisplay ind pos(30); CntrlDisplay ind pos(31); SflClear ind pos(32); filterChanged ind pos(71); Alarm ind pos(98); SflEnd ind pos(99); end-ds; RPGVideo_AttendeeWorkbook.docx 64 of 79 * Prototype for procedure to see, maintain delete dcl-pr orderMaintenance extpgm('EXER1003C'); *n packed(5:0); // order number *n char(1) ; // option end-pr; //?================== loadSfl() ; // C-Specs ================================= Load subfile with open orders Dou ExitRequest; // ?Display screen Write scr03; Exfmt scr02; ResetScreen() ; // ?Support Function Keys Select; When ExitRequest ; Leave; When RefreshRequest; ValidateInput(); // validate search on refresh request If msgLine <> *Blanks ; Iter; Endif; loadSfl() ; Iter; When NewOrder; pOrd# = 0 ; pOpt = 'A' ; orderMaintenance(pOrd#:pOpt) ; // Screen to enter new order Iter ; Other ; checkOptions() ; // Enter, read subfile ValidateInput() ; // See if filters changed If msgLine <> *Blanks ; Iter; Endif; If filterChanged ; // if filter fields changed LoadSfl() ; // reload subfile Endif ; Iter; Endsl; Enddo; *INlr = *ON; //---------------------------------------------------------------------------Dcl-proc LoadSfl; RPGVideo_AttendeeWorkbook.docx 65 of 79 // ?Initialize subfile rrn1 = 0 ; SflDisplay = *off; CntrlDisplay = *off; SflClear = *on; Write scr02; SflClear = *off; optS = ' ' ; // ?Load subfile Setll *Loval OrdrRec ; Dou %eof(csordpl01) ; Read OrdrRec ; If %eof(csordpl01) ; Leave ; Endif ; // Read Order File If CustNoF <> 0 and CustNoF <> Cust# ; Iter ; // Skip customers if use filter Endif; If Odate < OdateF8 ; // can use without check for zero Iter ; // because any valid date will qualify Endif; Ord#S = OrdNbr ; // Load fields OdateS = %dec(%date(Odate:*ISO):*MDY) ; OrdTotS = OrdTot ; PaymntS = Paymnt ; TwgtS = Twgt ; Select ; When Osts = ' ' ; OrdStsS = 'OPEN' ; When Osts = 'BO' ; OrdStsS = 'BACKORDER' ; Other ; OrdStsS = 'UNKNOWN' ; Endsl; CustNoS = Cust# ; Chain Cust# CustRec ; If %found ; CusNameS = %trimr(cFname) + ' ' + %trimr(cLname) ; Else ; CusNameS = 'Customer not found!!' ; Endif; rrn1 += 1 ; Write scr01; // Write subfile record If rrn1 = 9999 ; Leave ; Endif; // Stop if reach subfile limit RPGVideo_AttendeeWorkbook.docx 66 of 79 Enddo ; OrdNumD = RRN1 ; // ?Get ready to display, if there is something CntrlDisplay = *on; SflEnd = *on; If rrn1 > 0; SflDisplay = *on; Else; SflDisplay = *off ; msgLine = 'No records to display' ; Endif; SflDsp = 1 ; End-proc ; //---------------------------------------------------------------------------Dcl-proc checkOptions ; If SflDisplay = *off ; Return ; Endif ; // // If we didn't have anything to display there is nothing to read in SFL Dou %eof(exer1002d) ; Readc scr01 ; // Read changed records If %eof(exer1002d) ; Leave ; Endif ; If OptS = ' ' ; // Option could be changed, but blank Iter ; Endif ; If OptS = 'C' or OptS = 'V' or OptS = 'D' ; // valid options only orderMaintenance(Ord#S:OptS) ; // bring up order for appropriate Endif ; // action OptS = ' ' ; // clear option Update scr01 ; SflDsp = RRN1 ; // display subfile at the last action Enddo ; End-proc ; //---------------------------------------------------------------------------Dcl-proc validateInput ; If CustNoF <> 0 ; // need only one customer Chain CustNoF CustRec ; If not %found(cscstp) ; msgLine = 'Filter by Invalid Customer Number' ; Return ; Endif; Endif; If OdateF <> 0 ; RPGVideo_AttendeeWorkbook.docx 67 of 79 Monitor ; // orders from entered date forward OdateF8 = %dec(%date(OdateF:*MDY):*ISO) ; On-Error ; msgLine = 'Invalid From Date' ; OdateF8 = 0 ; Endmon; Else ; OdateF8 = 0 ; Endif ; End-proc; //---------------------------------------------------------------------------Dcl-proc ResetScreen; // ?Reset screen indicators msgLine = *Blanks ; Alarm = *off; End-proc ; **** End Of Source **** Program source EXER1003C /* TAG01 TAG02 This Program starts and ends commitment control for the order maintenace program EXER1003 and is called from program EXER1002. Pgm PARM(&ORDER &ACTION) Dcl Dcl VAR(&ORDER) TYPE(*DEC) LEN(5 0) VAR(&ACTION) TYPE(*CHAR) LEN(1) STRCMTCTL LCKLVL(*CHG) CMTSCOPE(*JOB) Call PGM(EXER1003) PARM(&ORDER &ACTION) */ EndCmtCtl Endpgm **** End Of Source **** Display file source EXER1003D A*%%TS SD 20170304 203348 MVALDMAN REL-V7R1M0 5770-WDS A***************************************************************** A*$ A*$ SYSTEM NAME: ORDER MAINTENANCE - SINGLE ORDER A*$ FILE NAME: EXER1003D RPGVideo_AttendeeWorkbook.docx 68 of 79 A*$ TYPE OF FILE: DSPF A*$ A*$ AUTHOR: MAX VALDMAN A*$ A*$ DESCRIPTION: A*$ A*$ FILE REVISION LOG: A*$ ----------------A*$ A*$ DATE PROGRAMMER PROJECT# DESCRIPTION OF REVISION A*$ -------- -------------- -------- ----------------------------A*$ A***************************************************************** A*%%EC A DSPSIZ(24 80 *DS3) A PRINT(*LIBL/QSYSPRT) A INDARA A*---------------------------------------------------------------A* A R SCR01 SFL A*%%TS SD 20170304 203348 MVALDMAN REL-V7R1M0 5770-WDS A LNITMNOH 3S 0H A QTYORDH 4S 0H A QTYHOLDH 4S 0H A TRACKH 7A H A OPTS 1A B 7 3 A 70 DSPATR(PR) A PRODNOS 6S 0O 7 6 A DESCRPS 25A O 7 13 A QTYORDS 4Y 0B 7 40EDTCDE(4) A 70 DSPATR(PR) A LINECSTS 12Y 2O 7 46EDTCDE(4 $) A QTYHOLDS 4Y 0B 7 63EDTCDE(4) A 70 DSPATR(PR) A TRACKS 7A B 7 69 A 70 DSPATR(PR) A STSS 2A O 7 78 A R SCR02 SFLCTL(SCR01) A*%%TS SD 20170304 192702 MVALDMAN REL-V7R1M0 5770-WDS A SFLSIZ(0045) A SFLPAG(0014) A CA03(03 'Exit') A CF05(05 'Refresh') A CF06(06 'New Order') A CA12(03) A CF07(07 'Delete') A 98 ALARM A 98 MSGALARM A OVERLAY A SFLCSRRRN(&SFLRRN) A 30 SFLDSP A 31 SFLDSPCTL A 32 SFLCLR A 99 SFLEND(*MORE) A SFLDSP 4S 0H SFLRCDNBR A SFLRRN 5S 0H A 1 2'Oper ID:' A 1 11USER RPGVideo_AttendeeWorkbook.docx 69 of 79 A 1 32'Order Maintenance' A DSPATR(HI) A DSPATR(UL) A 1 62'SCR02' A 1 72DATE A EDTCDE(Y) A 2 2'EXER1003' A 2 32'Program Mode:' A DSPATR(HI) A MODE 6A O 2 46DSPATR(HI) A 2 72TIME A 4 2'New Line:' A COLOR(BLU) A 4 12'Prod No-' A NPRODNO 6Y 0B 4 21EDTCDE(4) A 72 DSPATR(PR) A 4 30'Quantity-' A NQTYORD 4Y 0B 4 40EDTCDE(4) A 72 DSPATR(PR) A 4 47'Customer:' A COLOR(BLU) A CUSTNOH 6Y 0B 4 57EDTCDE(4) A 71 DSPATR(PR) A 4 65'Order #:' A COLOR(BLU) A ORD#H 5S 0O 4 74 A 5 2'Options: D=Delete' A DSPATR(HI) A 6 2'Opt' A COLOR(YLW) A 6 10'Product' A COLOR(YLW) A 6 39'Ord Q' A COLOR(YLW) A 6 48'Line $' A COLOR(YLW) A 6 62'Hld Q' A COLOR(YLW) A 6 69'Track #' A COLOR(YLW) A 6 78'Sts' A COLOR(YLW) A R SCR03 A*%%TS SD 20170304 174106 MVALDMAN REL-V7R1M0 5770-WDS A 23 3'F03=Exit F12=Cancel' A COLOR(BLU) A 75 23 27'F07=Delete' A COLOR(BLU) A MSGLINE 70A O 24 3DSPATR(BL) A*%%RS+<record-sequences> A*%%RS+ <sequence name="SCREEN1"> A*%%RS+ <device type="display" width="80" height="24" /> A*%%RS+ <record-write record-format="SCR03" /> A*%%RS+ <record-write record-format="SCR01" /> A*%%RS+ <record-write record-format="SCR02" /> A*%%RS+ </sequence> A*%%RS </record-sequences> RPGVideo_AttendeeWorkbook.docx 70 of 79 **** End Of Source **** Program source EXER1003 ctl-opt datfmt(*iso) datedit(*ymd) timfmt(*iso) DftActGrp(*No) truncnbr(*yes) option(*srcstmt : *nodebugio) ; // ************************************************************** // Displays order lines to maintain/option to enter new line * // and uses commitment control * // EXER1003 - COMMON RPG Video Series * // Written 03-04-17 * // ************************************************************** //?================== TAG03 TAG03 Files ================================= dcl-f exer1003d workstn sfile(scr01:rrn1) indds(f_keys); dcl-f csordp usage(*update: *output: *delete) keyed Commit; dcl-f csordprp usage(*update: *output: *delete) keyed Commit; dcl-f cscstp keyed; dcl-f csinvp keyed; //?================== Variables ================================= dcl-pr orderMaintenance extpgm('EXER1003'); // Declare program parameters *n packed(5:0); // pOrderNo *n char(1); // pAction end-pr; dcl-pi orderMaintenance; pOrderNo packed(5:0); pAction char(1); end-pi; dcl-s rrn1 packed(4); // rrn subfile 1 dcl-s q1 packed(5); dcl-s pMode char(1); dcl-s OdateF8 packed(8:0) ; dcl-s pOpt char(1) ; dcl-s pOrd# packed(5:0) ; dcl-s needToReload ind ; dcl-s counter packed(4:0) ; dcl-ds ProgramStatus PSDS; SourceLine# char(8) pos(21); // Source List line # ExceptType char(3) pos(40); // Exception type ExceptNumber char(4) pos(43); // Exception Number ExceptData char(80) pos(91); // Exception Data ExceptID char(4) pos(171); // Exception ID Date char(8) pos(191); // Date in *date fmt JobName char(10) pos(244); // Job Name UserID char(10) pos(254); // User RPGVideo_AttendeeWorkbook.docx 71 of 79 JobNumber zoned(6) pos(264); // Job Number end-ds; // ?Display Function Keys indicators dcl-ds F_Keys; ExitRequest ind pos(3); CancelRequest ind pos(12); DeleteRequest ind pos(7) ; SflDisplay ind pos(30); CntrlDisplay ind pos(31); SflClear ind pos(32); ProtectLine ind pos(70) ; ProtectCustomer ind pos(71); ProtectProductQty ind pos(72) ; DeleteOrder ind pos(75) ; Alarm ind pos(98); SflEnd ind pos(99); end-ds; //?================== C-Specs ================================= detectMode() ; loadSfl() ; Dou ExitRequest; // ?Display screen Write scr03; Exfmt scr02; ResetScreen() ; // ?Support Function Keys Select; When ExitRequest ; Leave; When DeleteRequest ; If DeleteOrder ; processDeleteRequest() ; Leave ; Endif; Other ; processAddChange() ; If msgLine <> *Blanks ; Iter; Endif; If needToReload ; loadSfl() ; Iter ; Endif; Iter; Endsl; RPGVideo_AttendeeWorkbook.docx 72 of 79 Enddo; *INlr = *ON; //---------------------------------------------------------------------------Dcl-proc detectMode; // // Detect program mode, turn on/off appropriate indicators, show program mode Ord#H = pOrderNo ; Select ; When pAction = 'A' ; Mode = 'ADD' ; ProtectProductQty = *ON ; ProtectLine = *ON ; MsgLine = 'Enter Customer Number' ; When pAction = 'C' ; Mode = 'CHANGE' ; ProtectCustomer = *ON ; When pAction = 'V' ; Mode = 'VIEW' ; ProtectLine = *ON ; ProtectCustomer = *ON ; ProtectProductQty = *ON ; When pAction = 'D' ; Mode = 'DELETE' ; ProtectLine = *ON ; ProtectCustomer = *ON ; ProtectProductQty = *ON ; DeleteOrder = *ON ; Other ; Mode = *Blanks ; Endsl; End-proc; //---------------------------------------------------------------------------Dcl-proc LoadSfl; // ?Initialize subfile rrn1 = 0 ; SflDisplay = *off; CntrlDisplay = *off; SflClear = *on; Write scr02; SflClear = *off; optS = ' ' ; If pAction <> 'A' ; Chain pOrderNo OrdrRec ; If %found(csordp) ; CustNoH = Cust# ; RPGVideo_AttendeeWorkbook.docx 73 of 79 Else ; CustNoH = 0 ; Endif; Endif; // ?Load subfile Setll Ord#H OrderRec ; // Dou %eof(csordprp) ; Reade Ord#H OrderRec ; If %eof(csordprp) ; Leave ; Endif ; Read Order File If pAction = 'C' ; If Sts = 'SH' ; ProtectLine = *ON ; // Can't change shipped line Else ; ProtectLine = *OFF ; Endif; Endif; If pAction = 'D' ; If Sts = 'SH' ; // Can't delete when something DeleteOrder = *Off ; // is shipped MsgLine = 'Order has shipped lines, cannot delete' ; Endif ; Endif; ProdNoS = ProdNo ; // Load fields Chain ProdNo InvRec ; If %found ; DescrpS = Descrp ; Else ; DescrpS = 'Product not found!!' ; Endif; QtyOrdS = QtyOrd ; QtyHoldS = QtyHold ; TrackS = Track ; LineCstS = LineCst ; StsS = Sts ; LnItmNoH = LnItmNo ; // Load hidden fields too QtyOrdH = QtyOrd ; QtyHoldH = QtyHold ; TrackH = Track ; rrn1 += 1 ; Write scr01; // Write them to the subfile record If rrn1 = 9999 ; Leave ; Endif; // Stop if reach subfile limit Enddo ; RPGVideo_AttendeeWorkbook.docx 74 of 79 // ?Get ready to display, if there is something CntrlDisplay = *on; SflEnd = *on; If rrn1 > 0; SflDisplay = *on; Else; SflDisplay = *off ; msgLine = 'No records to display' ; Endif; SflDsp = 1 ; End-proc ; //---------------------------------------------------------------------------Dcl-proc processAddChange ; If pAction = 'A' ; processAdd() ; Return ; Endif; If pAction = 'C' ; processChange() ; Return ; Endif; End-proc ; //---------------------------------------------------------------------------Dcl-proc processAdd ; // This is a brand new order needToReload = *OFF ; // // // TAG04 Make sure that work flow works - cuatomer # first product number when customer is established Validate all entires If ProtectProductQty and CustNoH = 0 ; MsgLine = 'MUST enter Customer # ' ; Return ; Endif; If ProtectProductQty and InvalidCustomer(CustNoH) ; MsgLine = 'Invalid Customer Number' ; Return ; Endif; If ProtectProductQty = *ON ; ProtectProductQty = *OFF ; ProtectCustomer = *ON ; Monitor; writeOrderHeader() ; Commit; MsgLine = 'Continue entering products' ; Return ; On-Error; MsgLine = 'Order Header Error'; RPGVideo_AttendeeWorkbook.docx 75 of 79 TAG05 ProtectProductQty = *On ; ProtectCustomer = *Off ; needToReload = *Off; Rolbk; Return; EndMon; Endif ; If InvalidProduct(NprodNo) ; MsgLine = 'Invalid Product entered' ; Return ; Endif; If NqtyOrd = 0 ; MsgLine = 'Must enter quantity' ; Return ; Endif; // // TAG04 TAG05 If got here - need to write product detail and reload subfile Monitor; WriteOrderDetail() ; needToReload = *ON ; Commit; Return ; On-Error; Rolbk; needToReload = *Off; MsgLine = 'Could not add Item'; Return; EndMon; End-proc ; //---------------------------------------------------------------------------Dcl-proc processChange ; // Changing existing order Monitor; needToReload = *OFF ; // Validate entires on a new line If NprodNo <> 0 and invalidProduct(NprodNo) ; MsgLine = 'Invalid Product entered' ; Return ; Endif; If NprodNo <> 0 and NqtyOrd = 0 ; MsgLine = 'Must enter quantity' ; Return ; Endif; If NprodNo <> 0 ; WriteOrderDetail() ; needToReload = *ON ; Endif; RPGVideo_AttendeeWorkbook.docx 76 of 79 // TAG04 TAG05 Process changes to existing lines For counter = 1 to lItems ; Chain counter scr01 ; If %found ; If OptS = 'D' ; // delete line Chain (pOrderNo:LnItmNoH) OrderRec ; If %found ; // no file name is intentional Delete OrderRec ; needToReload = *ON ; Endif; Iter ; Endif; If QtyOrdH <> QtyOrdS or // see if there was a change QtyHoldH <> QtyHoldS or TrackH <> TrackS ; Chain (pOrderNo:LnItmNoH) OrderRec ; If %found(csordprp) ; QtyOrd = QtyOrdS ; QtyHold = QtyHoldS ; Track = TrackS ; Update OrderRec ; needToReload = *ON ; Endif; Endif; Endif; Endfor; Commit; On-Error; Rolbk; needToReload = *Off; MsgLine = 'Problem changing the order'; EndMon; End-proc ; //---------------------------------------------------------------------------Dcl-proc writeOrderHeader ; // Create order header Setgt *HIVAL OrdrRec ; // Readp OrdrRec ; Ord#H = Ordnbr + 1 ; Clear *All OrdrRec ; Ordnbr = Ord#H ; Odate = %dec(%date:*ISO) ; Cust# = CustNoH ; Write OrdrRec ; Get last used order number End-proc ; //---------------------------------------------------------------------------Dcl-proc writeOrderDetail ; // Write order detail Clear *All OrderRec ; RPGVideo_AttendeeWorkbook.docx 77 of 79 Chain Ord#H OrdrRec ; If %found(csordp) ; lItems += 1 ; Update OrdrRec ; Endif; // // Increment number of lines in order header Ord# = Ord#H ; ProdNo = NProdNo ; QtyOrd = NQtyOrd ; LnItmNo = lItems ; LineCst = QtyOrd * SellPr ; Write OrderRec ; End-proc ; //---------------------------------------------------------------------------Dcl-proc InvalidCustomer ; // Validate customer number Dcl-pi InvalidCustomer ind ; checkCustNo packed(6:0) ; End-pi; dcl-s badCustNo ind ; Chain checkCustNo CustRec ; If not %found ; badCustNo = *ON ; Endif; Return badCustNo ; End-proc ; //---------------------------------------------------------------------------Dcl-proc InvalidProduct ; // Validate Product number Dcl-pi InvalidProduct ind ; checkProduct packed(6:0) ; End-pi; dcl-s badProduct ind ; Chain checkProduct InvRec ; If not %found ; badProduct = *ON ; Endif; Return badProduct ; End-proc ; //---------------------------------------------------------------------------Dcl-proc processDeleteRequest ; // // // Always delete detail records before header records so foreign key constraints can be more easily implemented at a later date // Begin monitoring for errors RPGVideo_AttendeeWorkbook.docx 78 of 79 Monitor; // Delete all order details Setll pOrderNo OrderRec ; Dou %eof(csordprp) ; Reade pOrderNo OrderRec ; If %eof(csordprp) ; Leave ; Endif; Delete OrderRec ; Enddo; // Delete order header Chain pOrderNo OrdrRec ; If %found(csordp) ; Delete OrdrRec ; Endif; TAG04 TAG05 // Commit Changes Commit; // Any Error in this procedure will issue a Rollback command On-error; Rolbk; EndMon; End-proc ; //---------------------------------------------------------------------------Dcl-proc ResetScreen; // ?Reset screen indicators msgLine = *Blanks ; Alarm = *off; End-proc ; **** End Of Source **** RPGVideo_AttendeeWorkbook.docx 79 of 79