RPG – FAQ & Howtos (IT Part.4)

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

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

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

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

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

Recent Posts

ACS Access Client Solution 1.1.9.5

I primi di Aprile è uscita la "Spring Version" di ACS Access Client Solution, versione 1.1.9.5 Interessanti novità soprattutto in…

2 giorni ago

Tim Rowe and Scott Forstie – Promo video for CEC 2024 – Milan

Se non vi bastava la ricca agenda delle sessioni del Common Europe Congress 2024, 3-6 Giugno Milano, ecco un altro…

2 giorni ago

Code for IBM i 2.10.0 – Debug IBM i con Visual Studio Code

Le funzioni di debug con Visual Studio Code sono disponibili da qualche tempo ma questa nuova versione 2.10.0 semplifica la…

5 giorni ago

ObjectConnect over TCP/IP

A distanza di due anni e mezzo dal mio post Trasferire oggetti con ObjectConnect ed Enterprise Extender, sono finalmente riuscito…

5 giorni ago

SQL: SELECT con i “superpoteri”

Con un piccolo trucco anche una semplice istruzione SELECT può eseguire qualsiasi comando di sistema ! Vediamo come...

6 mesi ago

NetServer per tutti – parte 5

Una mini-guida a puntate per la configurazione, gestione, uso e risoluzione dei problemi di IBM i NetServer

1 anno ago