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.


ADDRWRK_A - source code
**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


ADDRCHG_A - source code
**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.


EXWRKAD01 - Listen ("Work")-Programm mit Adressen
* 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


  • 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
  • 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


EXCHGAD01 - 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

Beispiel - Change-Programm Adress-Stamm - Haupt-Programm
/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.

EXCHAD01 - Prozedur int_ReadData()
*********************************************************************************
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

EXCHGAD01 - Prozedur int_HdrFldDfn()
*******************************************************************************
* 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


EXCHGAD01 - Prozedur int_HdrFldDfn()
********************************************************************************
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.

EXCHGADR01 - Prozedur int_ChkInput
**************************************************************************
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.

EXCHGADR01 - Prozedur int_WrtUpd
***************************************************************************
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

Prozedur Int_Dlt
**************************************************************************
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
Beispielcode
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

EXITPGM1 - Mustervorlage
      //********************************************************************************************
      //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) ');