terça-feira, 30 de setembro de 2014

Docking, Splitter, ALV OO e Set Handler


*  Fala Galera, hoje vamos dar andamento do Post anterior onde vamos brincar
* um pouco mais com os Container criados e vamos colocar ações no alv Editável.
* - Primeira coisa vamos trabalhar com evento do ALV para identificar o Duplo
* clique.
* - Cada duplo clique identificado irá atualizar outro alv de outro container.
*  Esse esquema de duplo clique faz com que os usuários te idolatrem, e
* não tem nada de difícil, então vamos pro código abaixo.
* Ahhhh.... Opinião, sugestão e críticas serão sempre bem vindas.... Valeo.
*&---------------------------------------------------------------------*
REPORT zcl_gui_splitter_container.

*Tipos
*&---------------------------------------------------------------------*
TYPES :
  
BEGIN OF ty_spfli,
   carrid   
TYPE scarr-carrid,
   carrname 
TYPE scarr-carrname,
   connid   
TYPE spfli-connid,
   cityfrom 
TYPE spfli-cityfrom,
   cityto   
TYPE spfli-cityto,
  
END OF   ty_spfli
  
.


*  Criação da classe que identifica o Method com o evento do alv.
*----------------------------------------------------------------------*
*       CLASS lcl_event_handler DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_event_handler DEFINITION.
  
PUBLIC SECTION.
    
METHODS:
      handle_double_click_header
        
FOR EVENT double_click OF cl_gui_alv_grid
        
IMPORTING e_row e_column es_row_no,

      handle_double_click_item
        
FOR EVENT double_click OF cl_gui_alv_grid
        
IMPORTING e_row e_column es_row_no.

ENDCLASS.                    "lcl_event_handler DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_event_handler IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_event_handler IMPLEMENTATION.
  
METHOD
    handle_double_click_header
.
    
PERFORM f_handler_dp_header USING e_row e_column es_row_no.
  
ENDMETHOD.                    "handle_double_click_header

  
METHOD
      handle_double_click_item
.
    
PERFORM f_handler_dp_item   USING e_row e_column es_row_no.
  
ENDMETHOD.                    "handle_double_click_item

ENDCLASS.                    "lcl_event_handler IMPLEMENTATION

* Tabelas internas
*&---------------------------------------------------------------------*
DATA :
  t_spfli        
TYPE TABLE OF ty_spfli,
  t_fcat_spfli   
TYPE TABLE OF lvc_s_fcat,
  t_sflight      
TYPE TABLE OF sflight,
  t_fcat_sflight 
TYPE TABLE OF lvc_s_fcat,
  t_saplane      
TYPE TABLE OF saplane,
  t_fcat_saplane 
TYPE TABLE OF lvc_s_fcat.

* Objetos
*&---------------------------------------------------------------------*
DATA :
  o_docking   
TYPE REF TO cl_gui_docking_container,
  o_splitter  
TYPE REF TO cl_gui_splitter_container
  
.
DATA :
  o_container_spfli    
TYPE REF TO cl_gui_container,
  o_container_sflight  
TYPE REF TO cl_gui_container,
  o_container_saplane  
TYPE REF TO cl_gui_container,
  o_alv_spfli          
TYPE REF TO cl_gui_alv_grid,
  o_alv_sflight        
TYPE REF TO cl_gui_alv_grid,
  o_alv_saplane        
TYPE REF TO cl_gui_alv_grid,
* olha aqui o objeto com referencia a classe que acabamos de criar acima.
  o_handler            
TYPE REF TO lcl_event_handler
  
.







* Inicio do processo
START-OF-SELECTION.

  
PERFORM f_selects.

  
CALL SCREEN 9001.

***  Modules da tela 9001 acima
***&---------------------------------------------------------------------*
**PROCESS BEFORE OUTPUT.
**  MODULE status_9001.
**  MODULE inicialization_9001.
**
**PROCESS AFTER INPUT.
**MODULE user_command_9001 AT EXIT-COMMAND.
*** MODULE USER_COMMAND_9001.

*&---------------------------------------------------------------------*
*&      Module  STATUS_9001  OUTPUT
*&---------------------------------------------------------------------*
MODULE status_9001 OUTPUT.
  
SET PF-STATUS 'ST_9001'.

ENDMODULE.                 " STATUS_9001  OUTPUT

*&---------------------------------------------------------------------*
*&      Module  INICIALIZATION_9001  OUTPUT
*&---------------------------------------------------------------------*
MODULE inicialization_9001 OUTPUT.

  
IF o_docking IS NOT BOUND.

* Criação de do Objeto docking que vai a tela chamada como referencia.
    
CREATE OBJECT o_docking
      
EXPORTING
*    parent                      =     " Parent container
        repid                       
sy-repid
        
" Report to Which This Docking Control is Linked
        dynnr                       
sy-dynnr
        
" Screen to Which This Docking Control is Linked
        extension                   
9999    " Control Extension
      
EXCEPTIONS
        cntl_error                  
1
        cntl_system_error           
2
        create_error                
3
        lifetime_error              
4
        lifetime_dynpro_dynpro_link 
5
        
OTHERS                      6
      
.

*&---------------------------------------------------------------------*
    
CREATE OBJECT o_splitter
      
EXPORTING
*      link_dynnr              =     " Screen Number
*      link_repid              =     " Report Name
*      shellstyle              =     " Window Style
*      left                    =     " Left-aligned
*      top                     =     " top
*      width                   =     " NPlWidth
*      height                  =     " Hght
*      metric                  = CNTL_METRIC_DYNPRO    " Metric
*      align                   = 15    " Alignment
        parent                  
o_docking    " Parent Container
        
rows                    =  2   " Number of Rows to be displayed
        columns                 
=  2  " Number of Columns to be Displayed
*      no_autodef_progid_dynnr =     " Don't Autodefined Progid and Dynnr?
*      name                    =     " Name
      
EXCEPTIONS
        cntl_error              
1
        cntl_system_error       
2
        
OTHERS                  3
      
.

* Definição das medidas dos containers
    
PERFORM f_define_container_extension
*         Row column Height Width
      
USING '1' '1'    '70'   '40'.

*  Aqui será feito a criação do Objeto Handler que identificará os
* duplos-cliques do user.
    
IF o_handler IS NOT BOUND.
      
CREATE OBJECT o_handler.
    
ENDIF.

  
ENDIF.

*  Eu tentei criar esses processo de forma generica porque existem varias
* partições e todos tem o processo similar, Mas o segredo da execução do
* evento será uma particularidade de cada container, portanto dentro de cada
* perform f_define_container.......
*&---------------------------------------------------------------------*
* Container Header ( 1,1 )
*&---------------------------------------------------------------------*
  
PERFORM f_create_container
*         Row Column  Container
    
USING '1' '1'     o_container_spfli.
  
PERFORM f_define_container_header.

*&---------------------------------------------------------------------*
* Container Item ( 1,2 )
*&---------------------------------------------------------------------*
  
PERFORM f_create_container
*         Row Column  Container
    
USING '1' '2'     o_container_sflight.
  
PERFORM f_define_container_item.

*&---------------------------------------------------------------------*
* Container Details ( 2,1 )
*&---------------------------------------------------------------------*
  
PERFORM f_create_container
*         Row Column  Container
    
USING '2' '1'     o_container_saplane.
  
PERFORM f_define_container_details.

ENDMODULE.                 " INICIALIZATION_9001  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_9001  INPUT
*&---------------------------------------------------------------------*
MODULE user_command_9001 INPUT.

  
CASE sy-ucomm.
    
WHEN 'BACK'.
      
LEAVE TO SCREEN 0.
    
WHEN 'CANCEL' OR 'EXIT'.
      
LEAVE PROGRAM.
    
WHEN OTHERS.
  
ENDCASE.

ENDMODULE.                 " USER_COMMAND_9001  INPUT
*&---------------------------------------------------------------------*
*&      Form  F_CREATE_CONTAINER
*&---------------------------------------------------------------------*
FORM f_create_container  USING row       TYPE i
                               col       
TYPE i
                               container 
TYPE REF TO cl_gui_container.

* Aqui é feito a criação do container com referencia a uma das partições.
  
o_splitter->get_container(
    
EXPORTING
      row    
row
      column 
col
    RECEIVING
      container 
container
      
).


ENDFORM.                    " F_CREATE_CONTAINER
*&---------------------------------------------------------------------*
*&      Form  F_DEFINE_CONTAINER_EXTENSION
*&---------------------------------------------------------------------*
FORM f_define_container_extension USING row    TYPE i
                                        column 
TYPE i
                                        height 
TYPE i
                                        width  
TYPE i.
* Altura
  
IF row IS NOT INITIAL
    
AND height IS NOT INITIAL.
    o_splitter
->set_row_height(
      
EXPORTING
        
id     row
        height 
height
        
).
  
ENDIF.

* Largura
  
IF column IS NOT INITIAL
    
AND width IS NOT INITIAL.
    o_splitter
->set_column_width(
      
EXPORTING
        
id    column
        width 
width
    
).
  
ENDIF.

ENDFORM.                    " F_DEFINE_CONTAINER_EXTENSION

*&---------------------------------------------------------------------*
*&      Form  F_DEFINE_CONTAINER_HEADER
*&---------------------------------------------------------------------*
FORM f_define_container_header .

  
DATA:
    lst_layout 
TYPE lvc_s_layo.

  
IF o_docking IS BOUND
    
AND o_alv_spfli IS NOT BOUND.

* Cria o ALV OO
    
CREATE OBJECT o_alv_spfli
      
EXPORTING
        i_parent          
o_container_spfli   " Parent Container
      
EXCEPTIONS
        error_cntl_create 
1
        error_cntl_init   
2
        error_cntl_link   
3
        error_dp_create   
4
        
OTHERS            5.

*  Comando que irá processar os Duplo cliques do User no ALV criado Acima.
* entrando no metodo desse objetos veremos tudo que será feito caso o User
* Clique duas vezes em uma linha do alv Header.
    
SET HANDLER o_handler->handle_double_click_header
      
FOR o_alv_spfli.

* Fieldcat
    
PERFORM f_fieldcat
      
TABLES  t_fcat_spfli
      
USING 'CARRID'   'T_SPFLI' 'CARRID'   'SCARR',
              
'CARRNAME' 'T_SPFLI' 'CARRNAME' 'SCARR',
              
'CONNID'   'T_SPFLI' 'CONNID'   'SPFLI',
              
'CITYFROM' 'T_SPFLI' 'CITYFROM' 'SPFLI',
              
'CITYTO'   'T_SPFLI' 'CITYTO'   'SPFLI'.

* Layout
    lst_layout
-zebra      'X'.
    lst_layout
-cwidth_opt 'X'.


* Exibe o ALV OO
    o_alv_spfli
->set_table_for_first_display(
      
EXPORTING
        is_layout                     
=  lst_layout   " Layout
      
CHANGING
        it_outtab                     
=  t_spfli        " Output Table
        it_fieldcatalog               
=  t_fcat_spfli   " Field Catalog
      
EXCEPTIONS
        invalid_parameter_combination 
1
        program_error                 
2
        too_many_lines                
3
        
OTHERS                        4
    
).

  
ELSE.

* Atualiza o ALV OO
    o_alv_spfli
->refresh_table_display(
      
EXCEPTIONS
        finished       
1
        
OTHERS         2
    
).

  
ENDIF.

ENDFORM.                    " F_DEFINE_CONTAINER_HEADER

*&---------------------------------------------------------------------*
*&      Form  F_SELECTS
*&---------------------------------------------------------------------*
FORM f_selects .

* Seleção para da alv Principal.
  
SELECT a~carrid a~carrname
         b
~connid b~cityfrom b~cityto
    
INTO TABLE t_spfli
    
FROM scarr AS a
    INNER 
JOIN spfli AS b
    
ON  a~carrid b~carrid.

ENDFORM.                    " F_SELECTS

*&---------------------------------------------------------------------*
*&      Form  F_FIELDCAT
*&---------------------------------------------------------------------*
FORM f_fieldcat TABLES fieldcat
  
USING fieldname tabname ref_field ref_table .

* Criação do Fieldcat
  
DATA :
    s_fcat 
TYPE lvc_s_fcat.

  s_fcat
-fieldname  fieldname.
  s_fcat
-tabname    tabname.
  s_fcat
-ref_field  ref_field.
  s_fcat
-ref_table  ref_table.

  
APPEND s_fcat TO fieldcat.

ENDFORM.                    " F_FIELDCAT

*&---------------------------------------------------------------------*
*&      Form  F_DEFINE_CONTAINER_ITEM
*&---------------------------------------------------------------------*
FORM f_define_container_item .

  
DATA:
    lst_layout 
TYPE lvc_s_layo.

  
IF o_docking IS BOUND
    
AND o_alv_sflight IS NOT BOUND.

    
CREATE OBJECT o_alv_sflight
      
EXPORTING
        i_parent          
o_container_sflight   " Parent Container
      
EXCEPTIONS
        error_cntl_create 
1
        error_cntl_init   
2
        error_cntl_link   
3
        error_dp_create   
4
        
OTHERS            5.

* Setando o Handler do ALV Item ( Container 1,2 )
    
SET HANDLER o_handler->handle_double_click_item
      
FOR o_alv_sflight.

* Fieldcat
    
PERFORM f_fieldcat
      
TABLES  t_fcat_sflight
      
USING 'CARRID'     'T_SFLIGHT' 'CARRID'     'SFLIGHT',
              
'CONNID'     'T_SFLIGHT' 'CONNID'     'SFLIGHT',
              
'FLDATE'     'T_SFLIGHT' 'FLDATE'     'SFLIGHT',
              
'PRICE'      'T_SFLIGHT' 'PRICE'      'SFLIGHT',
              
'CURRENCY'   'T_SFLIGHT' 'CURRENCY'   'SFLIGHT',
              
'PLANETYPE'  'T_SFLIGHT' 'PLANETYPE'  'SFLIGHT',
              
'PAYMENTSUM' 'T_SFLIGHT' 'PAYMENTSUM' 'SFLIGHT'
              
.

    lst_layout
-zebra      'X'.
    lst_layout
-cwidth_opt 'X'.

    o_alv_sflight
->set_table_for_first_display(
      
EXPORTING
        is_layout                     
=  lst_layout   " Layout
      
CHANGING
        it_outtab                     
t_sflight    " Output Table
        it_fieldcatalog               
t_fcat_sflight    " Field Catalog
      
EXCEPTIONS
        invalid_parameter_combination 
1
        program_error                 
2
        too_many_lines                
3
        
OTHERS                        4
    
).

  
ELSE.
    o_alv_sflight
->refresh_table_display(
  
EXCEPTIONS
    finished       
1
    
OTHERS         2
).
  
ENDIF.

ENDFORM.                    " F_DEFINE_CONTAINER_ITEM

*&---------------------------------------------------------------------*
*&      Form  F_HANDLER_HEADER
*&---------------------------------------------------------------------*
FORM f_handler_dp_header USING row    TYPE lvc_s_row
                               column 
TYPE lvc_s_col
                               row_id 
TYPE lvc_s_roid.

  
DATA :
    lst_spfli   
LIKE LINE OF t_spfli,
    lst_sflight 
LIKE LINE OF t_sflight.

* Identifica a linha que sofreu a ação.
  
READ TABLE t_spfli INTO lst_spfli
  
INDEX row_id-row_id.

*  faz uma seleção na tabela de Itens conforme dados que sofreram ação no
* alv Header.
  
SELECT *
    
FROM sflight
    
INTO TABLE t_sflight
    
WHERE carrid lst_spfli-carrid
      
AND connid lst_spfli-connid.

* Atualiza o alv Item.
  o_alv_sflight
->refresh_table_display(
    
EXCEPTIONS
      finished       
1
      
OTHERS         2
  
).

ENDFORM.                    " F_HANDLER_HEADER
*&---------------------------------------------------------------------*
*&      Form  F_HANDLER_DP_ITEM
*&---------------------------------------------------------------------*
FORM f_handler_dp_item USING row    TYPE lvc_s_row
                             column 
TYPE lvc_s_col
                             row_id 
TYPE lvc_s_roid.

  
DATA :
    lst_sflight 
LIKE LINE OF t_sflight.

* Identifica a linha do Item que sofreu a ação do user.
  
READ TABLE t_sflight INTO lst_sflight
    
INDEX row_id-row_id.


  
IF sy-subrc IS INITIAL.
*  Caso o User tenha clicado duas vezes no campo referente ao avião 'planetype'.
    
IF column 'PLANETYPE'.
*  seleção com os dados do Avião
      
SELECT *
        
FROM saplane
        
INTO TABLE t_saplane
        
WHERE planetype lst_sflight-planetype.
    
ENDIF.
  
ENDIF.

* Atualização da tabela de detalhes ( 2,1 )
  o_alv_saplane
->refresh_table_display(
    
EXCEPTIONS
      finished       
1
      
OTHERS         2
  
).

ENDFORM.                    " F_HANDLER_DP_ITEM
*&---------------------------------------------------------------------*
*&      Form  F_DEFINE_CONTAINER_DETAILS
*&---------------------------------------------------------------------*
FORM f_define_container_details .

  
DATA:
    lst_layout 
TYPE lvc_s_layo.

  
IF o_docking IS BOUND
    
AND o_alv_saplane IS NOT BOUND.

    
CREATE OBJECT o_alv_saplane
      
EXPORTING
        i_parent          
o_container_saplane   " Parent Container
      
EXCEPTIONS
        error_cntl_create 
1
        error_cntl_init   
2
        error_cntl_link   
3
        error_dp_create   
4
        
OTHERS            5.


    
PERFORM f_fieldcat
      
TABLES  t_fcat_saplane
      
USING 'PLANETYPE'  'T_SAPLANE' 'PLANETYPE'  'SAPLANE',
              
'SEATSMAX'   'T_SAPLANE' 'SEATSMAX'   'SAPLANE',
              
'WEIGHT'     'T_SAPLANE' 'WEIGHT'     'SAPLANE',
              
'WEI_UNIT'   'T_SAPLANE' 'WEI_UNIT'   'SAPLANE',
              
'OP_SPEED'   'T_SAPLANE' 'OP_SPEED'   'SAPLANE',
              
'SPEED_UNIT' 'T_SAPLANE' 'SPEED_UNIT' 'SAPLANE',
              
'SEATSMAX_B' 'T_SAPLANE' 'SEATSMAX_B' 'SAPLANE',
              
'SEATSMAX_F' 'T_SAPLANE' 'SEATSMAX_F' 'SAPLANE'
              
.

    lst_layout
-zebra      'X'.
    lst_layout
-cwidth_opt 'X'.

    o_alv_saplane
->set_table_for_first_display(
      
EXPORTING
        is_layout                     
lst_layout     " Layout
      
CHANGING
        it_outtab                     
t_saplane      " Output Table
        it_fieldcatalog               
t_fcat_saplane " Field Catalog
      
EXCEPTIONS
        invalid_parameter_combination 
1
        program_error                 
2
        too_many_lines                
3
        
OTHERS                        4
    
).


  
ELSE.
    o_alv_saplane
->refresh_table_display(
      
EXCEPTIONS
        finished       
1
        
OTHERS         2
    
).
  
ENDIF.

ENDFORM.                    " F_DEFINE_CONTAINER_DETAILS

9 comentários:

  1. PERFORM dentro de método n faz sentido

    ResponderExcluir
  2. Respostas
    1. Não adianta fazer OO com PERFORM dentro de método. Isso ai é a mesma coisa que mulher feia ter olho azul, fazer seguro de FUSCA... não tem porquê.

      Excluir
  3. PERFORM DENTRO DE METHOD. #RIP OO

    ResponderExcluir
  4. Acho que eu nunca vi algo tão absurdo quanto PERFORM dentro de método, e eu achando que já tinha visto de tudo.

    ResponderExcluir
  5. Sinceramente nao vejo qual o crime estao apontando....QUal seria o ganho de chamar outro método ali ao invez do perform...vejo que foi soh para organizar o codigo.

    ResponderExcluir
  6. Bom dia Amigo. Tem como fazer um exemplo, ou dar uma dica de como eu Jogo uma tela dentro do splitter.

    Ex: Tenho um menu lateral. Quando eu clico nele atualiza a tela da direita.

    No caso cada vez que eu clico ele chama um screen(0100, 0101) e assim por diante.











    ResponderExcluir
  7. Aeee Maurão,
    Da licença, to usando seu ALV como modelo aqui.. kkkk

    ResponderExcluir
  8. Caraca, Se for o Vinicius Que escreveu esse comentario estarei muito orgulhoso disso.

    ResponderExcluir