Поймать кнопку EXPAND в cl_salv_hierseq_table - PullRequest
2 голосов
/ 29 февраля 2020

Я отображаю иерархически-последовательный список через класс cl_salv_hierseq_table, по умолчанию все строки сжимаются, и пользователь может нажать кнопку + в любой строке, чтобы развернуть строки второго уровня.

Я пытаюсь выполнить пользовательский код, когда пользователь нажимает на кнопку + , чтобы развернуть строку.

По умолчанию нет способа поймать его, это обрабатывается внутри SAP. Если я настраиваю пользовательский статус GUI и определяю код пользовательской функции для кнопки F2 , запускается событие added_function, но я не могу определить, к какой строке относится.

Я также пытался перехватить событие link_click, но оно все равно не сработало.

Вот мой код:

report salv_hierseq.
tables: vbrp.
select-options:
werks for vbrp-werks default 'R001',
lgort for vbrp-lgort default 'NORS',
charg for vbrp-charg.

class lcl_report definition.
  public section.
    types:
      begin of ty_kp,
        exidv          type vekpvb-exidv,
        exida          type vekpvb-exida,
        ernam          type vekpvb-ernam,
        erdat          type vekpvb-erdat,
        aenam          type vekpvb-aenam,
        aedat          type vekpvb-aedat,
        vhilm          type vekpvb-vhilm,
        vhart          type vekpvb-vhart,
        vpobjkey       type vekpvb-vpobjkey,
        packvorschr_st type vekpvb-packvorschr_st,
        exidv2         type vekpvb-exidv2,
        venum          type vekpvb-venum,
        expand         type char01,
      end of ty_kp,
      begin of ty_po,
        matnr      type vepovb-matnr,
        velin      type vepovb-velin,
        vemng      type vepovb-vemng,
        vemeh      type vepovb-vemeh,
        werks      type vepovb-werks,
        lgort      type vepovb-lgort,
        sobkz      type vepovb-sobkz,
        qplos      type vepovb-qplos,
        /cwm/vemng type vepovb-/cwm/vemng,
        hu_lgort   type vepovb-hu_lgort,
        venum      type vepovb-venum,
        vepos      type vepovb-vepos,
      end of ty_po.

    data:
      w_vekp   type ty_kp,
      t_vekp   type standard table of ty_kp,
      w_vepo   type ty_po,
      t_vepo   type standard table of ty_po,
      o_hs_alv type ref to cl_salv_hierseq_table.
    methods:
      get_data,
      generate_output.
  private section.
    methods:
      set_pf_status      changing co_hs_alv type ref to cl_salv_hierseq_table,
      set_expand_option  changing co_hs_alv type ref to cl_salv_hierseq_table,
      set_event_handlers changing co_hs_alv type ref to cl_salv_hierseq_table,
      on_link_click      for event link_click        of cl_salv_events_hierseq importing row column level sender,
      on_added_function  for event added_function    of cl_salv_events_hierseq importing e_salv_function sender.
endclass.

start-of-selection.
  data: lo_report type ref to lcl_report.
  create object lo_report.
  lo_report->get_data( ).
  lo_report->generate_output( ).

class lcl_report implementation.
  method get_data.
    select * into corresponding fields of table @t_vepo from vepo where werks in @werks and lgort in @lgort and charg in @charg.
    select * into corresponding fields of table @t_vekp from vekp for all entries in @t_vepo where venum = @t_vepo-venum.
    if not t_vekp is initial.
      sort t_vekp by venum.
      select * from vepo into corresponding fields of table t_vepo for all entries in t_vekp where venum = t_vekp-venum.
      sort t_vepo by venum vepos.
      delete t_vepo where velin = '2' or velin = '3'.
    endif.
  endmethod.                    "get_data

  method generate_output.
    data: lt_bind type salv_t_hierseq_binding,
          la_bind like line of lt_bind.

    la_bind-master = 'VENUM'.
    la_bind-slave  = 'VENUM'.
    append la_bind to lt_bind.

    try.
        call method cl_salv_hierseq_table=>factory
          exporting
            t_binding_level1_level2 = lt_bind
          importing
            r_hierseq               = o_hs_alv
          changing
            t_table_level1          = t_vekp
            t_table_level2          = t_vepo.
      catch cx_root.
    endtry.

    me->set_event_handlers( changing co_hs_alv = o_hs_alv ).
    me->set_pf_status( changing co_hs_alv = o_hs_alv ).
    me->set_expand_option( changing co_hs_alv = o_hs_alv ).
    o_hs_alv->display( ).
  endmethod.                    "generate_output

  method set_event_handlers.
    data: lo_events type ref to cl_salv_events_hierseq.
    try .
        lo_events = co_hs_alv->get_event( ).
        set handler on_link_click for lo_events.
        set handler on_added_function for lo_events.
      catch cx_root.
    endtry.
  endmethod.

  method set_pf_status.
    data: lo_functions type ref to cl_salv_functions_list.
    lo_functions = co_hs_alv->get_functions(  ).
    lo_functions->set_all( abap_true ).

    co_hs_alv->set_screen_status( pfstatus = 'ZMM18VE' report = sy-repid set_functions = cl_salv_model_base=>c_functions_all ).
  endmethod.                    "set_pf_status

  method set_expand_option.
    data:
      lo_columns type ref to cl_salv_columns_hierseq,
      lo_column  type ref to cl_salv_column_hierseq.
    try.
        lo_columns = co_hs_alv->get_columns( 1 ).
        lo_columns->set_expand_column( 'EXPAND' ).
      catch cx_salv_data_error cx_root.                 "#EC NO_HANDLER
    endtry.
  endmethod.                    "set_expand_option


  method on_link_click.
        data lo_event type ref to cl_salv_events_hierseq.

        lo_event = o_hs_alv->get_event( ).
        field-symbols: <lfa_data> like line of lo_report->t_vekp.

        read table lo_report->t_vekp assigning <lfa_data> index row.
        check sy-subrc is initial.
        if <lfa_data>-expand is initial.
          <lfa_data>-expand = 'X'.
        else.
          clear <lfa_data>-expand.
        endif.

        lo_report->o_hs_alv->refresh( ).

  endmethod.

  method on_added_function.

  endmethod.
endclass.                    "lcl_report IMPLEMENTATION

1 Ответ

2 голосов
/ 01 марта 2020

Если я хорошо понимаю вопрос, вы хотите отловить событие при нажатии кнопки «Развернуть / Свернуть» ( + или - ) и определить, какая строка запрашивается.

Прежде всего, эта функция вообще не поддерживается, иначе было бы выделенное событие.

Я понимаю, что вы пытаетесь найти нестандартный обходной путь, поэтому позвольте мне продолжить что вы начали.

Обходной путь, который я предлагаю в дальнейшем, не поддерживается SAP .

Вы заметили, что нажатие этой кнопки соответствует позиционированию курсора на + / - (которая фактически считается полем с «горячей точкой») и нажатием кнопки F2 .

F2 * Кнопка 1024 * обычно соответствует двойному щелчку (событие DOUBLE_CLICK вызывается, когда оно выполняется в текстовых полях строки), но в случае + / - , это обрабатывается внутренне, и это событие не вызывается.

Ваша первоначальная идея переназначения клавиши F2 на код пользовательской функции через пользовательский GUI статус очень хороша. Он должен быть скопирован из состояния GUI SALV_TABLE_STANDARD из программы SAPLSALV_METADATA_STATUS, а в функциональных клавишах вы вводите любой код функции для F2 , например ZZ&IC1 (вместо предложенного &IC1) .

Осталось только определить, к какой строке относится. Вам необходимо отобразить c стандартный способ получения выбранной строки, основанный на сокрытии номера строки в глобальной переменной GS_HIDE-INDEX программы SAPLKKBL в каждой отображаемой строке списка ABAP и ее значение определяется путем определения местоположения курсора и чтения строки при нажатии кнопки или клавиши с помощью оператора READ CURRENT LINE или READ LINE currentline (currentline само определяется по GET CURSOR LINE currentline).

Надеемся, что глобальную переменную можно прочитать из любой программы с помощью оператора ASSIGN ('(programname)globalvariablename'), хотя это внутренний оператор, который не поддерживается SAP ( не жалуйтесь, если он будет удален в будущей версии).

В следующей программе при нажатии кнопки + в пятой строке отображается пользовательское сообщение «Запрос на расширение строки 5». «затем он вызывает стандартное поведение расширения дочерних узлов путем имитации стандартного кода функции &IC1 (помните, что он соответствует исходной клавише F2) через метод SET_FUNCTION:

enter image description here

enter image description here

CLASS lcl_report DEFINITION.
  PUBLIC SECTION.
    TYPES: BEGIN OF ty_scarr.
        INCLUDE TYPE scarr.
    TYPES: expand TYPE flag,
           END OF ty_scarr.
    DATA:
      t_scarr  TYPE STANDARD TABLE OF ty_scarr,
      t_spfli  TYPE STANDARD TABLE OF spfli,
      o_hs_alv TYPE REF TO cl_salv_hierseq_table.
    METHODS:
      get_data,
      generate_output.

  PRIVATE SECTION.
    METHODS:
      on_added_function FOR EVENT added_function OF cl_salv_events_hierseq
        IMPORTING e_salv_function sender.
ENDCLASS.

CLASS lcl_report IMPLEMENTATION.

  METHOD get_data.
    SELECT * FROM spfli INTO TABLE @t_spfli.
    SELECT * FROM scarr INTO TABLE @t_scarr.
    SORT t_scarr BY carrid.
    SORT t_spfli BY carrid connid.
  ENDMETHOD.

  METHOD generate_output.

    cl_salv_hierseq_table=>factory(
      EXPORTING
        t_binding_level1_level2 = VALUE #( ( master = 'CARRID' slave = 'CARRID' ) )
      IMPORTING
        r_hierseq               = o_hs_alv
      CHANGING
        t_table_level1          = t_scarr
        t_table_level2          = t_spfli ).

    SET HANDLER on_added_function FOR o_hs_alv->get_event( ).

    " ZMM18VE GUI status was created by copying the SALV_TABLE_STANDARD
    " from program SAPLSALV_METADATA_STATUS, and reassigning the
    " function key F2 to the new function code ZZ&IC1 (instead of &IC1).
    o_hs_alv->set_screen_status( pfstatus = 'ZMM18VE' report = sy-repid set_functions = cl_salv_model_base=>c_functions_all ).

    o_hs_alv->get_functions(  )->set_all( abap_true ).

    o_hs_alv->get_columns( 1 )->set_expand_column( 'EXPAND' ).

    o_hs_alv->display( ).

  ENDMETHOD.                    "generate_output

  METHOD on_added_function.
    DATA: cursor_field TYPE string.

    CASE e_salv_function.
      WHEN 'ZZ&IC1'.
        ASSIGN ('(SAPLKKBL)GS_HIDE-INDEX') TO FIELD-SYMBOL(<index>).
        CHECK sy-subrc = 0.
        GET CURSOR FIELD cursor_field.
        CASE cursor_field.
          WHEN 'SYM_MINUS_FOLDER'.
            MESSAGE |Request to collapse line { <index> }| TYPE 'I'.
          WHEN 'SYM_PLUS_FOLDER'.
            MESSAGE |Request to expand line { <index> }| TYPE 'I'.
        ENDCASE.
        " Execute standard Expand/Collapse
        o_hs_alv->set_function( '&IC1' ).
    ENDCASE.

  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.
  DATA: lo_report TYPE REF TO lcl_report.
  CREATE OBJECT lo_report.
  lo_report->get_data( ).
  lo_report->generate_output( ).
...