Toolmaker Produkt-Dokumentation
Beispiel-Programme
Inhaltsübersicht
Dieser Abschnitt zeigt einige Beispiel-Programme mit dem Minimum, das für ein funktionierendes RPGWX-Programm erforderlich ist.
The RPGWXSMPL - RPGwx Sample Application
Work-Program ADDRWRK_A
This is a rather simple List program that lets the user select a record in an address file and edit it. Also you can create a new address record.
**FREE // ============================================================================= // RPGWX - Sample Programs Variant A / Simple - Record I/O // ============================================================================= // This is an example for an essential RPGWX "Work" or "List"-program using // record i/o to access the data. // It deals with the file "SMPADDR1" of the sample application: // - display a list of records // - Button to add a record // - Context menu to edit/view/copy/delete a record // The program that does all this processing is "A_TYPECHG". // There are only the most essential commands that are necessary // ========================================================================= // Adapt this program to your own file: // Globally replace // SMPADDRF --> your file's record format name // SMPADDR1 --> your file's name // ======================================================================== /define HActGrp ctl-opt bnddir('RPGWX') ; /Include QCPYLESRC,WX_HCOPYR // aus WX_SPECS hier kopiert /Include QCPYLESRC,DW_HSpecs // aus WX_SPECS hier kopiert /Include QCPYLESRC,DWCHLPDDCL /COPY QPROLESRC,WX_PROTO /COPY QPROLESRC,DWGetFile /COPY QCPYLESRC,HTML dcl-s lclHandle uns(3); // ============================================================================== // Main Program // ============================================================================== *INLR=*On; // create the URL for the appropriate Wiki-page WxHlpUrl_DS.Bas = 'https://toolmaker.atlassian.net/wiki/spaces/'; WxHlpUrl_DS.Section = 'DOKU/'; WxHlpUrl_DS.Pagnr = 'pages/539656516/'; WxHlpUrl_DS.Anchor = 'Beispiel-Programme#Beispiel-Programme-TheRPGWXSMPL-RPGwxSampleApplication'; WxHlpUrl_DS.Icon = 'Info.png'; WxHlpUrl = %trim(WxHlpUrl_DS.Bas) + %trim(WxHlpUrl_DS.Section) + %trim(WxHlpUrl_DS.Pagnr) + %trim(WxHlpUrl_DS.Anchor) + ',*NONE,' + %trim(WxHlpUrl_DS.Icon); //Prepare the HTML to present a list display HAD0010 = Header for the Addresses display // Wx_OpnHTMLWrk('HAD0010': 'ADDRCHG_A'); Wx_OpnHTMLWrk('HAD0010': 'ADDRCHG_A' : '' : 'HelpDoc(HLP3000, ' + WxHlpUrl + ')' ); // Define the the file to be used and the the fields that will be used for filtering // 1. table name (SMPADDR1) // 2. first field to be used for a search in the file (ID) // 3. options "casesensitive" - make the search case sensitive (by default it is case-insensitive) // 4ff. up to nine more fields to be scanned in the search Wx_GenFlt('SMPADDR1' : 'ADID' : '' : 'ADNAME1' : 'ADNAME2' : 'ADSTRCITY' : 'ADSTRZIP'); // Context-menu and buttons // Default will be there automatically: Add, Change, Copy, Delete, Display // later on we will use procedures Wx_CtxMenuItmXXXXXX to alter this. // Define the columns of the list ("Work Table") // Wx_WrkKeyFld defines a unique field to access the data (could be the RRN, too) Wx_WrkKeyFld('ADID'); Wx_WrkFld('ADNAME1' : 'FAD0200'); Wx_WrkFld('ADNAME2' : 'FAD0300'); Wx_WrkFld('ADNAME3' : 'FAD0400'); Wx_WrkFld('ADSTRCITY': 'FAD0800'); Wx_WrkFld('ADSTRZIP' : 'FAD0700'); Wx_WrkFld('ADCNTRY' : 'FAD1200'); // enable the view of the program's source lclHandle = Wx_LastOpnHandleWrkTblErr('1'); callp dw_wt_enbledit(Wx_GetPtrWrkTbl(lclHandle): 'RPGWXSMPL': 'QPGMSRC': 'ADDRWRK_A' ); // Present the HTML file Wx_WrtWrkTbl(); Return;
Change-Program ADDRCHG_A
**FREE // ============================================================================= // RPGWX - Sample Programs Variant A / Simple - Record I/O // ============================================================================= // This is an example for an essential RPGWX "Change"-program using // record i/o to access the data. // It deals with the file "SMPADDR1" of the sample application: // - add / update / view a record // - delete one or more records // File acces is via Chain, Write, Update and Delete commands. // There are only the most essential commands that are necessary // ========================================================================= // Adapt this program to your own file: // 1. Globally replace // SMPADDRF --> your file's record format name // SMPADDR1 --> your file's name // 2. Adapt the dcl-s statments for the GblKey - variables so that they // are of the same type and length of your file // 3. Adapt the field names, FADxxxx and HADxxxx message-ids to your needs // // or in detail: // (A) Change the dcl-F statement to your file // (B) Change the dcl-s - statements so that the variables are declared // with the same type and length as the keys of your file // (C) Change the two dcl-ds statements to your file // (D) adapt the header to your needs // (E) change the file name to your file // (F) change the file name to your file // (G) change the file name to your file // (H) change field names and headers to your file's names // (I) change the file name to your file // (J) change the file name to your file // (K) change field names (ADxxxUSER and ADxxxDATE to your needs) // (L) change the record format name to your file's record format name // (M) change the record format name to your file's record format name // ========================================================================= // 2022-04-14: in WX_HSPECS steht die Anweisung: "BndDir('WXBNDDIR': 'DWBNDDIR': 'QC2LE')" // Wir brauchen aber (hoffentlich) nur das Bnddir RPGWX. Deshalb habe ich // den COPY für WX_HSPECS auskommentiert, ctl-opt hier direkt einggetragen // und die anderen H-Einträge aus WX_HSPECS hierherkopiert // /COPY QCPYLESRC,WX_HSPECS /define HActGrp ctl-opt bnddir('RPGWX') ; /Include QCPYLESRC,WX_HCOPYR // aus WX_SPECS hier kopiert /Include QCPYLESRC,DW_HSpecs // aus WX_SPECS hier kopiert /COPY QCPYLESRC,WX_FLDREF // ===================================================================== // (A) File - declaration // ===================================================================== dcl-F SMPADDR1 keyed usage(*input : *output : *update : *delete); // Prototypes /COPY QPROLESRC,WX_PROTO // ===================================================================== // Gobal field definitions - individual for the app // ===================================================================== // ---------------------------------------- // (B) primary key of the file as a scalar variable // and as a table // ---------------------------------------- dcl-S GblKey int(10); dcl-S GblArrKeys int(10) dim(RefElemCGI); // ---------------------------------------- // (C) the file's buffer as data structure // ---------------------------------------- dcl-Ds dsADDR ExtName('SMPADDR1') Inz End-Ds; dcl-Ds dsADDRSav LikeDS(dsADDR) Inz; // ===================================================================== // Gobal field definitions - necessary for RPGWX // ===================================================================== dcl-S GblErrMsg like(FldRef.MsgText); dcl-Ds PGMSDS PSDS Qualified; Pgm Char(10) pos(1); MsgTxt Char(80) pos(91); JobNam Char(10) pos(244); JobNr Zoned(6:0) pos(264); User Char(10) pos(254); CurrUsr Char(10) pos(358); end-Ds; dcl-S GblIndex uns(3); // ===================================================================== // Main program // ===================================================================== // 1. Retrieve file key(s) from previous program // Use Wx_GetDBKeyXXX and Wx_GetDBKeyArrXXX depending on the datatype // of the file's key: // Char / Int /Dec / UC GblKey = Wx_GetDBKeyInt(); GblArrKeys = Wx_GetDBKeyArrInt(); // 2. Process modes // a) internally in this program - without a dialog (i.e. delete record(s) // b) externally by other programs Select; When Wx_isModeDelete(); Int_Dlt(); When Wx_isMode('MYMODE'); // DoSomething ENDSL; // 3. Read record from the file Int_ReadData(); // 4. Define files and fields to RPGWX // 4.1 Open the HTML-document (Msg HAD0020="Edit Address") // (D) adapt the header to your needs Wx_OpnHTMLChg('HAD0020'); // 4.2 Define the name of the file to be changed // (E) change the file name to your file Wx_ChgFile('SMPADDR1'); // 4.3. Define the header-information // individual programming - not used in this simple example // Int_DfnFldHdr(); // 4.4. Define the field information Int_DfnFldChg(); // 5. Set default data before showing the display Int_SetFldDft(); // 5. Show the display and get the user's input Wx_GetChgInput(); // 6. Check the changed data (invidual programming) Int_ChkInput(); // 7. Update the record (invidual programming) GblErrMsg = Int_WrtUpd(); // re-publish the HTML-document or go back // to previous display Wx_WrtChgTbl(GblErrMsg); Return; // ======================================================= // Read a record // ======================================================= dcl-Proc Int_ReadData; // ======================================================= dcl-pi Int_ReadData OpDesc end-pi; // (F) change the file name to your file If GblKey > *Zeros; Chain GblKey SMPADDR1; ENDIF; // (G) change the file name to your file If GblKey = *Zeros or Not %Found(SMPADDR1); Clear dsADDR; ENDIF; Return; End-Proc Int_ReadData; // ======================================================= // You can define your own header for each field in // the display // In this simple example we do not use this. // The function would be // Wx_HdrText // ======================================================= // dcl-Proc Int_DfnFldHdr; // ======================================================= // dcl-pi Int_DfnFldHdr OpDesc end-pi; // Return; // // End-Proc Int_DfnHldHdr; // ======================================================= dcl-Proc Int_DfnFldChg; // ======================================================= dcl-pi Int_DfnFldChg OpDesc end-pi; // 1. Define the I/O fields from the various tables/views/indices // --> the fields must exist in the files that were defined previously // --> the I/O fields must be defined in data structures // (H) change field names and headers to your file's names Wx_ChgFld('ADID' : %Addr(ADID) : 'FAD0000' : 'Output'); // rsch / 2020-03-24 // Problem mit ADTYPE als Parameter: wird beim Ändern nicht weggespeichert Wx_ChgFld('ADTYPE' : %Addr(ADTYPE) : 'FAD0100' : 'CTL(ADTYPE)' ); // Wx_ChgFld('ADTYPE' : %Addr(ADTYPE) : 'FAD0100' ); Wx_ChgFld('ADNAME1' : %Addr(ADNAME1) : 'FAD0200'); Wx_ChgFld('ADNAME2' : %Addr(ADNAME2) : 'FAD0300'); Wx_ChgFld('ADNAME3' : %Addr(ADNAME3) : 'FAD0400'); Wx_ChgFld('ADNAME4' : %Addr(ADNAME4) : 'FAD0500'); Wx_ChgFld('ADSTRNAME' : %Addr(ADSTRNAME) : 'FAD0600'); Wx_ChgFld('ADSTRZIP' : %Addr(ADSTRZIP) : 'FAD0700'); Wx_ChgFld('ADSTRCITY' : %Addr(ADSTRCITY) : 'FAD0800'); Wx_ChgFld('ADBOXNBR' : %Addr(ADBOXNBR) : 'FAD0900'); Wx_ChgFld('ADBOXZIP' : %Addr(ADBOXZIP) : 'FAD1000'); Wx_ChgFld('ADBOXCITY' : %Addr(ADBOXCITY) : 'FAD1100'); Wx_ChgFld('ADCNTRY' : %Addr(ADCNTRY) : 'FAD1200'); Wx_ManChgFldTimestamp('ADWRTDATE' : %Addr(ADWRTDATE) : 'FXX0010' : 'Output'); Wx_ChgFld('ADWRTUSER' : %Addr(ADWRTUSER) : 'FXX0020' : 'Output'); Wx_ManChgFldTimestamp('ADCHGDATE' : %Addr(ADCHGDATE) : 'FXX0030' : 'Output'); Wx_ChgFld('ADCHGUSER' : %Addr(ADCHGUSER) : 'FXX0040' : 'Output'); Return; End-Proc Int_DfnFldChg; // ======================================================= // Set default values for individual fields as // needed. // ======================================================= dcl-Proc Int_SetFldDft; // ======================================================= dcl-pi Int_SetFldDft OpDesc end-pi; // if Wx_isModeAdd(); // ADACTFROM = %Timestamp; // endif; end-proc Int_SetFldDft; // ======================================================= dcl-Proc Int_ChkInput; // ======================================================= dcl-pi Int_ChkInput OpDesc end-pi; dcl-s cstTimestmpEmpty timestamp inz; Monitor; // Plain output - no che checks performed If Wx_isModeOutput(); Return; ENDIF; // check the data entered - individual programming // The active-until date must be greater than the active from date // if Wx_isModeAdd() or Wx_isModeChange; // if ADACTUNTL <> cstTimestmpEmpty // and ADACTUNTL < ADACTFROM; // Wx_FldErr('EDT0010' : 'ADACTUNTL'); // return; // endif; // endif; On-Error; Wx_WrtChgTbl(PGMSDS.MsgTxt); endmon; return; end-Proc Int_ChkInput; // ===================================================================== //* Procedure name: Int_WrtUpd // Notes Write or Update a record // Re-Reading the record is necessary, because a web // application like RPGWX works session-less //* Returns: '' = Success otherwise Error Text // ===================================================================== dcl-Proc Int_WrtUpd; // ===================================================================== dcl-Pi Int_WrtUpd Like(FldRef.MsgText) OpDesc End-Pi; dcl-S RtnErrMsg Like(FldRef.MsgText); Monitor; // No update if // a) only display-mode // b) errors occurred If Wx_isModeOutput() or Wx_isChgFldErr(); Return ''; ENDIF; // Update the record // 1. Save the data to the "Sav" data structure dsADDRSav = dsADDR; // 2. If in "change" mode, re-read the record // (I) change the file name to your file If GblKey <> *Zeros; Clear dsADDR; Chain GblKey SMPADDR1; ENDIF; // 3. Fill the file buffer from the "Sav" data structure dsADDR = dsADDRSav; // 4. Write or Update the record, whichever is appropriate // Change the Standard-fields for creation/change // (J) change the file name to your file // (K) change field names (ADxxxUSER and ADxxxDATE to your needs) // (L) change the record format name to your file's record format name If not %found(SMPADDR1) or GblKey = *zeros; //Information for Creation Date/Time/User ADWRTDATE = %Timestamp; ADWRTUSER = PgmSDS.CurrUsr; Write SMPADDRF; Else; ADCHGDATE = %Timestamp; ADCHGUSER = PgmSDS.CurrUsr; Update SMPADDRF; ENDIF; On-Error; dsADDR = dsADDRSav; Return PGMSDS.MsgTxt; EndMon; Return ' '; End-Proc Int_WrtUpd; // ======================================================= // Delete one or more records // ======================================================= dcl-Proc Int_Dlt; // ======================================================= dcl-pi Int_Dlt OpDesc end-pi; dcl-s LocIndex uns(3); dcl-s LocErrMsg Like(FldRef.MsgText); monitor; // Delete the records selected // (M) change the record format name to your file's record format name For LocIndex = 1 To %Elem(GblArrKeys); if GblArrKeys(LocIndex) = *zeros; Leave; endif; delete(E) GblArrKeys(LocIndex) SMPADDRF; If %Error; LocErrMsg = 'Error occured when trying to delete the record'; ENDIF; ENDFOR; On-Error; Wx_RtnPrv(PGMSDS.MsgTxt); ENDMON; // Terminate routine and return to previous program Wx_RtnPrv(LocErrMsg); End-Proc Int_Dlt;
Work-Programm EXWRKAD01
Bei dem Programm EXWRKAD01 handelt es sich um eine einfache List-Anzeige, mit einem generischen Filter und den Standard-Kontext-Menü-Punkten Ändern, Kopieren, Löschen, Eigenschaften/Anzeigen, sowie dem Standard-Button erfassen.
EXWRKAD01 – Web-Anzeige
Abbildung 37: Work-Programm EXWRKAD01 - Adress-Stamm
EXWRKAD01 - Source Code
In dem Programm EXWRKAD01 wird der Adress-Stamm(Tabelle/Datei ADRESSEX) angezeigt.
Es wird ein generischer Filter definiert, durch die Spalten/Felder NAME1F, STASSE und ORT nach der eingegebenen Zeichenkombination in der gleichen Groß/Klein-Schreibweise durchsucht werden.
Ein Kontext-Menü mit den Standard-Kontext-Menü-Punkten Ändern, Kopieren, Löschen und Eigenschaften (=Anzeigen) wird automatisch hinzugefügt.
Als eindeutiger Schlüssel für die Folge-Programme wird die relative Satz-Nr. verwendet.
Die Spalten/Felder KUNDENR, NAME1F, STRASSE, LAND, PLZ und ORT aus der Tabelle/Datei ADRESSEX werden angezeigt. Das Land wird mittig ausgerichtet und durch als Länder-Flagge aufbereitet.
Beim ersten Aufruf werden die Datensätze nach Land, Postleitzahl und Kunde sortiert ausgegeben.
* H-Bestimmungen * ------------------------ H/COPY QCPYLESRC,WX_HSPECS * F-Bestimmungen * ------------------------ * keine erforderlich. Die zu verwendende Tabelle wird mit * der Anweisung Wx_WrkKey('ADRESSEX': *On) bestimmt. * D-Bestimmungen * ------------------------ * in diesem Beispielprogramm nicht erfoderlich * Prototypes * ------------------------ D/INCLUDE QPROLESRC,WX_PROTO * Globale D-Bestimmungen * ------------------------ * in diesem Beispielprogramm nicht erfoderlich ************************************************************************** * M A I N P R O G R A M ************************************************************************** /Free *INLR = *On; //HTML-Dokument öffnen Wx_OpnHTMLWrk('HDR0001': 'EXCHGADR01'); //Definieren generischen Filter Wx_GenFlt('ADRESSEX': 'NAME1F': 'casesensitive': 'STRASSE': 'ORT'); //Definieren Kontext-Menü/Buttons //--> Default (= Hinzufügen, Ändern, Kopieren, Löschen, Anzeigen) Wx_CtxMnuItmChange(); Wx_CtxMnuItmDelete(); Wx_CtxMnuItmProperty(); Wx_CtxMnuItm('EXCHGADR02': 'Test BHA': 'Window icn(start.gif)'); //Definieren Spalten für Work Table Wx_WrkKey('ADRESSEX': *On); Wx_WrkFld('KundeNr': 'FLD0001'); Wx_WrkFld('Name1F': 'FLD0002'); Wx_WrkFld('Strasse': 'FLD0003'); Wx_WrkFld('Land': 'FLD0006': ' center CTL(Country)'); Wx_WrkFld('PLZ': 'FLD0004'); Wx_WrkFld('Ort': 'FLD0005'); Wx_WrkDftOrder('Land': 'PLZ': 'KundeNr'); //HTML-Dokument ausgeben Wx_WrtWrkTbl(); Return; /End-Free
- Copy-Strecke Wx_HSPECS - H-Bestimmungen
- Copy-Strecke Wx_PROTO – Prototypen für alle RPGWX-Prozeduren
- Wx_OpnHTMLWrk – Definieren Standard-HTML-Dokument
- HDR0001 - Überschrift: Message-Id = Adress-Stamm
- EXCHGADR01 - Standard-Folgeprogramm: – Detail-Anzeige
- Wx_GenFlt – Generischen Filter (Suchfeld im Header) definieren
- ADRESSEX - Name der Datei
- Name1F, Strasse und Ort - zu durchsuchende Spalten
- casesensitive - bei der Suche ist Groß-/Kleinschreibung zu berücksichtigen
- ADRESSEX - Name der Datei
- Wx_CtxMnuItm - Anweisungen zum Zusammenstellen des Kontextmenüs
- Wx_CtxMnuItmChange() - Ändern
- Wx_CtxMnuItmDelete() - Löschen
- Wx_CtxMnuItmProperty() -Eigenschaften anzeigen
- Wx_CtxMnuItm('EXCHGADR02' : 'Test BHA' : Window icn(start.gif)') - nur ein Beispiel für einen frei definierten Kontextmenü-Eintrag
- Wx_WrkKey – Definieren der relativen Satz-Nr. als eindeutigen Key
- ADRESSEX - Datei aus der die relative Satz-Nr. ermittelt werden soll
- *ON - Bei dem eindeutigen Schlüssel handelt es dich um die relative Satz-Nr.
- Wx_WrkFld – Spalten Definieren
- KundeNr - Spalte KUNDENR aus Datei ADRESSEX
- Überschrift: Message-Id FLD0001 = Kunden-Nr.
- NameF1 - Spalte NAME1F aus Datei ADRESSEX
- Überschrift: Message-Id FLD0002 = Name.
- Strasse - Spalte STRASSE aus Datei ADRESSEX
- Überschrift: Message-Id FLD0003 = Strasse
- Land - Spalte LAND aus Datei ADRESSEX
- Überschrift: Message-Id FLD0006 = Land
- Aufbereitung als Flagge und zentrierte Ausrichtung über Optionen CENTER und CTL(COUNTRY)
- Postleitzahl - Spalte PLZ in Datei ADRESSEX
- Überschrift: Message-Id FLD0004 = Postleitzahl
- Ort - Spalte Ort in Datei ADRESSEX
- Überschrift: Message-Id FLD0005 = Ort
- KundeNr - Spalte KUNDENR aus Datei ADRESSEX
- Wx_WrkDftOrder: Default Sortierung nach Land, Postleitzahl, Kunden-Nr.
- Wx_WrtWrkTbl: HTML-Dokument aufbereiten und ausgeben
Change-Programm EXCHGAD01
Das Programm ExCHGAD01 ist das Folge-Programm, das aus der List-Anzeige des Adress-Stamms beim Hinzufügen, Ändern, Löschen oder Anzeigen von Datensätzen aufgerufen wird.
In dem Programm werden die Ein-/Ausgabe-Felder mit einigen wenigen Optionen definiert und aufgerufen. Zum Einlesen und Fortschreiben der Datensätze, sowie für die zusätzliche Eingabe-Prüfung ist individuelle Programmierung erforderlich.
EXCHGAD01 - Web-Anzeige
Abbildung 38: Beispiel Change-Programm - Adress-Stamm
EXCHGAD01 - Source Code
Um das Beispiel-Programm und die zugehörigen Erklärungen so übersichtlich wie möglich zu machen, wurde es in mehrere Abschnitte aufgeteilt.
- H-, F- und globale D-Bestimmungen
- Haupt-Programm
- "int_" - Unterroutinen
H-, F- und globale D-Bestimmungen
*************************************************************************** * H – B E S T I M M U N G E N *************************************************************************** D/COPY QCPYLESRC,WX_HSPECS *************************************************************************** * F – B E S T I M M U N G E N *************************************************************************** FADRESSEX IF E DISK Rename(Adresse: AdresseF) FADRESSEI01UF A E DISK Rename(Adresse: AdresseF1) *************************************************************************** * D – B E S T I M M U N G E N *************************************************************************** * PROTOTYPING *-------------------------------------------------------------------------- D/INCLUDE QPROLESRC,WX_PROTO * Interne Prozeduren ------------------------- * Ab Release 7.1 sind Prototypen für interne Prozeduren nicht mehr erforderlich /If Not Defined (*V7R1M0) * Datensätze einlesen und Default-Werte setzen D Int_ReadData PR OpDesc * Define Fields to Display D Int_DfnFldHdr PR OpDesc D Int_DfnFldChg PR OpDesc * Eingabe-Prüfung D Int_ChkInput PR OpDesc * Datensätze verarbeiten D Int_WrtUpd PR Like(FldRef.MsgText) OpDesc D Int_Dlt PR OpDesc /EndIf *************************************************************************** * G L O B A L E F E L D D E F I N I T I O N E N *************************************************************************** D GblKey S 10I 0 D GblArrKeys S 10I 0 Dim(RefElemCGI) D GblErrMsg S Like(FldRef.MsgText) D DSAdresse E DS ExtName(AdresseX) Inz D DSAdresseSav DS LikeDS(DSAdresse) Inz D GblIndex S 3U 0 D PGMSDS SDS Qualified D MsgTxt 80A Overlay(PGMSDS: 91)
- Datei ADRESSEX: Adress-Stamm
Definition als Input-File für ungeschlüsselten Zugriff, da aus dem vorgelagerten Work-Programm die relative Satz-Nr. übergeben wird.
Datensatz wird eingelesen um die erforderlichen Daten in Datenstrukturen einzulesen.
- Datei ADRESSEI01 – logische Datei auf Adress-Stamm
Definition als Update-File für ungeschlüsselten Zugriff.
Wird erst unmittelbar vor dem Update/Write eingelesen.
- Copy-Strecke Wx_PROTO – Prototypen für alle RPGWX-Prozeduren
- Prototypen für interne Prozeduren
Zur Strukturierung des Source-Codes werden in dem Beispiel-Programm interne Prozeduren verwendet.
Vor Release 7.1 müssen auch für interne Prozeduren Prototypen angelegt werden.
Ab Release 7.1. ist die Angabe von Prototypen für interne Prozeduren optional.
- Globale Feld-Deklarationen
- GblKey: Globale Variable, in der die relative Satz-Nr., die aus dem vorgelagerten Work-Programm übergeben wird, empfangen wird.
- Verwendung zum Einlesen des Datensatzes zum Ändern, Kopieren oder Anzeigen.
- GblArrKeys:Globale Feldgruppe, in der die relative Satz-Nummern der im vorgelagerten Work-Programm zum Löschen ausgewählten Datensätze, empfangen werden.
- Verwendung zum Löschen der Datensätze
- GblIndex: Index zur Feldgruppe GblArrKeys.
- GblErrMsg: Im Fehler-Fall wird über diese Variable eine Nachricht ausgegeben
- DSAdresse: Datenstruktur, in die der Datensatz für das Ändern, Kopieren oder Anzeigen eingelesen wird.
- Die Datenstruktur bzw. die zugehörigen Datenstruktur-Unterfelder werden zum Austausch zwischen dem RPG-Programm und der Web-Ausgabe verwendet.
- DSAdresseSav: Datenstruktur in der die erfassten Daten kurzfristig gesichert werden.
- Der Datensatz, der geändert werden soll, kann wegen der stateless Programmierung erst unmittelbar vor dem Update eingelesen werden. Die erfassten Daten müssen kurzfristig weggesichert werden und nach dem Einlesen des Datensatzes übertragen werden. Dies erfolgt mit Hilfe der Datenstruktur DSAdresseSav.
- PGMSDS: Programm-Status-Datenstruktur mit Unterfeld MSGTXT
Im Fehlerfall wird automatisch ein Fehler-Text in die Datenstruktur bzw. in das Unter-Feld MSGTXT übertragen. Diese Fehler-Meldung wird im Programm in die Variable GblErrMsg übertragen und in der Web-Anwendung angezeigt.
Eine vollständige Definition der Programm-Status-Datenstruktur (mit allen Datenstruktur-Unterfeldern) ist in der folgenden Copy-Strecke hinterlegt und kann auch vom RPGWX-Programmierer verwendet werden.
- Teil-Datei: _PGMSDS
- Datei:QCPYLESRC
- Bibliothek: DIRWEB
Haupt-Programm
Um das Haupt-Programm so übersichtlich wie möglich zu halten, wurden die einzelnen Schritte als Sub-Procedure-Aufrufe hinterlegt.
Es bleibt jedoch dem Programmierer überlassen, ob er ebenfalls Sub-Procedures verwenden will, oder ob er stattdessen lieber Subroutinen verwendet, oder ob er alle Schritte im Haupt-Programm ausführen möchte.
Sub-Procedures im Beispiel-Programm
- Int_ReadData() – Einlesen der Daten über Schlüssel-Feld oder relative Satz-Nr.
- Int_DfnFldHdr() – Definieren von Header-Informationen
- Int_DfnFldChg() – Definieren der Ein-/Ausgabe-Felder
- Int_ChkInput() – Eingabe-Prüfung
- Int_WrtUpd() – Fortschreiben der erfassten Daten
- Int_Dlt() – Löschen der Daten-Sätze über Schlüssel-Felder oder relative Satz-Nr.
/Free *INLR = *On; //1. Einlesen der Schlüssel- und Parameter-Werte GblKey = Wx_GetDBKeyInt(); GblArrKeys = Wx_GetDBKeyArrInt(); //2. Verarbeiten Modi ohne Dialog-Anzeige (z.B. Sätze Löschen) // oder Modi, die in anderen Programmen verarbeitet werden Select; When Wx_isModeDelete(); Int_Dlt(); When Wx_isMode('MYMODE'); //DoSomething EndSL; //3. Daten einlesen (individuelle Programmierung) Int_ReadData(); //4. Definieren Dateien und Felder für RPGWX // 4.1. HTML Dokument öffnen // 4.2. Dateien definieren // 4.3. Header-Informationen // 4.4. Ein-/Ausgabe-Felder definieren Wx_OpnHTMLChg('HDR0003'); Wx_ChgFile('AdresseX'); Int_DfnFldHdr(); Int_DfnFldChg(); //5. Retrieve Changed Input Data Wx_GetChgInput(); //6. Eingabe-Prüfung (Individuelle Programmierung) Int_ChkInput(); //7. Daten fortschreiben (Individuelle Programmierung) GblErrMsg = Int_WrtUpd(); //8. Setzen Parameter-Werte für Folge-Aufrufe (sofern erforderlich) //HTML-Dokument erneut ausgeben //oder auf vorherige Anzeige zurückspringen Wx_WrtChgTbl(GblErrMsg); Return; /End-Free
- Wx_GetDBKeyInt() - Einlesen der eindeutigen Schlüssel-Werte
Über die Funktion Wx_GetDBKeyInt()t wird die relative Satz-Nr., die im vorgelagerten Programm bei den Aktionen Ändern, Anzeigen, Kopieren und Löschen übergeben wird, ermittelt und als ganzzahliger Wert in die Variable GblKey ausgegeben.
- Wx_GetDBKeyArrInt() – Einlesen der eindeutigen Schlüssel-Werte in Feldgruppe
Über die Funktion Wx_GetDBKeyInt() werden die relativen Satz-Nummern, die im vorgelagerten Programm bei der Festlegung der zu löschenden Datensätze ausgewählt wurden, ermittelt und als ganzzahlige Werte in die Feldgruppe GblArrKeys übernommen.
- Wx_isModeDelete() - Prüfen Modus Löschen
Über die Funktion Wx_isModeDelete() wird geprüft, ob Datensätze gelöscht werden sollen.
Sofern Datensätze gelöscht werden sollen wird die Prozedur Int_Dlt() aufgerufen. In dieser Funktion wird auch der Rücksprung auf das vorgelagerte Programm gesteuert. Damit ist das Beenden des Programms (z.B. über OpCode Return) an dieser Stelle nicht erforderlich.
- Int_ReadData – Einlesen der Daten
Individuelle Programmierung: In dieser Prozedur wird der Datensatz basierend auf der in der Variable GblKey ausgegebenen relativen Satz-Nr. eingelesen.
- Wx_OpnHTMLChg() – Definieren Standard-HTML-Dokument
- Überschrift: Message-Id HDR0003 = Adress-Stamm – Details
Die Angabe eines Folge-Programms ist an dieser Stelle nicht erforderlich, da das Programm beim nächsten Durchlauf erneut aufgerufen wird. Der Rücksprung auf das vorgelagerte Programm wird über RPGWX-Prozeduren gesteuert.
- Wx_ChgFile() – Definieren der Dateien/Tabellen/Views für das Change-Programm
- ADRESSEX Datei Adress-Stamm, die verarbeitet wird
- Int_DfnFldHdr() – Definieren der Header-Informationen
- Int_DfnFldChg() – Definieren der Ein-/Ausgabe-Felder
- Wx_GetChgInput() – Empfangen Eingabe-Daten
Beim ersten Durchlauf wird das HTML-Dokument mit den zuvor definierten Ein-/Ausgabe-Felder ausgegeben und das Programm beendet.
Beim nächsten Durchlauf werden die erfassten Daten empfangen.
Der RPGWX-Programmierer muss sich weder um das Beenden, noch um die Fortsetzung des Programms kümmern, sondern lediglich die Prozedur Wx_GetChgInput() aufrufen
- Wx_IntChkInput() – Individuelle Eingabe-Prüfung
- Int_WrtUpd() – Fortschreiben der Datensätze
Individuelle Programmierung: Im Fehlerfall wird aus der internen Prozedur Int_WrtUpd eine Fehlermeldung in die Variable GblErrMsg ausgegeben.
- Wx_WrtChgTbl() – HTML-Dokument ausgeben bzw. Steuerung des Rücksprungs.
Sofern weder eine individuelle Fehlermeldung noch beim Fortschreiben des Datensatzes eine globale Fehlermeldung ausgegeben wurde, wird das Programm beendet und auf das vorgelagerte Programm zurückgesprungen.
Sofern ein Fehler aufgetreten ist, wird das HTML-Dokument erneut, mit den entsprechenden Fehlermeldungen ausgegeben.
Int_ReadData() – Einlesen Daten
In der Funktion Int_ReadData() wird der zu ändernde oder anzuzeigende Datensatz im Input-Modus eingelesen.
Der Zugriff auf die Daten muss vom RPGWX-Programmierer codiert werden. Dabei ist es unerheblich, ob der Zugriff über native I/O (z.B. Chain) oder mit Hilfe von embedded SQL erfolgt.
********************************************************************************* P* Procedure name: Int_ReadData P* Purpose: Einlesen der Daten für die Ein-/Ausgabe-Felder P* Aufgrund der STATELESS Programmierung sollten die Dateien als P* INPUT-Files definiert sein. P* Die Ausgabe muss in Datenstrukturen erfolgen P* (wegen Pointer-Handling) P* Returns: P* Parameters: ******************************************************************************** P Int_ReadData B D Int_ReadData PI OpDesc *--------------------------------------------------------------------------------- /FREE If GblKey > *Zeros; Chain GblKey AdresseF; EndIf; If GblKey = *Zeros or Not %Found(AdresseX); Clear DSAdresse; EndIf; Return; /END-FREE P Int_ReadData E
- Einlesen des Datensatzes im Input Modus in die Datenstruktur DSADRESSE
Das Einlesen des Datensatzes erfolgt nur dann, wenn aus dem vorgelagerten Programm eine relative Satz-Nr. übergeben wurde (bzw. wenn die Variable GblKey über die Funktion Wx_GetDBKeyInt() gefüllt wurde),
- Sofern kein Datensatz eingelesen wurde, wird die Datenstruktur DSADRESSE initialisiert.
- Da es sich bei dieser Prozedur um Individual-Programmierung handelt, könnten weitere Default-Werte in den Datenstruktur-Unterfeldern von DSADRESSE gesetzt werden.
Int_DfnFldHdr() – Header Information
******************************************************************************* * Procedure name: Int_DfnFldHdr * Purpose: Definieren / Ausgeben Header Informationen * Returns: * Parameters: **************************************************************************** P Int_DfnFldHdr B D Int_DfnFldHdr PI OpDesc *------------------------------------------------------------------------------- /FREE //Header-Texte (Prozedur Wx_HdrText) können unabhängig von //den registrierten Dateien/Tabellen/Views und //den darin hinterlegten Feldern/Spalten angelegt werden. //Header-Informationen, die sich auf Feld-Werte beziehen werden über //Prozedur Wx_HdrFld() definiert. //Das Feld muss in den zuvor definierten Dateien/Tabellen/Views vorhanden sein Return; /END-FREE
- In diesem Beispiel-Programm werden keine Header-Informationen benötigt.
Int_ChgFldDfn() – Ein-/Ausgabe-Feld-Definition
******************************************************************************** P* Procedure name: Int_DfnFldChg P* Purpose: Definieren der Ein-/Ausgabe-Felder P* Die Ein-/Ausgabe-Felder müssen in Datenstrukturen hinterlegt P* sein, unabhängig davon ob Datei-Felder oder Arbeits-Felder P* definiert werden P* Wegen Pointer-Handling P* Returns: P* Parameters: ****************************************************************************** P Int_DfnFldChg B D Int_DfnFldChg PI OpDesc *-------------------------------------------------------------------------- /FREE //1. Definieren Ein-/Ausgabe-Felder aus Dateien/Tabellen/Views // --> Felder müssen in den zuvor definierten Dateien/Tabellen/Views // vorhanden sein // -> Ein/Ausgabe-Felder müssen in Datenstrukturen hinterlegt sein Wx_ChgFld('KundeNr': %Addr(KundeNr): 'FLD0001': 'Range(000000, 999999) Right Required'); Wx_ChgFld('Name1F': %Addr(Name1F): 'FLD0002': 'Required'); Wx_ChgFld('Name2F': %Addr(Name2F): 'Name 2' : 'IMG(test.bmp)'); Wx_ChgFld('Strasse': %Addr(Strasse): 'FLD0003'); Wx_ChgFld('Land': %Addr(Land): 'FLD0006': 'CTL(Country) required'); Wx_ChgFld('PLZ': %Addr(PLZ): 'FLD0012': 'NoNewLin'); Wx_ChgFld('Ort': %Addr(Ort): '': 'Required SelectList'); //2. Definieren Arbeits-Felder als Ein-/Ausgabe-Variablen // -> Ein/Ausgabe-Felder müssen in Datenstrukturen hinterlegt sein Return; /END-FREE P Int_DfnFldChg... P E
Das Feld KundenNr ist in der Datei ADRESSEX hinterlegt und damit ein Datenstruktur-Unterfeld in der Datenstruktur DSADRESSE.
- KundeNr - Name des Feldes in Datei ADRESSEX
- %ADDR(KundeNr) - Da ein Austausch von Daten zwischen dem RPG- und dem HTML-Skript erfolgen muss und Daten in jedem beliebigen Datentypen definiert sein können, muss ein Pointer auf das Datenstruktur-Unterfeld KUNDENR übergeben werden.
- FLD0001 - Message-Id = Kunde-Nr.
- Option Range(000000, 999999) Right Required - Gültiger Bereich zwischen 0 und 999999, rechtsbündig angeordnet und Muss-Feld
Das Feld Name1F ist in der Datei ADRESSEX hinterlegt und damit ebenfalls ein Datenstruktur-Unterfeld in der Datenstruktur DSADRESSE.
- Name1F - Name des Feldes in Datei ADRESSEX
- %ADDR(Name1F) - Da ein Austausch von Daten zwischen dem RPG- und dem HTML-Skript erfolgen muss und Daten in jedem beliebigen Datentypen definiert sein können, muss ein Pointer auf das Datenstruktur-Unterfeld NAME1F übergeben werden.
- FLD0002 - Message-Id = Name
- Option Required - Muss-Feld
Das Feld Name2F ist in der Datei ADRESSEX hinterlegt und damit ebenfalls ein Datenstruktur-Unterfeld in der Datenstruktur DSADRESSE.
- Name2F - Name des Feldes in Datei ADRESSEX
- %ADDR(Name2F) - Da ein Austausch von Daten zwischen dem RPG-und dem HTML-Skript erfolgen muss und Daten in jedem beliebigen Datentypen definiert sein können, muss ein Pointer auf das Datenstruktur-Unterfeld NAME2F übergeben werden.
- Name 2 - Anstatt einer Message-Id wird die Beschreibung direkt angegeben.
Das Feld Strasse ist in der Datei ADRESSEX hinterlegt und damit ebenfalls ein Datenstruktur-Unterfeld in der Datenstruktur DSADRESSE.
- Strasse - Name des Feldes in Datei ADRESSEX
- %ADDR(Strasse) - Da ein Austausch von Daten zwischen dem RPG-und dem HTML-Skript erfolgen muss und Daten in jedem beliebigen Datentypen definiert sein können, muss ein Pointer auf das Datenstruktur-Unterfeld STRASSE übergeben werden.
- FLD0003 - Message-Id = Strasse
Das Feld Land ist in der Datei ADRESSEX hinterlegt und damit ebenfalls ein Datenstruktur-Unterfeld in der Datenstruktur DSADRESSE.
- Land - Name des Feldes in Datei ADRESSEX
- %ADDR(Land) - Da ein Austausch von Daten zwischen dem RPG-und dem HTML-Skript erfolgen muss und Daten in jedem beliebigen Datentypen definiert sein können, muss ein Pointer auf das Datenstruktur-Unterfeld LAND übergeben werden.
- FLD0006 - Message-Id = Land
- Option CTL(Country) required - Aufbereitung des Landes als Flagge und Muss-Feld
Das Feld PLZ ist in der Datei ADRESSEX hinterlegt und damit ebenfalls ein Datenstruktur-Unterfeld in der Datenstruktur DSADRESSE.
- PLZ - Name des Feldes in Datei ADRESSEX
- %ADDR(PLZ) - Da ein Austausch von Daten zwischen dem RPG-und dem HTML-Skript erfolgen muss und Daten in jedem beliebigen Datentypen definiert sein können, muss ein Pointer auf das Datenstruktur-Unterfeld PLZ übergeben werden.
- FLD0012 - Message-Id = Land
- Option NoNewLin - Das nächste Ein-/Ausgabe-Feld wird in der gleichen Zeile definiert
Das Feld Ort ist in der Datei ADRESSEX hinterlegt und damit ebenfalls ein Datenstruktur-Unterfeld in der Datenstruktur DSADRESSE.
- ORT - Name des Feldes in Datei ADRESSEX
- %ADDR(ORT) - Da ein Austausch von Daten zwischen dem RPG-und dem HTML-Skript erfolgen muss und Daten in jedem beliebigen Datentypen definiert sein können, muss ein Pointer auf das Datenstruktur-Unterfeld ORT übergeben werden
- ' ' - Da der Ort in der gleichen Zeile wie die PLZ angegeben werden soll ist keine Beschreibung erforderlich
- Option Required - Muss-Feld
Int_ChkInput() – Eingabe-Prüfung
Sofern zusätzliche Eingabe-Prüfungen erforderlich sind, können diese in dieser Prozedur vom RPGWX-Programmierer codiert werden.
Die Prozedur sollte nur dann ausgeführt werden, wenn auch Daten eingegeben wurden, d.h. eine Ausführung im Anzeige-Modus ist nicht erforderlich.
Da es sich bei der Eingabe-Prüfung um individuelle Programmierung handelt, bleibt es dem RPGWX-Programmierer überlassen, wie der die Prüfungen codiert und ob er diese Prozedur überhaupt verwenden will.
************************************************************************** P* Procedure name: Int_ChkInput P* Purpose: Individuelle Eingabe-Prüfung P* Returns: P* Parameters: *************************************************************************** P Int_ChkInput B D Int_ChkInput PI OpDesc *-------------------------------------------------------------------------- /FREE Monitor; //Nur reine Ausgabe --> Keine Eingabe-Prüfung If Wx_isModeOutput(); Return; EndIf; //Individuelle Eingabe-Prüfung [...] On-Error; Wx_WrtChgTbl(PGMSDS.MsgTxt); EndMon; Return; /END-FREE P Int_ChkInput E
- Wx_isModeOutput() - Die Ein-Ausgabe-Prüfung erfolgt nicht, im Anzeige-Modus.
Die Prozedur wird beendet und keine Prüfung ausgeführt.
- In diesem Beispiel-Programm sind keine weiteren individuellen Prüfungen erforderlich.
Int_WrtUpd() – Daten fortschreiben
Fortschreiben der erfassten Daten.
Aufgrund der stateless Programmierung, muss der zu ändernde Datensatz vor dem Fortschreiben erneut eingelesen werden um ihn dann mit den geänderten Feldern zu versorgen und dann wegzuschreiben.
*************************************************************************** P* Procedure name: Int_WrtUpd P* Purpose: Fortschreiben Daten in Datei Adresse P* Erneutes Einlesen des Datensatzes erforderlich, P* wegen STATELESS Programmierung P* Returns: P* Parameters: **************************************************************************** P Int_WrtUpd B D Int_WrtUpd PI Like(FldRef.MsgText) OpDesc D RtnErrMsg S Like(FldRef.MsgText) *--------------------------------------------------------------------------- /FREE Monitor; //Nur Anzeige oder Fehler --> Kein Update/Write = Ende Prozedur If Wx_isModeOutput() or Wx_isChgFldErr(); Return ''; EndIf; //Fortschreiben Datensatz //1. Sichern der Ein-/Ausgabe-Daten //2. Erneutes Einlesen des Datensatzes (wegen STATELESS Programmierung) //3. Erfasste Daten in den eingelesenen Datensatz übernehmen //4. Datensatz fortschreiben DSAdresseSav = DSAdresse; If GblKey <> *Zeros; Clear DSAdresse; Chain GblKey AdresseF1; EndIf; DSAdresse = DSAdresseSav; If Not %Found(AdresseI01) or GblKey = *Zeros; Write AdresseF1; Else; Update AdresseF1; EndIf; On-Error; DSAdresse = DSAdresseSav; Return PGMSDS.MsgTxt; EndMon; Return ''; /END-FREE P Int_WrtUpd... P E
- Die Prozedur wird nicht ausgeführt (bzw. sofort beendet), sofern im Anzeige-Modus (Wx_isModeOutput()) gearbeitet wird oder ein Fehler angezeigt werden soll (Wx_isChgFldErr()).
- Die in Datenstruktur DSADRESSE hinterlegten Ein-/Ausgabe-Werte werden in Datenstruktur DSADRESSESav übertagen.
- Der Datensatz wird im Update-Modus eingelesen, sofern aus dem vorgelagerten Programm eine relative Satz-Nr. übergeben wurde (GblKey > *Zeros)
- Die in der Datenstruktur DSADRESSESav gesicherten Daten werden in die Datenstruktur DSADRESSE übertragen.
- Sofern ein Datensatz eingelesen wurde wird dieser Datensatz aktualisiert.
- Sofern kein Datensatz eingelesen wurde wird ein neuer Datensatz geschrieben.
- Wurden der Datensatz ordnungsgemäß fortgeschrieben, wird die Prozedur ohne Fehlermeldung verlassen.
- Tritt beim Einlesen (im Update-Modus) oder beim Fortschreiben der Datensätze ein Fehler auf, wird in den On-Error-Zweig der Monitor-Group verzweigt.
Die Fehlermeldung, die in der Programm-Status-Datenstruktur ausgegeben wird, wird als Rückgabe-Wert ausgegeben.
Int_Dlt() – Datensätze löschen
************************************************************************** P* Procedure name: Int_Dlt P* Purpose: Löschen Datensätze aus Datei Adresse P* Returns: P* Parameters: ************************************************************************** P Int_Dlt B D Int_Dlt PI OpDesc D LocIndex S 3U 0 D LocErrMsg S Like(FldRef.MsgText) *------------------------------------------------------------------------- /FREE Monitor; //Verarbeiten der zu löschenden Datensätze For LocIndex = 1 To %Elem(GblArrKeys); If GblArrKeys(LocIndex) = *Zeros; Leave; EndIf; Delete(E) GblArrKeys(LocIndex) AdresseF1; If %Error; LocErrMsg = 'Fehler beim Löschen'; EndIf; EndFor; On-Error; Wx_RtnPrv(PGMSDS.MsgTxt); EndMon; //Programm beenden und Rücksprung auf vorheriges Programm Wx_RtnPrv(LocErrMsg); /END-FREE P Int_Dlt E
- Verarbeitung aller relativen Satz-Nr. die im vorhergehenden Programm zum Löschen ausgewählt wurden, und die über Prozedur Wx_GetDBKeyArrInt() in die Feldgruppe GblArrKeys eingelesen wurden.
- Löschen der Datensätze
- Sollte beim Löschen der Datensätze ein Fehler auftreten, wird der Fehler abgefangen und die Fehlermeldung in der lokalen Variablen LocErrMsg gespeichert.
- Wurden alle Datensätze gelöscht, wird durch Aufruf der Prozedur Wx_RtnPrv() auf das vorgelagerte Programm zurückverzweigt. Sofern eine Fehlermeldung gesichert wurde, wird diese an das vorgelagerte Programm ausgegeben und dort angezeigt.
Aus einem WRK-Programm ein anderes WRK-Programm aufrufen
Am Beispiel: aus der List-Anzeige der Kunden sollen mit rechtem Mausklick und "Mit Angeboten arbeiten" alle Aufträge zu dem gewählten Kunden angezeigt werden.
- EXWRKADDR ist das WRK-Programm für die Addressen
- EXWRKORDH ist das WRK-Programm für die Aufträge
Dcl-S GblErrMsg Like(FldRef.TextVar); Dcl-S GblArrKey Like(FldRef.TextVar) Dim(RefElemCGI); Dcl-S GblCustNo Char(15) Inz; ---------------------------------------------------------------------------------- In EXWRKADDR heisst es: ---------------------------------------------------------------------------------- Wx_CtxMnuItm('EXWRKORDH': 'DSP0044': ''); ---------------------------------------------------------------------------------- Und in EXWRKORDH wird der Key geholt und dann die Bedingung gesetzt: ---------------------------------------------------------------------------------- Clear GblArrKey; GblArrKey = Wx_GetDBKeyFldChar(); If %Len(%Trim(GblArrKey(1))) <> *Zeros; Int_GetCustNo(); Wx_WrkWhere('CustNo = ' + '' + %Trim(GblCustNo) + '' + ' '); EndIf; Wx_OpnHTMLWrk('TIT0011':'EXCHGORDH'); Wx_FltFile('ORDERHDV1'); ---------------------------------------------------------------------------------- Die Unterprozedur int_GetCustNo holt den Schlüssel zum Kunden aus den Parametern ---------------------------------------------------------------------------------- DCL-Proc Int_GetCustNo; DCL-PI Int_GetCustNo OpDesc; END-PI; DCL-S LocRRN Int(10) inz; Dcl-S LocErrMsg Char(80) Inz; Monitor; LocRRN = %INT(%Trim(GblArrKey(1))); On-Error; EndMon; Monitor; Exec SQL Select CustNo into : GblCustNo From AdrListX Where RRN(AdrListX) = : LocRRN Fetch First Row Only; On-Error; DW_SndSQLErrMsg(SQLCODE: SQLERM); LocErrMsg = PGMSDS.MsgTxt; //Fehler-Text sichern EndMon; End-Proc;
In einem CHG-Programm eine Tabelle darstellen mit Wx_HtmlTbl und Wx_HtmlTblColhdg
In diesem Beispiel sich wiederholende Felder (Datum1, Qualifikation1, Aktiv1, Datum2, Qualifikation2, Aktiv2, usw.) eines Satzes als Tabelle nebeneinander dargestellt:
Dafür wird eine HTML-Tabelle aufgebaut, mit Hilfe der beiden Funktionen Wx_HtmlTbl
und Wx_HtmlTblColhdg.
Der Code dazu sieht so aus:
Exit-Programm für die Darstellungs-Steuerung in Spalten in Wrk-Programmen
In der Funktion Wx_WrkFld() kann eigener Code eingebunden werden mit der Funktion exit().
In der Funktion kann ein selbstgeschriebenes Serviceprogramm benannt werden.
Hier ist ein Beispiel für solch ein Serviceprogramm.
Beispielcode
//******************************************************************************************** //Object Name : EXITPGM1 //******************************************************************************************** //Example Programm for userexit functions //******************************************************************************************** // Create: // 1. CRTSQLRPGI OBJ(QTEMP/EXITPGM1) SRCFILE(<srclib>/<srcfil) COMMIT(*NONE) OBJTYPE(*MODULE) // 2. CRTSRVPGM SRVPGM(<objlib>/EXITPGM1) MODULE(QTEMP/EXITPGM1) EXPORT(*ALL) TGTRLS(*CURRENT) // // This sort of program does need any BND-Sources or BNDDIR-entires // // At runtime <objlib> must be in the application's library list //******************************************************************************************** //H E A D E R S P E C I F I C A T I O N S //******************************************************************************************** CTL-Opt NoMain ; //******************************************************************************************* //S E T O P T I O N S T A T E M E N T F O R S Q L //******************************************************************************************* //******************************************************************************************** // B E G I N E X P O R T E D P R O C E D U R E S //******************************************************************************************** //******************************************************************************************** // Procedure name: SC // Purpose: Set Colors for negative Values // // Returns: // Parameters: //******************************************************************************************** // ---------------------------------------------------------- // Procedure Interface - mandatory for each procedure // ---------------------------------------------------------- DCL-Proc SC Export; DCL-PI SC ; opaque pointer ; // Pointer for Data Structure SESS_DS field VARCHAR(10) ; // Field Name value VARCHAR(1024); // Field Value mode INT(10) ; // Mode 1=Inp.Req/2=Inp/5=List/3=Output html VARCHAR(32767); // HTML Code End-Pi; //-------------------------------------------------------------------------------------------- // ---------------------------------------------------------- // Example code: change the font color to red, // if the value is negative // any valid HTML or JavaScript can be used in the variable HTML // i.e. instead of // "color:red;" // you could use "background-color:red;color:blue;" // that change the background to red and the font to blue. // ---------------------------------------------------------- Select; WHEN %scan('-':%trim(value)) > 0 ; // Check for negative sign in the string HTML = '<a style="color:red;">' + // Set Color Atributes %TRIM(value) + // original Value '</a>' ; // Terminator OTHER; HTML = %TRIM(value); // original Value is returend without HTML envelope ENDSL; return; End-Proc SC ;
Aufruf im WRK-Programm
Das oben dargestellte Programm wird so im WRK-Programm so aufgerufen;
Wx_WrkFld('FELDNME' : 'FELDBEZEICHNUNG' :'Exit(SC, EXITPGM1) ');