sabato 25 gennaio 2020

Gestione Layout di default in liste ALV - Workaround.

Nelle liste di tipo ALV (acronimo di Abap List Viewer...ma viene bene anche come Advance List Viewer) l'utente può, in taluni casi (e vediamo sotto come possono essere pilotati), scegliere il layout da usare come default.

Questa impostazione però non vale per il solo suo utente, ma definisce il default valido per TUTTI gli utenti che lanciano il report. Non ho trovato il modo di definire un layout di visualizzazione in modo che sia default per alcuni utenti, mentre per altri no.

Questo è un workaround a cui ho pensato per poter bypassare il problema.


SAP dà la possibilità di salvare dei layout particolari, specifici dell'utente, i quali possono essere definiti di default per l'utente; l'attribuzione vale per il solo utente e "comanda" rispetto all'impostazione di default che vale per tutti.

Questo risolve, in parte, il problema di assegnazione con default che possono essere differenti. Con questa gestione si presentano però alcuni problemi di gestione:

Supponiamo di avere un report che ha 2 layout e 100 utenti che lo lanciano: se si vuole che i default siano differenti, ogni utente deve salvarsi la propria visualizzazione personale; inoltre, se c'è necessità di modificare un layout standard, la modifica deve essere replicata ad ogni utente che ha salvato la sua variante personale.

Piuttosto seccante ed è davvero un peccato che, a livello di utente, non si possa impostare un default che vale solo per l'utente stesso.

Vediamo intanto in che tabelle vengono memorizzati i dati relativi ai layout:

Tabelle

LTDX Archivio generico per variante di visualizzazione.



LTDXT Testi per varianti di visualizzazione.



LTDXD Varianti di visualizzazione default.



La mia idea è questa: salvare un layout personale, con un nome particolare, che se impostato di default per l'utente, allora richiama un layout standard. Poichè i nomi di quelli standard devono necessariamente iniziare con il carattere "/", allora pensavo di definire questa regola:

se il nome variante di default inizia con un carattere particolare (inizialmente volevo utilizzare un carattere speciale tipo "#", ma purtroppo non è possibile e, per i layout specifici utente, si devono utilizzare caratteri A-Z), per esempio "Y", allora si verifica se esiste la variante con / iniziale (sostituendo la Y) e si lancia la chiamata ALV usando quella visualizzazione.

Questo un semplice report ALV

*&---------------------------------------------------------------------*
*& Report Z_61
*&---------------------------------------------------------------------*
REPORT z_61.

TYPE-POOLS: slis.

DATA: report_id LIKE sy-repid.
DATA: i_sbook   LIKE sbook OCCURS 0.
DATA: i_layout  TYPE slis_layout_alv.

*----------------------------------------------------------------------*
* Inizio programma
*----------------------------------------------------------------------*
START-OF-SELECTION.

  SELECT * FROM sbook INTO TABLE i_sbook UP TO 200 ROWS.

  report_id = sy-repid.

  PERFORM f1000_layout_init CHANGING i_layout.

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program = report_id
      i_structure_name   = 'SBOOK'
      is_layout          = i_layout
      i_save             = 'A'
    TABLES
      t_outtab           = i_sbook.

FORM f1000_layout_init CHANGING i_layout TYPE slis_layout_alv.
  CLEAR i_layout.
  i_layout-colwidth_optimize = 'X'.
ENDFORM.

Dove ho definito questi layout standard:


variante /DATA


variante /IMPORTO


lo standard per tutti gli utenti è "/IMPORTO"

e questo layout personale:


Questa la modifica prima della chiamata che mostra l'output

* ----- Workaround per gestione Layout default per utente -----
  DATA: spec_layout TYPE disvariant,
        wa_variant  LIKE spec_layout-variant.

  SELECT SINGLE VARIANT FROM LTDXD INTO wa_variant
                       WHERE REPORT = sy-repid
                         AND USERNAME = sy-uname
                         AND VARIANT > 'Y '
                         AND VARIANT < 'YZZZZZZZZZZZ'.
  IF sy-subrc = 0.
    wa_variant+0(1) = '/'.
    MOVE wa_variant TO spec_layout-variant.
    MOVE sy-repid   TO spec_layout-report.
* verifico se esiste variante standard
    CALL FUNCTION 'LVC_VARIANT_EXISTENCE_CHECK'
      CHANGING
        cs_variant    = spec_layout
      EXCEPTIONS
        wrong_input   = 1
        not_found     = 2
        program_error = 3
        OTHERS        = 4.
    IF sy-subrc <> 0.
      CLEAR spec_layout.
    ENDIF.
  ENDIF.
* ----- FINE Workaround ---------------------------------------

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program = report_id
      i_structure_name   = 'SBOOK'
      is_layout          = i_layout
      i_save             = 'A'
      is_variant         = spec_layout
    TABLES
      t_outtab           = i_sbook.

nella chiamata ho aggiunto la riga evidenziata in giallo.

Quando l'utente lancia il report viene mostrato l'output utilizzando il layout standard /DATA.

Questo risolve la seconda parte del problema, cioè dà la possibilità all'utente di salvare una variante personale che però serve solo come riferimento per caricare un'altra variante standard.

Si potrebbe includere il codice in un FM in modo che sia semplice la chiamata.

L'attivazione o meno della possibilità di salvare varianti standard o varianti personali è controllata tramite questo parametro di chiamata del FM:

      i_save             = 'A'

' ' : l'utente può modificare la variante ma non ha la possibilità di salvare.
'U' : l'utente può modificare la variante ma può salvare solo varianti personali.
'X' : l'utente può modificare la variante ma può salvare solo varianti standard.
'A' : l'utente può modificare la variante e può salvare varianti standard e anche personali.

Nota: il controllo sull'iniziale del nome delle varianti personali è hardcoded nel metodo CHECK_INPUT_VARIANT della classe CL_ALV_CUL_LAYOUT_SAVE_AS:

* user specific layout shall be saved
  if s_screen-user_specific = abap_true.
*    data: ls_variant type disvariant.
*    move-corresponding s_screen to ls_variant.
*    r_okcode = R_LAYOUT_EDITOR->get_layout_handler( )->is_variant_name_valid( ls_variant ).
*    if r_okcode eq abap_false.
    if me->s_screen-variant(1) ca 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
      s_screen-username = sy-uname.
      r_okcode = abap_true.
    else.
      message i054(0k).
    endif.
    return.
  endif.

Se si volesse gestire il carattere "#" si deve modificare lo standard; ho provato via debug a salvare una variante personale che inizia con "#" e non ho avuto particolari problemi di gestione.

Nessun commento:

Posta un commento