RPG IV : Un arbre n-aires (en cours…)

Le programme d’illustration permet de créer une structure hiérarchique d’éléments contenant chacun un libellé et une valeur. Cette structure débute par un élément parent « racine » auquel on ajoute ensuite des éléments « fils ». Eléments « fils » pouvant eux-mêmes être parents d’autres éléments et ainsi de suite. Une procédure permet ensuite, pour un élément donné, d’obtenir des informations sur le nombre d’éléments « descendants » et leurs valeurs cumulées.

Cet exemple est aussi l’occasion d’illustrer l’utilisation de procédures stateless reposant sur des handles. Cette méthode – de mon point de vue – est un peu la frontière entre la programmation procédurale et la programmation objet. Vous en trouverez une présentation ici

Utilisation du service

Quelques lignes de code valant mieux qu’un long discours, nous commençons par la partie cliente.

Le programme suivant utilise le service pour créer une structure contenant des éléments intitulés « Elément x », ayant chacun une valeur de 10 puis interroge la valeur cumulée pour un élément.

Les sorties se font dans la joblog.

     h dftactgrp(*no) actgrp('NDP400')
     h bnddir('NDP400')
      **********************************************************************************************
      *                                                                                            *
      * neditespas400.com / Cédric Chapuis / Mars 2015                                             *
      *                                                                                            *
      * Exemple de création d'un arbre n-aires en RPG IV ILE.                                      *
      *                                                                                            *
      * ------------------------------------------------------------------------------------------ *
      *                                                                                            *
      * Licence Creative Commons Attribution 4.0 International (CC BY 4.0)                         *
      *                                                                                            *
      **********************************************************************************************

      /COPY QRPGLEINC,ARB001


     d T_ARB001...
     d                 pr                  extpgm('T_ARB001')

     d T_ARB001...
     d                 pi



      *-- Prototypes locaux ------------------------------------------------------------------------

     d log...
     d                 pr
     d    msg...
     d                             1024a   const



      *-- Variables globales -----------------------------------------------------------------------


     d hElement...
     d                 s                   like(m_hElement)

     d hTmp...
     d                 s                   like(m_hElement)

     d infElm...
     d                 ds                  likeds(m_infElement)




      **********************************************************************************************
      *
      *
      *
      **********************************************************************************************
      /free

       // Création de la racine
       hElement = creElement(*null: 'Racine': 0);

       // Création d'un nouvel élément sous la racine
       creElement(hElement: 'Elément 1': 10);

       // Création d'un nouvel élément sous la racine
       hElement = creElement(hElement: 'Elément 2': 10);

       // Création d'un sous-élément pour "Element 2"
       creElement(hElement: 'Elément 2.1': 10);

       // Création d'un sous-élément pour "Element 2"
       // On garde dans hTmp un handle vers ce nouvel élément.
       hTmp = creElement(hElement: 'Elément 2.2': 10);

       // Récupère le handle vers Element 2.1
       hElement = rcpParent(hElement);

       // Création d'un nouvel élément sous la racine
       creElement(rcpRacine(hElement): 'Elément 3': 10);

       // Création d'un nouvel élément sous la racine
       hElement = creElement(rcpRacine(hElement): 'Elément 4': 10);

       // Création de deux sous-élément pour "Element 4"
       creElement(hElement: 'Elément 4.1': 10);
       creElement(hElement: 'Elément 4.2': 10);

       // Création d'un sous-élément pour "Element 4
       hElement = creElement(hElement: 'Elément 4.3': 10);

       // Création de 4 sous-éléments pour 'Elément 4.3'
       creElement(hElement: 'Elément 4.3.1': 10);
       creElement(hElement: 'Elément 4.3.2': 10);
       creElement(hElement: 'Elément 4.3.3': 10);
       creElement(hElement: 'Elément 4.3.4': 10);

       // Récupère l'élément parent de "Elément 4.3"
       hElement = rcpParent(hElement);

       // Création de 2 sous-éléments pour 'Elément 4'
       creElement(hElement: 'Elément 4.4': 10);
       creElement(hElement: 'Elément 4.5': 10);

       // Ajout d'élément au groupe 2
       creElement(hTmp: 'Elément 2.1.1': 10);
       creElement(hTmp: 'Elément 2.1.2': 10);

       // Affichage depuis  "Elément 4.3"
       log('** Affichage depuis l''élément "' + infLibelle(hElement) + '"');
       affElement(hElement);

       // Récupère un handle vers la racine de la structure
       hElement = rcpRacine(hElement);

       // Affichage depuis la racine
       log('** Affichage depuis l''élément "' + infLibelle(hElement) + '"');
       affElement(rcpRacine(hElement));

       // Récupère les informations sur la structure depuis la racine
       stsElement(hElement: %addr(infElm));

       // Affichage des informations
       log('** Informations depuis: "' + infLibelle(hElement) + '"');
       log('Somme des valeurs : ' + %char(infElm.val));
       log('Nombre d''élément simple : ' + %char(infElm.nbrSimple));
       log('Nombre d''élément parent : ' + %char(infElm.nbrParent));

       // Suppression de l'arbre complet
       log('** Suppression depuis : "' + infLibelle(hElement) + '"');
       supElement(rcpRacine(hElement));

       *inlr = *on;

      /end-free






      *---------------------------------------------------------------------------------------------
      *
      * log
      *
      * Permet d'alimenter la Joblog.
      *
      *---------------------------------------------------------------------------------------------
     p log...
     p                 b
     d                 pi
     d    msg_...
     d                             1024a   const
     d sndpgmmsg       pr                  extpgm('QMHSNDPM')
     d  msgid                         7a   const
     d  msgf                         20a   const
     d  msgdta                    32767a   const options(*varsize)
     d  msgdtalen                    10i 0 const
     d  msgtype                      10a   const
     d  callstkent                   10a   const
     d  callstkcnt                   10i 0 const
     d  msgkey                        4a
     d  error                              likeds(error)
     d error           ds                  qualified
     d  provided                     10i 0
     d  available                    10i 0
     d  msgid                         7a
     d  rsvd                          1a
     d  msgdta                       80
     d msgkey          s              4a
     d log_INFO...
     d                 s             10a   inz('*INFO')
     d msgid           c                   'CPF9897'
     d msgf            c                   'QCPFMSG   *LIBL     '
      /free

       sndpgmmsg(msgid
         : msgf
         : %trimr(msg_)
         : %len(%trimr(msg_))
         : log_INFO
         : '*'
         : 0
         : msgkey
         : error);

      /end-free
     p                 e

Résultat (via DSPJOBLOG)

Notez que si les libellés sont ordonnés c’est qu’ils ont été créés dans cet ordre.

** Affichage depuis "Elément 4"
-- Elément 4 (Val.: 10)
---- Elément 4.1 (Val.: 10)
---- Elément 4.2 (Val.: 10)
---- Elément 4.3 (Val.: 10)
------ Elément 4.3.1 (Val.: 10)
------ Elément 4.3.2 (Val.: 10)
------ Elément 4.3.3 (Val.: 10)
------ Elément 4.3.4 (Val.: 10) 
---- Elément 4.4 (Val.: 10) 
---- Elément 4.5 (Val.: 10)
** Affichage depuis "Racine" 
-- Racine (Val.: 0) 
---- Elément 1 (Val.: 10)
---- Elément 2 (Val.: 10)
------ Elément 2.1 (Val.: 10)
------ Elément 2.2 (Val.: 10)
-------- Elément 2.1.1 (Val.: 10)
-------- Elément 2.1.2 (Val.: 10)
---- Elément 3 (Val.: 10)
---- Elément 4 (Val.: 10)
------ Elément 4.1 (Val.: 10)
------ Elément 4.2 (Val.: 10)
------ Elément 4.3 (Val.: 10) 
-------- Elément 4.3.1 (Val.: 10) 
-------- Elément 4.3.2 (Val.: 10) 
-------- Elément 4.3.3 (Val.: 10) 
-------- Elément 4.3.4 (Val.: 10) 
------ Elément 4.4 (Val.: 10) 
------ Elément 4.5 (Val.: 10) 
** Informations depuis: "Racine" 
Somme des valeurs : 170 
Nombre d'élément simple : 13
Nombre d'élément parent : 5 
** Suppression depuis : "Racine"
Suppression de l'élément "Elément 4.5" 
Suppression de l'élément "Elément 4.4" 
Suppression de l'élément "Elément 4.3.4"
Suppression de l'élément "Elément 4.3.3"
Suppression de l'élément "Elément 4.3.2"
Suppression de l'élément "Elément 4.3.1"
Suppression de l'élément "Elément 4.3" 
Suppression de l'élément "Elément 4.2" 
Suppression de l'élément "Elément 4.1" 
Suppression de l'élément "Elément 4"
Suppression de l'élément "Elément 3"
Suppression de l'élément "Elément 2.1.2"
Suppression de l'élément "Elément 2.1.1"
Suppression de l'élément "Elément 2.2" 
Suppression de l'élément "Elément 2.1" 
Suppression de l'élément "Elément 2"
Suppression de l'élément "Elément 1"
Suppression de la racine "Racine"