ABAP 根据数据元素和字段值查表

*&---------------------------------------------------------------------*
*& Report ZCRMR_SEARCH_TABLE
*&---------------------------------------------------------------------*
*&程序功能描述:V1.4(20190907)
*&*1---根据数据元素和字段值查表
*&*2---ALV显示查询结果
*&*3---增加根据字段值,模糊搜索所有系统表相同值的逻辑(20210901)
*&*3.1---因SAP 内存管理配置,和表数据量太大,导致内存溢出,程序异常的表,
*&       增加排除表选项。
*&*3.2---通过增加排除表选项,仍出现程序异常的,增加处理日志表,
*&       每处理一行将,当前行和 下一行表格记录到日志表中,当前表即为查询异常表。
*&*4---增加自动创建透明表逻辑,用于创建日志表
*&*5---Author: lijq21@qq.com
*&---------------------------------------------------------------------*
REPORT ZCRMR_SEARCH_TABLE.
TYPE-POOLS sscr.
DATA: restrict TYPE sscr_restrict,
      optlist  TYPE sscr_opt_list,
      ass      TYPE sscr_ass.

CONSTANTS:c_uptorows  TYPE i VALUE 50000,
          c_tmp_table TYPE tabname VALUE 'YTMP_TABLE_LOG'.

*DD02VV  DD03VV  DD01L  .
TABLES:dd02l.
DATA: BEGIN OF is_itab,
        tabname      TYPE tabname,
        fieldname    TYPE fieldname,
        tabclass  TYPE tabclass,
        position  TYPE tabfdpos,
        value_flg TYPE c,
        msg       TYPE char100,
      END OF is_itab,
      it_itab LIKE TABLE OF is_itab.

DATA:where_tab(100) OCCURS 0 WITH HEADER LINE,
     lv_cx_root     TYPE REF TO cx_root,
     lv_ref         TYPE REF TO data,

     ls_dd02l       TYPE dd02l,
     lt_dd02l       TYPE TABLE OF dd02l,

     struct_type    TYPE REF TO cl_abap_structdescr,
     comp_tab       TYPE        cl_abap_structdescr=>component_table,
     itab_type      TYPE REF TO cl_abap_tabledescr,
     dref           TYPE REF TO data,
     ls_dfies_tab   TYPE dfies,
     lt_dfies_tab   TYPE TABLE OF dfies,
     lv_field_value TYPE string,
     lv_json_str    TYPE string,
     lv_tabix       LIKE sy-tabix,
     lv_string      TYPE string,
     lv_flag        TYPE c,
     lv_count       TYPE i,
     lv_snum        TYPE i,
     lv_enum        TYPE i,
     lv_length      TYPE i,
     lv_msg         TYPE string,
     lv_fieldname_s TYPE string,
     lv_offset      TYPE i,
     lv_rows        TYPE i.

RANGES: r_tname FOR dd02l-tabname.
DATA:rs_tname  LIKE LINE OF r_tname.

FIELD-SYMBOLS : <lt_outtab>       TYPE STANDARD TABLE,
                <ls_outtab>       TYPE any,
                <dyn_field_value> TYPE any,
                <lt_tmptab>       TYPE STANDARD TABLE,
                <ls_tmptab>       TYPE any,
                <fs_itab>         LIKE is_itab,
                <fs_value>        TYPE any.
*------------------------------------------------------------------------*
* SELECTION-SCREEN
*------------------------------------------------------------------------*
SELECTION-SCREEN: BEGIN OF BLOCK b1 WITH FRAME.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 2(20) text2.
*PARAMETERS:p_value TYPE /plmb/gos_key_value.
SELECT-OPTIONS :s_value FOR (ty_string) NO-EXTENSION NO INTERVALS.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN: END OF BLOCK b1.

SELECTION-SCREEN: BEGIN OF BLOCK b2 WITH FRAME.

SELECTION-SCREEN BEGIN OF LINE.
PARAMETERS:r_bt1 RADIOBUTTON GROUP g1 DEFAULT 'X' USER-COMMAND a.
SELECTION-SCREEN COMMENT 3(40) text4.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN: BEGIN OF BLOCK b3 WITH FRAME.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(20) text1.
PARAMETERS:p_rname TYPE rollname." OBLIGATORY.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(17) text5.
SELECT-OPTIONS:s_class FOR dd02l-tabclass NO INTERVALS DEFAULT 'TRANSP'.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN: END OF BLOCK b3.

SELECTION-SCREEN SKIP.

SELECTION-SCREEN BEGIN OF LINE.
PARAMETERS:r_bt2 RADIOBUTTON GROUP g1.
SELECTION-SCREEN COMMENT 3(40) text3.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN: BEGIN OF BLOCK b4 WITH FRAME.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(19) text8.
SELECT-OPTIONS:s_tname FOR dd02l-tabname NO INTERVALS.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(22) text9."从所有表中第 xxx 个表开始执行
PARAMETERS:p_snum TYPE i.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(22) text10."执行到第 xxx 个表结束
PARAMETERS:p_enum TYPE i.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN SKIP.
SELECTION-SCREEN: BEGIN OF BLOCK b5 WITH FRAME TITLE text14.
SELECTION-SCREEN BEGIN OF LINE.
PARAMETERS:c_tmp AS CHECKBOX DEFAULT 'X'.
SELECTION-SCREEN COMMENT 5(50) text12."启用并创建处理顺序临时表YTMP_TABLE
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN BEGIN OF LINE.
PARAMETERS:c_clear AS CHECKBOX." DEFAULT 'X'.
SELECTION-SCREEN COMMENT 5(50) text13."清空临时表重新开始记录
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN END OF BLOCK b5.

*---提示信息:
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 3(40) text6.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 5(50) text7.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 5(50) text11.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 5(50) text15.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN END OF BLOCK b4.
SELECTION-SCREEN END OF BLOCK b2.

*------------------------------------------------------------------------*
* INITIALISATION
*------------------------------------------------------------------------*
INITIALIZATION.
  text1 = '数据元素'."'Data Elements'.
  text2 = '搜索值'."'Search field value'.
  text3 = '全系统表模糊搜索'.
  text4 = '根据指定数据元素和值查找对应的表'.
  text5 = '表类别' ." 'Table Category'.
  text6 = '提示:1 将搜索所有系统表,耗时很久。'.
  text7 = '      2 根据搜索值搜索所有表中所有表字段值相同的记录。'.
  text11 = '      3 当数据异常(内存溢出)或查询部分表,可以指定开始和结束的行数'.
  text8 = '排除表名称'.
  text9 = '从所有表中第 xxx 个表开始执行'.
  text10 = '执行到第 xxx 个表结束'.
  text12 = '启用并创建日志表YTMP_TABLE_LOG'.
  text13 = '清空临时表重新开始记录'.
  text14 = '日志表记录'.
  text15 = '      4 排除表名称支持 ABC* 格式的模糊排除'.

*---表类别
  CLEAR:optlist ,ass.
  optlist-name = 'OBJECTKEY1'.
  optlist-options-eq = 'X'.
*  optlist-options-bt = ''.
  APPEND optlist TO restrict-opt_list_tab.
  ass-kind = 'S'.
  ass-name = 'S_CLASS'.
  ass-sg_main = 'I'.
  ass-sg_addy = space.
  ass-op_main = 'OBJECTKEY1'.
  APPEND ass TO restrict-ass_tab.

*---排除表名称
  CLEAR:optlist ,ass.
  optlist-name = 'OBJECTKEY2'.
  optlist-options-eq = 'X'.
  APPEND optlist TO restrict-opt_list_tab.
  ass-kind = 'S'.
  ass-name = 'S_TNAME'.
  ass-sg_main = 'I'.
  ass-sg_addy = space.
  ass-op_main = 'OBJECTKEY2'.
  APPEND ass TO restrict-ass_tab.

  CALL FUNCTION 'SELECT_OPTIONS_RESTRICT'
    EXPORTING
*     PROGRAM                =
      restriction            = restrict
*     DB                     = ' '
    EXCEPTIONS
      too_late               = 1
      repeated               = 2
      selopt_without_options = 3
      selopt_without_signs   = 4
      invalid_sign           = 5
      empty_option_list      = 6
      invalid_kind           = 7
      repeated_kind_a        = 8
      OTHERS                 = 9.

AT SELECTION-SCREEN OUTPUT.
  IF r_bt1 = 'X'.
    LOOP AT SCREEN.
      IF screen-name EQ 'S_TNAME-LOW' OR screen-name CP '*NUM*'
      OR screen-name EQ 'C_TMP' OR screen-name EQ 'C_CLEAR'.
        screen-input = 0.
        MODIFY SCREEN.
      ENDIF.
    ENDLOOP.
    CLEAR:s_tname[].
  ELSE.
    LOOP AT SCREEN.
      IF  screen-name EQ 'P_RNAME' OR screen-name EQ 'S_CLASS-LOW'.
        screen-input = 0.
        MODIFY SCREEN.
      ENDIF.
    ENDLOOP.
    CLEAR:p_rname,p_snum,p_enum.

*---因部份表数据量太大且与查询没有太大关联,所以初始化排除。
    PERFORM exclude_tname USING 'COVREF'.
    PERFORM exclude_tname USING 'STERM_LINK'.
    PERFORM exclude_tname USING 'SMIMCONT1'.
    PERFORM exclude_tname USING 'REPOSRC'.
    PERFORM exclude_tname USING 'DOKTL'.
    PERFORM exclude_tname USING 'DD03L'.
    PERFORM exclude_tname USING 'D010*'.
    PERFORM exclude_tname USING 'SEO*'.
    PERFORM exclude_tname USING 'E07*'.

  ENDIF.
*------------------------------------------------------------------------*
*START-OF-SELECTION.
*------------------------------------------------------------------------*
START-OF-SELECTION.

  IF s_value[] IS INITIAL.
    MESSAGE '搜索值不能为空!' TYPE 'S' DISPLAY LIKE 'E'.
    RETURN.
  ENDIF.

  IF r_bt1 = 'X'.
    IF p_rname IS INITIAL.
      MESSAGE '数据元素不能为空!' TYPE 'S' DISPLAY LIKE 'E'.
      RETURN.
    ENDIF.

    CLEAR:it_itab.
    TRANSLATE p_rname TO UPPER CASE.
    SELECT tabname fieldname tabclass position FROM dd03vv INTO CORRESPONDING FIELDS OF TABLE it_itab
                                              WHERE as4local = 'A'
                                                AND tabclass IN s_class "= 'TRANSP'
                                                AND rollname = p_rname.
    SORT it_itab BY tabname position.
    lv_count = lines( it_itab ).

    LOOP AT it_itab ASSIGNING <fs_itab>.

      PERFORM show_progress_indicator USING sy-tabix.

      CLEAR:where_tab[],where_tab.
      CONCATENATE <fs_itab>-fieldname 'IN S_VALUE' INTO where_tab SEPARATED BY space.
      APPEND where_tab.

      IF <fs_itab>-tabclass NE 'TRANSP' AND <fs_itab>-tabclass NE 'VIEW' .
        CONTINUE.
      ENDIF.

      TRY .
          CREATE DATA lv_ref TYPE (p_rname)."定义数据元素类型变量
          ASSIGN lv_ref->* TO <fs_value> .

          SELECT SINGLE (<fs_itab>-fieldname) FROM (<fs_itab>-tabname) INTO <fs_value> WHERE (where_tab).
          IF sy-subrc = 0.
            <fs_itab>-value_flg = 'X'.
          ENDIF.
        CATCH cx_root INTO lv_cx_root.
          <fs_itab>-msg  = lv_cx_root->get_text( ).
      ENDTRY.
    ENDLOOP.
  ELSE.

    SELECT tabname as4vers FROM dd02l
      INTO CORRESPONDING FIELDS OF TABLE lt_dd02l
                                   WHERE as4local = 'A'
                                     AND tabclass = 'TRANSP'.
*                                     AND tabname = 'ZSSFT_BATCH_CFG'.

    SORT lt_dd02l BY tabname DESCENDING as4vers DESCENDING.
    DELETE ADJACENT DUPLICATES FROM lt_dd02l COMPARING tabname.

*---删除排除表
    LOOP AT s_tname INTO rs_tname.
      IF rs_tname-low CS '*'.
        CLEAR:lv_length.
        REPLACE ALL OCCURRENCES OF '*' IN rs_tname-low  WITH ''.
        CONDENSE rs_tname-low  NO-GAPS.
        lv_length = strlen( rs_tname-low ).
        IF lv_length GE 1.
          LOOP AT lt_dd02l INTO ls_dd02l WHERE tabname CS rs_tname-low.
            IF ls_dd02l-tabname+0(lv_length) = rs_tname-low..
              DELETE lt_dd02l WHERE tabname = ls_dd02l-tabname .
*              WRITE: / ls_dd02l-tabname .
            ENDIF.
          ENDLOOP.
        ENDIF.
      ELSE.
        DELETE lt_dd02l WHERE tabname = rs_tname-low.
      ENDIF.
    ENDLOOP.

    lv_count = lines( lt_dd02l ).

    IF p_snum IS INITIAL.
      lv_snum = 1.
    ELSE.
      lv_snum = p_snum.
    ENDIF.

    IF p_enum IS INITIAL.
      lv_enum = lv_count.
    ELSE.
      lv_enum = p_enum.
    ENDIF.

    IF c_tmp = 'X'.
*---创建日志表
      PERFORM creat_temp_table.

      DATA:lv_tablename TYPE string.
      struct_type ?= cl_abap_typedescr=>describe_by_name( c_tmp_table ).
      itab_type   ?= cl_abap_tabledescr=>create( struct_type ).
      CREATE DATA dref TYPE HANDLE itab_type.
      ASSIGN dref->* TO <lt_tmptab>.

      CREATE DATA dref TYPE HANDLE struct_type.
      ASSIGN dref->* TO <ls_tmptab>.

      IF c_clear = 'X'.
        DELETE FROM (c_tmp_table).
        COMMIT WORK AND WAIT.
      ELSE.
*---取表c_tmp_table 的所有值
        SELECT * FROM (c_tmp_table) INTO TABLE  @<lt_tmptab>.
      ENDIF.
    ENDIF.

    LOOP AT lt_dd02l INTO ls_dd02l FROM lv_snum TO lv_enum.
      CLEAR:lv_tabix.
      lv_tabix = sy-tabix.

      PERFORM show_progress_indicator USING sy-tabix.

*---更新日志表,如果数据在日志表中,则跳过不处理
      IF c_tmp = 'X'.
        IF c_clear NE 'X'.
*          CLEAR:lv_flag.
*          LOOP AT <lt_tmptab> INTO <ls_tmptab>
*            UNASSIGN <dyn_field_value>.
*            ASSIGN COMPONENT 'TABNAME'  OF STRUCTURE <ls_tmptab> TO <dyn_field_value> .
*            IF ls_dd02l-tabname = <dyn_field_value> .
*              lv_flag = 'X'.
*              EXIT.
*            ENDIF.
*          ENDLOOP.

          CLEAR:lv_string.
          CONCATENATE  ''''  ls_dd02l-tabname '''' INTO lv_string.
          CONCATENATE 'TABNAME = ' lv_string  INTO lv_string SEPARATED BY space.

          LOOP AT <lt_tmptab> INTO <ls_tmptab> WHERE (lv_string).
          ENDLOOP.
          IF sy-subrc = 0.
            CONTINUE.
          ENDIF.
        ENDIF.

        CLEAR:<ls_tmptab>.
        UNASSIGN <dyn_field_value>.
        ASSIGN COMPONENT 'TABNAME' OF STRUCTURE <ls_tmptab> TO <dyn_field_value> .
        <dyn_field_value>  = ls_dd02l-tabname.

        UNASSIGN <dyn_field_value>.
        ASSIGN COMPONENT 'SEQUENCE' OF STRUCTURE <ls_tmptab> TO <dyn_field_value> .
        <dyn_field_value>  = lv_tabix.
        MODIFY (c_tmp_table) FROM <ls_tmptab>.
        COMMIT WORK AND WAIT.
      ENDIF.

      UNASSIGN:<lt_outtab>.
      struct_type ?= cl_abap_typedescr=>describe_by_name( ls_dd02l-tabname ).
*      comp_tab    = struct_type->get_components( ).
*      struct_type = cl_abap_structdescr=>create( comp_tab ).
      itab_type   ?= cl_abap_tabledescr=>create( struct_type ).

      CREATE DATA dref TYPE HANDLE itab_type.
      ASSIGN dref->* TO <lt_outtab>.

      CREATE DATA dref TYPE HANDLE struct_type.
      ASSIGN dref->* TO <ls_outtab>.

      CLEAR:lt_dfies_tab.
      CALL FUNCTION 'DDIF_FIELDINFO_GET'
        EXPORTING
          tabname        = ls_dd02l-tabname
        TABLES
          dfies_tab      = lt_dfies_tab
        EXCEPTIONS
          not_found      = 1
          internal_error = 2
          OTHERS         = 3.

      CLEAR:lv_fieldname_s.

*---取表主键字段,作为搜索ORDER BY 排序字段。
      LOOP AT lt_dfies_tab INTO ls_dfies_tab WHERE keyflag = 'X'.
        IF lv_fieldname_s IS INITIAL.
          lv_fieldname_s = ls_dfies_tab-fieldname.
        ELSE.
          CONCATENATE lv_fieldname_s ',' ls_dfies_tab-fieldname INTO lv_fieldname_s.
        ENDIF.
      ENDLOOP.

      CLEAR:lv_flag.
*---用OFFSET 偏移量分页查询表数据。
      lv_offset = 0.
      lv_rows = 0.
      DO.
        lv_rows = lv_rows + c_uptorows.
        TRY.
            CLEAR:<lt_outtab>.
            SELECT * FROM (ls_dd02l-tabname) ORDER BY (lv_fieldname_s)
                                           INTO TABLE @<lt_outtab>
                                                UP TO @c_uptorows ROWS
                                               OFFSET @lv_offset. "偏移量
            IF sy-subrc NE 0.
              EXIT.
            ENDIF.
          CATCH cx_root INTO lv_cx_root.
            CLEAR:lv_msg.
            lv_msg  = lv_cx_root->get_text( ).
            lv_msg = '表' && ls_dd02l-tabname && '取数异常' && lv_msg.
            WRITE: / lv_msg.
            CONTINUE.
        ENDTRY.

        LOOP AT <lt_outtab> INTO <ls_outtab> .

*---逐个字段比较查询值。"经测试 将内表行转成JSON字符串,效率太低。
          LOOP AT lt_dfies_tab INTO ls_dfies_tab.
            READ TABLE it_itab TRANSPORTING NO FIELDS WITH KEY tabname = ls_dfies_tab-tabname
                                                            fieldname  = ls_dfies_tab-fieldname.
            IF sy-subrc = 0.
              CONTINUE.
            ENDIF.

            UNASSIGN <dyn_field_value>.
            ASSIGN COMPONENT ls_dfies_tab-fieldname OF STRUCTURE <ls_outtab> TO <dyn_field_value> .
            IF sy-subrc = 0.
              TRY.
                  CLEAR:lv_field_value.
                  lv_field_value = <dyn_field_value>.
*                  IF p_value = lv_field_value.
                  IF lv_field_value IN s_value[]."包含关系
                    CLEAR:is_itab.
                    is_itab-tabname    = ls_dfies_tab-tabname.
                    is_itab-fieldname  = ls_dfies_tab-fieldname.
                    is_itab-value_flg  = 'X'.
                    APPEND is_itab TO it_itab.

                    IF lv_flag IS INITIAL.
                      lv_flag = 'X'.
                    ENDIF.

                  ENDIF.
                CATCH cx_root INTO lv_cx_root.
                  CLEAR:lv_msg.
                  lv_msg  = lv_cx_root->get_text( ).
                  lv_msg = '字段' && ls_dfies_tab-tabname && '-' && ls_dfies_tab-fieldname && '值异常' && lv_msg.
                  WRITE: / lv_msg.
              ENDTRY.
            ENDIF.
          ENDLOOP.
        ENDLOOP.
        FREE:<lt_outtab>.

        lv_offset = lv_offset + c_uptorows.
      ENDDO.
      SORT it_itab BY tabname fieldname.
      DELETE ADJACENT DUPLICATES FROM it_itab COMPARING tabname fieldname.

      IF lv_flag = 'X' AND c_tmp = 'X'.
*---取表c_tmp_table 的所有值
        CLEAR:<ls_tmptab>.
        CLEAR:lv_string.

        CONCATENATE  ''''  ls_dd02l-tabname '''' INTO lv_string.
        CONCATENATE 'TABNAME = ' lv_string  INTO lv_string SEPARATED BY space.

        SELECT SINGLE * FROM (c_tmp_table) INTO @<ls_tmptab> WHERE (lv_string) .
        IF sy-subrc = 0.
          UNASSIGN <dyn_field_value>.
          ASSIGN COMPONENT 'FLAG' OF STRUCTURE <ls_tmptab> TO <dyn_field_value> .
          <dyn_field_value> = 'X'.
          MODIFY (c_tmp_table) FROM <ls_tmptab>.
          COMMIT WORK AND WAIT.
        ENDIF.
      ENDIF.
    ENDLOOP.
  ENDIF.
  SORT it_itab BY value_flg DESCENDING tabname fieldname.
  PERFORM display_alv.

*------------------------------------------------------------------------*
*END-OF-SELECTION.
*------------------------------------------------------------------------*
END-OF-SELECTION.
*&---------------------------------------------------------------------*
*&      Form  SHOW_PROGRESS_INDICATOR
*&---------------------------------------------------------------------*
FORM show_progress_indicator USING iv_percent TYPE i.
  DATA: lv_percent TYPE i,
        lv_text    TYPE string.

  lv_percent = iv_percent * 100 / lv_count.
  lv_text = '数据查询中...  ' && lv_percent && '%' && '(' && iv_percent && '/' && lv_count && ')'.
  CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
    EXPORTING
      percentage = lv_percent
      text       = lv_text.

ENDFORM. " SHOW_PROGRESS_INDICATOR
*&---------------------------------------------------------------------*
*&      Form  DISPLAY_ALV
*&---------------------------------------------------------------------*
FORM display_alv .
  DATA: gr_table     TYPE REF TO cl_salv_table,
        gr_columns   TYPE REF TO cl_salv_columns_table,
        gr_column    TYPE REF TO cl_salv_column_table,
        gr_functions TYPE REF TO cl_salv_functions_list,
        gr_display   TYPE REF TO cl_salv_display_settings.

  TRY.
      CALL METHOD cl_salv_table=>factory
        IMPORTING
          r_salv_table = gr_table
        CHANGING
          t_table      = it_itab.
    CATCH cx_salv_msg .
  ENDTRY.

  gr_functions = gr_table->get_functions( ).
*  gr_functions->set_default( ).
  gr_functions->set_all( abap_true ).
  gr_columns = gr_table->get_columns( ).
  gr_columns->set_optimize( 'X' ).

  DEFINE set_visible.
    gr_column ?= gr_columns->get_column( &1 ).
    gr_column->set_visible( &2 ).
    gr_column->set_technical( &3 ).
  END-OF-DEFINITION.

*--显示字段控制
  set_visible 'TABNAME'   'X' ''.
  set_visible 'FIELDNAME' 'X' ''.
  IF r_bt1 = 'X'.
    set_visible 'TABCLASS'  'X' ''.
  ELSE.
    set_visible 'TABCLASS'  '' ''.
  ENDIF.
  set_visible 'POSITION'  '' ''.
  set_visible 'VALUE_FLG' 'X' ''.

  IF r_bt1 = 'X'.
    set_visible 'MSG' 'X' ''.
  ELSE.
    set_visible 'MSG'  '' ''.
  ENDIF.

  DEFINE  set_text.
    gr_column ?= gr_columns->get_column( &1 ).
    gr_column->set_long_text( &2 ).
    gr_column->set_medium_text( &3 ).
    gr_column->set_short_text( &4 ).
  END-OF-DEFINITION.

  set_text 'TABNAME'      'Table Name'   'Table Name'   'Table Name'.
  set_text 'FIELDNAME'    'Field Name'   'Field Name'   'Field Name'.
  IF r_bt1 = 'X'.
    set_text 'TABCLASS'    'Table Category'   'Table Category'   'TableClass'.
  ENDIF.
  set_text 'VALUE_FLG'    'Result'       'Result'       'Result'.
  IF r_bt1 = 'X'.
    set_text 'MSG'          'MSG'          'MSG'          'MSG'.
  ENDIF.
*  gr_display = gr_table->get_display_settings( ).
*  gr_display->set_striped_pattern( cl_salv_display_settings=>true ).
*  gr_display->set_list_header('Header Test').

  gr_table->display( ).

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  EXCLUDE_TNAME
*&---------------------------------------------------------------------*
FORM exclude_tname  USING    VALUE(p_tname).
  READ TABLE s_tname TRANSPORTING NO FIELDS WITH KEY low = p_tname.
  IF sy-subrc NE 0.
    CLEAR:rs_tname.
    rs_tname-sign   = 'I'.
    rs_tname-option = 'EQ'.
    rs_tname-low    = p_tname.
    APPEND rs_tname TO s_tname.
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  CREAT_TEMP_TABLE
*&---------------------------------------------------------------------*
FORM creat_temp_table .
  DATA:lv_tabname      TYPE tabname.
  SELECT SINGLE tabname FROM dd02l INTO lv_tabname
                                 WHERE as4local = 'A'
                                   AND tabclass = 'TRANSP'
                                   AND tabname  = c_tmp_table.
  CHECK sy-subrc NE 0.

  DATA: lt_new_object         TYPE comt_gox_def_header,
        lt_old_object         LIKE lt_new_object,
        lv_dbtab1_name        TYPE char32,
        ls_new_object         LIKE LINE OF lt_new_object,
        ls_new_object_details TYPE LINE OF comt_gox_table_entry_fields,
        lt_returntab          TYPE bapirettab,
        ls_return             LIKE LINE OF lt_returntab.

  ls_new_object-object_type = 'TABLE'.
  ls_new_object-object_name = c_tmp_table.

  TRY.
      DATA(lv_guid) = cl_system_uuid=>if_system_uuid_static~create_uuid_c32( ).
    CATCH cx_uuid_error .
  ENDTRY.

* technical setting " 可参照FM: DDIF_TABL_GET 输出结构  DD02V 和 DD09V 字段域值赋值。
  ls_new_object-key_guid = lv_guid.
  DATA(lv_parent_guid) = ls_new_object-key_guid.
  ls_new_object_details-fieldname = 'TABCLASS'.
  ls_new_object_details-fieldvalue = 'TRANSP'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.

  ls_new_object_details-fieldname = 'CONTFLAG'."表交付和维护:交付类
  ls_new_object_details-fieldvalue = 'A'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.

  ls_new_object_details-fieldname = 'MAINFLAG'."数据浏览器/表视图编辑
  ls_new_object_details-fieldvalue = 'X'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.
*--逻辑存储参数
  ls_new_object_details-fieldname = 'TABART'. "技术设置:技术类
  ls_new_object_details-fieldvalue = 'APPL0'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.

  ls_new_object_details-fieldname = 'TABKAT'."技术设置:大小类别
  ls_new_object_details-fieldvalue = '0'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.
*--缓冲
  ls_new_object_details-fieldname = 'BUFFALLOW'."允许/不允许缓冲的指示器
  ls_new_object_details-fieldvalue = 'N'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.
*--缓冲类型
  ls_new_object_details-fieldname = 'PUFFERUNG'.
  ls_new_object_details-fieldvalue = ' '.
  APPEND ls_new_object_details TO ls_new_object-details.

*--键值字段数
  CLEAR ls_new_object_details.
  ls_new_object_details-fieldname = 'SCHFELDANZ'.
  ls_new_object_details-fieldvalue = '0'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.

*--增强类别
  CLEAR ls_new_object_details.
  ls_new_object_details-fieldname = 'EXCLASS'.
  ls_new_object_details-fieldvalue = '3'. "可以增强(字符或数字型)
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.

  APPEND ls_new_object TO lt_new_object.
  CLEAR ls_new_object.

*  表:YTMP_TABLE  字段
*  MANDT        MANDT
*  TABNAME      TABNAME
*  NEXT_TABNAME    TABNAME

  "表字段可以用EXCEL上传批量转换,参照后续截图。
*-字段1
  ls_new_object-object_type = 'TABLE_FIELD'.
  TRY.
      CLEAR:lv_guid.
      lv_guid = cl_system_uuid=>if_system_uuid_static~create_uuid_c32( ).
    CATCH cx_uuid_error .
  ENDTRY.
  ls_new_object-key_guid            = lv_guid.
  ls_new_object-parent_key          = lv_parent_guid.
  ls_new_object-object_name         = 'MANDT'. "field name
  ls_new_object_details-fieldname   = 'POSITION'.
  ls_new_object_details-fieldvalue  = '1'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.

  ls_new_object_details-fieldname = 'KEYFLAG'. "Key
  ls_new_object_details-fieldvalue = 'X'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.

  ls_new_object_details-fieldname = 'NOTNULL'. "initial
  ls_new_object_details-fieldvalue = 'X'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.

  ls_new_object_details-fieldname = 'ROLLNAME'.
  ls_new_object_details-fieldvalue = 'MANDT'. "字段参考数据元素
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.

  APPEND ls_new_object TO lt_new_object.
  CLEAR ls_new_object.

*-字段2
  ls_new_object-object_type = 'TABLE_FIELD'.
  TRY.
      CLEAR:lv_guid.
      lv_guid = cl_system_uuid=>if_system_uuid_static~create_uuid_c32( ).
    CATCH cx_uuid_error .
  ENDTRY.
  ls_new_object-key_guid            = lv_guid.
  ls_new_object-parent_key          = lv_parent_guid.
  ls_new_object-object_name         = 'TABNAME'. "field name
  ls_new_object_details-fieldname   = 'POSITION'.
  ls_new_object_details-fieldvalue  = '2'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.

  ls_new_object_details-fieldname = 'KEYFLAG'. "Key
  ls_new_object_details-fieldvalue = 'X'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.

  ls_new_object_details-fieldname = 'NOTNULL'. "initial
  ls_new_object_details-fieldvalue = 'X'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.

  ls_new_object_details-fieldname = 'ROLLNAME'.
  ls_new_object_details-fieldvalue = 'TABNAME'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.

  APPEND ls_new_object TO lt_new_object.
  CLEAR ls_new_object.

*-字段3
  ls_new_object-object_type = 'TABLE_FIELD'.
  TRY.
      CLEAR:lv_guid.
      lv_guid = cl_system_uuid=>if_system_uuid_static~create_uuid_c32( ).
    CATCH cx_uuid_error .
  ENDTRY.
  ls_new_object-key_guid            = lv_guid.
  ls_new_object-parent_key          = lv_parent_guid.
  ls_new_object-object_name         = 'SEQUENCE'. "field name
  ls_new_object_details-fieldname   = 'POSITION'.
  ls_new_object_details-fieldvalue  = '3'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.

  ls_new_object_details-fieldname   = 'ROLLNAME'.
  ls_new_object_details-fieldvalue  = 'BDL_SEQ'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.

  APPEND ls_new_object TO lt_new_object.
  CLEAR ls_new_object.

*-字段4
  ls_new_object-object_type = 'TABLE_FIELD'.
  TRY.
      CLEAR:lv_guid.
      lv_guid = cl_system_uuid=>if_system_uuid_static~create_uuid_c32( ).
    CATCH cx_uuid_error .
  ENDTRY.
  ls_new_object-key_guid            = lv_guid.
  ls_new_object-parent_key          = lv_parent_guid.
  ls_new_object-object_name         = 'FLAG'. "field name
  ls_new_object_details-fieldname   = 'POSITION'.
  ls_new_object_details-fieldvalue  = '4'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.

  ls_new_object_details-fieldname   = 'ROLLNAME'.
  ls_new_object_details-fieldvalue  = 'XFLAG'.
  APPEND ls_new_object_details TO ls_new_object-details.
  CLEAR ls_new_object_details.

  APPEND ls_new_object TO lt_new_object.
  CLEAR ls_new_object.

  REFRESH lt_returntab.


  lv_dbtab1_name = c_tmp_table.
  CALL FUNCTION 'GOX_GEN_TABLE_STD'
    EXPORTING
      iv_object_name = lv_dbtab1_name
      it_object_new  = lt_new_object
      it_object_old  = lt_old_object
      iv_devclass    = '$TMP'  "local
*     IV_REQUEST_WB  =
    IMPORTING
      et_bapireturn  = lt_returntab
*     ET_TRANSPORT   =
    .

  CHECK lt_returntab IS INITIAL.

  DATA: lv_ddobjname TYPE ddobjname,
        ls_dd02v     TYPE dd02v.

  lv_ddobjname = lv_dbtab1_name.
  CALL FUNCTION 'DDIF_TABL_GET'
    EXPORTING
      name          = lv_ddobjname
      state         = 'A'
      langu         = sy-langu
    IMPORTING
      dd02v_wa      = ls_dd02v
    EXCEPTIONS
      illegal_input = 1
      OTHERS        = 2.
  IF sy-subrc <> 0.
    RETURN.
  ENDIF.

  ls_dd02v-mainflag = 'X'.
  CALL FUNCTION 'DDIF_TABL_PUT'
    EXPORTING
      name              = lv_ddobjname
      dd02v_wa          = ls_dd02v
    EXCEPTIONS
      tabl_not_found    = 1
      name_inconsistent = 2
      tabl_inconsistent = 3
      put_failure       = 4
      put_refused       = 5
      OTHERS            = 6.
  IF sy-subrc <> 0.
    RETURN.
  ENDIF.

* active table
  CALL FUNCTION 'DDIF_TABL_ACTIVATE'
    EXPORTING
      name     = lv_ddobjname
      auth_chk = ' '.
ENDFORM.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值