OVS – SELECT OPTIONS em Web Dynpro

Neste post descrevo passo a passo a criação de um relatório Web Dynpro usando o componente ALV, com SELECT OPTIONS como filtro de pesquisa, criaremos também uma ajuda de pesquisa para o SELECT OPTIONS usando o componente OVS.

Referência para definições do componente OVS

Criaremos uma tela de seleção para o programa que será formada por dois grupos (Componente Group) Seleção de Dados e Relatório. No primeiro o usuário informa a Companhia Aérea e o Número do Voo. Quando o botão Pesquisar é clicado, os dados referentes ao filtro informado são carregados no grupo Relatório em um ViewContainerUIElement ou ALV.

Vamos ao passo a passo!

Criando o Componente Web Dynpro

Transação SE80-> Selecione o item Componente Web Dynpro/Interface.

Informe o nome do componente: ZWD_XXX.

web dynpro - select options - 1

Informe uma descrição para o componente.

Observe que é sugerida a criação de uma visão com o Nome MAIN. Altere o nome se preferir e confirme.

web dynpro - select options - 2

Salve como Objeto Local.

O programa é criado com a estrutura abaixo:

web dynpro - select options - 3

Definindo o Contexto

Selecione o COMPONENTCONTROLLER. Vamos criar os itens do CONTEXT,  onde definimos o campos usados no relatório. Clique com o botão direito em CONTEXT -> Create -> Node.

web dynpro - select options - 4

Informe o nome SELECAO para o node e no Dictionary structure informe a tabela SFLIGHT.

web dynpro - select options - 5

Clique em ADD Atributes…  Selecione os campos CARRID e CONNID e confirme.

web dynpro - select options - 6

Adicione agora o Node Relatório com todos os campos da tabela sflight. E altere a cardinalidade para 0…n.

web dynpro - select options - 7

Selecione a View MAIN na aba Context.

Clique e arraste o node SELECAO do Context COMPONENTCONTROLLER para o Context da MAIN

web dynpro - select options - 8

web dynpro - select options - 9

Desenhando o Layout

Selecione a aba Layout.

Clique com o botão direito em ROOTUIELEMENTCONTAINER e selecione Element einfugn para adicionar um elemento na tela.

web dynpro - select options - 10

Vamos criar inicialmente 2 componentes do tipo GROUP que serão divididos em Seleção de Dados e Relatório.

web dynpro - select options - 11

Ficará assim:

web dynpro - select options - 12

Adicione 2 TransparentContainer

web dynpro - select options - 13

Altere a propriedade WIDTH do grupo Relatório para 100% para que ele ocupe toda a tela.

Agora iremos adicionar os itens de seleção de dados.

Para o carrid iremos montar um Select Options. Adicione um componente ViewContainerUIElement com o nome CARRID no primeiro TC1.

Adicione o componente LABEL com o nome lbl_connid no TC2.

Para o nº do voo adicione também o componente INPUTFIELD com o nome connid.

Altere a propriedade VALUE dos INPUTFIELD clique no botão do lado e selecione os respectivos atributos no contexto criado

web dynpro - select options - 14

Altere a propriedade Layout Data do lbl_connid para MatrixHeadData.

web dynpro - select options - 15

Adicione agora um botão para a pesquisa.

web dynpro - select options - 16

Ficará assim:

web dynpro - select options - 17

Vamos criar uma Ação para o botão.

Clique no botão do evento OnAction informe os dados abaixo e confirme.

Action: Busca_dados

Description: Busca dados tabela SFLIGHT.

web dynpro - select options - 18

Altere a propriedade texto para “Pesquisar”.

Usando o componente OVS no Web Dynpro

Vamos adicionar o componentes que serão utilizados.

Selecione o componente ZWD_TESTE_AS. Adicione o componentes:

  • SALV_WD_TABLE dando a ele o nome de ALV.
  • WDR_OVS dando a ele o nome de OVS
  • WDR_SELECT_OPTIONS dando a ele o nome de SELECT_OPTIONS.

web dynpro - select options - 19

Selecione a MAIN Aba propriedades clique no botão para adicionar o componente ALV.

Selecione o SALV_WD_TABLE – INTERFACE CONTROLLER.

web dynpro - select options - 20

web dynpro - select options - 21

Faça o mesmo para os componentes OVS e SELECT_OPTIONS.

web dynpro - select options - 22

Vamos alterar o campo do Context para OVS.

web dynpro - select options - 23

Selecione a aba Layout. Vamos adicionar agora o componente ViewContainerUiElement no Grupo 2. Nome ALV.

Codificação Web Dynpro

Vamos ao código!

Abra o método BUSCAR_DADOS. Basta dar 2 cliques no evento OnAction.

web dynpro - select options - 24

Inicialmente vamos declarar nossa tabela de saída e também os tipos necessários para a exibição de mensagem.

***  Tabela de saída
DATA: ti_saida TYPE STANDARD TABLE OF sflight.

***  Mensagens
DATA: lo_api_controller  TYPE REF TO if_wd_controller,
lo_message_manager TYPE REF TO if_wd_message_manager,
message_id TYPE string.

Agora vamos ler os 2 parâmetros que criamos.

Clique no botão Web Dynpro Code Wizard “Varinha mágica! Que cria o código para nós!”

Clique em Context e selecione o Node Seleção.

web dynpro - select options - 25

Será gerado o código abaixo no método busca_dados..

method ONACTIONBUSCA_DADOS .
DATA: ti_saida TYPE STANDARD TABLE OF sflight.

DATA lo_nd_selecao TYPE REF TO if_wd_context_node.
DATA lo_el_selecao TYPE REF TO if_wd_context_element.
DATA ls_selecao TYPE wd_this->element_selecao.

*   navigate from  to  via lead selection
lo_nd_selecao = wd_context->get_child_node( name = wd_this->wdctx_selecao ).

*   get element via lead selection
lo_el_selecao = lo_nd_selecao->get_element( ).
*   @TODO handle not set lead selection
IF lo_el_selecao IS INITIAL.
ENDIF.

*   get all declared attributes
lo_el_selecao->get_static_attributes(
IMPORTING
static_attributes = ls_selecao ).
endmethod.

Para montar o select options devemos adicionar os atributos:

  • M_HANDLER                                     Tipo      IF_WD_SELECT_OPTIONS
  • M_WD_SELECT_OPTIONS        Tipo      IWCI_WDR_SELECT_OPTIONS

web dynpro - select options - 26

Vamos agora selecionar os dados na tabela. Adicione o código que contém a leitura do select option e a seleção dos dados.

*** Ler dados do Select-Options
  rt_carrid = wd_this->m_handler->get_range_table_of_sel_field( i_id = 'CARRID' ).
  ASSIGN rt_carrid->* TO <fs_carrid>.

  IF <fs_carrid> IS NOT INITIAL.
    LOOP AT <fs_carrid> INTO wa_r_carrid .
      wa_r_carrid-low = wa_r_carrid-low.
      wa_r_carrid-high = wa_r_carrid-high.
      IF wa_r_carrid-high IS NOT INITIAL.
        wa_r_carrid-sign   = 'I'.
        wa_r_carrid-option = 'BT'.
      ELSE.
        CLEAR wa_r_carrid-option.
        wa_r_carrid-option = 'EQ'.
      ENDIF.
      APPEND wa_r_carrid TO ti_r_carrid.
    ENDLOOP.
  ENDIF.

  IF ls_selecao-connid IS NOT INITIAL.
    vl_where  =  ' connid = ls_selecao-connid '.
  ENDIF.

  SELECT * FROM sflight INTO TABLE ti_saida
    WHERE carrid IN  ti_r_carrid
    AND  (vl_where)
    ORDER BY carrid .

Vá ao context da MAIN e crie o atributo EXIBE_RELATORIO do tipo WDUI_VISIBILITY coloque 1 como valor default. Selcione o Componete na aba layout e altera propriedade visible para o atributo criado.

web dynpro - select options - 27

web dynpro - select options - 28

E declare a variável no código do botão.

 DATA lv_exibe_relatorio TYPE wd_this->element_context-exibe_relatorio.

Adicione os tipos necessários para a saída do relatório:

*** Tela de Saída
DATA lo_nd_relatorio TYPE REF TO if_wd_context_node.
DATA lo_el_relatorio TYPE REF TO if_wd_context_element.
DATA ls_relatorio TYPE wd_this->element_relatorio.
DATA lo_el_context TYPE REF TO if_wd_context_element.

E adicione o código abaixo a após o select.

IF ti_saida IS INITIAL.

    lo_api_controller ?= wd_this->wd_get_api( ).

    CALL METHOD lo_api_controller->get_message_manager
      RECEIVING
        message_manager = lo_message_manager.

*     report message
    CALL METHOD lo_message_manager->report_message
      EXPORTING
        message_text = 'Não Foram encontrados Dados'
      RECEIVING
        message_id   = message_id.

    lv_exibe_relatorio = 1.

  ELSE.
* navigate from  to  via lead selection
    lo_nd_relatorio = wd_context->get_child_node( name = wd_this->wdctx_relatorio ).

    lo_nd_relatorio->bind_table( new_items = ti_saida set_initial_elements = abap_true ).

    lv_exibe_relatorio = 2.

  ENDIF.

* get element via lead selection
  lo_el_context = wd_context->get_element( ).

  wd_this->configura_alv( ).
* set single attribute
  lo_el_context->set_attribute(
    name =  `EXIBE_RELATORIO`
    value = lv_exibe_relatorio ).

O código completo do método Busca Dados.

METHOD onactionbusca_dados .

***  Tabela de saída
  DATA: ti_saida TYPE STANDARD TABLE OF sflight.
***  Mensagens
  DATA: lo_api_controller  TYPE REF TO if_wd_controller,
        lo_message_manager TYPE REF TO if_wd_message_manager,
        message_id TYPE string.
*** Tela de Seleção
  DATA lv_exibe_relatorio TYPE wd_this->element_context-exibe_relatorio.

  DATA lo_nd_selecao TYPE REF TO if_wd_context_node.
  DATA lo_el_selecao TYPE REF TO if_wd_context_element.
  DATA ls_selecao TYPE wd_this->element_selecao.

*** Tela de Saída
  DATA lo_nd_relatorio TYPE REF TO if_wd_context_node.
  DATA lo_el_relatorio TYPE REF TO if_wd_context_element.
  DATA ls_relatorio TYPE wd_this->element_relatorio.
  DATA lo_el_context TYPE REF TO if_wd_context_element.

*** tabela para o select option
  DATA:  ti_r_carrid TYPE RANGE OF sflight-carrid.
  DATA: wa_r_carrid LIKE LINE OF ti_r_carrid .
  FIELD-SYMBOLS: <fs_carrid> TYPE table.

  DATA: rt_carrid TYPE REF TO data.
  DATA  vl_where  TYPE string.
*   navigate from  to  via lead selection
  lo_nd_selecao = wd_context->get_child_node( name = wd_this->wdctx_selecao ).

*   get element via lead selection
  lo_el_selecao = lo_nd_selecao->get_element( ).
*   @TODO handle not set lead selection
  IF lo_el_selecao IS INITIAL.
  ENDIF.

*   get all declared attributes
  lo_el_selecao->get_static_attributes(
    IMPORTING
      static_attributes = ls_selecao ).


*** Ler dados do Select-Options
  rt_carrid = wd_this->m_handler->get_range_table_of_sel_field( i_id = 'CARRID' ).
  ASSIGN rt_carrid->* TO <fs_carrid>.

  IF <fs_carrid> IS NOT INITIAL.
    LOOP AT <fs_carrid> INTO wa_r_carrid .
      wa_r_carrid-low = wa_r_carrid-low.
      wa_r_carrid-high = wa_r_carrid-high.
      IF wa_r_carrid-high IS NOT INITIAL.
        wa_r_carrid-sign   = 'I'.
        wa_r_carrid-option = 'BT'.
      ELSE.
        CLEAR wa_r_carrid-option.
        wa_r_carrid-option = 'EQ'.
      ENDIF.
      APPEND wa_r_carrid TO ti_r_carrid.
    ENDLOOP.
  ENDIF.

  IF ls_selecao-connid IS NOT INITIAL.
    vl_where  =  ' connid = ls_selecao-connid '.
  ENDIF.

  SELECT * FROM sflight INTO TABLE ti_saida
    WHERE carrid IN  ti_r_carrid
    AND  (vl_where)
    ORDER BY carrid .

  IF ti_saida IS INITIAL.

    lo_api_controller ?= wd_this->wd_get_api( ).

    CALL METHOD lo_api_controller->get_message_manager
      RECEIVING
        message_manager = lo_message_manager.

*     report message
    CALL METHOD lo_message_manager->report_message
      EXPORTING
        message_text = 'Não Foram encontrados Dados'
      RECEIVING
        message_id   = message_id.

    lv_exibe_relatorio = 1.

  ELSE.
* navigate from  to  via lead selection
    lo_nd_relatorio = wd_context->get_child_node( name = wd_this->wdctx_relatorio ).

    lo_nd_relatorio->bind_table( new_items = ti_saida set_initial_elements = abap_true ).

    lv_exibe_relatorio = 2.

  ENDIF.

* get element via lead selection
  lo_el_context = wd_context->get_element( ).

  wd_this->configura_alv( ).
* set single attribute
  lo_el_context->set_attribute(
    name =  `EXIBE_RELATORIO`
    value = lv_exibe_relatorio ).
ENDMETHOD.

Vamos agora criar o método que irá configurar o ALV definindo por exemplo, zebrado nas linhas do ALV, número de linhas que serão exibidas, etc.

METHOD configura_alv .

  DATA: lo_cmp_usage           TYPE REF TO if_wd_component_usage,
        lo_interfacecontroller TYPE REF TO iwci_salv_wd_table,
        lo_config              TYPE REF TO cl_salv_wd_config_table,
        lo_table_conf          TYPE REF TO if_salv_wd_table_settings,
        lo_column_conf         TYPE REF TO if_salv_wd_column_settings.

  DATA: lo_columns            TYPE salv_wd_t_column_ref,
        lo_column             TYPE REF TO cl_salv_wd_column,
        lo_header             TYPE REF TO cl_salv_wd_column_header.

  DATA:lr_comp_if_alv TYPE REF TO iwci_salv_wd_table,
       lr_config      TYPE REF TO if_salv_wd_table_settings.

  lo_cmp_usage = wd_this->wd_cpuse_alv( ).
  IF lo_cmp_usage->has_active_component( ) IS INITIAL.
    lo_cmp_usage->create_component( ).
  ENDIF.

  lo_interfacecontroller = wd_this->wd_cpifc_alv( ).
  lo_config = lo_interfacecontroller->get_model( ).
*
* Table settings
  lo_table_conf ?= lo_config.

*** Define exibição do ALV com as linhas "zebradas"
  lo_table_conf->set_design( cl_wd_table=>e_design-alternating ).
  lo_table_conf->set_read_only( abap_true ).

***Remove coluna de seleção de linhas
  lo_table_conf->set_selection_mode( cl_wd_table=>e_selection_mode-none ).

***Define número mínimo de linhas
  lr_comp_if_alv = wd_this->wd_cpifc_alv( ).
  lr_config = lr_comp_if_alv->get_model( ).
  lr_config->set_visible_row_count( 10   ).

ENDMETHOD.

Selecione a Window ZWD_TESTE_AS clique com o botão direito no ALV e em Incorporar visão/Embed View.

web dynpro - select options - 29

Selecione o component ALV / TABLE.

web dynpro - select options - 30

web dynpro - select options - 31

Salve e Ative.

Selecione o item INTERFACECONTROLLER_USAGE do componente ALV. Clique em Controler Usage e selecione o componente ZWD_TESTE_AS

web dynpro - select options - 32

Clique no node RELATORIO e arraste para o node DATA do INTERFACECONTROLLER

web dynpro - select options - 33

Crie o método SELECT_OPTIONS e adicione o código abaixo:

METHOD select_options .

  DATA:  lt_range_table TYPE REF TO data,
        rt_range_table   TYPE REF TO data,
        read_only        TYPE abap_bool,
        typename         TYPE string.

  DATA: lr_componentcontroller TYPE REF TO ig_componentcontroller,
        l_ref_cmp_usage        TYPE REF TO if_wd_component_usage.

* create the used component
  l_ref_cmp_usage = wd_this->wd_cpuse_select_options( ).
  IF l_ref_cmp_usage->has_active_component( ) IS INITIAL.
    l_ref_cmp_usage->create_component( ).
  ENDIF.

  wd_this->m_wd_select_options = wd_this->wd_cpifc_select_options( ).
* init the select screen
  wd_this->m_handler = wd_this->m_wd_select_options->init_selection_screen( ).

  wd_this->m_handler->set_global_options(
                              i_display_btn_cancel  = abap_false
                              i_display_btn_check   = abap_false
                              i_display_btn_reset   = abap_false
                              i_display_btn_execute = abap_false ).

* create a range table that consists of this new data element
  lt_range_table = wd_this->m_handler->create_range_table( i_typename =  'S_CARR_ID' ).


* add a new field to the selection
  wd_this->m_handler->add_selection_field( i_id = 'CARRID'
                                      i_description = 'Compania Aérea'
                                      it_result = lt_range_table
                                      i_read_only = read_only
                                      i_obligatory = abap_false
                                      i_value_help_type = if_wd_value_help_handler=>co_prefix_ovs ).


ENDMETHOD.

Nesse trecho i_value_help_type if_wd_value_help_handler=>co_prefix_ovs ). definimos que o select opions irá usar o nosso OVS.

Devemos incluir no método modify view a chamada do select option:

METHOD wddomodifyview .

IF  first_time EQ abap_true.
DATA: lo_ddk    TYPE REF TO cl_wd_dropdown_by_key.
wd_this->select_options( ).
ENDIF.

ENDMETHOD.

Devemos também incluir o método ON_OVS que irá montar a ajuda de pesquisa.

METHOD on_ovs .

  TYPES:
    BEGIN OF lty_stru_input,
*   add fields for the display of your search input here
      carrid TYPE s_carr_id,
      carrname TYPE  s_carrname,
    END OF lty_stru_input.
  TYPES:
    BEGIN OF lty_stru_list,
*   add fields for the selection list here
      carrid TYPE s_carr_id,
      carrname TYPE  s_carrname,
    END OF lty_stru_list.

  DATA: ls_search_input  TYPE lty_stru_input,
        lt_select_list   TYPE STANDARD TABLE OF lty_stru_list,
        ls_text          TYPE wdr_name_value,
        lt_label_texts   TYPE wdr_name_value_list,
        lt_column_texts  TYPE wdr_name_value_list,
        lv_window_title  TYPE string,
        lv_table_header  TYPE string,

        vl_where TYPE string.

  DATA: lv_carrid TYPE s_carr_id,
        lv_carrname TYPE  s_carrname.


  FIELD-SYMBOLS: <ls_query_params> TYPE lty_stru_input,
                 <ls_selection>    TYPE lty_stru_list,
                  <lt_sel_opt_result> TYPE STANDARD TABLE.

  CASE i_ovs_data-m_ovs_callback_object->phase_indicator.

    WHEN if_wd_ovs=>co_phase_0.  "configuration phase, may be omitted


      ls_text-name = `CARRID`.
      ls_text-value = `Companhia Aérea`.
      INSERT ls_text INTO TABLE lt_label_texts.
      ls_text-name = `CARRNAME`.
      ls_text-value = `Nome de uma companhia aérea`.
      INSERT ls_text INTO TABLE lt_label_texts.

      ls_text-name = `CARRID`.
      ls_text-value = `Companhia Aérea`.
      INSERT ls_text INTO TABLE lt_column_texts.
      ls_text-name = `CARRNAME`.
      ls_text-value = `Nome de uma companhia aérea`.
      INSERT ls_text INTO TABLE lt_column_texts.

      i_ovs_data-m_ovs_callback_object->set_configuration(
                label_texts  = lt_label_texts
                column_texts = lt_column_texts
                window_title = lv_window_title
                table_header = lv_table_header ).


    WHEN if_wd_ovs=>co_phase_1.  "set search structure and defaults
*     pass the values to the OVS component
      i_ovs_data-m_ovs_callback_object->set_input_structure(
          input = ls_search_input ).

    WHEN if_wd_ovs=>co_phase_2.
      ASSIGN i_ovs_data-m_ovs_callback_object->query_parameters->*
                              TO <ls_query_params>.

      lv_carrid =  <ls_query_params>-carrid.
      lv_carrname =  <ls_query_params>-carrname.
      IF lv_carrid IS NOT INITIAL.
        vl_where = ' a~carrid = lv_carrid '.
      ENDIF.
      IF  lv_carrname IS NOT INITIAL.
        IF vl_where  IS INITIAL.
          vl_where = ' a~carrname  = lv_carrname '.
        ELSE.
          vl_where = ' and a~carrname  = lv_carrname '.
        ENDIF.
      ENDIF.

      SELECT DISTINCT b~carrid a~carrname
      FROM scarr AS a INNER JOIN sflight AS b ON a~carrid = b~carrid
      INTO TABLE lt_select_list
        WHERE (vl_where)
      ORDER BY b~carrid.

      i_ovs_data-m_ovs_callback_object->set_output_table( output = lt_select_list ).

    WHEN if_wd_ovs=>co_phase_3.

      ASSIGN i_ovs_data-m_ovs_callback_object->selection->* TO <ls_selection>.
      ASSIGN i_ovs_data-mt_selected_values->* TO <lt_sel_opt_result>.
      INSERT <ls_selection>-carrid INTO TABLE <lt_sel_opt_result>.

  ENDCASE.
ENDMETHOD.

Selecione a Window ZWD_TESTE3_AS clique com o botão direito no CARRID e em Incorporar visão/Embed View.

web dynpro - select options - 34

Selecione o component SELECT_OPTIONS.

web dynpro - select options - 35

web dynpro - select options - 36

Adicione o método ON_OVS Type 1

Selecione o componente SELECT_OPTIONS -> ON_OVS.

web dynpro - select options - 37

Deverá ficar assim:

web dynpro - select options - 38

Criando aplicação Web Dynpro

Vamos criar agora a aplicação do programa. Onde veremos o resultado.

web dynpro - select options - 39

Salve-a como Objeto local.

Salve e Ative toda a aplicação.

Vamos testar o programa.

Clique com o botão direito na aplicação criada e em Testar. O navegador é aberto, selecione o filtro e pesquise!

web dynpro - select options - 40

 

 

Resultado: Web Dynpro com select-options

web dynpro - select options - 41 web dynpro - select options - 42 web dynpro - select options - 43 web dynpro - select options - 44

Aline Cristina

Formada em Sistemas de Informação pelo Centro Universitário do Leste De Minas Gerais – Unileste-MG. Comecei com PHP, passei pelo C# e atualmente atuo como consultora ABAP, na equipe de desenvolvimento de sistemas de uma grande indústria no leste de MG.

Você pode gostar...