Cerca nel blog

giovedì 19 dicembre 2024

Funzionalità MESH

Funzionalità MESH


Spesso ci capita di lavorare con complesse relazioni tra tabelle, ad esempio: BKPF->BSEG->LFA1->LFBK. Spesso, ci affidiamo a cicli nidificati e condizioni di chiave ripetitive durante la lettura della tabella di intestazione/elemento per gestire tali relazioni. Ma c'è un modo migliore chiamato Mesh.

La mesh è fondamentalmente una struttura complessa che consente di recuperare record dipendenti da più tabelle.

Una Mesh separa la definizione di una relazione dal suo utilizzo: se ad esempio un record di elemento ha un campo "parent_key" che contiene la chiave del suo record di intestazione, questo viene definito solo una volta all'interno della Mesh. Senza una Mesh, questa informazione viene ripetuta in ogni LOOP in cui iteriamo sugli elementi di un'intestazione e in ogni READ TABLE in cui leggiamo l'intestazione di un elemento. Se c'è una modifica nel modello di dati, nel migliore dei casi solo la definizione di Mesh deve essere modificata ma non tutti i LOOP e le READ TABLE.

Come componenti di questo tipo di struttura sono consentite solo tabelle interne e riferimenti a tabelle interne. Nel contesto Mesh, queste tabelle interne sono chiamate "nodi", ma sono comunque solo tabelle interne e, oltre alle speciali operazioni Mesh che vedremo nelle prossime sezioni, possiamo fare qualsiasi cosa con loro come possiamo fare con una tabella interna dichiarata all'esterno di una Mesh.

Associazioni inverse

Per ogni associazione definita nella Mesh, il runtime genera automaticamente l'associazione inversa, ovvero scambia il nodo sorgente e quello di destinazione e di conseguenza l'ordine dei campi nella condizione di relazione. Tale associazione "specchiata" ha lo stesso nome dell'originale, ma "^" come prefisso e "~" seguito dal nuovo nodo di destinazione (il nodo sorgente originale) come suffisso.

Esempio

REPORT zprova_mesh.

TYPEStt_bkpf_2 TYPE HASHED TABLE OF bkpf WITH UNIQUE KEY  bukrs belnr gjahr,
       tt_bseg_2 TYPE HASHED TABLE OF bseg WITH UNIQUE KEY  bukrs belnr 
                                                            gjahr buzei,
       tt_lfa1_2 TYPE HASHED TABLE OF lfa1 WITH UNIQUE KEY  lifnr,

       BEGIN OF MESH ty_mesh,
         bkpf TYPE tt_bkpf_2 ASSOCIATION _bseg TO bseg ON bukrs bukrs
                                                    AND belnr belnr
                                                    AND gjahr gjahr,
         bseg TYPE tt_bseg_2 ASSOCIATION _bkpf TO bkpf ON bukrs bukrs
                                                    AND belnr belnr
                                                    AND gjahr gjahr
                           ASSOCIATION _lfa1 TO lfa1 ON lifnr lifnr,
         lfa1 TYPE tt_lfa1_2 ASSOCIATION _bseg TO bseg ON lifnr lifnr,
       END OF MESH ty_mesh.


PARAMETERSp_vendor TYPE lifnr OBLIGATORY.

START-OF-SELECTION.
  SELECT *
    FROM lfa1
    INTO TABLE @DATA(gt_lfa1)
    WHERE lifnr @p_vendor.

  SELECT *
    INTO TABLE @DATA(gt_bseg)
    FROM bseg
    FOR ALL ENTRIES IN @gt_lfa1
    WHERE lifnr @gt_lfa1-lifnr.

  SELECT *
    INTO TABLE @DATA(gt_bkpf)
    FROM bkpf
    FOR ALL ENTRIES IN @gt_bseg
    WHERE bukrs @gt_bseg-bukrs
      AND belnr @gt_bseg-belnr
      AND gjahr @gt_bseg-gjahr.


  DATA(lt_meshVALUE ty_mesh(
          bkpf VALUE #FOR ls_bkpf IN gt_bkpf
                        bukrs     ls_bkpf-bukrs
                          belnr     ls_bkpf-belnr
                          gjahr     ls_bkpf-gjahr
                        )
                       )

          bseg VALUE #FOR ls_bseg IN gt_bseg
                        bukrs     ls_bseg-bukrs
                          belnr     ls_bseg-belnr
                          gjahr     ls_bseg-gjahr
                          buzei     ls_bseg-buzei
                          lifnr     ls_bseg-lifnr
                        )
                       )

          lfa1 VALUE #FOR ls_lfa1 IN gt_lfa1
                        lifnr     ls_lfa1-lifnr
                          name1     ls_lfa1-name1
                          name2     ls_lfa1-name2
                          name3     ls_lfa1-name3
                          name4     ls_lfa1-name4
                        )
                       )
  ).


* Stampiamo i dati della BSEG
  WRITE' Dati della BSEG '.
  WRITE' --------------- '.
  LOOP AT lt_mesh-lfa1\_bseg[ lt_mesh-lfa1[ lifnr p_vendor ] ] 
        ASSIGNING FIELD-SYMBOL(<lfs_bseg>).
    WRITE/ <lfs_bseg>-bukrs<lfs_bseg>-belnr
             <lfs_bseg>-gjahr<lfs_bseg>-buzei<lfs_bseg>-lifnr.
  ENDLOOP.

* Stampiamo i dati della BKPF
  WRITE' Dati della BKPF '.
  WRITE' --------------- '.
  LOOP AT lt_mesh-lfa1\_bseg[ lt_mesh-lfa1[ 
lifnr p_vendor ] ]\_bkpf[ ] 
        ASSIGNING FIELD-SYMBOL(<lfs_bkpf>).
    WRITE/ <lfs_bkpf>-bukrs<lfs_bkpf>-belnr<lfs_bkpf>-gjahr.
  ENDLOOP.

* Stampiamo i dati della BSEG
  WRITE' Dati della BSEG con Associazione '.
  WRITE' --------------- '.
  LOOP AT lt_mesh-lfa1\^_lfa1~bseg[ lt_mesh-lfa1[ lifnr p_vendor ] ] 
          ASSIGNING FIELD-SYMBOL(<lfs_bseg2>).
    WRITE/ <lfs_bseg2>-bukrs<lfs_bseg2>-belnr
             <lfs_bseg2>-gjahr<lfs_bseg2>-buzei<lfs_bseg2>-lifnr.
  ENDLOOP.

* Stampiamo i dati della BKPF
  WRITE' Dati della BKPF con Associazione '.
  WRITE' --------------- '.
LOOP AT lt_mesh-lfa1\^_lfa1~bseg[ lt_mesh-lfa1[ lifnr p_vendor ] ]\^_bseg~bkpf[ ]
        ASSIGNING FIELD-SYMBOL(<lfs_BKPF2>).
    WRITE/ <lfs_BKPF2>-bukrs<lfs_BKPF2>-belnr<lfs_BKPF2>-gjahr.
  ENDLOOP.

END-OF-SELECTION.



Eseguendo il report: