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.
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.
Salve como Objeto Local.
O programa é criado com a estrutura abaixo:
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.
Informe o nome SELECAO para o node e no Dictionary structure informe a tabela SFLIGHT.
Clique em ADD Atributes… Selecione os campos CARRID e CONNID e confirme.
Adicione agora o Node Relatório com todos os campos da tabela sflight. E altere a cardinalidade para 0…n.
Selecione a View MAIN na aba Context.
Clique e arraste o node SELECAO do Context COMPONENTCONTROLLER para o Context da MAIN
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.
Vamos criar inicialmente 2 componentes do tipo GROUP que serão divididos em Seleção de Dados e Relatório.
Ficará assim:
Adicione 2 TransparentContainer
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
Altere a propriedade Layout Data do lbl_connid para MatrixHeadData.
Adicione agora um botão para a pesquisa.
Ficará assim:
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.
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.
Selecione a MAIN Aba propriedades clique no botão para adicionar o componente ALV.
Selecione o SALV_WD_TABLE – INTERFACE CONTROLLER.
Faça o mesmo para os componentes OVS e SELECT_OPTIONS.
Vamos alterar o campo do Context para OVS.
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.
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.
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
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.
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.
Selecione o component ALV / TABLE.
Salve e Ative.
Selecione o item INTERFACECONTROLLER_USAGE do componente ALV. Clique em Controler Usage e selecione o componente ZWD_TESTE_AS
Clique no node RELATORIO e arraste para o node DATA do INTERFACECONTROLLER
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.
Selecione o component SELECT_OPTIONS.
Adicione o método ON_OVS Type 1
Selecione o componente SELECT_OPTIONS -> ON_OVS.
Deverá ficar assim:
Criando aplicação Web Dynpro
Vamos criar agora a aplicação do programa. Onde veremos o resultado.
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!