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

文章目录

  • 需求
  • 一、实现效果
    • 1.1 输入表名
    • 1.2 选择表中字段
    • 1.3 执行
    • 1.4 填入条件 点击查询
    • 1.5 数据更改前
    • 1.6 选择更新字段的checlbox 更改状态 然后【更改数据】
    • 1.7 勾选后继续
    • 1.8 新增修改日志表
  • 二、代码
    • 2.1 主程序
    • 2.2 INCLUDE
      • 2.2.1 TOP
      • 2.2.2 CLS
      • 2.2.3 EVT
      • 2.2.4 F01
      • 2.2.5 屏幕相关
      • 2.2.6 相关文本
  • 总结


需求

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

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

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

V3:
修复:特殊转换例程alpha 输出过多0的问题
在结构中新增了length字段 控制转换例程输出长度
2022/03/28

V4:
修复:把值设置为空可能出现的bug
2022/03/29

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


一、实现效果

1.1 输入表名

SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第1张图片

1.2 选择表中字段

SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第2张图片
SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第3张图片

1.3 执行

自动带出表中关键字,且更新字段checkbox不可选
此处我设置的有校验,至少要有一个关键字填有数据(在low中有值)作为查询条件
SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第4张图片

1.4 填入条件 点击查询

SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第5张图片

1.5 数据更改前

SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第6张图片

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

把审批状态改为4,点击更新数据,提示勾选更新字段
SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第7张图片

1.7 勾选后继续

SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第8张图片
看更新后底表此条数据,已更新
SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第9张图片

1.8 新增修改日志表

查看修改日志
SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第10张图片

二、代码

2.1 主程序

*&---------------------------------------------------------------------*
*& Report  ZTEST_UPDATE_DATA_COMMON
*&         Description:动态生成alv 并实现更新底表数据
*&---------------------------------------------------------------------*
*&         Author:WUSL
*&         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所用到结构
可参照如下
SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第11张图片

ZOPTION为阈值,方便后续写SQL
SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第12张图片
表名配置表:ZTEST_D_COM_TAB
SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第13张图片
文本表:ZTEST_D_COM_TABT
SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第14张图片
日志表:ZTEST_D_COM_TCLOG
SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第15张图片

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©_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
         .

    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.

*                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-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©_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.

                      *                      空条件
                      IF <fv_value> IS ASSIGNED AND <fv_value> IS INITIAL.
                        lv_where_tab = 'SPACE'.
                      ELSE.
                        lv_where_tab = '''' && <fv_value> && ''''.
                      ENDIF.
                      
                      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.

*                      置空处理
                      IF <fv_value> IS ASSIGNED AND <fv_value> IS INITIAL.
                        lv_str = 'SPACE'.
                      ELSE.
                        lv_str = '''' && <fv_value> && ''''.
                      ENDIF.
                      
                      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>.
*                      ADD  20220328  置空优化
                      IF <fv_value> IS INITIAL.
                        ls_tclog-zaftval = 'SPACE'.
                      ELSE.
                        ls_tclog-zaftval = <fv_value>.
                      ENDIF.
*                    END  ADD

                      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
SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第16张图片

在内创建一个containner 命名为GV_CON
SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第17张图片

屏幕元素清单中设置OK_CODE
SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第18张图片
SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第19张图片

2.2.6 相关文本

SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第20张图片
SAP ABAP动态生成OOALV 并实现更新底表数据的需求_第21张图片


总结

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

你可能感兴趣的:(ABAP小工具,sap,abap,database)