/* POPUP INI */
/* POPUP FIM */

Conteúdo

ALV com Layout informado na tela de parâmetros

Basicamente você escolhe o layout do relatório já na tela de parâmetros.

Para isto é necessário que antes você tenha gravado um layout, claro!


REPORT ZSAPeiros.
* Global Declarations
DATA:
  gs_key      TYPE salv_s_layout_key,
  gs_layouts  TYPE salv_s_layout_info,
  gs_layout   TYPE lvc_s_layo,
  gt_saida    TYPE TABLE OF mara,
  gt_fieldcat TYPE lvc_t_fcat,
  gs_variant  TYPE disvariant.

* Parameters
PARAMETERS p_layout TYPE slis_vari.

* Action for Layout parameter field
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_layout.
  gs_key-report = sy-repid.
  gs_layouts    = cl_salv_layout_service=>f4_layouts( s_key = gs_key
                                                      restrict = '1' ).
  p_layout      = gs_layouts-layout.

START-OF-SELECTION.
* Populate Data Report
  SELECT * UP TO 10 ROWS FROM mara INTO TABLE gt_saida.

  IF sy-subrc IS INITIAL.
    SORT gt_saida BY matnr.
  ENDIF.

* Layout
  gs_layout-col_opt    = abap_true.
  gs_layout-zebra      = abap_true.

* Layout Variant
  gs_variant-report    = sy-repid.
  gs_variant-variant   = p_layout.

* Get fields from structure/table
  CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
    EXPORTING
      i_structure_name       = 'MARA'
      i_client_never_display = abap_true
    CHANGING
      ct_fieldcat            = gt_fieldcat
    EXCEPTIONS
      inconsistent_interface = 1
      program_error          = 2
      OTHERS                 = 3.

* Display ALV Report Data
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
    EXPORTING
      i_callback_program = sy-repid
      is_layout_lvc      = gs_layout
      it_fieldcat_lvc    = gt_fieldcat
      i_save             = abap_true
      is_variant         = gs_variant
    TABLES
      t_outtab           = gt_saida[]
    EXCEPTIONS
      program_error      = 1
      OTHERS             = 2.

  IF sy-subrc IS NOT INITIAL.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

Função onde você passa uma tabela e ela retorna um ALV lindão, inclusive com opção de ser em POPUP


Então bate aquele momento que você volta a brincar com classes e métodos, então lembra que o mundo é perfeito, que desenvolvedores são os caras, e que OO não são dois olhinhos esbugalhados.

Bem-vindo à Orientação a Objetos.

Esta função basta você passar como parâmetro uma tabela populada, dados de posicionamento/popup se quiser, e então ela retorna um ALV bunitinho já formatado, inclusive se for TYPE Standard, com campos chave, etc. Sendo assim, um exemplo prático para padronizar relatórios.

FUNCTION ZF_SAPeiros.
*"----------------------------------------------------------------------
*"*"Interface local:
*"  IMPORTING
*"     REFERENCE(I_INI_COLUNA) TYPE I    OPTIONAL
*"     REFERENCE(I_FIM_COLUNA) TYPE I    OPTIONAL
*"     REFERENCE(I_INI_LINHA)  TYPE I    OPTIONAL
*"     REFERENCE(I_FIM_LINHA)  TYPE I    OPTIONAL
*"     REFERENCE(I_POPUP)      TYPE FLAG OPTIONAL
*"  TABLES
*"      T_TABELA               TYPE STANDARD TABLE
*"----------------------------------------------------------------------
* EXEMPLO DE COMO CHAMÁ-LA:
*"----------------------------------------------------------------------
*TYPES:
*  BEGIN OF ty_mara,
*    matnr TYPE mara-matnr,
*    END OF ty_mara.
*
*SELECT matnr
*  UP TO 10 ROWS
*  FROM mara
*  INTO TABLE t_mara.
*
*sy-title = 'SAPeiros: Registros da tabela MARA'.
*
*CALL FUNCTION 'ZF_ALV_SIMPLES'
*  EXPORTING
*    i_ini_coluna = 1          "Início da coluna
*    i_fim_coluna = 100        "Fim da coluna
*    i_ini_linha  = 1          "Início da linha
*    i_fim_linha  = 10         "Fim da linha
*    i_popup      = abap_true  "Exibir como popup
*  TABLES
*    t_tabela     = t_mara.    "Tabela a ser exibida
*=======================================================================
* Classes locais
  DATA:
    cl_alv        TYPE REF TO cl_salv_table,          "ALV
    cl_functions  TYPE REF TO cl_salv_functions_list. "Funções do ALV

* Instancia o ALV com dados enviados para T_TABELA
  TRY.

      cl_salv_table=>factory(
        IMPORTING
          r_salv_table = cl_alv
        CHANGING
          t_table      = t_tabela[] ).

    CATCH cx_salv_msg.

  ENDTRY.

* Recupera e habilita todas as funções do ALV
  cl_functions = cl_alv->get_functions( ).
  cl_functions->set_all( abap_true ).

* Verifica se o ALV foi criado com sucesso
  IF cl_alv IS BOUND.

* Se Popup marcado, seta para exibir em modo popup
    IF i_popup EQ abap_true.

      cl_alv->set_screen_popup(
        start_column = i_ini_coluna
        end_column   = i_fim_coluna
        start_line   = i_ini_linha
        end_line     = i_fim_linha ).

    ENDIF.

* Exibe Relatório ALV
    cl_alv->display( ).

  ENDIF.
ENDFUNCTION.

ALV Simplão com hotspot que chama a VA02


ALV que lista os documentos da VBAK, e ao clicar no documento, você é direcionado para VA02.
REPORT ZSAPeiros.

* DEFINIÇÃO DE TIPOS ---------------------------------------------------
TYPES:
  BEGIN OF ty_relatorio,
    vbeln         TYPE          vbak-vbeln,         "Documento de vendas
    erdat         TYPE          vbak-erdat,         "Data criação
    END OF ty_relatorio.


* TABELAS/ESTRUTURAS INTERNAS ------------------------------------------
DATA:
  t_fieldcat      TYPE          slis_t_fieldcat_alv,"Fieldcat alv grid
  w_fieldcat      TYPE          slis_fieldcat_alv,  "Fieldcat alv grid
  w_layout        TYPE          slis_layout_alv,    "Layout alv grid
  t_relatorio     TYPE TABLE OF ty_relatorio,       "Relatório
  w_relatorio     TYPE          ty_relatorio.       "Relatório


* PARÂMETROS -----------------------------------------------------------
* Parâmetros de Seleção
SELECTION-SCREEN: BEGIN OF BLOCK b01 WITH FRAME TITLE text-t01.
SELECT-OPTIONS:
  s_vbeln         FOR  w_relatorio-vbeln OBLIGATORY.
SELECTION-SCREEN: END OF BLOCK b01.


* INICIAR OBJETOS ------------------------------------------------------
INITIALIZATION.
  sy-title = 'SAPeiros: ALV Hotspot pf-status'.
  %_s_vbeln_%_app_%-text = 'Documento de vendas'.


* SELEÇÃO DOS DADOS ----------------------------------------------------
START-OF-SELECTION.
* Seleção dos Dados
  PERFORM f_seleciona.


* PROCESSAMENTO DOS DADOS ----------------------------------------------
END-OF-SELECTION.
* Monta estrutura e layout do relatório
  CHECK t_relatorio[] IS NOT INITIAL.
  PERFORM zf_estrutura_layout.

* Exibe relatório com dados selecionados
  PERFORM f_relatorio.


* FORMS ----------------------------------------------------------------
* ----------------------------------------------------------------------
* Seleção dos Dados
* ----------------------------------------------------------------------
FORM f_seleciona.
  SELECT vbeln erdat
    FROM vbak
    INTO TABLE t_relatorio
   WHERE vbeln IN s_vbeln.

  IF sy-subrc IS INITIAL.
    SORT t_relatorio BY vbeln.
  ENDIF.
ENDFORM.                    "f_seleciona


*-----------------------------------------------------------------------
* Monta layout e estrutura de campos do relatório
*-----------------------------------------------------------------------
FORM zf_estrutura_layout.
* Layout
  CLEAR w_layout.
  w_layout-zebra             = abap_true.

* Campos do relatório
  CLEAR t_fieldcat[].

  w_fieldcat-tabname        = 'T_RELATORIO'.
  w_fieldcat-fieldname      = 'VBELN'.
  w_fieldcat-ref_tabname    = 'VBAK'.
  w_fieldcat-ref_fieldname  = 'VBELN'.
  w_fieldcat-hotspot        = abap_true.
  w_fieldcat-emphasize      = abap_true.
  w_fieldcat-outputlen      = 14.
  APPEND w_fieldcat TO t_fieldcat.
  CLEAR w_fieldcat.

  w_fieldcat-tabname        = 'T_RELATORIO'.
  w_fieldcat-fieldname      = 'ERDAT'.
  w_fieldcat-ref_tabname    = 'VBAK'.
  w_fieldcat-ref_fieldname  = 'ERDAT'.
  w_fieldcat-outputlen      = 10.
  APPEND w_fieldcat TO t_fieldcat.
  CLEAR w_fieldcat.
ENDFORM.                    "zf_estrutura_layout


*-----------------------------------------------------------------------
* Exibe relatório com dados selecionados
*-----------------------------------------------------------------------
FORM f_relatorio.
  sy-title = 'SAPeiros: ALV Hotspot pf-status'.

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program      = sy-repid
      is_layout               = w_layout
      it_fieldcat             = t_fieldcat
      i_callback_user_command = 'USER_COMMAND_ALV'
    TABLES
      t_outtab                = t_relatorio
    EXCEPTIONS
      program_error           = 1
      OTHERS                  = 2.

  IF sy-subrc IS NOT INITIAL.

    MESSAGE ID sy-msgid
          TYPE sy-msgty
        NUMBER sy-msgno
          WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

  ENDIF.
ENDFORM.                    "f_relatorio


*-----------------------------------------------------------------------
* Ações do ALV
*-----------------------------------------------------------------------
FORM user_command_alv USING u_ucomm       TYPE sy-ucomm
                            us_self_field TYPE slis_selfield.
  IF u_ucomm EQ '&IC1'.

    IF us_self_field-fieldname EQ 'VBELN'.

      READ TABLE t_relatorio
            INTO w_relatorio
           INDEX us_self_field-tabindex.

      IF sy-subrc IS INITIAL.

        SET PARAMETER ID 'AUN' FIELD w_relatorio-vbeln.
        CALL TRANSACTION 'VA02' AND SKIP FIRST SCREEN.

      ENDIF.

    ENDIF.

  ENDIF.
ENDFORM.                    "user_command_alv

ALV TOP-OF-PAGE - Deixando seu relatório mais elegante

Uma das características do REUSE_ALV_GRID_DISPLAY é ter a possibilidade de colocar imagens e informações diversas em seu cabeçalho. Podendo ser feito com TOP-OF-PAGE e HTML-TOP-OF-PAGE.

Cada um possui sua característica, porém detalhes de cor, tabulações, etc, você terá mais opções com HTML-TOP-OF-PAGE.

--- TOP-OF-PAGE ---

--- HTML-TOP-OF-PAGE ---


REPORT ZSAPeiros.

TYPES:
   BEGIN OF ty_saida,
     campo1(4)  TYPE c,
     campo2(6)  TYPE p DECIMALS 3,
     color(4)   TYPE c,
   END OF ty_saida.

TYPE-POOLS:
   slis.

DATA:
  gt_saida      TYPE TABLE OF ty_saida,
  wa_saida      TYPE          ty_saida,
  gt_fieldcat   TYPE TABLE OF slis_fieldcat_alv,
  wa_fieldcat   TYPE          slis_fieldcat_alv,
  wa_layout     TYPE          slis_layout_alv.


PARAMETERS:
  p_top_1       RADIOBUTTON GROUP r1,
  p_top_2       RADIOBUTTON GROUP r1.


INITIALIZATION.
  sy-title = 'SAPeiros: ALV TOP-OF-PAGE'.
  %_p_top_1_%_app_%-text = 'TOP-OF-PAGE'.
  %_p_top_2_%_app_%-text = 'HTML-TOP-OF-PAGE'.


START-OF-SELECTION.
* Seleção dos dados
  PERFORM frm_select_data.


END-OF-SELECTION.
  sy-title = 'SAPeiros: ALV TOP-OF-PAGE'.

* Monta estrutura do relatório
  PERFORM frm_alv_fieldcat.

* Define detalhes no layout do relatório
  PERFORM frm_alv_layout.

* Exibe o relatório
  PERFORM frm_alv_show.


*---------------------------------------------------------------------*
* Seleção dos dados
*---------------------------------------------------------------------*
FORM frm_select_data.
  wa_saida-campo1 = '1'.
  wa_saida-campo2 = '8'.
  APPEND wa_saida TO gt_saida.

  wa_saida-campo1 = '2'.
  wa_saida-campo2 = '-73'.
  APPEND wa_saida TO gt_saida.

  wa_saida-campo1 = '3'.
  wa_saida-campo2 = '20'.
  APPEND wa_saida TO gt_saida.

  wa_saida-campo1 = '4'.
  wa_saida-campo2 = '50'.
  APPEND wa_saida TO gt_saida.

  wa_saida-campo1 = '5'.
  wa_saida-campo2 = '-55'.
  APPEND wa_saida TO gt_saida.

  wa_saida-campo1 = '6'.
  wa_saida-campo2 = '90'.
  APPEND wa_saida TO gt_saida.

  wa_saida-campo1 = '7'.
  wa_saida-campo2 = '100'.
  APPEND wa_saida TO gt_saida.

* Atualiza cores das linhas
  LOOP AT gt_saida INTO wa_saida.

    IF wa_saida-campo2 < 0.
      wa_saida-color = 'C610'. "Vermelho
    ELSEIF wa_saida-campo2 > 0 AND wa_saida-campo2 < 50.
      wa_saida-color = 'C310'. "Amarelo
    ELSEIF wa_saida-campo2 >= 50.
      wa_saida-color = 'C510'. "Azul
    ENDIF.

    MODIFY gt_saida FROM wa_saida INDEX sy-tabix.

  ENDLOOP.
ENDFORM.                    "frm_select_data


*---------------------------------------------------------------------*
* Monta estrutura do relatório
*---------------------------------------------------------------------*
FORM frm_alv_fieldcat.
  CLEAR wa_fieldcat.
  wa_fieldcat-fieldname = 'CAMPO1'.
  wa_fieldcat-seltext_m = 'Campo 1'.
  wa_fieldcat-tabname   = 'GT_SAIDA'.
  APPEND wa_fieldcat TO gt_fieldcat.

  CLEAR wa_fieldcat.
  wa_fieldcat-fieldname = 'CAMPO2'.
  wa_fieldcat-seltext_m = 'Campo 2'.
  wa_fieldcat-tabname   = 'GT_SAIDA'.
  APPEND wa_fieldcat TO gt_fieldcat.
ENDFORM.                    "frm_alv_fieldcat


*---------------------------------------------------------------------*
* Define detalhes no layout do relatório
*---------------------------------------------------------------------*
FORM frm_alv_layout.
  wa_layout-expand_all        = 'X'.
  wa_layout-colwidth_optimize = 'X'.
  wa_layout-zebra             = 'X'.
  wa_layout-info_fieldname    = 'COLOR'.
ENDFORM.                    "frm_alv_layout


*---------------------------------------------------------------------*
* Exibe o relatório
*---------------------------------------------------------------------*
FORM frm_alv_show.
  DATA:
    lv_repid      TYPE sy-repid.              "Nome do Programa

  lv_repid = sy-repid.

  IF p_top_1 = abap_true.

    CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
      EXPORTING
        i_callback_program     = lv_repid
        i_callback_top_of_page = 'TOP_OF_PAGE'
        is_layout              = wa_layout
        it_fieldcat            = gt_fieldcat[]
      TABLES
        t_outtab               = gt_saida
      EXCEPTIONS
        program_error          = 1
        OTHERS                 = 2.

  ELSE.

    CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
      EXPORTING
        i_callback_program          = lv_repid
        i_callback_html_top_of_page = 'HTML_TOP_OF_PAGE'
        is_layout                   = wa_layout
        it_fieldcat                 = gt_fieldcat[]
      TABLES
        t_outtab                    = gt_saida
      EXCEPTIONS
        program_error               = 1
        OTHERS                      = 2.

  ENDIF.

  IF sy-subrc <> 0.
    LEAVE LIST-PROCESSING.
  ENDIF.
ENDFORM.                    "frm_alv_show


* TOPO standard
FORM top_of_page.
* Declarações locais
  DATA:
    gt_header     TYPE slis_t_listheader,     "H = Header, S = Selection, A = Action
    wa_header     TYPE slis_listheader,       "H = Header, S = Selection, A = Action
    lv_texto      TYPE slis_listheader-info,  "Texto
    lv_linesc(10) TYPE c.                     "Qtd registros

* Título
  wa_header-typ  = 'H'.
  wa_header-info = 'Relatório de linhas coloridas'.
  APPEND wa_header TO gt_header.
  CLEAR wa_header.

* Usuário
  wa_header-typ  = 'S'.
  wa_header-key  = 'Usuário:'.
  wa_header-info = sy-uname.
  APPEND wa_header TO gt_header.
  CLEAR wa_header.

* Data
  wa_header-typ  = 'S'.
  wa_header-key  = 'Data:'.
  WRITE sy-datum TO wa_header-info DD/MM/YYYY.
  APPEND wa_header TO gt_header.
  CLEAR wa_header.

* Hora
  wa_header-typ  = 'S'.
  wa_header-key  = 'Hora:'.
  wa_header-info = sy-uzeit.
  APPEND wa_header TO gt_header.
  CLEAR wa_header.

* Número de registros
  DESCRIBE TABLE gt_saida LINES lv_linesc.
  CONCATENATE 'Registros:'
              lv_linesc
         INTO lv_texto
              SEPARATED BY space.
  wa_header-typ  = 'A'.
  wa_header-info = lv_texto.
  APPEND wa_header TO gt_header.
  CLEAR wa_header.

* Imprime o cabeçalho
  CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
    EXPORTING
      it_list_commentary = gt_header
      i_logo             = 'ENJOYSAP_LOGO'.
ENDFORM.                    "top_of_page


* TOPO formato HTML
FORM html_top_of_page USING document TYPE REF TO cl_dd_document.
* Declarações locais
  DATA:
    lv_text(255)  TYPE c,                     "Texto
    lv_linesc(10) TYPE c.                     "Qtd registros

* Título
  CALL METHOD document->add_text
    EXPORTING
      text      = 'Relatório de linhas coloridas'
      sap_style = 'heading'.

* Distância da imagem
  CALL METHOD document->add_gap
    EXPORTING
      width = 150.

* Imagem
  CALL METHOD document->add_picture
    EXPORTING
      picture_id = 'ENJOYSAP_LOGO'.

* Linha horizontal
  CALL METHOD document->new_line( ).

  lv_text(185) = sy-uline.

  CALL METHOD document->add_text
    EXPORTING
      text = lv_text.

* Usuário
  CALL METHOD document->new_line( ).

  CALL METHOD document->add_text
    EXPORTING
      text         = 'Usuário:'
      sap_color    = cl_dd_area=>list_heading_inv
      sap_emphasis = cl_dd_area=>strong.

  CALL METHOD document->add_gap
    EXPORTING
      width = 2.

  WRITE sy-uname TO lv_text.

  CALL METHOD document->add_text
    EXPORTING
      text = lv_text.

* Data
  CALL METHOD document->new_line( ).

  CALL METHOD document->add_text
    EXPORTING
      text         = 'Data:'
      sap_color    = cl_dd_area=>list_heading_inv
      sap_emphasis = cl_dd_area=>strong.

  CALL METHOD document->add_gap
    EXPORTING
      width = 6.

  WRITE sy-datum TO lv_text DD/MM/YYYY.

  CALL METHOD document->add_text
    EXPORTING
      text = lv_text.

* Hora
  CALL METHOD document->new_line( ).

  CALL METHOD document->add_text
    EXPORTING
      text         = 'Hora:'
      sap_color    = cl_dd_area=>list_heading_inv
      sap_emphasis = cl_dd_area=>strong.

  CALL METHOD document->add_gap
    EXPORTING
      width = 6.

  WRITE sy-uzeit TO lv_text.

  CALL METHOD document->add_text
    EXPORTING
      text = lv_text.

* Número de registros
  CALL METHOD document->new_line( ).

  DESCRIBE TABLE gt_saida LINES lv_linesc.

  CALL METHOD document->add_text
    EXPORTING
      text         = 'Registros:'
      sap_color    = cl_dd_area=>list_heading_inv
      sap_emphasis = cl_dd_area=>strong.

  CALL METHOD document->add_gap
    EXPORTING
      width = 0.

  lv_text = lv_linesc.

  CALL METHOD document->add_text
    EXPORTING
      text = lv_text.
ENDFORM.                    "html_top_of_page

ALV com linhas coloridas

ALV é o relatório mais comum da SAP, e possui vários tipos. O exemplo abaixo é um ALV simples onde as linhas mudam de cor de acordo com sua necessidade.
Ótimo para ressaltar dados importantes.

---Exemplo---

REPORT ZSAPeiros.

TYPES:
   BEGIN OF ty_saida,
     campo1(4)  TYPE c,
     campo2(6)  TYPE p DECIMALS 3,
     color(4)   TYPE c,
   END OF ty_saida.

TYPE-POOLS:
   slis.

DATA:
  gt_saida      TYPE TABLE OF ty_saida,
  wa_saida      TYPE          ty_saida,
  gt_fieldcat   TYPE TABLE OF slis_fieldcat_alv,
  wa_fieldcat   TYPE          slis_fieldcat_alv,
  wa_layout     TYPE          slis_layout_alv.

* Seleção dos dados
PERFORM frm_select_data.

* Monta estrutura do relatório
PERFORM frm_alv_fieldcat.

* Define detalhes no layout do relatório
PERFORM frm_alv_layout.

* Exibe o relatório
PERFORM frm_alv_show.


*---------------------------------------------------------------------*
* Seleção dos dados
*---------------------------------------------------------------------*
FORM frm_select_data.
  wa_saida-campo1 = '1'.
  wa_saida-campo2 = '8'.
  APPEND wa_saida TO gt_saida.

  wa_saida-campo1 = '2'.
  wa_saida-campo2 = '-73'.
  APPEND wa_saida TO gt_saida.

  wa_saida-campo1 = '3'.
  wa_saida-campo2 = '20'.
  APPEND wa_saida TO gt_saida.

  wa_saida-campo1 = '4'.
  wa_saida-campo2 = '50'.
  APPEND wa_saida TO gt_saida.

  wa_saida-campo1 = '5'.
  wa_saida-campo2 = '-55'.
  APPEND wa_saida TO gt_saida.

  wa_saida-campo1 = '6'.
  wa_saida-campo2 = '90'.
  APPEND wa_saida TO gt_saida.

  wa_saida-campo1 = '7'.
  wa_saida-campo2 = '100'.
  APPEND wa_saida TO gt_saida.

* Atualiza cores das linhas
  LOOP AT gt_saida INTO wa_saida.

    IF wa_saida-campo2 < 0.
      wa_saida-color = 'C610'. "Vermelho
    ELSEIF wa_saida-campo2 > 0 AND wa_saida-campo2 < 50.
      wa_saida-color = 'C310'. "Amarelo
    ELSEIF wa_saida-campo2 >= 50.
      wa_saida-color = 'C510'. "Azul
    ENDIF.

    MODIFY gt_saida FROM wa_saida INDEX sy-tabix.

  ENDLOOP.
ENDFORM.                    "frm_select_data


*---------------------------------------------------------------------*
* Monta estrutura do relatório
*---------------------------------------------------------------------*
FORM frm_alv_fieldcat.
  CLEAR wa_fieldcat.
  wa_fieldcat-fieldname = 'CAMPO1'.
  wa_fieldcat-seltext_m = 'Campo 1'.
  wa_fieldcat-tabname   = 'GT_SAIDA'.
  APPEND wa_fieldcat TO gt_fieldcat.

  CLEAR wa_fieldcat.
  wa_fieldcat-fieldname = 'CAMPO2'.
  wa_fieldcat-seltext_m = 'Campo 2'.
  wa_fieldcat-tabname   = 'GT_SAIDA'.
  APPEND wa_fieldcat TO gt_fieldcat.
ENDFORM.                    "frm_alv_fieldcat


*---------------------------------------------------------------------*
* Define detalhes no layout do relatório
*---------------------------------------------------------------------*
FORM frm_alv_layout.
  wa_layout-expand_all        = 'X'.
  wa_layout-colwidth_optimize = 'X'.
  wa_layout-zebra             = 'X'.
  wa_layout-info_fieldname    = 'COLOR'.
ENDFORM.                    "frm_alv_layout


*---------------------------------------------------------------------*
* Exibe o relatório
*---------------------------------------------------------------------*
FORM frm_alv_show.
  DATA:
    lv_repid    TYPE sy-repid.

  lv_repid = sy-repid.

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program = lv_repid
      is_layout          = wa_layout
      it_fieldcat        = gt_fieldcat[]
    TABLES
      t_outtab           = gt_saida
    EXCEPTIONS
      program_error      = 1
      OTHERS             = 2.

  IF sy-subrc <> 0.
    LEAVE LIST-PROCESSING.
  ENDIF.
ENDFORM.                    "frm_alv_show

2 ou mais ALVs na mesma tela

Um exemplo simples de ALV Write onde é possível mostrar 2 ou mais relatórios na tela.
REPORT ZSAPeiros.

TYPE-POOLS: slis.

TYPES:
* Estrutura de campos do ALV1
  BEGIN OF ty_alv1,
    carrid TYPE sflight-carrid,                   "Campo 1
    connid TYPE sflight-connid,                   "Campo 2
    END OF ty_alv1,

* Estrutura de campos do ALV2
  BEGIN OF ty_alv2,
    carrid TYPE sflight-carrid,                   "Campo 1
    END OF ty_alv2.

* Tabelas e estruturas globais
DATA:
  gt_fieldcat1 TYPE          slis_t_fieldcat_alv WITH HEADER LINE, "Alv campos
  gt_fieldcat2 TYPE          slis_t_fieldcat_alv WITH HEADER LINE, "Alv campos
  gt_events    TYPE          slis_alv_event OCCURS 0, "Alv eventos
  gt_alv1      TYPE TABLE OF ty_alv1 INITIAL SIZE 0,  "Alv 1
  gt_alv2      TYPE TABLE OF ty_alv2 INITIAL SIZE 0,  "Alv 2
  wa_layout    TYPE          slis_layout_alv.         "Alv layout

* Variáveis globais
DATA:
  gv_repid   TYPE sy-repid,                       "Programa
  gv_alv(30) TYPE c.                              "Alv


* Seleciona dados
PERFORM p_seleciona_dados.

* Define layout de tela
PERFORM p_layout.

* Monta campos do Alv 1
PERFORM p_fieldcat1.

* Monta campos do Alv 2
PERFORM p_fieldcat2.

* Mescla e visualiza relatório
PERFORM p_ver_relatorio.


*---------------------------------------------------------------------*
* Seleciona dados
*---------------------------------------------------------------------*
FORM p_seleciona_dados.
  SELECT carrid connid FROM sflight
    INTO TABLE gt_alv1
   UP TO 10 ROWS.

  IF sy-subrc IS NOT INITIAL.
    CLEAR gt_alv1[].
  ENDIF.

  SELECT carrid FROM sflight
    INTO TABLE gt_alv2
   UP TO 10 ROWS.

  IF sy-subrc IS NOT INITIAL.
    CLEAR gt_alv2[].
  ENDIF.
ENDFORM.                    "p_seleciona_dados


*---------------------------------------------------------------------*
* Define layout de tela
*---------------------------------------------------------------------*
FORM p_layout.
  wa_layout-colwidth_optimize = 'X'.
ENDFORM.                    "p_layout


*---------------------------------------------------------------------*
* Monta campos do Alv 1
*---------------------------------------------------------------------*
FORM p_fieldcat1.
  CLEAR gt_fieldcat1.
  gt_fieldcat1-seltext_l = 'CARRID'.
  gt_fieldcat1-row_pos = 0.
  gt_fieldcat1-col_pos = 1.
  gt_fieldcat1-fieldname = 'CARRID'.
  APPEND gt_fieldcat1.

  CLEAR gt_fieldcat1.
  gt_fieldcat1-seltext_l = 'CONNID'.
  gt_fieldcat1-row_pos = 0.
  gt_fieldcat1-col_pos = 1.
  gt_fieldcat1-fieldname = 'CONNID'.
  APPEND gt_fieldcat1.
ENDFORM.                    "p_fieldcat1


*---------------------------------------------------------------------*
* Monta campos do Alv 2
*---------------------------------------------------------------------*
FORM p_fieldcat2.
  CLEAR gt_fieldcat2.
  gt_fieldcat2-seltext_l = 'CARRID'.
  gt_fieldcat2-row_pos = 0.
  gt_fieldcat2-col_pos = 1.
  gt_fieldcat2-fieldname = 'CARRID'.
  APPEND gt_fieldcat2.
ENDFORM.                    "p_fieldcat2


*---------------------------------------------------------------------*
* Mescla e visualiza relatório
*---------------------------------------------------------------------*
FORM p_ver_relatorio.

  gv_repid = sy-repid.

  CALL FUNCTION 'REUSE_ALV_BLOCK_LIST_INIT'
    EXPORTING
      i_callback_program = gv_repid.

  gv_alv = 'GT_ALV1'.
  CALL FUNCTION 'REUSE_ALV_BLOCK_LIST_APPEND'
    EXPORTING
      is_layout                  = wa_layout
      it_fieldcat                = gt_fieldcat1[]
      i_tabname                  = gv_alv
      it_events                  = gt_events
    TABLES
      t_outtab                   = gt_alv1
    EXCEPTIONS
      program_error              = 1
      maximum_of_appends_reached = 2.

  gv_alv = 'GT_ALV2'.
  CALL FUNCTION 'REUSE_ALV_BLOCK_LIST_APPEND'
    EXPORTING
      is_layout                  = wa_layout
      it_fieldcat                = gt_fieldcat2[]
      i_tabname                  = gv_alv
      it_events                  = gt_events
    TABLES
      t_outtab                   = gt_alv2
    EXCEPTIONS
      program_error              = 1
      maximum_of_appends_reached = 2.

  CALL FUNCTION 'REUSE_ALV_BLOCK_LIST_DISPLAY'.
ENDFORM.                    "p_ver_relatorio

ALV Tree / Hierárquico

ALV é o relatório mais comum da SAP, e possui vários tipos. Um deles é chamado de ALV TREE, onde é possível amarrar um item ao outro, e visualizar no formato de árvore, conforme abaixo.

---Exemplo---

REPORT ZSAPeiros.

************************************************************************************
* ICONES
************************************************************************************
INCLUDE <icon>.                                               " Ícones diversos


************************************************************************************
* TIPOS
************************************************************************************
TYPES:
* Tabela de saída
  BEGIN OF ty_relatorio,
    vbeln               TYPE lips-vbeln,
    posnr               TYPE lips-posnr,
    matnr               TYPE lips-matnr,
  END OF ty_relatorio,

* Tabela para localizar ítens na árvore
  BEGIN OF ty_indice,
    tabix               TYPE lvc_nkey,                  " Número da linha na tabela
    linha               TYPE lvc_nkey,                  " Número de linha na árvore
  END OF ty_indice.


************************************************************************************
* CONTAINERS
************************************************************************************
DATA:
  g_alv_tree            TYPE REF TO cl_gui_alv_tree,          " Objeto árvore ALV
  g_custom_container    TYPE REF TO cl_gui_custom_container.  " Objeto container


************************************************************************************
* TABELAS E SUAS ESTRUTURAS
************************************************************************************
DATA:
  t_lips                TYPE TABLE OF ty_relatorio,
  w_lips                TYPE          ty_relatorio,
  t_relatorio           TYPE TABLE OF ty_relatorio,
  t_relatorio_itens     TYPE TABLE OF ty_relatorio,
  w_relatorio           TYPE          ty_relatorio,
  ti_fieldcat           TYPE          lvc_t_fcat,
  wa_fieldcat           TYPE LINE OF  lvc_t_fcat,
  ti_relacao            TYPE TABLE OF ty_indice,
  wa_relacao            TYPE          ty_indice.


************************************************************************************
* CONSTANTES
************************************************************************************
CONSTANTS:  c_raiz  TYPE lvc_nkey VALUE ''.          " Diretório raiz.(árvore)


************************************************************************************
* TELA DE SELEÇÃO
************************************************************************************
SELECTION-SCREEN BEGIN OF BLOCK bl1.
SELECT-OPTIONS:
  p_vbeln FOR w_lips-vbeln OBLIGATORY.
SELECTION-SCREEN END OF BLOCK bl1.


************************************************************************************
* START-OF-SELECTION
************************************************************************************
START-OF-SELECTION.
* Seleção dos dados
  PERFORM f_seleciona_dados.

* Tela do ALV Hierarquico
  CALL SCREEN 0100. "Dê 2 cliques para criar a tela 0100 -> Foto 01
* Nesta tela, 0100, criar um Custon Control com o nome MAIN_CONTAINER -> Foto 02
* Após criar a tela e o container, vá para o código onde terá o PBO e PAI -> Foto 03


************************************************************************************
* FORMS
************************************************************************************
************************************************************************************
* SELEÇÃO DOS DADOS
************************************************************************************
FORM f_seleciona_dados.
  SELECT vbeln posnr matnr
    FROM lips
    INTO TABLE t_lips
   WHERE vbeln IN p_vbeln.

  LOOP AT t_lips INTO w_lips.
    w_relatorio-vbeln = w_lips-vbeln.
    w_relatorio-posnr = w_lips-posnr.
    w_relatorio-matnr = w_lips-matnr.
    APPEND w_relatorio TO t_relatorio.
    CLEAR w_relatorio.
  ENDLOOP.
ENDFORM.                    "f_seleciona_dados


************************************************************************************
* CAMPOS A SEREM VISUALIZADOS NO ALV
************************************************************************************
FORM build_fieldcatalog.
  wa_fieldcat-fieldname     = 'POSNR'.
  wa_fieldcat-coltext       = 'Item'.
  wa_fieldcat-ref_table     = 'LIPS'.
  wa_fieldcat-ref_field     = 'POSNR'.
  APPEND wa_fieldcat TO ti_fieldcat.
  CLEAR wa_fieldcat.
ENDFORM.                    "build_fieldcatalog


************************************************************************************
* DESCRIÇÃO CAMPO PRINCIPAL DO CABEÇALHO NA ÁRVORE DO ALV
************************************************************************************
FORM build_hierarchy_header CHANGING p_hierarchy_header TYPE treev_hhdr.
  p_hierarchy_header-heading = 'Fornecimento'.
  p_hierarchy_header-tooltip = 'Fornecimento / Material'.
ENDFORM.                    "build_hierarchy_header


************************************************************************************
* PBO OUTPUT
************************************************************************************
MODULE pbo OUTPUT.
* TELA DE BOTÕES
  SET PF-STATUS 'STATUS_1000'. 
* Dê 2 cliques no nome do pf-status para criar a tela 1000 -> Foto 04
* E onde você irá adicionar os botões EXIT BACK CANC -> Foto 05

* Verifica se já existe container criado então, evitando runtime error
  IF g_alv_tree IS INITIAL.
*   Cria container ALVTree
    PERFORM create_alvtree_container.
*   Cria objeto ALVTree dentro do container
    PERFORM create_object_in_container.
*   Cria controle ALVTree vazio
    PERFORM create_empty_alvtree_control.
*   Cria hierarquia do ALVTree
    PERFORM create_alvtree_hierarchy.
  ENDIF.

* Retorno de Erros possíveis
  CALL METHOD cl_gui_cfw=>flush.
ENDMODULE.                    "pbo OUTPUT


************************************************************************************
* PAI INPUT
************************************************************************************
MODULE pai INPUT.
  DATA: v_okcode TYPE sy-ucomm.
  CASE v_okcode.
    WHEN 'EXIT' OR 'BACK' OR 'CANC'.
*     Retorno de Erros possíveis e volta para tela inicial
      CALL METHOD cl_gui_cfw=>flush.
      LEAVE TO SCREEN 0.
    WHEN OTHERS.
*     Retorno de Erros possíveis e volta para tela inicial
      CALL METHOD cl_gui_cfw=>flush.
      LEAVE TO SCREEN 0.
  ENDCASE.
ENDMODULE.                    "pai INPUT


************************************************************************************
* CRIA O CUSTOM CONTAINER
************************************************************************************
FORM create_alvtree_container.
  CREATE OBJECT g_custom_container
    EXPORTING
      container_name              = 'MAIN_CONTAINER'
    EXCEPTIONS
      cntl_error                  = 1
      cntl_system_error           = 2
      create_error                = 3
      lifetime_error              = 4
      lifetime_dynpro_dynpro_link = 5.

  IF sy-subrc <> 0.
  ENDIF.
ENDFORM.                    "create_alvtree_container


************************************************************************************
* CRIA O ALVTREE CONTAINER
************************************************************************************
FORM create_object_in_container.
  CREATE OBJECT g_alv_tree
    EXPORTING
      parent                      = g_custom_container
      node_selection_mode         = cl_gui_column_tree=>node_sel_mode_single
      item_selection              = 'X'
      no_html_header              = 'X'
      no_toolbar                  = ''
    EXCEPTIONS
      cntl_error                  = 1
      cntl_system_error           = 2
      create_error                = 3
      lifetime_error              = 4
      illegal_node_selection_mode = 5
      failed                      = 6
      illegal_column_name         = 7.

  IF sy-subrc <> 0.
  ENDIF.
ENDFORM.                    "create_object_in_container


************************************************************************************
* CRIA O CONTROLE ALVTREE (VAZIO)
************************************************************************************
FORM create_empty_alvtree_control.
* Ajusta o cabeçalho da árvode do ALV
  DATA e_hierarchy_header TYPE treev_hhdr.
  PERFORM build_hierarchy_header CHANGING e_hierarchy_header.

* Monta os campos a serem visualizados
  PERFORM build_fieldcatalog.

* Ativa a árvore
  CALL METHOD g_alv_tree->set_table_for_first_display
    EXPORTING
      is_hierarchy_header = e_hierarchy_header
    CHANGING
      it_outtab           = t_relatorio_itens
      it_fieldcatalog     = ti_fieldcat.
ENDFORM.                    "create_empty_alvtree_control


************************************************************************************
* CRIA HIERARQUIA
************************************************************************************
FORM create_alvtree_hierarchy.
* Carrega os ítens na árvore
  PERFORM carrega_itens_na_arvore.

* Otimiza o tamanho das colunas
  CALL METHOD g_alv_tree->column_optimize
    EXCEPTIONS
      start_column_not_found = 1
      end_column_not_found   = 2
      OTHERS                 = 3.

* Envia os dados para o frontend
  CALL METHOD g_alv_tree->frontend_update.
ENDFORM.                    "create_alvtree_hierarchy


************************************************************************************
* MONTA CABEÇALHO
************************************************************************************
FORM monta_cabecalho CHANGING p_node_key TYPE lvc_nkey.
  DATA: ld_node_text   TYPE lvc_value,    " Valor apresentado no cabeçalho
        lt_item_layout TYPE lvc_t_layi,   " Carrega layout do item
        ls_item_layout TYPE lvc_s_layi,   " Carrega layout do item
        is_node_layout TYPE lvc_s_layn.   " Ícones de seleção "pastinha"

* Neste caso, a separação será pelo VBELN, conforme abaixo:
  ls_item_layout-fieldname = g_alv_tree->c_hierarchy_column_name.
  ls_item_layout-style     = cl_gui_column_tree=>style_default.
  ld_node_text             = w_relatorio-vbeln.
  APPEND ls_item_layout TO lt_item_layout.
  CLEAR  ls_item_layout.

* Substitui o ícone da "pastinha"
  is_node_layout-n_image   = icon_rating_positive. "Item Aberto
  is_node_layout-exp_image = icon_rating_minus.    "Item Fechado

* Adiciona a "pastinha"
  CALL METHOD g_alv_tree->add_node
    EXPORTING
      i_relat_node_key = c_raiz
      i_relationship   = cl_gui_column_tree=>relat_last_child
      is_node_layout   = is_node_layout
      it_item_layout   = lt_item_layout
      i_node_text      = ld_node_text
      is_outtab_line   = w_relatorio
    IMPORTING
      e_new_node_key   = p_node_key.
ENDFORM.                    "monta_cabecalho


************************************************************************************
* MONTA ITENS
************************************************************************************
FORM add_item_line USING    p_relate_key TYPE lvc_nkey
                   CHANGING p_node_key   TYPE lvc_nkey.
  DATA: ld_node_text TYPE lvc_value,      " Valor apresentado no head
        lt_item_layout TYPE lvc_t_layi,   " Carrega layout do item
        ls_item_layout TYPE lvc_s_layi,   " Carrega layout do item
        is_node_layout TYPE lvc_s_layn.   " Ícones de seleção "pastinha"

* Neste caso, abaixo do VBELN, informado anteriormente ao montar o Cebeçalho,
* será apresentado os Materiais (MATNR)
  ls_item_layout-fieldname = g_alv_tree->c_hierarchy_column_name.
  ls_item_layout-style     = cl_gui_column_tree=>style_default.
  ld_node_text             = w_relatorio-matnr.
  APPEND ls_item_layout TO lt_item_layout.
  CLEAR ls_item_layout.

* Substitui o ícone da "folinha"
  is_node_layout-n_image   = icon_material. "Item Aberto
  is_node_layout-exp_image = icon_material. "Item Fechado

* Adiciona "folinha"
  CALL METHOD g_alv_tree->add_node
    EXPORTING
      i_relat_node_key = p_relate_key
      i_relationship   = cl_gui_column_tree=>relat_last_child
      is_node_layout   = is_node_layout
      it_item_layout   = lt_item_layout
      i_node_text      = ld_node_text
      is_outtab_line   = w_relatorio
    IMPORTING
      e_new_node_key   = p_node_key.
ENDFORM.                    "add_item_line


************************************************************************************
* CARREGA ITENAS NA ÁRVORE DO ALVTREE
************************************************************************************
FORM carrega_itens_na_arvore.
* Variáveis auxiliares para montagem das "pastinhas", neste caso, por MATNR
  DATA: v_item        TYPE lips-matnr,     " Material
        v_cabeca_key  TYPE lvc_nkey,       " Chave de posição de head
        v_item_key    TYPE lvc_nkey.       " Chave de posição de item

  LOOP AT t_relatorio INTO w_relatorio.

*   Controle da linha da árvore X linha da tabela
*   Serve para localizar a linha da tabela que se refere cada linha da árvore.
    wa_relacao-tabix = sy-tabix.

    ADD 1 TO wa_relacao-linha.

*   Neste caso, cria uma nova hierarquia para cada novo VBELN
    IF w_relatorio-vbeln <> v_item.
      v_item = w_relatorio-vbeln.
*     Adiciona uma "pastinha"
      PERFORM monta_cabecalho CHANGING v_cabeca_key.
      APPEND wa_relacao TO ti_relacao.
      ADD 1 TO wa_relacao-linha.
    ENDIF.

*   Neste caso, adiciona os itens referentes ao VBELN
    PERFORM add_item_line USING v_cabeca_key
                       CHANGING v_item_key.

    APPEND wa_relacao TO ti_relacao.

  ENDLOOP.
ENDFORM.                    "carrega_itens_na_arvore

Foto 01

Foto 02

Foto 03

Foto 04

Foto 05 
/* POPUP INI */ /* POPUP FIM */