SAP ABAP动态生成OOALV 并实现更新底表数据的需求

本文已参与「新人创作礼」活动,一起开启掘金创作之路

需求

根据要求,生产系统要收回部分账号的debug权限,用户或顾问需要更改单据状态之后就不能再利用SE16/SE16N进行DEBUG更改数据了,现统一做一个通用程序来查询更改底表数据。

V1: 功能操作总体思路: 根据选择屏幕输入的表名与字段名,动态生成OOALV,查询出对应数据并实现可更新底表数据

V2: 新增:保存修改日志,优化程序等

V3: 修复:特殊转换例程ALPHA 转换后字符串长度过长的问题

目前程序为V3最终版,后期有什么新想法会更新的


一、实现效果

1.1 输入表名

在这里插入图片描述

1.2 选择表中字段

在这里插入图片描述 在这里插入图片描述

1.3 执行

自动带出表中关键字,且更新字段checkbox不可选 此处我设置的有校验,至少要有一个关键字填有数据(在low中有值)作为查询条件
在这里插入图片描述

1.4 填入条件 点击查询

在这里插入图片描述

1.5 数据更改前

在这里插入图片描述

1.6 选择更新字段的checlbox 更改状态 然后【更改数据】

把审批状态改为4,点击更新数据,提示勾选更新字段 在这里插入图片描述

1.7 勾选后继续

在这里插入图片描述 看更新后底表此条数据,已更新 在这里插入图片描述

1.8 新增修改日志表

查看修改日志 在这里插入图片描述

二、代码

2.1 主程序

*&---------------------------------------------------------------------*
*& Report  ZTEST_UPDATE_DATA_COMMON
*&         Description:动态生成alv 并实现更新底表数据
*&---------------------------------------------------------------------*
*&         Author:
*&         Date:20220223
*&---------------------------------------------------------------------*

REPORT ztest_update_data_common.

INCLUDE:ztest_update_data_common_top,
        ztest_update_data_common_cls,
        ztest_update_data_common_evt,
        ztest_update_data_common_f01.

AT SELECTION-SCREEN ON  VALUE-REQUEST FOR s_tabnam-low.
  PERFORM frm_request_f4_tab USING 'S_TABNAM-LOW'.

AT SELECTION-SCREEN ON  VALUE-REQUEST FOR s_flnam-low.
  PERFORM frm_request_f4_field USING 'S_FLNAM-LOW'.

INITIALIZATION.

START-OF-SELECTION.

  PERFORM frm_check_input_or_auth.

  CALL SCREEN 100.

*  采用OOALV
*  container NAME: GV_CON
复制代码

2.2 INCLUDE

2.2.1 TOP

*&---------------------------------------------------------------------*
*&  包含                ZTEST_UPDATE_DATA_COMMON_TOP
*&---------------------------------------------------------------------*


TABLES:ztest_d_com_tab,dd03d.

DATA:go_100_cc    TYPE REF TO cl_gui_custom_container,
     go_100_split TYPE REF TO cl_gui_splitter_container.

DATA:gt_fieldcat_200          TYPE                   lvc_t_fcat,
     gt_fieldcat_300          TYPE                   lvc_t_fcat,
*     gs_fieldcat              TYPE                   lvc_s_fcat,
     gs_layout                TYPE                   lvc_s_layo,

     gs_stable                TYPE                   lvc_s_stbl,
     go_200_cc                TYPE REF TO            cl_gui_container,
     go_300_cc                TYPE REF TO            cl_gui_container,
     go_200_grid              TYPE REF TO            cl_gui_alv_grid,
     go_300_grid              TYPE REF TO            cl_gui_alv_grid,

     gs_200_disvariant        TYPE                   disvariant,
     gs_300_disvariant        TYPE                   disvariant,
     gv_200_fill              TYPE                   boolean,
     gv_300_fill              TYPE                   boolean,
     gt_200_toolbar_ex        TYPE                   ui_functions,
     gt_300_toolbar_ex        TYPE                   ui_functions,

     gt_fields_t              TYPE STANDARD TABLE OF dd03p,
     gt_fields                TYPE TABLE OF          ztest_s_field_com,
     gs_field                 TYPE                   ztest_s_field_com
     .

FIELD-SYMBOLS:<ft_dyn_table> TYPE STANDARD TABLE.

SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.

SELECT-OPTIONS:
s_tabnam FOR ztset_d_com_tab-tabname MODIF ID g1 NO INTERVALS NO-EXTENSION,
s_flnam FOR dd03d-fieldname MODIF ID g1 NO INTERVALS.

SELECTION-SCREEN ULINE.

SELECTION-SCREEN END OF BLOCK b1.
复制代码

ztest_s_field_com为屏幕中上面的alv所用到结构 可参照如下

fields.png

ZOPTION为阈值,方便后续写SQL 在这里插入图片描述 表名配置表:ZTEST_D_COM_TAB 在这里插入图片描述 文本表:ZTEST_D_COM_TABT 在这里插入图片描述 日志表:ZTEST_D_COM_TCLOG 在这里插入图片描述

2.2.2 CLS

user command 等实现方法

动态SQL查询与动态SQL更新底表数据均在这里面

*&---------------------------------------------------------------------*
*&  包含                ZTEST_UPDATE_DATA_COMMON_CLS
*&---------------------------------------------------------------------*
CLASS lcl_event_receiver_200 DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
*      handle_double_click FOR EVENT double_click OF cl_gui_alv_grid
*        IMPORTING
*            e_row
*            e_column
*            es_row_no,
*
*      handle_top_of_page FOR EVENT top_of_page OF cl_gui_alv_grid
*        IMPORTING
*            e_dyndoc_id,
*
*      handle_hotspot_click FOR EVENT hotspot_click OF cl_gui_alv_grid
*        IMPORTING
*            e_row_id
*            e_column_id,

      handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
        IMPORTING
            e_object
            e_interactive,

      handle_command FOR EVENT user_command OF cl_gui_alv_grid
        IMPORTING
            e_ucomm.

  PRIVATE SECTION.
ENDCLASS. "lcl_event_receiver_200 DEFINITION

CLASS lcl_event_receiver_200 IMPLEMENTATION.

*  METHOD handle_double_click.
*
*  ENDMETHOD.
*
*  METHOD handle_top_of_page.
*
*  ENDMETHOD.
*
*  METHOD handle_hotspot_click.
*
*  ENDMETHOD.

  METHOD handle_toolbar.

*    DATA:ls_tb TYPE stb_button.
    FIELD-SYMBOLS:<fs_s_tb> TYPE stb_button.
*----------------------------------------------------------------------*
* 新增button
*----------------------------------------------------------------------*
*分隔符
    APPEND INITIAL LINE TO e_object->mt_toolbar ASSIGNING <fs_s_tb>.
    <fs_s_tb>-butn_type = 3.
*    执行查询
    APPEND INITIAL LINE TO e_object->mt_toolbar ASSIGNING <fs_s_tb>.
    <fs_s_tb>-butn_type = 0."0 button;2 button list.
    <fs_s_tb>-function = 'EXEC'.
    <fs_s_tb>-icon = icon_execute_object.
    <fs_s_tb>-text = text-002.

**    去除可能影响结果的按钮
*    LOOP AT e_object->mt_toolbar INTO ls_tb.

*      IF ls_tb-function EQ '&LOCAL&CUT' OR ls_tb-function EQ '&LOCAL&PASTE'
*        OR ls_tb-function EQ '&LOCAL&APPEND' OR ls_tb-function EQ '&LOCAL&INSERT_ROW'
*         OR ls_tb-function EQ '&LOCAL&DELETE_ROW' OR ls_tb-function EQ '&LOCAL&COPY_ROW'.
*        DELETE e_object->mt_toolbar INDEX sy-tabix.
*      ENDIF.

*    ENDLOOP.

  ENDMETHOD.

  METHOD handle_command.

    DATA:lv_tabname(30) TYPE          c,
         lt_where_tab   TYPE          rsds_where_tab,
         lv_where_tab   TYPE          sychar72,
         lv_where_tab1  TYPE          sychar72,
         lv_key_init    TYPE          sap_bool,
         lt_celltab     TYPE          lvc_t_styl,
         lt_celltab_t   TYPE TABLE OF lvc_s_styl,
         ls_celltab     TYPE          lvc_s_styl,

*         struct_type    TYPE REF TO   cl_abap_structdescr,
*         lt_comp_tab    TYPE          cl_abap_structdescr=>component_table,
*         ls_comp_tab    LIKE LINE OF  lt_comp_tab,
*         lo_type        TYPE REF TO   cl_abap_datadescr,
*         lv_str         TYPE          string,
         lv_value       TYPE          string,
         lv_convt       TYPE          rs38l_fnam,
         lv_length      TYPE          int4
         .

    FIELD-SYMBOLS:<fs_dyn_wa> TYPE            any,
                  <ft_tab>    TYPE ANY TABLE.

    lv_tabname = s_tabnam-low.
    gs_stable-row = 'X'.
    gs_stable-col = 'X'.

    IF go_200_grid IS BOUND.

      CALL METHOD go_200_grid->refresh_table_display
        EXPORTING
          is_stable = gs_stable
        EXCEPTIONS
          finished  = 1
          OTHERS    = 2.

    ENDIF.

    CASE e_ucomm.
      WHEN 'EXEC'.

*        确保主键有值
        LOOP AT gt_fields INTO gs_field WHERE key_flag EQ abap_true.

          IF gs_field-low IS NOT INITIAL.
            lv_key_init = abap_true.
            EXIT.
          ENDIF.

        ENDLOOP.

        IF lv_key_init NE abap_true.
          MESSAGE i147(zps) WITH text-009.
        ELSE.

*          struct_type ?= cl_abap_typedescr=>describe_by_name( s_tabnam-low )."结构类型
*          lt_comp_tab = struct_type->get_components( )."组成结构体的各个字段组件

          LOOP AT gt_fields INTO gs_field WHERE low IS NOT INITIAL.

*            READ TABLE lt_comp_tab INTO ls_comp_tab WITH KEY name = gs_field-fieldname.
*            IF sy-subrc EQ 0.
*
*              lo_type = ls_comp_tab-type.
*              lv_str = lo_type->absolute_name.
*              REPLACE ALL OCCURRENCES OF '\TYPE=' IN lv_str WITH ``.
*              "(将lv_string 中 所有 \TYPE= 删除 )
*              IF sy-subrc EQ 0.

*            处理内外码不一致的数据 有转换例程的就转换为内码,本身是内码的不做处理
            CLEAR:lv_value.
            IF gs_field-convexit IS NOT INITIAL.

              lv_convt = 'CONVERSION_EXIT_' && gs_field-convexit && '_INPUT'.

              CALL FUNCTION lv_convt
                EXPORTING
                  input  = gs_field-low
                IMPORTING
                  output = lv_value.
              IF lv_value IS NOT INITIAL.

*                ADD   20220324
*                避免前导零转换例程多出0
                IF strlen( lv_value ) > gs_field-length.
                  lv_length = strlen( lv_value ) - gs_field-length.
                  lv_value = lv_value+lv_length(gs_field-length).
                ENDIF.
*                END  ADD

                gs_field-low = lv_value.

              ENDIF.

              IF gs_field-high IS NOT INITIAL.

                CALL FUNCTION lv_convt
                  EXPORTING
                    input  = gs_field-high
                  IMPORTING
                    output = lv_value.
                IF lv_value IS NOT INITIAL.

                  gs_field-high = lv_value.

                ENDIF.

              ENDIF.

            ENDIF.

*              ENDIF.
*            ENDIF.

            IF gs_field-zoption EQ 'BETWEEN'.
              IF gs_field-low IS NOT INITIAL AND gs_field-high IS NOT INITIAL.

                lv_where_tab = '''' && gs_field-low && ''''.
                lv_where_tab1 = '''' && gs_field-high && ''''.
                CONCATENATE gs_field-fieldname gs_field-zoption lv_where_tab 'AND' lv_where_tab1 INTO lv_where_tab SEPARATED BY ' '.

              ELSE.

                MESSAGE i147(zps) WITH text-010.
                CLEAR:lt_where_tab.
                IF <ft_dyn_table> IS NOT INITIAL.
                  CLEAR:<ft_dyn_table>.
                ENDIF.
                EXIT.

              ENDIF.

            ELSEIF gs_field-zoption EQ 'LIKE'.

              lv_where_tab = '''' && '%' && gs_field-low && '%' && ''''.
              CONCATENATE gs_field-fieldname gs_field-zoption lv_where_tab INTO lv_where_tab SEPARATED BY ' '.

            ELSE.

              lv_where_tab = '''' && gs_field-low && ''''.
              CONCATENATE gs_field-fieldname gs_field-zoption lv_where_tab INTO lv_where_tab SEPARATED BY ' '.

            ENDIF.

            IF lt_where_tab IS NOT INITIAL.
              CONCATENATE 'AND' lv_where_tab INTO lv_where_tab SEPARATED BY ' '.
            ENDIF.
            APPEND lv_where_tab TO lt_where_tab.

          ENDLOOP.


*        获取当前alv内容 并拼凑查询条件
          IF <ft_dyn_table> IS ASSIGNED AND lt_where_tab IS NOT INITIAL.

            SELECT * INTO CORRESPONDING FIELDS OF TABLE <ft_dyn_table>
              FROM (lv_tabname)
              WHERE (lt_where_tab).

            IF go_300_grid IS BOUND AND sy-subrc EQ 0.

*              设置无勾选更新字段不可编辑

              CLEAR:lt_celltab,lt_celltab_t.
              LOOP AT gt_fields INTO gs_field WHERE key_flag NE abap_true.

                IF  gs_field-zif_edit NE abap_true.
                  ls_celltab-style = cl_gui_alv_grid=>mc_style_disabled.
                ELSEIF gs_field-zif_edit EQ abap_true.
                  ls_celltab-style = cl_gui_alv_grid=>mc_style_enabled.
                ENDIF.
                ls_celltab-fieldname = gs_field-fieldname.
                APPEND ls_celltab TO lt_celltab_t.

              ENDLOOP.

*              由于LT_CELLTAB参考的表类型是排序表 需要对结果承接并排序再赋值
              IF lt_celltab_t IS NOT INITIAL.

                SORT lt_celltab_t BY fieldname.
                APPEND LINES OF lt_celltab_t TO lt_celltab.

              ENDIF.

              LOOP AT <ft_dyn_table> ASSIGNING <fs_dyn_wa>.

                ASSIGN COMPONENT 'CELLTAB' OF STRUCTURE <fs_dyn_wa> TO <ft_tab>.
                IF sy-subrc EQ 0.
                  <ft_tab> = lt_celltab.
                ENDIF.

              ENDLOOP.

              IF <ft_dyn_table_tmp> IS ASSIGNED.

                <ft_dyn_table_tmp> = <ft_dyn_table>.

              ENDIF.

              CALL METHOD go_300_grid->refresh_table_display
                EXPORTING
                  is_stable = gs_stable
                EXCEPTIONS
                  finished  = 1
                  OTHERS    = 2.

            ENDIF.

          ENDIF.

        ENDIF.
      WHEN OTHERS.
    ENDCASE.

  ENDMETHOD.

ENDCLASS.

CLASS lcl_event_receiver_300 DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
        IMPORTING
            e_object
            e_interactive,

      handle_command FOR EVENT user_command OF cl_gui_alv_grid
        IMPORTING
            e_ucomm.

  PRIVATE SECTION.
ENDCLASS. "lcl_event_receiver_300 DEFINITION

CLASS lcl_event_receiver_300 IMPLEMENTATION.

  METHOD handle_toolbar.

*    DATA:ls_tb TYPE stb_button.
    FIELD-SYMBOLS:<fs_s_tb> TYPE stb_button.
*----------------------------------------------------------------------*
* 新增button
*----------------------------------------------------------------------*
*分隔符
    APPEND INITIAL LINE TO e_object->mt_toolbar ASSIGNING <fs_s_tb>.
    <fs_s_tb>-butn_type = 3.
*    执行更新
    APPEND INITIAL LINE TO e_object->mt_toolbar ASSIGNING <fs_s_tb>.
    <fs_s_tb>-butn_type = 0."0 button;2 button list.
    <fs_s_tb>-function = 'UPD_DATA'.
    <fs_s_tb>-icon = icon_budget_update.
    <fs_s_tb>-text = text-003.

**    去除可能影响结果的按钮
*    LOOP AT e_object->mt_toolbar INTO ls_tb.

*      IF ls_tb-function EQ '&LOCAL&CUT' OR ls_tb-function EQ '&LOCAL&PASTE'
*      OR ls_tb-function EQ '&LOCAL&APPEND' OR ls_tb-function EQ '&LOCAL&INSERT_ROW'
*      OR ls_tb-function EQ '&LOCAL&DELETE_ROW' OR ls_tb-function EQ '&LOCAL&COPY_ROW'.
*        DELETE e_object->mt_toolbar INDEX sy-tabix.
*      ENDIF.

*    ENDLOOP.

  ENDMETHOD.

  METHOD handle_command.

    DATA:lv_tabname   TYPE          tabname,
*         lv_fieldname TYPE          dd03d-fieldname,
         lt_where_tab TYPE          rsds_where_tab,
         lv_where_tab TYPE          sychar72,
         lv_value     TYPE          string,
         lv_count     TYPE          int2,
*         lv_fail      TYPE          sap_bool,
         lv_str       TYPE          string,
         lv_chgid     TYPE          int4,
         lv_tabix     TYPE          sy-tabix,

         ls_tclog     TYPE          ztest_d_com_tclog,
         lt_tclog     TYPE TABLE OF ztest_d_com_tclog
         .
    FIELD-SYMBOLS:<fs_dyn_wa>  TYPE any,
                  <fs_dyn_wa1> TYPE any,
                  <fv_value>   TYPE any,
                  <fv_value1>  TYPE any.

    lv_tabname = s_tabnam-low.

    CASE e_ucomm.
      WHEN 'UPD_DATA'.
*        根据alv更新底表数据

        IF <ft_dyn_table> IS ASSIGNED.

          READ TABLE gt_fields WITH KEY zif_edit = abap_true TRANSPORTING NO FIELDS.
          IF sy-subrc NE 0.

            MESSAGE i147(zps) WITH text-012.

          ELSE.

*            更新数据
            CLEAR:lt_where_tab,lt_tclog,lv_count.
            IF <ft_dyn_table> IS ASSIGNED.

              LOOP AT <ft_dyn_table> ASSIGNING <fs_dyn_wa>.

                lv_tabix = sy-tabix.

*                日志表
                SELECT MAX( zchgid ) INTO lv_chgid
                FROM ztest_d_com_tclog
                WHERE zchguser EQ sy-uname.
                IF sy-subrc NE 0.
                  lv_chgid = 0.
                ENDIF.

                CLEAR:lt_where_tab,lv_value,ls_tclog.

                ls_tclog-zchguser = sy-uname.
                ls_tclog-zchgdb = s_tabnam-low.
                CALL FUNCTION 'IB_CONVERT_INTO_TIMESTAMP'
                  EXPORTING
                    i_datlo     = sy-datum
                    i_timlo     = sy-timlo
                    i_tzone     = sy-zonlo
                  IMPORTING
                    e_timestamp = ls_tclog-zchgtimes.

                LOOP AT gt_fields INTO gs_field.

                  ls_tclog-zchgfield = gs_field-fieldname.
                  ls_tclog-zchgid = lv_chgid = lv_chgid + 1.

                  IF lv_chgid GE 9999999999.
                    MESSAGE e147(zps) WITH '当前用户修改表记录将超过9999999999条限制,请先清理!'.
                  ENDIF.

                  ASSIGN COMPONENT gs_field-fieldname OF STRUCTURE <fs_dyn_wa> TO <fv_value>.
                  IF sy-subrc EQ 0.

                    IF gs_field-zif_edit NE abap_true.

                      lv_where_tab = '''' && <fv_value> && ''''.
                      CONCATENATE gs_field-fieldname 'EQ' lv_where_tab INTO lv_where_tab SEPARATED BY ' '.

                      IF lt_where_tab IS NOT INITIAL.
                        CONCATENATE 'AND' lv_where_tab INTO lv_where_tab SEPARATED BY ' '.
                      ENDIF.
                      APPEND lv_where_tab TO lt_where_tab.

                      IF <ft_dyn_table_tmp> IS ASSIGNED.

                        READ TABLE <ft_dyn_table_tmp> ASSIGNING <fs_dyn_wa1> INDEX lv_tabix.
                        IF sy-subrc EQ 0.

                          ASSIGN COMPONENT gs_field-fieldname OF STRUCTURE <fs_dyn_wa1> TO <fv_value1>.
                          IF sy-subrc EQ 0.
                            ls_tclog-zfroval = <fv_value1>.
                          ENDIF.

                        ENDIF.

                      ENDIF.
                      CLEAR:ls_tclog-zaftval.
                      APPEND ls_tclog TO lt_tclog.

                    ELSE.

                      lv_str = '''' && <fv_value> && ''''.
                      CONCATENATE gs_field-fieldname '=' lv_str INTO lv_str SEPARATED BY ' '.
                      IF lv_value IS NOT INITIAL.
                        CONCATENATE lv_value lv_str INTO lv_value SEPARATED BY ' '.
                      ELSE.
                        lv_value = lv_str.
                      ENDIF.

                      IF <ft_dyn_table_tmp> IS ASSIGNED.

                        READ TABLE <ft_dyn_table_tmp> ASSIGNING <fs_dyn_wa1> INDEX lv_tabix.
                        IF sy-subrc EQ 0.

                          ASSIGN COMPONENT gs_field-fieldname OF STRUCTURE <fs_dyn_wa1> TO <fv_value1>.
                          IF sy-subrc EQ 0.
                            ls_tclog-zfroval = <fv_value1>.
                          ENDIF.

                        ENDIF.

                      ENDIF.
                      ls_tclog-zaftval = <fv_value>.
                      APPEND ls_tclog TO lt_tclog.

                    ENDIF.

                  ENDIF.

                ENDLOOP.

                IF lv_value IS NOT INITIAL AND lt_where_tab IS NOT INITIAL.

*                  有值改变的才更新值 和保存到日志表
                  CLEAR:lv_str.
                  LOOP AT lt_tclog INTO ls_tclog.

                    IF ls_tclog-zfroval NE ls_tclog-zaftval AND ls_tclog-zaftval IS NOT INITIAL.
                      lv_str = 'X'.
                      EXIT.
                    ENDIF.

                  ENDLOOP.

                  IF NOT lv_str IS INITIAL.

                    UPDATE (lv_tabname) SET (lv_value) WHERE (lt_where_tab).
                    IF sy-subrc NE 0.
                      ROLLBACK WORK.
*                      lv_fail = abap_true.
                      MESSAGE i147(zps) WITH text-013.
                      EXIT.
                    ELSE.

*                    更新日志到底表
                      IF lt_tclog IS NOT INITIAL.

                        MODIFY ztest_d_com_tclog FROM TABLE lt_tclog.

                      ENDIF.
                    ENDIF.

                    COMMIT WORK.

*                    统计更新条数
                    lv_count = lv_count + 1.

                  ENDIF.

                ENDIF.

              ENDLOOP.

            ENDIF.


*            IF lv_fail NE abap_true.

*              IF <ft_dyn_table> IS ASSIGNED.
*
*                lv_count = lines( <ft_dyn_table> ).
*
*              ENDIF.
            IF lv_count GE 1.
              MESSAGE i147(zps) WITH text-014 lv_count.
            ENDIF.

*            ENDIF.

          ENDIF.

        ELSE.

          MESSAGE i147(zps) WITH text-011.

        ENDIF.

      WHEN OTHERS.
    ENDCASE.

    gs_stable-row = 'X'.
    gs_stable-col = 'X'.

    IF go_300_grid IS BOUND.

      CALL METHOD go_300_grid->refresh_table_display
        EXPORTING
          is_stable = gs_stable
        EXCEPTIONS
          finished  = 1
          OTHERS    = 2.

    ENDIF.

  ENDMETHOD.

ENDCLASS.
复制代码

2.2.3 EVT

初始化动态ALV,获取数据,分割CONTAINER

*----------------------------------------------------------------------*
***INCLUDE ZTEST_UPDATE_DATA_COMMON_EVT.
*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*&      Module  STATUS_0100  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
  SET PF-STATUS 'ZSTATUS'.
  SET TITLEBAR 'ZT001'.
ENDMODULE.                 " STATUS_0100  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0100  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE user_command_0100 INPUT.

  DATA:ok_code LIKE sy-ucomm,
       save_ok LIKE sy-ucomm.

  save_ok = ok_code.
  CLEAR:ok_code.

  CASE save_ok.
    WHEN '&F03' OR '&F15' OR '&F12'.
      LEAVE TO SCREEN 0.
*    WHEN .
    WHEN OTHERS.
  ENDCASE.

ENDMODULE.                 " USER_COMMAND_0100  INPUT
*&---------------------------------------------------------------------*
*&      Module  SCR_100_INIT  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE scr_100_init OUTPUT.

  PERFORM frm_get_data.
*  PERFORM frm_set_display_param.

ENDMODULE.                 " SCR_100_INIT  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  ALV_SCREEN_SPLITER  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE alv_screen_spliter OUTPUT.

*  "alv splitter
  IF go_100_split IS NOT BOUND.

    IF go_100_cc IS NOT BOUND.

      CREATE OBJECT go_100_cc
        EXPORTING
          container_name = 'GC_CON'.

    ENDIF.

    CREATE OBJECT go_100_split
      EXPORTING
        parent  = go_100_cc
        rows    = 2
        columns = 1.

    IF go_200_cc IS NOT BOUND.

      CALL METHOD go_100_split->get_container
        EXPORTING
          row       = 1
          column    = 1
        RECEIVING
          container = go_200_cc.

      CALL METHOD go_100_split->set_column_width
        EXPORTING
          id    = 1
          width = 100.

    ENDIF.

    IF go_300_cc IS NOT BOUND.

      CALL METHOD go_100_split->get_container
        EXPORTING
          row       = 2
          column    = 1
        RECEIVING
          container = go_300_cc. "go_container

      CALL METHOD go_100_split->set_column_width
        EXPORTING
          id    = 2
          width = 100.

    ENDIF.

  ENDIF.

ENDMODULE.                 " ALV_SCREEN_SPLITER  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  SCR_100_DSP  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE scr_100_dsp OUTPUT.

  IF gv_200_fill NE abap_true.

    IF go_200_grid IS NOT BOUND.

      CREATE OBJECT go_200_grid
        EXPORTING
          i_parent = go_200_cc.

    ENDIF.

    PERFORM frm_set_fieldcat USING 200 CHANGING gt_fieldcat_200.

    PERFORM frm_set_layout USING 200 CHANGING gs_layout.

*   保存格式
    CLEAR gs_200_disvariant.
    gs_200_disvariant-report = sy-repid.
    gs_200_disvariant-handle = '200'.
    gs_200_disvariant-username = sy-uname.

*    CREATE OBJECT go_event.
*    SET HANDLER lcl_event_receiver_200=>handle_double_click FOR go_200_grid.     "穿透-双击事件
    SET HANDLER lcl_event_receiver_200=>handle_toolbar FOR go_200_grid.          "工具栏
    SET HANDLER lcl_event_receiver_200=>handle_command FOR go_200_grid.          "自定义事件

*    主键设置不可选更新
    PERFORM frm_init_style_tab.

*    取消部分按钮
    PERFORM frm_build_excl_func_rstgr USING 200 CHANGING gt_200_toolbar_ex.

*    设置下拉列表
*    PERFORM frm_set_list_dropdown.

*   第一次显示ALV
    go_200_grid->set_table_for_first_display(
    EXPORTING
      is_variant           = gs_200_disvariant
      i_save               = 'U'
      is_layout            = gs_layout
      it_toolbar_excluding = gt_200_toolbar_ex
    CHANGING
      it_fieldcatalog      = gt_fieldcat_200
      it_outtab            = gt_fields ).

    gv_200_fill = abap_true.

    CALL METHOD go_200_grid->register_edit_event "注册编辑事件,否则不会触发更新事件
      EXPORTING
        i_event_id = cl_gui_alv_grid=>mc_evt_modified.

  ELSE.

* 刷新ALV
    go_200_grid->refresh_table_display( ).

  ENDIF.


*  CALL METHOD cl_gui_cfw=>flush.

ENDMODULE.                 " SCR_100_DSP  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  SCR_300_INIT  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*MODULE scr_300_init OUTPUT.
*
*ENDMODULE.                 " SCR_300_INIT  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  SCR_300_DSP  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE scr_300_dsp OUTPUT.

*  初始化动态结构,内表

  DATA:
*    dref_str             TYPE REF TO  data,
    dref_tab             TYPE REF TO  data,
*    dref_s               TYPE REF TO  data,
*    elem_type            TYPE REF TO  cl_abap_elemdescr,
    struct_type          TYPE REF TO  cl_abap_structdescr,
    lo_struct_include    TYPE REF TO  cl_abap_structdescr,
    table_type           TYPE REF TO  cl_abap_tabledescr,
    lt_comp_tab          TYPE         cl_abap_structdescr=>component_table,
    lt_component_include TYPE         cl_abap_structdescr=>component_table,
    ls_comp_tab          LIKE LINE OF lt_comp_tab,
    lv_tabix             TYPE         sy-tabix.
*    获取screen_0100值
  DATA:lt_fields_t TYPE TABLE OF dd03p,
       ls_field_t  TYPE          dd03p,
       lv_tabname  TYPE          dd03p-tabname.


*  ASSIGN
  IF gt_fields_t IS NOT INITIAL.

    CLEAR:lt_comp_tab.

*        创建动态结构
*    elem_type ?= cl_abap_elemdescr=>get_string( ).
*    CREATE DATA dref_s TYPE HANDLE elem_type .

*        动态创建结构类型
    struct_type ?= cl_abap_typedescr=>describe_by_name( s_tabnam-low )."结构类型
    lt_comp_tab = struct_type->get_components( )."组成结构体的各个字段组件

    lv_tabname = s_tabnam-low.

    CALL FUNCTION 'DDIF_TABL_GET'
      EXPORTING
        name          = lv_tabname
        langu         = sy-langu
      TABLES
        dd03p_tab     = lt_fields_t
      EXCEPTIONS
        illegal_input = 1
        OTHERS        = 2.
    IF sy-subrc EQ 0.

      LOOP AT lt_fields_t INTO ls_field_t WHERE fieldname EQ '.INCLUDE'.

        CLEAR:lt_component_include.
        lo_struct_include ?= cl_abap_typedescr=>describe_by_name( ls_field_t-precfield ).
        lt_component_include = lo_struct_include->get_components( ).
        APPEND LINES OF lt_component_include TO lt_comp_tab.

      ENDLOOP.

    ENDIF.
    
*      添加celltab控制可编辑性
    CLEAR:lt_component_include.
    lo_struct_include ?= cl_abap_typedescr=>describe_by_name( 'ZTEST_S_FIELD_COM' ).
    lt_component_include = lo_struct_include->get_components( ).

    LOOP AT lt_component_include INTO ls_comp_tab.
      IF ls_comp_tab-name EQ 'CELLTAB'.
        APPEND ls_comp_tab TO lt_comp_tab.
      ENDIF.
    ENDLOOP.

    LOOP AT lt_comp_tab INTO ls_comp_tab.
      lv_tabix = sy-tabix.
*      READ TABLE gt_fields_t INTO ls_field_t WITH KEY fieldname = gs_field-fieldname.
*      IF sy-subrc EQ 0.
*
*        ls_comp_tab-name = ls_field_t-fieldname."为结构新增一个成员
*        ls_comp_tab-type = elem_type."新增成员的类型对象
*        INSERT ls_comp_tab INTO lt_comp_tab INDEX lv_index.
*
*      ENDIF.
      READ TABLE gt_fields WITH KEY fieldname = ls_comp_tab-name TRANSPORTING NO FIELDS.
      IF sy-subrc NE 0 AND ls_comp-tab-name NE 'CELLTAB'.
        DELETE lt_comp_tab INDEX lv_tabix.
      ENDIF.

    ENDLOOP.

    IF lt_comp_tab IS NOT INITIAL.

      struct_type = cl_abap_structdescr=>create( lt_comp_tab[] ).
*      CREATE DATA dref_str TYPE HANDLE struct_type."使用结构类型对象来创建结构对象
*      lo_linetype ?= cl_abap_structdescr=>create( p_components = lt_component ).
      table_type = cl_abap_tabledescr=>create( p_line_type = struct_type ).

      CREATE DATA dref_tab TYPE HANDLE table_type.
      ASSIGN dref_tab->* TO <ft_dyn_table>.

    ENDIF.

  ELSE.

    LEAVE TO SCREEN 0.

  ENDIF.
*  设置alv
  IF gv_300_fill NE abap_true.

    IF go_300_grid IS NOT BOUND.

      CREATE OBJECT go_300_grid
        EXPORTING
          i_parent = go_300_cc.

    ENDIF.

    PERFORM frm_set_fieldcat USING 300 CHANGING gt_fieldcat_300.

    PERFORM frm_set_layout USING 300 CHANGING gs_layout.

*   保存格式
    CLEAR gs_300_disvariant.
    gs_300_disvariant-report = sy-repid.
    gs_300_disvariant-handle = '200'.
    gs_300_disvariant-username = sy-uname.

*    CREATE OBJECT go_event.
    SET HANDLER lcl_event_receiver_300=>handle_toolbar FOR go_300_grid.          "工具栏
    SET HANDLER lcl_event_receiver_300=>handle_command FOR go_300_grid.          "自定义事件

*    取消部分按钮
    PERFORM frm_build_excl_func_rstgr USING 300 CHANGING gt_300_toolbar_ex.

*   第一次显示ALV
    go_300_grid->set_table_for_first_display(
    EXPORTING
      is_variant           = gs_300_disvariant
      i_save               = 'U'
      is_layout            = gs_layout
      it_toolbar_excluding = gt_300_toolbar_ex
    CHANGING
      it_fieldcatalog      = gt_fieldcat_300
      it_outtab            = <ft_dyn_table> ).

    gv_200_fill = abap_true.

  ELSE.

* 刷新ALV
    go_300_grid->refresh_table_display( ).

  ENDIF.

ENDMODULE.                 " SCR_300_DSP  OUTPUT
复制代码

2.2.4 F01

选择屏幕搜索帮助的实现,alv layout ; fieldcat设置等等

*&---------------------------------------------------------------------*
*&  包含                ZTEST_UPDATE_DATA_COMMON_F01
*&---------------------------------------------------------------------*



*&---------------------------------------------------------------------*
*&      Form  frm_request_f4_tab
*&---------------------------------------------------------------------*
*       获取可修改表
*----------------------------------------------------------------------*
*      -->P_0045   text
*----------------------------------------------------------------------*
FORM frm_request_f4_tab  USING pv_field TYPE help_info-dynprofld.

"ztest_d_com_tabt是ztest_d_com_tab的文本表	

  DATA: BEGIN OF ls_value_tab,
          tabname TYPE ztest_d_com_tab-tabname,
          tabdesc TYPE ztest_d_com_tabt-tabdesc,
        END OF ls_value_tab,
        lt_value_tab LIKE TABLE OF          ls_value_tab,
        lt_tab       LIKE STANDARD TABLE OF ls_value_tab.

  DEFINE lm_modify_tab.
    ls_value_tab-tabname = &1.
    ls_value_tab-tabdesc = &2.
    APPEND ls_value_tab TO lt_value_tab.
    CLEAR ls_value_tab.
  END-OF-DEFINITION.

*  表  表描述
*  应用外连接 即使没有英文描述 也应把空描述带出
  SELECT a~tabname,b~tabdesc
    FROM ztest_d_com_tab AS a LEFT OUTER JOIN ztest_d_com_tabt AS b
    ON a~tabname EQ b~tabname
    INTO CORRESPONDING FIELDS OF TABLE @lt_tab
    WHERE b~spras EQ @sy-langu.
  IF sy-subrc EQ 0.

    LOOP AT lt_tab INTO ls_value_tab.

      lm_modify_tab ls_value_tab-tabname ls_value_tab-tabdesc.

    ENDLOOP.

*  设置搜索结果
    CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
      EXPORTING
        retfield        = 'TABNAME'
        dynpprog        = sy-repid
        dynpnr          = sy-dynnr
        dynprofield     = pv_field
        value_org       = 'S'
      TABLES
        value_tab       = lt_value_tab
      EXCEPTIONS
        parameter_error = 1
        no_values_found = 2
        OTHERS          = 3.
    IF sy-subrc <> 0.
*   Implement suitable error handling here
    ENDIF.

  ENDIF.

ENDFORM.                    " frm_request_f4_tab
*&---------------------------------------------------------------------*
*&      Form  FRM_REQUEST_F4_FIELD
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_0055   text
*----------------------------------------------------------------------*
FORM frm_request_f4_field  USING pv_field TYPE help_info-dynprofld.

  DATA:lt_fields TYPE STANDARD TABLE OF dd03p,
       ls_field  TYPE                   dd03p,
       lv_tab    TYPE                   ddobjname,
       lv_str    TYPE                   string.

  DATA: BEGIN OF ls_value_tab,
          fieldname TYPE dd03p-fieldname,
          fieldtext TYPE dd03p-ddtext,
        END OF ls_value_tab,
        lt_value_tab LIKE STANDARD TABLE OF ls_value_tab.

  DEFINE lm_modify_field.
    ls_value_tab-fieldname = &1.
    ls_value_tab-fieldtext = &2.
    APPEND ls_value_tab TO lt_value_tab.
    CLEAR ls_value_tab.
  END-OF-DEFINITION.

  lv_str = s_tabnam-low.
  lv_tab = lv_str.

  CALL FUNCTION 'DDIF_TABL_GET'
    EXPORTING
      name          = lv_tab
      langu         = sy-langu
    TABLES
      dd03p_tab     = lt_fields
    EXCEPTIONS
      illegal_input = 1
      OTHERS        = 2.
  IF sy-subrc EQ 0.

    LOOP AT lt_fields INTO ls_field.

      IF ls_field-fieldname EQ 'MANDT' OR ls_field-fieldname EQ '.INCLUDE' OR ls_field-keyflag EQ 'X'.
        CONTINUE.
      ELSE.
        lm_modify_field ls_field-fieldname ls_field-ddtext.
      ENDIF.

    ENDLOOP.


*  设置搜索结果
    CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
      EXPORTING
        retfield        = 'FIELDNAME'
        dynpprog        = sy-repid
        dynpnr          = sy-dynnr
        dynprofield     = pv_field
        value_org       = 'S'
      TABLES
        value_tab       = lt_value_tab
      EXCEPTIONS
        parameter_error = 1
        no_values_found = 2
        OTHERS          = 3.
    IF sy-subrc <> 0.
*   Implement suitable error handling here
    ENDIF.

  ENDIF.


ENDFORM.                    " FRM_REQUEST_F4_FIELD
*&---------------------------------------------------------------------*
*&      Form  FRM_SHOWDATA_VIA_SEL
*&---------------------------------------------------------------------*
*       展示将更改数据
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
*FORM frm_showdata_via_sel .
*
**  PERFORM frm_set_fieldcat.
*
*ENDFORM.                    " FRM_SHOWDATA_VIA_SEL
*&---------------------------------------------------------------------*
*&      Form  FRM_GET_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_get_data .

*    获取screen_0100值
  DATA: ls_field_t TYPE dd03p,
        lv_tabname TYPE dd03p-tabname.

  lv_tabname = s_tabnam-low.

  CALL FUNCTION 'DDIF_TABL_GET'
    EXPORTING
      name          = lv_tabname
      langu         = sy-langu
    TABLES
      dd03p_tab     = gt_fields_t
    EXCEPTIONS
      illegal_input = 1
      OTHERS        = 2.
  IF sy-subrc EQ 0.

    LOOP AT gt_fields_t INTO ls_field_t.

      CLEAR:gs_field.

      IF ls_field_t-fieldname EQ 'MANDT' OR ls_field_t-fieldname EQ '.INCLUDE'.
        CONTINUE.
      ELSE.

        IF ls_field_t-keyflag EQ 'X'.

          gs_field-convexit = ls_field_t-convexit.
          gs_field-length = ls_field_t-leng.
          gs_field-fieldname = ls_field_t-fieldname.
          gs_field-ddtext = ls_field_t-ddtext.
          gs_field-zoption = 'EQ'.  "DEFAULT   EQ
          gs_field-key_flag = ls_field_t-keyflag.
          APPEND gs_field TO gt_fields.

        ELSE.

          READ TABLE s_flnam WITH KEY low = ls_field_t-fieldname TRANSPORTING NO FIELDS.
          IF sy-subrc EQ 0.

            gs_field-convexit = ls_field_t-convexit.
            gs_field-length = ls_field_t-leng.
            gs_field-fieldname = ls_field_t-fieldname.
            gs_field-ddtext = ls_field_t-ddtext.
            gs_field-zoption = 'EQ'.  "DEFAULT   EQ
            APPEND gs_field TO gt_fields.

          ENDIF.

        ENDIF.
      ENDIF.

    ENDLOOP.

  ELSE.

    MESSAGE e147(zps) WITH 'TABNAME ERROR!'.

  ENDIF.


ENDFORM.                    " FRM_GET_DATA
*&---------------------------------------------------------------------*
*&      Form  FRM_SET_DISPLAY_PARAM
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
*FORM frm_set_display_param .
*
*ENDFORM.                    " FRM_SET_DISPLAY_PARAM
*&---------------------------------------------------------------------*
*&      Form  FRM_SET_FIELDCAT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_set_fieldcat USING pv_cc TYPE int2
                      CHANGING pt_fieldcat.

  DATA:ls_field_t TYPE dd03p,
       lv_edit    TYPE sap_bool.

  IF pv_cc EQ 200.

    PERFORM frm_fill_fieldcat USING
          'ZTEST_S_FIELD_COM' 'FIELDNAME' 'FIELDNAME'  text-004 '' '' '' '' '' 'X'
    CHANGING pt_fieldcat.
    PERFORM frm_fill_fieldcat USING
          'ZTEST_S_FIELD_COM' 'DDTEXT' 'DDTEXT'  text-015 '' '' '' '' '' 'X'
    CHANGING pt_fieldcat.
    PERFORM frm_fill_fieldcat USING
          'ZTEST_S_FIELD_COM' 'ZOPTION' 'ZOPTION'  text-005 '' '' '' 'X' '' ''
    CHANGING pt_fieldcat.
    PERFORM frm_fill_fieldcat USING
          'ZTSET_S_FIELD_COM' 'LOW' 'LOW'  text-006 '' '' '' 'X' '' ''
    CHANGING pt_fieldcat.
    PERFORM frm_fill_fieldcat USING
          'ZTEST_S_FIELD_COM' 'HIGH' 'HIGH'  text-007 '' '' '' 'X' '' ''
    CHANGING pt_fieldcat.
    PERFORM frm_fill_fieldcat USING
          'ZTEST_S_FIELD_COM' 'ZIF_EDIT' 'ZIF_EDIT'  text-008 'X' '' '' 'X' '' ''
    CHANGING pt_fieldcat.

  ELSEIF pv_cc EQ 300.

    LOOP AT gt_fields_t INTO ls_field_t.

      IF ls_field_t-fieldname EQ 'MANDT' OR ls_field_t-fieldname EQ '.INCLUDE'.
        CONTINUE.
      ELSE.
        IF ls_field_t-keyflag EQ abap_true.

          PERFORM frm_fill_fieldcat USING
                s_tabnam-low ls_field_t-fieldname ls_field_t-fieldname ls_field_t-ddtext '' '' '' '' '' 'X'
          CHANGING pt_fieldcat.

        ELSE.

          READ TABLE s_flnam WITH KEY low = ls_field_t-fieldname TRANSPORTING NO FIELDS.
          IF sy-subrc EQ 0.

*            CLEAR:lv_edit.
*            READ TABLE gt_fields WITH KEY fieldname = ls_field_t-fieldname
*            zif_edit = abap_true TRANSPORTING NO FIELDS.
*            IF sy-subrc EQ 0.
*              lv_edit = abap_true.
*            ENDIF.
            lv_edit = abap_true.

            PERFORM frm_fill_fieldcat USING
                  s_tabnam-low ls_field_t-fieldname ls_field_t-fieldname ls_field_t-ddtext '' '' '' lv_edit '' 'X'
            CHANGING pt_fieldcat.

          ENDIF.

        ENDIF.

      ENDIF.

    ENDLOOP.

  ENDIF.

ENDFORM.                    " FRM_SET_FIELDCAT
*&---------------------------------------------------------------------*
*&      Form  FRM_CHECK_INPUT_OR_AUTH
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_check_input_or_auth.

  DATA:lv_msg TYPE string.

  IF s_tabnam IS INITIAL OR s_flnam IS INITIAL.

    MESSAGE w147(zps) WITH '请输入表名与字段名!'.
    STOP.

  ENDIF.

ENDFORM.                    " FRM_CHECK_INPUT_OR_AUTH

*&---------------------------------------------------------------------*
*&      Form  frm_fill_fieldcat
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->PV_REFTABLE   text
*      -->PV_REFFIELD   text
*      -->PV_FIELDNAME  text
*      -->PV_COLTEXT    text
*      -->PV_CHECKBOX   text
*      -->PV_NOZERO     text
*      -->PV_OUTPUTLEN  text
*      -->PV_EDIT       text
*      -->PCT_FIELDCAT  text
*----------------------------------------------------------------------*
FORM frm_fill_fieldcat USING pv_reftable
      pv_reffield
      pv_fieldname
      pv_coltext
      pv_checkbox
      pv_nozero
      pv_outputlen
      pv_edit
      pv_hotspot
      pv_key
*      pv_style
CHANGING pct_fieldcat TYPE lvc_t_fcat.
  DATA: ls_fieldcat TYPE lvc_s_fcat.
  ls_fieldcat-ref_table = pv_reftable .
  ls_fieldcat-ref_field = pv_reffield .
  ls_fieldcat-fieldname = pv_fieldname .
*  IF pv_fieldname EQ 'ZOPTION'.
*    ls_fieldcat-drdn_hndl = '1'.
*  ENDIF.
  ls_fieldcat-coltext = pv_coltext .
  ls_fieldcat-checkbox = pv_checkbox.           "多选框
  ls_fieldcat-no_zero = pv_nozero.              "去除前导零
*  ls_fieldcat-outputlen = pv_outputlen.
  ls_fieldcat-edit = pv_edit.                   "是否可编辑
  ls_fieldcat-hotspot = pv_hotspot.             "单击事件
  ls_fieldcat-key = pv_key.
*  ls_fieldcat-style = pv_style.
*  ls_fieldcat-DRDN_FIELD = pv_
*  IF pv_fieldname EQ 'ZOPTION'.
*
*    ls_fieldcat-drdn_field  = 'ZOPTION'.
*    ls_fieldcat-drdn_hndl   = '1' .
*
*  ENDIF.

  APPEND ls_fieldcat TO pct_fieldcat.
  CLEAR ls_fieldcat.
ENDFORM. " frm_fill_fieldcat

*&---------------------------------------------------------------------*
*&      Form  frm_set_layout
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->PCS_LAYOUT text
*----------------------------------------------------------------------*
FORM frm_set_layout USING pv_cc TYPE int2
                    CHANGING pcs_layout TYPE lvc_s_layo.

  CLEAR:pcs_layout.
  CONSTANTS: lc_stylefname LIKE pcs_layout-stylefname VALUE 'CELLTAB'.
  "设置layout格式
  pcs_layout-cwidth_opt = 'X'.
*  pcs_layout-box_fname = 'SEL'.
  pcs_layout-sel_mode = 'A'.
*  IF pv_cc EQ 200.
  pcs_layout-stylefname = lc_stylefname.
*  ENDIF.
*  pcs_layout-zebra = 'X'.

ENDFORM. " FRM_SET_LAYOUT
*&---------------------------------------------------------------------*
*&      Form  FRM_INIT_STYLE_TAB
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_init_style_tab.

  DATA:lt_celltab TYPE lvc_t_styl,
       ls_celltab TYPE lvc_s_styl,
       l_index    TYPE i.

  LOOP AT gt_fields INTO gs_field WHERE key_flag EQ abap_true.
    CLEAR : gs_field-celltab. "不为空会报错
    IF gs_field-celltab IS INITIAL.
      l_index = sy-tabix.
      REFRESH lt_celltab.
      ls_celltab-fieldname = 'ZIF_EDIT'.
      IF gs_field-key_flag IS NOT INITIAL.
        ls_celltab-style = cl_gui_alv_grid=>mc_style_disabled.
      ELSE.
        ls_celltab-style = cl_gui_alv_grid=>mc_style_enabled.
      ENDIF.
      INSERT ls_celltab INTO TABLE lt_celltab.
*      IF gs_field-zoption NE 'BETWEEN'.
*        ls_celltab-style = cl_gui_alv_grid=>mc_style_disabled.
*      ELSE.
*        ls_celltab-style = cl_gui_alv_grid=>mc_style_enabled.
*      ENDIF.
*      ls_celltab-fieldname = 'HIGH'.

      INSERT LINES OF lt_celltab INTO TABLE gs_field-celltab.
      MODIFY gt_fields FROM gs_field INDEX l_index.
    ENDIF.
  ENDLOOP.

ENDFORM.                    " FRM_INIT_STYLE_TAB

FORM frm_build_excl_func_rstgr USING pv_cc TYPE int2
                               CHANGING ct_excl_func TYPE ui_functions.
  APPEND: cl_gui_alv_grid=>mc_fc_detail TO ct_excl_func,
  cl_gui_alv_grid=>mc_fc_check TO ct_excl_func,
  cl_gui_alv_grid=>mc_fc_loc_append_row TO ct_excl_func,
  cl_gui_alv_grid=>mc_fc_loc_delete_row TO ct_excl_func,
  cl_gui_alv_grid=>mc_fc_refresh TO ct_excl_func,
  cl_gui_alv_grid=>mc_fc_loc_undo TO ct_excl_func,
  cl_gui_alv_grid=>mc_fc_loc_cut TO ct_excl_func,
  cl_gui_alv_grid=>mc_fc_loc_copy TO ct_excl_func,
  cl_gui_alv_grid=>mc_fc_loc_copy_row TO ct_excl_func,
  cl_gui_alv_grid=>mc_fc_loc_paste TO ct_excl_func,
  cl_gui_alv_grid=>mc_fc_loc_paste_new_row TO ct_excl_func,
*          cl_gui_alv_grid=>mc_fg_sort TO ct_excl_func,
  cl_gui_alv_grid=>mc_fc_find TO ct_excl_func,
  cl_gui_alv_grid=>mc_fc_loc_insert_row TO ct_excl_func,
  cl_gui_alv_grid=>mc_fc_subtot TO ct_excl_func,
  cl_gui_alv_grid=>mc_mb_variant TO ct_excl_func,
*          cl_gui_alv_grid=>mc_mb_filter TO ct_excl_func,
  cl_gui_alv_grid=>mc_fc_print TO ct_excl_func,
  cl_gui_alv_grid=>mc_mb_view TO ct_excl_func,
  cl_gui_alv_grid=>mc_fc_graph TO ct_excl_func,
  cl_gui_alv_grid=>mc_fc_info TO ct_excl_func,
  cl_gui_alv_grid=>mc_mb_sum TO ct_excl_func,
  cl_gui_alv_grid=>mc_mb_export TO ct_excl_func.

*  200屏幕仅保留查询按钮
  IF pv_cc EQ 200.

    APPEND:
    cl_gui_alv_grid=>mc_fc_sort_asc TO ct_excl_func,
    cl_gui_alv_grid=>mc_fc_sort_dsc TO ct_excl_func,
    cl_gui_alv_grid=>mc_fc_filter TO ct_excl_func.

  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  FRM_SET_LIST_DROPDOWN
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
*FORM frm_set_list_dropdown .

**  此种方法不适用
**  我想展示为有key  有value的形式

*  DATA:gt_drp TYPE lvc_t_drop,
*       gs_drp TYPE lvc_s_drop.
*
*  gs_drp-handle = '1' .
*  gs_drp-value = 'A' .
*  APPEND gs_drp TO gt_drp .
*
*  gs_drp-handle = '1' .
*  gs_drp-value = 'B' .
*  APPEND gs_drp TO gt_drp .
*
*  gs_drp-handle = '1' .
*  gs_drp-value = 'C' .
*  APPEND gs_drp TO gt_drp.

**  在fieldcat中设置对应字段句柄  为1

**  在调用alv之前
*  CALL METHOD gs_alv->set_drop_down_table
*
*  EXPORTING
*
*    it_drop_down = gt_drp.

*ENDFORM.                    " FRM_SET_LIST_DROPDOWN
复制代码

2.2.5 屏幕相关

创建一个屏幕 标号100 在这里插入图片描述

在内创建一个containner 命名为GV_CON 在这里插入图片描述

屏幕元素清单中设置OK_CODE 在这里插入图片描述 在这里插入图片描述

2.2.6 相关文本

在这里插入图片描述 在这里插入图片描述


总结

查询数据,生成alv均为动态控制,直接针对选择字段更新数据,可实现多字段值同时更新,可复用性高

猜你喜欢

转载自juejin.im/post/7080063062421700621