quarta-feira, 27 de novembro de 2013

ALV OO - Editável valores modificados

- No ALV existe um parâmetro no FIELDCAT que indica se um determinado campo é editável ou
não.
SLIS_FIELDCAT_ALV-EDIT  ou
LVC_S_FCAT-EDIT

Se marcados esse campos o campo fica editável, mas no caso de uma coluna de valor editável e uma outra coluna que faz o cálculo com esse campo, no momento q vc alterar o valor e dar <ENTER> o campo não se atualiza automaticamente, somente se vc colocar um botão para recalcular os valores eles serão atualizados.

Utilizando o evento do ALV objeto DATA_CHANGED os valores podem ser atualizados ao dar <ENTER> sem a necessidade de uma segunda ação do usuário.

- Para isso vc tem que declarar uma classe para o evento.

*---------------------------------------------------------------------*
*       CLASS CL_ALV_EVENT DEFINITION
*---------------------------------------------------------------------*
CLASS cl_alv_event DEFINITION.

  PUBLIC SECTION.

    METHODS handle_data_changed
      FOR EVENT data_changed OF cl_gui_alv_grid
      IMPORTING er_data_changed e_ucomm.

ENDCLASS.                    "cl_tree_event_rec DEFINITION



- No meu caso em vez de implentar a rotina dentro da chamada do método, eu criei um perfom para ficar mais bonito.

*----------------------------------------------------------------------*
*       CLASS cl_alv_event IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS cl_alv_event IMPLEMENTATION.

  METHOD handle_data_changed.
    PERFORM alv_data_changed USING er_data_changed e_ucomm.
  ENDMETHOD.                    "handle_data_changed
ENDCLASS.                    "cl_alv_event IMPLEMENTATION


Depois declaro o meu objeto para o evento
DATA gcl_alv_event    TYPE REF TO cl_alv_event.

Na criação do ALV eu defino o evento

  CALL METHOD gcl_grid->set_table_for_first_display
    EXPORTING
      i_save               = 'A'
      is_layout            = lw_layout
      it_toolbar_excluding = lt_exc_toolb
    CHANGING
      it_outtab            = gt_pin
      it_fieldcatalog      = gt_fcat_alv
      it_filter            = lt_filter.

  CREATE OBJECT gcl_alv_event.

  SET HANDLER gcl_alv_event->handle_data_changed  FOR gcl_grid.


  CALL METHOD gcl_grid->register_edit_event
    EXPORTING
      i_event_id = cl_gui_alv_grid=>mc_evt_enter.


O método REGISTER_EDIT_EVENT é importante, pois determina que o evento que vc colocar no parâmetro I_EVENT_ID será o trigger para o evento DATA_CHANGED ser executado. no meu caso o ENTER - coloquei um atributo da classe para não colocar constante no programa. Se quiser podem colocar outro ID de evento.

- Não esquecer de marcar o campo EDIT do seu FIELDCAT.
  LOOP AT gt_fcat_alv ASSIGNING <lfsw_fcat>.

    CASE <lfsw_fcat>-fieldname.
      WHEN 'TFRNR'.
        <lfsw_fcat>-ref_table = 'LFA1'.
        <lfsw_fcat>-ref_field = 'LIFNR'.
        <lfsw_fcat>-edit = 'X'.
    ENDCASE.

  ENDLOOP.


- Codificando o evento DATA_CHANGED
- O método GET_CELL_VALUE retorna o valor digitado do campo.
- O metodo ADD_PROTOCOL_ENTRY gera a mensagem de erro caso o campo digitado esteja errado por alguma validação
- O método MODIFY_CELL modifica qualquer célula que se queira caso exista um outro campo dependente do digitado. Esse seria o caso de um valor calculado de acordo com um valor digitado pelo usuário.
- Uma coisa muito importante é que essa modificações são feitas em tela, não modifica o valor da tabela interna passada no método SET_TABLE_FOR_FIRST_DISPLAY. Então seria correto nesse código ao ser alterado um campo, não esquecer de alterar a tabela interna também.


*&---------------------------------------------------------------------*
*&      Form  ALV_DATA_CHANGED
*&---------------------------------------------------------------------*
FORM alv_data_changed USING fcl_data TYPE REF TO cl_alv_changed_data_protocol
                            f_ucomm TYPE sy-ucomm. "#EC NEEDED

  DATA: lw_mod_cells TYPE lvc_s_modi.

  DATA: l_tfrnr TYPE zxxtpin_lote-tfrnr.

  LOOP AT fcl_data->mt_good_cells INTO lw_mod_cells.

    CASE lw_mod_cells-fieldname.
      WHEN  'TFRNR'.

        CALL METHOD fcl_data->get_cell_value
          EXPORTING
            i_row_id    = lw_mod_cells-row_id
            i_fieldname = lw_mod_cells-fieldname
          IMPORTING
            e_value     = l_tfrnr.

        CHECK l_tfrnr IS NOT INITIAL.

        SELECT COUNT( * )
          FROM lfa1
         WHERE lifnr EQ l_tfrnr.

        IF sy-subrc <> 0.

          CALL METHOD fcl_data->add_protocol_entry
            EXPORTING
              i_msgid     = 'ZXXPIN'
              i_msgno     = '003'
              i_msgty     = 'E'
              i_msgv1     = l_tfrnr
              i_fieldname = lw_mod_cells-fieldname
              i_row_id    = lw_mod_cells-row_id.

        ELSE.
          CALL METHOD fcl_data->modify_cell
            EXPORTING
              i_row_id    = lw_mod_cells-row_id
              i_fieldname = lw_mod_cells-fieldname
              i_value     = lw_sflight-carrname.

        ENDIF.


    ENDCASE.

  ENDLOOP.

ENDFORM.                    " ALV_DATA_CHANGED

Nenhum comentário:

Postar um comentário