01 - Programmazione01a - RPG

RPG – FAQ & Howtos (IT Part.4)

Last Updated on 12 Maggio 2021 by Roberto De Pedrini

Third episode of the RPG series – FAQ & Howtos, the previous episodes can be found here;

RPG-FAQ-028: RPG Rimappare singoli campi in un Array

Spesso abbiamo la necessità di “rimappare” una serie di capi (ad esempio Mese01, Mese02 … Mese12) in un array per gestire i singoli valori dei campi in cicli DO ecc.

Possiamo utilizzare diverse tecniche … ne prendo un paio da questa discussione di Midrange.com;

Example 01:

Dcl-DS *N;
  SlOthCtr1;
  SlOthCtr2;
  SlOthCtr3;
  SlOthCtr4;
  SlOthCtr5;
  SlOthCtr6;
  SlOthCtr7;
  SlOthCtr8;
  SlOthCtr9;
  SlOthCtr10;
  SlOthCtr11;
  SlOthCtr12;
  SlOthCtr13;
  SlOthCtr14;
  SlOthCtr15;
  SlOthCtr16;
  SlOthCtr17;
  SlOthCtr18;
  SlOthCtr19;
  SlOthCtr20;
  SlOthCtr21;
  SlOthCtr22;
  SlOthCtr23;
  SlOthCtr24;
  SlOthCtr25;
  SlOthCtr26;
  SlOthCtr27;
  SlOthCtr28;
  Containers Char(40) Dim(28) Pos(1);
End-Ds;

Example 2, usinge SAMEPOS 
dcl-ds *n;
   SlOthCtr1;
   SlOthCtr2;
     .
     .
   SlOthCtr28;
   Containers like(SlOthCtr1) dim(28) samepos(SlOthCtr1);
end-ds;

Example 3, using pointer

Since you already have a data structure that contains the S1othCtr*
fields, try this:

Dcl-S Container Char(40) Dim(28) based(ptrCTR);

Dcl-S ptrCTR Pointer inz(%addr(S1OthCtr1));

Una alternativa interessante è quella di utilizzare il LATERAL join per portare i dati in “verticale” quindi permettersi una FETCH da SQL Embedded direttamente dentro l’array:

create table qtemp/monthly (month1 numeric(11,2), month2 numeric(11,
2), month3 numeric(11,2), month4 numeric(11,2), month5 numeric(11,2),
month6 numeric(11,2), month7 numeric(11,2), month8 numeric(11,2),
month9 numeric(11,2),  month10 numeric(11,2),
month11 numeric(11,2), month12 numeric(11,2));

insert into qtemp/monthly values(100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200);

select mo.* from monthly, lateral ( values 
(1, month1), 
(2, month2), 
(3, month3),
(4, month4), 
(5, month5), 
(6, month6),
(7, month7), 
(8, month8), 
(9, month9),
(10, month10), 
(11, month11), 
(12, month12)
)as mo (month, total)

RPG-FAQ-029: Gestione errori nelle API “Unix-Like”

Per intercettare gli errori quando utilizziamo le API Unix-Like dobbiamo “leggere” Error Number utilizzando la procedure “__errno”, come in questo esempio

//* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//* GetErrorMessageId
//*   Get the error message Id for the Unix Error.
//*   Input     - None
//*   Out       - None
//*   Returns   - Message Id.
//* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
dcl-proc GetErrorMessageId;
  dcl-pi *N Char(7) end-pi;

  dcl-pr GetErrorNumberApi Pointer ExtProc('__errno') end-pr;

  dcl-s ErrorNumber Int(10) Based(PtrErrorNumber);

  PtrErrorNumber = GetErrorNumberApi();

  Return 'CPE' + %Char(ErrorNumber);

end-proc;

O, alternativamente, utilizzando le procedure della QCLE come in questo esempio:

H BNDDIR('QC2LE')
    
         D/copy qrpglesrc,socket_h
         D/copy qrpglesrc,errno_h
    
            .... more code is found here ....
    
         c                   if        socket(AF_INET:SOCK_STREAM:IPPROTO_IP)<0
         c
         c                   select
         c                   when      errno = EACCES
         c                   eval      Msg = 'Permission Denied'
    
         c                   when      errno = EAFNOSUPPORT
         c                   eval      Msg = 'Address Family not supported!'
    
         c                   when      errno = EIO
         c                   goto      TryAgainMaybe
    
            ... etc, etc, etc ...
    
         c                   endsl
    
            .... more code is found here ....
    
          /define ERRNO_LOAD_PROCEDURE
          /copy libsor/qrpglesrc,errno_h

Maggiori approfondimenti in questo post di Scott Klement: RPG IV Socket Tutorial – Error Handling

RPG-FAQ-030: Gestione Files e Directory IFS con RPG

Possiamo gestire (scrivere, leggere, modificare ecc) files e directory IFS da RPG utilizzando diverse tecniche:

RPG-FAQ-031: Retrieve Message from a Message File

Una richiesta su Midrange.com si chiedeva “I need a way to retrieve messages from a message file and merge the MSGDTA values into it.” e sono arrivati alcuni source che utilizzano l’API QMHRTVM:

RTVMSGTXT By Thomas Raddatz

**free
// ================================================================== *
//  Retrieve message text with QMHRTVM API
// By Thomas Raddatz
// ================================================================== *
ctl-opt main(main) dftactgrp(*no) actgrp(*new);

dcl-pr main extpgm('RTVMSGTXT');
end-pr;

dcl-pr retrieveMessageText like(string_t) extproc(*dclcase);
  i_library char(10) const;
  i_msgF    char(10) const;
  i_msgID   char(10) const;
  i_msgData char(4096) options(*varsize) const;
end-pr;

// Commonly used templates
dcl-s string_t varchar(2048) template;

dcl-ds qObj_t qualified template;
  name       char(10);
  lib        char(10);
end-ds;

dcl-ds errCode_t qualified template;
  bytPrv     int(10);
  bytAvl     int(10);
  excID      char(7);
  reserved_1 char(1);
  excDta     char(256);
end-ds;

// The program entry point
dcl-proc main;
  dcl-pi *n;
  end-pi;

  dcl-s msgText like(string_t);
  dcl-s dsplyTxt varchar(50);
  dcl-s rc char(1);

  msgText = retrieveMessageText(
            'QSYS': 'QCPFMSG': 'CPF9811': 'MYPGM     MYLIBRARY ');

  dsplyTxt = %subst(msgText: 1: 50);

  dsply dsplyTxt rc;

end-proc;

// -------------------------------------------------------------------
//   Retrieve message text.
// -------------------------------------------------------------------
dcl-proc retrieveMessageText;
  dcl-pi *n like(string_t);
    i_library char(10) const;
    i_msgF    char(10) const;
    i_msgID   char(10) const;
    i_msgData char(4096) options(*varsize) const;
  end-pi;

  // The return value
  dcl-s msgText like(string_t);

  // Format RTVM0100 of QMHRTVM API
  dcl-ds rtvm0100_t qualified template;
    bytRet     int(10);
    bytAvl     int(10);
    lenMsgRet  int(10);
    lenMsgAvl  int(10);
    lenHlpRet  int(10);
    lenHlpAvl  int(10);
    data       char(4096);
  end-ds;

  // The Retrieve Message (QMHRTVM) API
  dcl-pr QMHRTVM extpgm('QMHRTVM');
    o_msgInf         char(32767) options(*varsize);
    i_length         int(10)     const;
    i_format         char(8)     const;
    i_msgID          char(7)     const;
    i_qMsgF          char(20)    const;
    i_rplData        char(32767) const options(*varsize);
    i_rpldataLen     int(10)     const;
    i_rplVars        char(10)    const;
    i_rtnCtrlChrs    char(10)    const;
    io_ErrCode       char(32767) options(*varsize);
  end-pr;

  dcl-ds qMsgF likeds(qObj_t);
  dcl-ds errCode likeds(errCode_t);
  dcl-ds rtvm0100 likeds(rtvm0100_t);

  qMsgF.name = i_msgF;
  qMsgF.lib  = i_library;

  QMHRTVM(rtvm0100: %size(rtvm0100): 'RTVM0100': i_msgID: qMsgF:
          i_msgData: %len(i_msgData): '*YES': '*NO': errCode);

  if (errCode.bytAvl = 0 and rtvm0100.lenMsgRet > 0);
    msgText = %subst(rtvm0100.data: 1: rtvm0100.lenMsgRet);
  else;
    msgText = '';
  endif;

  return msgText;

end-proc;

e SYIMSGR di Darryl Freinkel

F* Program Name: SYIMSGR        Created:  4/22/2021 By DHF

     F* Overview: This program is a utility program that retrieves a message from a

     F*           message file and substitutes the MSGDTA values into the
 message

     F*           returning the message to the calling program.

     F*           This utility is needed as there are program in the system
that are either

     F*           cloned from an interactive program or are part of an
interactive program

     F*           but the screen functions have been bypassed. However, the
programs still

     F*           have code to display the message in the command line. When
the screen

     F*           displays are bypassed, the messages are sent to the
message queue but are

     F*           never displayed.
     F*

     F*           Use this utility to get a complete message and email the
message out,
     F*           or send the message to the joblog.
     F*

     F*           When emailing, use the command SYREMLC.
     F*
     F*    By Darryl Freinkel
     F*

     F********************************************************************

     F* Notes:

     F*

     F********************************************************************

     F* Modifications:                                                   *

     F********************************************************************

     F*

     F********************************************************************

     H*

     H optimize(*basic) option(*expdds:*nodebugio)

     h/if defined(*CRTBNDRPG)

     h dftactgrp(*no) actgrp(*New)

     h/else

     h* dftactgrp(*NO)

     h/endif

     H*

     F***************************************************************************

      * Retrieve Message data ( QMHRTVM ) API


      **************************************************************************

     D* #RtvMsg...

     D*                PI         32766a   varying

     D syimsgr         pi                    extpgm('SYIMSGR')

     D pMsgId                         7    const

     D pMsgFlib                      20    const

     D pMsgRplDta                  2048a   const options(*varsize)

     D pRplSubVal                    10    const

     D pFmtCtlChar                   10    const

     D pRtn_Message                  80a



      *include downloads/qcopysrc,RTVM0200Ds

      * Return format for QMHRTVM api

     D RTVM0200Ds      DS

     D  rBytRtn                      10i 0

     D  rBytAvl                      10i 0

     D  rMsgSev                      10i 0

     D  rAlertIndx                   10i 0

     D  rAlertOpt                     9a

     D  rLogInd                       1a

     D                                2a

     D  rLenRplyRet                  10i 0

     D  rLenRplyAvl                  10i 0

     D  rLenMsgRet                   10i 0

     D  rLenMsgAvl                   10i 0

     D  rLenMsgHlpRet                10i 0

     D  rLenMsgHlpAvl                10i 0

     D  rMessage                   4096a

     D  rMessageHelp               4096a


      *include downloads/qcopysrc,QMHRTVM

      * Receive Message QMHRTVM API

     D QMHRTVM         PR                  extpgm('QMHRTVM')

     D  pMsgData                  32767a   const options(*varsize)

     D  pMsgDataLen                  10i 0 const

     D  pFormat                       8a   const

     D  pMsgId                        7a   const

     D  pMsgFileLib                  20a   const

     D  pRplData                  32767a   const options(*varsize)

     D  pRplDataLen                  10i 0 const

     D  pRplSubVar                   10a   const

     D  pRtnCtlChar                  10a   const

     D  pErr0200                            like(Errc0200Ds)


      * API Error Data Structure - ERRC0200 format

     d ERRC0200ds      Ds                  inz qualified

     d  MsgKey                       10i 0 inz(-1)

     d  BytesProv                    10i 0 inz(%size(ERRC0200Ds.MsgData))

     d  BytesAval                    10i 0

     d  MsgID                         7a

     d  filler                        1a

     d  cCCSID                       10i 0

     d  OffMsgData                   10i 0

     d  LenMsgData                   10i 0

     d  MsgData                   32767a


     D LenRplDta       s             10i 0 inz

     D LenMsgDta       s             10i 0 inz

     d FmtCtlChr       s             10a

     d RplSubVal       s             10a


      /free

                clear Errc0200Ds;

                clear RTVM0200Ds;


                Errc0200Ds.BytesProv = %size(Errc0200Ds.MsgData);

                LenMsgDta = %size(RTVM0200ds);

                LenRplDta = 0;

                LenRplDta = %len(pMsgRplDta);

                if LenRplDta > 0;

                   RplSubVal   = '*YES';

                   FmtCtlChr   = '*NO';

                else;

                   RplSubVal   = '*NO';

                   FmtCtlChr   = '*NO';

                Endif;


                // Get message data

               QMHRTVM( RTVM0200Ds   :  LenMsgDta   :

                         'RTVM0200'   :  pMsgID      :

                         pMsgFlib     :

                         pMsgRplDta   : LenRplDta    :

                         RplSubVal    : FmtCtlChr    :

                         Errc0200Ds ) ;


                // return RTVM0200ds;

               prtn_message = %trim(rMessage);

                *inlr = *on;

      /end-free

     P*  #RtvMsg...

     P*                 E

RPG-FAQ-032: DSPF e i Check-Boxes (Booth Martin Tribute)

Riporto qui di seguito una serie di link al Booth Martin Tribute web site sotto Midrange.com …. Booth Martin, che ci ha lasciati ad Agosto 2020, aveva creato una raccolta di codice RPG e SQL veramente interessante … vi porto solo qualche esempio e vi invito a visitare il nuovo sito all’url: https://boothmartin.midrange.com/

Iniziamo con una guida all’uso dei Check Boxes nei Display File DSPF : https://boothmartin.midrange.com/Code_Samples/Check_Boxes/check_boxes.html

CheckBoxes02

RPG-FAQ-033: Scrivere su IFS con RPG (Booth Martin Tribute)

Un esempio di programma che scrive su IFS: https://boothmartin.midrange.com/Code_Samples/IFS/ifs.html

WRKLNK0203

RPG-FAQ-034: DSPF e Menu Bar (Booth Martin Tribute)

Usare i Menu Bar (menu a tendina) nei DSPF interagendo con il mouse? Ecco un esempio: https://boothmartin.midrange.com/Code_Samples/Menu_Bar/menu_bar.html

RPG-FAQ-035: Progress Bar e DSPF (Booth Martin Tribute)

Restiamo nei Display File con una Progress Bar per vedere l’avanzamento di un JOB:https://boothmartin.midrange.com/Code_Samples/_Progress_Bar/_progress_bar.html

RPG-FAQ-036: Un Text Data Editor 5250 ? (Booth Martin Tribute)

Un text data editor 5250 costruito con un Subfile: https://boothmartin.midrange.com/Subfiles/Data_Editor/data_editor.html

Data Editor

RPG-FAQ-037: Visualizzare immagini dal 5250 (STRPCCMD) ? (Booth Martin Tribute)

Visualizzare le immagini di prodotti / articoli da un Subfile? Ecco un esempio con STRPCCMD: https://boothmartin.midrange.com/Subfiles/Show_Image/show_image.html

SFL Image02
Related Posts
DB2 for i SQL – Stringhe – POSSTR-LOCATE-LOCATE_IN_STRING (IT)

Introduzione Spesso, nelle nostre applicazioni, abbiamo la necessità di lavorare con le stringhe di testo e l'SQL del DB2 può Read more

DB2 for i & SQL – FAQ & Howto (Part. 1) (IT)

Database DB2 e SQL ... forse lo strumento più potente e completo che abbiamo sulla piattaforma IBM i: ecco una Read more

Annuncio IBM i 7.4

Arriva direttamente con l'uovo di Pasqua questo annuncio IBM per le novità della versione IBM i 7.4, versione iNext secondo Read more

Generated Always Columns – Approfondimenti (IT)

Introduzione "Generated Always Column": sono colonne, campi, di una tabella il cui contenuto è controllato direttamente dal sistema ... e Read more

--- Roberto De Pedrini Faq400.com
About author

Founder di Faq400 Srl, IBM Champion, ideatore del sito Faq400.com e del Blog blog.faq400.com. Sviluppatore RPG da quando avevo i pantaloni corti, forte sostenitore della piattaforma IBM i (ex AS400), ho sempre cercato di convididere le mie conoscenze con gli altri tramite forum, eventi e corsi. Oggi, tramite Faq400 Srl, cerchiamo di aiutare le aziende a sfruttare al meglio questa fantastica piattaforma IBM i.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *