ABAP SALV实现弹出ALV选择

该代码示例展示了如何在ABAP中使用SALV(REUSE_ALV_POPUP_TO_SELECT)弹出ALV表格,实现单选功能。通过设置选择模式、调整列宽、隐藏列、修改列描述以及获取选定行数据,实现了所需的功能。在实现过程中遇到了列自适应、隐藏列、单选效果、列描述修改和获取选择数据等问题,最终通过SALV的API方法找到了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题场景

需要弹出一个ALV并获取选择的数据

实现思路

  1. 跳转屏幕
  2. 弹出ALV(通过SALV
  3. 弹出ALV(通过REUSE_ALV_POPUP_TO_SELECT

实现效果

因为这里需要的是单选,所以没有多选列
在这里插入图片描述

实现代码

 MODULE sel_zfretype INPUT.

  DATA:lt_zmmt041 LIKE TABLE OF zmmt041,
       lt_twlad   LIKE TABLE OF twlad,
       lt_twlad01 LIKE TABLE OF twlad.
  DATA:lfdnr TYPE lfdnr_twlad.

  DATA: lt_msg TYPE rs_t_msg,
        ls_msg TYPE bal_s_msg.
  DATA: lf_one_msg_as_sys_msg TYPE flag.

  DATA go_alv TYPE REF TO cl_salv_table.
  DATA: go_functions  TYPE REF TO cl_salv_functions_list,
        go_selections TYPE REF TO cl_salv_selections,
        go_layout     TYPE REF TO cl_salv_layout,
        go_display    TYPE REF TO cl_salv_display_settings.
  DATA: gr_columns TYPE REF TO cl_salv_columns_table.
  DATA: gr_column TYPE REF TO cl_salv_column_table.
  DATA lt_rows TYPE salv_t_row.
  DATA:ls_row TYPE LINE OF salv_t_row.

  DATA:lv_wlzs LIKE zmmtydand-menge.

  DATA:BEGIN OF lt_sel OCCURS 1,
         zbjh       LIKE zmmt041-zbjh,
         zxmh       LIKE zmmt041-zxmh,
         zfylx      LIKE zmmt041-zfylx,
         zfylx_t    LIKE zmmt041-zfylx_t,
         zvendor    LIKE zmmt041-zvendor,
         name2      LIKE zmmt041-name2,
         zkunnr     LIKE zmmt041-zkunnr,
         name1      LIKE zmmt041-name1,
         zarea      LIKE zmmt041-zarea,
         zcity      LIKE zmmt041-zcity,
         zcountry   LIKE zmmt041-zcountry,
         zarea_t    LIKE zsdt010-zarea_t,
         zcity_t    LIKE zsdt010-zcity_t,
         zcountry_t LIKE zsdt010-zcounty_t,
         zdj        LIKE zmmt041-zdj,
         zdtszl     LIKE zmmt041-zdtszl,
         zsl        LIKE zmmt041-zsl,
         zbz        LIKE zmmt041-zbz.
  DATA:END OF lt_sel.
  DATA:lt_lfa1     LIKE TABLE OF lfa1 WITH HEADER LINE,
       lt_zsdt0101 TYPE TABLE OF zsdt010 WITH HEADER LINE.
  REFRESH:lt_zmmt041,lt_twlad,lt_twlad01.
  "校验供应商
  IF g_wa_data-lifnr IS INITIAL.
    REFRESH lt_msg.
    CLEAR ls_msg.
    ls_msg-msgty = 'E'.
    ls_msg-msgid = 'ZMM01'.
    ls_msg-msgno = '113'.

    APPEND ls_msg TO lt_msg.
    IF lt_msg IS NOT INITIAL.
      cl_epic_ui_services=>show_messages_with_alog(
             it_messages       = lt_msg
             iv_one_msg_direct = lf_one_msg_as_sys_msg ).
      CLEAR:g_wa_item_fre-zfretype.
      RETURN.
    ENDIF.
  ENDIF.

  "处理费用类型描述
  CHECK g_wa_item_fre-zfrename <> '运输费用'.
  IF g_wa_item_fre-zfrename EQ '运输费用'.
    RETURN.
  ELSE.
    SELECT SINGLE zfrename INTO g_wa_item_fre-zfrename
    FROM zmmt037
    WHERE zfretype  = g_wa_item_fre-zfretype.
  ENDIF.
  CLEAR:g_wa_item_fre-zfredj,g_wa_item_fre-zfresl,g_wa_item_fre-zfretax,g_wa_item_fre-zfrecefy,g_wa_item_fre-zfreje.
  "处理单价和税率
  SELECT * FROM zmmt041 INTO CORRESPONDING FIELDS OF TABLE lt_zmmt041
  WHERE zvendor =  g_wa_data-lifnr AND vstel = g_wa_data-vstel
  AND zwxp = g_wa_data-zwxp AND zfylx = g_wa_item_fre-zfretype
  AND zstatus = '3' AND zyxqc < sy-datum AND zyxqd > sy-datum
  AND zwzc = g_wa_data-zwzc.

  "modify by wangk at 20230214 其他费用选择逻辑变更
  "处理最小桶数/重量,过滤高于最小桶数/重量的
  lv_wlzs = 0.
  LOOP AT g_it_item.
    lv_wlzs = lv_wlzs + g_it_item-menge.
  ENDLOOP.

  DELETE lt_zmmt041[] WHERE zdtszl >= lv_wlzs.
  IF lt_zmmt041[] IS INITIAL.
    g_wa_item_fre-zfrejhw = 'X'.
    RETURN.
  ENDIF.
  "选择报价
  REFRESH:lt_sel,lt_lfa1,lt_zsdt0101.
  MOVE-CORRESPONDING lt_zmmt041[] TO lt_sel[].

  SELECT * FROM lfa1 INTO CORRESPONDING FIELDS OF TABLE lt_lfa1
  FOR ALL ENTRIES IN lt_sel
  WHERE lifnr = lt_sel-zvendor.
  SELECT * FROM zsdt010 INTO CORRESPONDING FIELDS OF TABLE lt_zsdt0101.

  LOOP AT lt_sel INTO DATA(ls_sel).
    "供应商
    READ TABLE lt_lfa1 WITH KEY lifnr = ls_sel-zvendor.
    IF sy-subrc = 0.
      ls_sel-name2 = lt_lfa1-sortl.
    ENDIF.
    "三级地址
    IF ls_sel-zarea IS NOT INITIAL.
      READ TABLE lt_zsdt0101 WITH KEY zarea = ls_sel-zarea.
      IF sy-subrc = 0.
        ls_sel-zarea_t = lt_zsdt0101-zarea_t.
      ENDIF.
    ENDIF.
    IF ls_sel-zcity IS NOT INITIAL.
      READ TABLE lt_zsdt0101 WITH KEY zcity = ls_sel-zcity zarea = ls_sel-zarea.
      IF sy-subrc = 0.
        ls_sel-zcity_t = lt_zsdt0101-zcity_t.
      ENDIF.
    ENDIF.
    IF ls_sel-zcountry IS NOT INITIAL.
      READ TABLE lt_zsdt0101 WITH KEY zcounty = ls_sel-zcountry  zcity = ls_sel-zcity zarea = ls_sel-zarea.
      IF sy-subrc = 0.
        ls_sel-zcountry_t = lt_zsdt0101-zcounty_t.
      ENDIF.
    ENDIF.
    MODIFY lt_sel FROM ls_sel.
    CLEAR:ls_sel.
  ENDLOOP.

  TRY.
      cl_salv_table=>factory(
        IMPORTING
          r_salv_table = go_alv"方法生成的ALV容器对象
        CHANGING
          t_table      = lt_sel[] )."alv展示的数据

    CATCH cx_salv_msg.
  ENDTRY.
  go_functions = go_alv->get_functions( ).
  go_functions->set_all( 'X' )."设置默认按键
  go_selections = go_alv->get_selections( ).
  go_selections->set_selection_mode( if_salv_c_selection_mode=>single )."设置选择模式
  go_display = go_alv->get_display_settings( ).
  go_display->set_fit_column_to_table_size( 'X' )."列自适应

  gr_columns = go_alv->get_columns( ).
  gr_columns->set_optimize( 'X' ).
  gr_column ?= gr_columns->get_column( 'ZBZ' )."需处理的列
  gr_column->set_long_text( '备注' ).
  gr_column->set_medium_text( '备注' ).
  gr_column->set_short_text( '备注' ).
*gr_column->set_output_length( 15 ).
  gr_column ?= gr_columns->get_column( 'NAME2' )."需处理的列
  gr_column->set_long_text( '分包方' ).
  gr_column->set_medium_text( '分包方' ).
  gr_column->set_short_text( '分包方' ).
  gr_column ?= gr_columns->get_column( 'NAME1' )."需处理的列
  gr_column->set_long_text( '送达方' ).
  gr_column->set_medium_text( '送达方' ).
  gr_column->set_short_text( '送达方' ).
  gr_column ?= gr_columns->get_column( 'ZAREA_T' )."需处理的列
  gr_column->set_long_text( '目的城市(省)' ).
  gr_column->set_medium_text( '目的城市(省)' ).
  gr_column->set_short_text( '省' ).
  gr_column ?= gr_columns->get_column( 'ZCITY_T' )."需处理的列
  gr_column->set_long_text( '目的城市(市)' ).
  gr_column->set_medium_text( '目的城市(市)' ).
  gr_column->set_short_text( '市' ).
  gr_column ?= gr_columns->get_column( 'ZCOUNTRY_T' )."需处理的列
  gr_column->set_long_text( '目的城市(县//镇)' ).
  gr_column->set_medium_text( '目的城市(县//镇)' ).
  gr_column->set_short_text( '县/区/镇' ).
  gr_column ?= gr_columns->get_column( 'ZDTSZL' )."需处理的列
  gr_column->set_long_text( '最低桶数/重量' ).
  gr_column->set_medium_text( '最低桶数/重量' ).
  gr_column->set_short_text( '最低桶数/重量' ).
  gr_column ?= gr_columns->get_column( 'ZDJ' )."需处理的列
  gr_column->set_long_text( '单价' ).
  gr_column->set_medium_text( '单价' ).
  gr_column->set_short_text( '单价' ).


  gr_column ?= gr_columns->get_column( 'ZAREA' ).
  gr_column->set_visible( cl_salv_column_table=>false ).
  gr_column ?= gr_columns->get_column( 'ZCITY' ).
  gr_column->set_visible( cl_salv_column_table=>false ).
  gr_column ?= gr_columns->get_column( 'ZCOUNTRY' ).
  gr_column->set_visible( cl_salv_column_table=>false ).
  gr_column ?= gr_columns->get_column( 'ZFYLX' ).
  gr_column->set_visible( cl_salv_column_table=>false ).
  gr_column ?= gr_columns->get_column( 'ZBJH' ).
  gr_column->set_visible( cl_salv_column_table=>false ).
  gr_column ?= gr_columns->get_column( 'ZXMH' ).
  gr_column->set_visible( cl_salv_column_table=>false ).
  gr_column ?= gr_columns->get_column( 'ZVENDOR' ).
  gr_column->set_visible( cl_salv_column_table=>false ).
  gr_column ?= gr_columns->get_column( 'ZKUNNR' ).
  gr_column->set_visible( cl_salv_column_table=>false ).
  gr_column ?= gr_columns->get_column( 'ZSL' ).
  gr_column->set_visible( cl_salv_column_table=>false ).

  IF go_alv IS BOUND.
    go_alv->set_screen_popup(
      start_column = 10
      end_column  = 110
      start_line  = 5
      end_line    = 15 ).
    go_alv->display( ). "调用显示方法
  ENDIF.

  REFRESH:lt_rows.
  lt_rows = go_selections->get_selected_rows( ).
  IF lt_rows[] IS INITIAL.
    g_wa_item_fre-zfrejhw = 'X'.
    RETURN.
  ENDIF.
  LOOP AT lt_rows INTO ls_row.
    READ TABLE lt_sel INTO DATA(ls_zmmt041) INDEX ls_row.
    g_wa_item_fre-zfredj = ls_zmmt041-zdj.
    g_wa_item_fre-zfretax = ls_zmmt041-zsl.
    g_wa_item_fre-zfrejhw = ''.
    CLEAR:ls_row.
  ENDLOOP.
ENDMODULE.     

实现过程思路

  1. 因为屏幕这块做的比较多了,所以这次就想通过ALV实现,一开始使用的函数:REUSE_ALV_POPUP_TO_SELECT。使用这个函数遇到了1个问题:无法实现单选。一直没有找到解决方案,就放弃了。
  2. 采用SALV实现,系统提供了一个示例程序可以参考:SALV_TEST_TABLE_SELECTIONS
    使用这个方案也是需要解决几个问题:a.列的宽度自适应 b.隐藏列 c.实现单单选效果 d.修改列对应的描述 e.获取返回的数据
    问题a: 想通过下面这个方法实现
go_display = go_alv->get_display_settings( ).
go_display->set_fit_column_to_table_size( 'X' )."列自适应

但是调试一直不生效,没找到问题出在哪里。
后面通过另外一种方案实现:

gr_columns = go_alv->get_columns( ).
gr_columns->set_optimize( 'X' ).

成功达到了想要的效果。
问题b:
这里我想到了fieldcat,但是SALV的fieldcat是通过以下实现的

gr_column ?= gr_columns->get_column( 'ZAREA' ).
gr_column->set_visible( cl_salv_column_table=>false ).

问题c:

go_selections = go_alv->get_selections( ).
go_selections->set_selection_mode( if_salv_c_selection_mode=>single )."设置选择模式

这里有几种选择模式
在这里插入图片描述
问题d:

gr_columns = go_alv->get_columns( ).
gr_column ?= gr_columns->get_column( 'ZBZ' )."需处理的列
gr_column->set_long_text( '备注' ).
gr_column->set_medium_text( '备注' ).
gr_column->set_short_text( '备注' ).
*gr_column->set_output_length( 15 ).

gr_column下面有很多方法
在这里插入图片描述
这里面也有几个关于前导0的函数,我也是多次调试没有生效,截止到现在没有找到问题的原因,因为最近需求比较急,我就没花时间去深究。
问题e:
在display( )方法后面可以通过函数获取选择的行。

IF go_alv IS BOUND.
  go_alv->set_screen_popup(
    start_column = 10
    end_column  = 110
    start_line  = 5
    end_line    = 15 ).
  go_alv->display( ). "调用显示方法
ENDIF.

REFRESH:lt_rows.
lt_rows = go_selections->get_selected_rows( ).

LOOP AT lt_rows INTO ls_row.
  READ TABLE lt_sel INTO DATA(ls_zmmt041) INDEX ls_row.
ENDLOOP.

附加收获

下面是一段逻辑流,遇到的问题及解决方案:

  1. 编辑后保存不了——没有写FIELD
  2. 写了MODULE没有生效——需要计算的数据一定顺序一定在被计算的后面,比如下面的zfreje和zfrecefy是由zfredj和zfresl计算出来的,那么顺序上zfreje和zfrecefy要在上面
  3. 改了zfretype其他字段没有更新——因为zfretype的优先级最高,所以要放在最后,这样zfretype对应的MODULE才会覆盖前面的字段。
  LOOP AT g_it_item_fre.
    CHAIN.
      FIELD g_wa_item_fre-zno.
      FIELD g_wa_item_fre-zfreje.
      FIELD g_wa_item_fre-zfrecefy.
      FIELD g_wa_item_fre-zfredj MODULE js_zfreje ON REQUEST.
      FIELD g_wa_item_fre-zfresl MODULE js_zfreje ON REQUEST.
      FIELD g_wa_item_fre-zfretax.
      FIELD g_wa_item_fre-zfrejhw.
      FIELD g_wa_item_fre-zfretype MODULE sel_zfretype ON REQUEST.

      MODULE tab_item_fre_modify ON CHAIN-REQUEST.
    ENDCHAIN.

    FIELD g_wa_item_fre-box
      MODULE tab_item_fre_mark ON REQUEST.
  ENDLOOP.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值