• 物料主数据批导


    *&---------------------------------------------------------------------*
    *& Report  ZMAINTAIN_MATERAIL
    *&
    *&---------------------------------------------------------------------*
    *&
    *&
    *&---------------------------------------------------------------------*
    
    REPORT zmaintain_materail.
    
    CONSTANTS cnst_excel_file_path_name TYPE string VALUE '物料主数据导入Excel文件路径'.
    CONSTANTS cnst_button_text TYPE string VALUE '执行物料导入'.
    CONSTANTS cnst_button_text_test TYPE string VALUE '导入测试,不提交数据库'.
    CONSTANTS cnst_button_text_bg TYPE string VALUE '提交后台执行'.
    CONSTANTS cnst_button_text_job_info TYPE string VALUE '查看JOB信息'.
    CONSTANTS cnst_template_name TYPE string VALUE '物料主数据导入模板'.
    
    *//***************************************************************************
    TABLES sscrfields.
    DATA functxt TYPE smp_dyntxt.
    TYPE-POOLS icon.
    SELECTION-SCREEN: FUNCTION KEY 1,FUNCTION KEY 2.
    *//***************************************************************************
    PARAMETERS p_file TYPE rlgrap-filename.
    PARAMETERS p_bg TYPE abap_bool DEFAULT abap_false NO-DISPLAY."// 用于标识后台执行,创建job时赋值ABAP_TRUE
    PARAMETERS p_srtfd TYPE indx_srtfd NO-DISPLAY."//用于保存内表
    PARAMETERS p_srtfd1 TYPE indx_srtfd NO-DISPLAY. "//用于保存内表结构
    *//***************************************************************************
    DATA: BEGIN OF gs_field,
            fieldname TYPE fieldname,
          END OF gs_field.
    DATA gt_fields LIKE TABLE OF gs_field.
    *//***************************************************************************
    DATA: BEGIN OF gs_field_list,
            fieldname TYPE string,
            fielddesc TYPE string,
          END OF gs_field_list,
          gt_fields_list LIKE TABLE OF gs_field_list.
    *//***************************************************************************
    DATA gs_job TYPE tbtcjob.
    DATA gs_job_return TYPE bapiret2.
    DATA go_job TYPE REF TO zcl_job.
    *//***************************************************************************
    
    DATA gr_error TYPE REF TO cx_root.
    
    DATA gv_test_run TYPE char1 VALUE IS INITIAL.
    DATA gv_background TYPE abap_bool VALUE abap_false.
    
    FIELD-SYMBOLS <gt_output> TYPE STANDARD TABLE.
    DATA gt_output_table TYPE REF TO data.
    
    *//***************************************************************************
    *//***************************************************************************
    CLASS lcl_process DEFINITION.
      PUBLIC SECTION.
        CLASS-DATA: lo_salv      TYPE REF TO cl_salv_table,
                    lo_container TYPE REF TO cl_gui_container,
                    lo_docking   TYPE REF TO cl_gui_docking_container,
                    lo_events    TYPE REF TO cl_salv_events_table.
        CLASS-DATA: lr_columns TYPE REF TO cl_salv_columns.
        CLASS-DATA lr_column TYPE REF TO cl_salv_column.
        CLASS-DATA lr_columns_table TYPE REF TO cl_salv_columns_table.
        CLASS-DATA lr_column_table TYPE REF TO cl_salv_column_table.
    
        CLASS-DATA component_tab TYPE cl_abap_structdescr=>component_table.
    
        CLASS-METHODS read_excel IMPORTING i_file   TYPE rlgrap-filename
                                 CHANGING  it_table TYPE STANDARD TABLE OPTIONAL.
    
        CLASS-METHODS display
          IMPORTING button_text TYPE string OPTIONAL
          CHANGING  it_table    TYPE STANDARD TABLE OPTIONAL.
    
        CLASS-METHODS on_user_command FOR EVENT added_function OF cl_salv_events IMPORTING e_salv_function.
        CLASS-METHODS on_link_click FOR EVENT if_salv_events_actions_table~link_click OF cl_salv_events_table
          IMPORTING row column.
        CLASS-METHODS on_doubleclick FOR EVENT if_salv_events_actions_table~double_click OF cl_salv_events_table
          IMPORTING sender row column.
        CLASS-METHODS refresh.
    
    
        CLASS-DATA: BEGIN OF gwa_field_relation,
                      excel_original_text TYPE string,
                      excel_fieldname     TYPE string,
                      excel_column_seq    TYPE i,
                      tab_desc            TYPE string.
                      INCLUDE TYPE dfies.
        CLASS-DATA:END OF gwa_field_relation.
        CLASS-DATA gt_field_relation LIKE TABLE OF gwa_field_relation.
    
        CLASS-METHODS prepare_field_relation_logic IMPORTING tabname TYPE char30.
        CLASS-METHODS prepare_field_relation.
    
        CLASS-DATA: BEGIN OF gs_bapi_ext_relation,
                      tabname            TYPE        char30,
                      fieldname          TYPE        char30,
                      tabname_bapi_ext   TYPE        char30,
                      fieldname_bapi_ext TYPE        char30,
                      tabname_bapi_extx  TYPE        char30,
                      bapi_ext_row       TYPE REF TO data,
                      bapi_ext_rowx      TYPE REF TO data,
                    END OF gs_bapi_ext_relation,
                    gt_bapi_ext_relation LIKE TABLE OF gs_bapi_ext_relation.
    
    ENDCLASS.
    *//***************************************************************************
    *//***************************************************************************
    START-OF-SELECTION.
      IF p_bg = abap_false.
        gv_background = abap_false.
        lcl_process=>read_excel( i_file = p_file ).
        CHECK <gt_output> IS ASSIGNED.
        CHECK <gt_output> IS NOT INITIAL.
        lcl_process=>display( EXPORTING button_text = cnst_button_text CHANGING it_table = <gt_output> ).
      ELSE.
        CLEAR gt_fields.
        IMPORT itab_structure = gt_fields FROM DATABASE indx(zx) ID p_srtfd1.
        IF gt_fields IS INITIAL.
          MESSAGE '无法获取所处理的内表的结构' TYPE 'S' DISPLAY LIKE 'E'.
          RETURN.
        ENDIF.
        DATA go_structdescr TYPE REF TO cl_abap_structdescr.
        DATA go_tabledesc TYPE REF TO cl_abap_tabledescr.
        DATA go_datadescr TYPE REF TO cl_abap_datadescr.
        DATA gt_components TYPE abap_component_tab.
        CLEAR gt_components.
        go_datadescr ?= cl_abap_datadescr=>describe_by_name( 'STRING' ).
        LOOP AT gt_fields ASSIGNING FIELD-SYMBOL(<ls_field>).
          APPEND INITIAL LINE TO gt_components ASSIGNING FIELD-SYMBOL(<gs_component>).
          IF <ls_field>-fieldname <> '_RETURN'.
            <gs_component>-name = <ls_field>-fieldname.
            <gs_component>-type = go_datadescr.
          ELSE.
            DATA return_temp TYPE TABLE OF bapi_matreturn2.
            <gs_component>-name = <ls_field>-fieldname.
            <gs_component>-type ?= cl_abap_datadescr=>describe_by_data( return_temp )..
          ENDIF.
        ENDLOOP.
        TRY.
            go_structdescr = cl_abap_structdescr=>create( gt_components ).
            go_tabledesc = cl_abap_tabledescr=>create( go_structdescr ).
          CATCH cx_root INTO DATA(lv_create_error).
            MESSAGE |构建内表失败:{ lv_create_error->get_text( ) }| TYPE 'S' DISPLAY LIKE 'E'.
            RETURN.
        ENDTRY.
        CREATE DATA gt_output_table TYPE HANDLE go_tabledesc.
        ASSIGN gt_output_table->* TO <gt_output>.
        TRY.
            IMPORT itab = <gt_output> FROM DATABASE indx(zx) ID p_srtfd.
          CATCH cx_root INTO DATA(lx_import_error).
            MESSAGE |导入内表内容失败:{ lx_import_error->get_text( ) }| TYPE 'S' DISPLAY LIKE 'E'.
            RETURN.
        ENDTRY.
        IF <gt_output> IS INITIAL.
          MESSAGE '没有找到合适的数据,无法后台执行处理,请确认!' TYPE 'S' DISPLAY LIKE 'E'.
        ELSE.
          PERFORM frm_exec.
          MESSAGE |{ repeat( val = '*'  occ = 80 ) }| TYPE 'S'.
          MESSAGE '处理完成,请检查' TYPE 'S'.
          MESSAGE |{ repeat( val = '*'  occ = 80 ) }| TYPE 'S'.
        ENDIF.
    
      ENDIF.
    *//***************************************************************************
    *//***************************************************************************
    INITIALIZATION.
      %_p_file_%_app_%-text = cnst_excel_file_path_name.
    
      functxt-text = ''."最多四十个字符.如果有按钮icon_text的话,就不显示了
      functxt-icon_id = icon_xxl.
      functxt-quickinfo = '指定导入字段,生成导入模板'.
      functxt-icon_text = '指定导入字段,生成导入模板'.
      sscrfields-functxt_01 = functxt.
      functxt-text = ''."最多四十个字符.如果有按钮icon_text的话,就不显示了
      functxt-icon_id = icon_history.
      functxt-quickinfo = '查看设置的模板'.
      functxt-icon_text = '查看设置的模板'.
      sscrfields-functxt_02 = functxt.
    *//***************************************************************************
    *//***************************************************************************
    AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
      p_file = zcl_excel_tools=>get_upload_path( ).
    *//***************************************************************************
    *//***************************************************************************
    AT SELECTION-SCREEN.
      CASE sy-ucomm.
        WHEN 'FC01'.
    *      CALL SELECTION-SCREEN 9000  STARTING AT 20 1 ENDING AT 170 22.
          lcl_process=>prepare_field_relation( ).
          DATA(gdt_selected) = zcl_tabbed=>select(
            is_alv = VALUE #(
                io_tabbed = zcl_tabbed=>new( lcl_process=>gt_field_relation )
                iv_alv_except_fields = |excel_original_text,excel_field_name,excel_column_seq,| &&
                                       |excel_fieldname,authorid,keyflag,lowercase,mac,genkey,noforkey,| &&
                                       |noauthch,sign,ltrflddis,bidictrlc,outputstyle,nohistory,ampmformat,checktable,precfield,| &&
                                       |mask,masklen,comptype,lfieldname,dynpfld,f4availabl,valexi,reptext,logflag,scrlen1,scrlen2,| &&
                                       |scrlen3,headlen,langu,position,offset|
                iv_alv_fields_desc = |tab_desc:BAPI结构名| &&
                                     ||
                iv_alv_fields_position = |fieldtext:3,fieldname:3,tab_Desc:5,rollname:5,domname:5,leng:5,intlen:5|
            )
          ).
          PERFORM frm_get_selected_fields USING gdt_selected.
        WHEN 'FC02'.
          PERFORM frm_view_templates.
      ENDCASE.
    *//***************************************************************************
    *//***************************************************************************
    AT SELECTION-SCREEN OUTPUT.
    *//***************************************************************************
    *//***************************************************************************
    
    *//***************************************************************************
    *//***************************************************************************
    FORM frm_get_selected_fields USING idt_selected TYPE REF TO data.
    
      FIELD-SYMBOLS <lt_selected> TYPE STANDARD TABLE.
      ASSIGN idt_selected->* TO <lt_selected>.
      CHECK sy-subrc = 0.
      DATA lt_selected LIKE lcl_process=>gt_field_relation.
      CLEAR lt_selected.
      MOVE-CORRESPONDING <lt_selected> TO lt_selected.
      CHECK lt_selected IS NOT INITIAL.
    
      DATA lo_struct TYPE REF TO cl_abap_structdescr.
      DATA lo_table TYPE REF TO cl_abap_tabledescr.
      DATA lo_data TYPE REF TO cl_abap_datadescr.
    
      DATA components TYPE cl_abap_structdescr=>component_table.
      CLEAR: components.
      lo_data ?= cl_abap_datadescr=>describe_by_name( 'STRING' ).
      DO lines( lt_selected ) TIMES.
        APPEND INITIAL LINE TO components ASSIGNING FIELD-SYMBOL(<ls_comp>).
        <ls_comp>-name = 'COL' && sy-tabix.
        <ls_comp>-type = lo_data.
      ENDDO.
      lo_struct = cl_abap_structdescr=>create( components ).
      lo_table = cl_abap_tabledescr=>create( lo_struct ).
    
      DATA t_table TYPE REF TO data.
      FIELD-SYMBOLS <t_table> TYPE STANDARD TABLE.
      DATA ls_row1 TYPE REF TO data.
      FIELD-SYMBOLS <ls_row1> TYPE any.
      DATA ls_row2 TYPE REF TO data.
      FIELD-SYMBOLS <ls_row2> TYPE any.
    
      CREATE DATA ls_row1 TYPE HANDLE lo_struct.
      ASSIGN ls_row1->* TO <ls_row1>.
      CREATE DATA ls_row2 TYPE HANDLE lo_struct.
      ASSIGN ls_row2->* TO <ls_row2>.
    
      CREATE DATA t_table TYPE HANDLE lo_table.
      ASSIGN t_table->* TO <t_table>.
    
      DATA lv_counter TYPE i VALUE IS INITIAL.
      CLEAR gt_fields_list.
    
      LOOP AT lt_selected ASSIGNING FIELD-SYMBOL(<ls_selected>).
        lv_counter = lv_counter + 1.
        ASSIGN COMPONENT lv_counter OF STRUCTURE <ls_row1> TO FIELD-SYMBOL(<value1>).
        <value1> = <ls_selected>-tabname && '-' && <ls_selected>-fieldname.
        ASSIGN COMPONENT lv_counter OF STRUCTURE <ls_row2> TO FIELD-SYMBOL(<value2>).
        <value2> = <ls_selected>-scrtext_l.
        APPEND INITIAL LINE TO gt_fields_list ASSIGNING FIELD-SYMBOL(<ls_field_list>).
        <ls_field_list>-fieldname = <value1>.
        <ls_field_list>-fielddesc = <value2>.
      ENDLOOP.
    
      APPEND <ls_row1> TO <t_table>.
      APPEND <ls_row2> TO <t_table>.
    
      "//弹出框,输入模板名称
      DATA ls_name TYPE j_3gbelk.
      CLEAR ls_name.
      zcl_xhl=>get_input_values( EXPORTING iv_structure_name = 'J_3GBELK'
                                           iv_fields = 'J_3GVVCOM1'
                                 CHANGING cs_structure = ls_name ).
      IF ls_name-j_3gvvcom1 IS INITIAL.
        ls_name-j_3gvvcom1 = |物料主数据导入模板-{ sy-datum }-{ sy-uzeit }|.
      ENDIF.
    
      DATA ls_indx TYPE indx.
      CLEAR ls_indx.
      TRY.
          ls_indx-srtfd = cl_system_uuid=>create_uuid_c22_static( ).
        CATCH cx_root.
      ENDTRY.
      ls_indx-relid  = 'ZX'.
      ls_indx-usera = 'MAT_MAINTAIN'.
      ls_indx-aedat = sy-datum.
      ls_indx-pgmid = ls_name-j_3gvvcom1.
      EXPORT itab = gt_fields_list TO DATABASE indx(zx) FROM ls_indx ID ls_indx-srtfd.
      COMMIT WORK.
    
      PERFORM download_template USING <t_table> ''.
    
    ENDFORM.
    
    *//***************************************************************************
    *//***************************************************************************
    CLASS lcl_process IMPLEMENTATION.
    *//********************************************************************
      METHOD read_excel.
    
        DATA(lo_excel) = zcl_excel_tools=>upload_by_fdt( CONV #( i_file ) ).
        ASSIGN lo_excel->gt_excel->* TO FIELD-SYMBOL(<lt_excel>).
    
        DATA lo_struct TYPE REF TO cl_abap_structdescr.
        DATA lo_table TYPE REF TO cl_abap_tabledescr.
        DATA lo_data TYPE REF TO cl_abap_datadescr.
    
        DATA components TYPE cl_abap_structdescr=>component_table.
        FIELD-SYMBOLS <component> TYPE LINE OF cl_abap_structdescr=>component_table.
        DATA component TYPE LINE OF cl_abap_structdescr=>component_table.
    
        lo_data ?= cl_abap_datadescr=>describe_by_name( 'STRING' ).
        lo_table ?= cl_abap_tabledescr=>describe_by_data( <lt_excel> ).
        lo_struct ?= lo_table->get_table_line_type( ).
        component_tab = lo_struct->get_components( ).
        MOVE-CORRESPONDING component_tab TO components.
    
        component-name = '_SEQ'.
        component-type = lo_data.
        APPEND component TO components.
    
        component-name = '_ICON'.
        component-type = lo_data.
        APPEND component TO components.
    
        component-name = '_MSG'.
        component-type = lo_data.
        APPEND component TO components.
    
        component-name = '_CLICK'.
        component-type = lo_data.
        APPEND component TO components.
    
        DATA return_temp TYPE TABLE OF bapi_matreturn2.
        component-name = '_RETURN'.
        component-type ?= cl_abap_datadescr=>describe_by_data( return_temp )..
        APPEND component TO components.
    
        lo_struct = cl_abap_structdescr=>create( components ).
        lo_table = cl_abap_tabledescr=>create( lo_struct ).
        CREATE DATA gt_output_table TYPE HANDLE lo_table.
        ASSIGN gt_output_table->* TO <gt_output>.
    
        MOVE-CORRESPONDING <lt_excel> TO <gt_output>.
    
        LOOP AT <gt_output> ASSIGNING FIELD-SYMBOL(<row>).
          CHECK sy-tabix > 2.
          ASSIGN COMPONENT '_SEQ' OF STRUCTURE <row> TO FIELD-SYMBOL(<value>).
          IF <value> IS ASSIGNED.
            <value> = sy-tabix - 2.
          ENDIF.
          ASSIGN COMPONENT '_MSG' OF STRUCTURE <row> TO <value>.
          IF <value> IS ASSIGNED.
            <value> = '等待导入'.
          ENDIF.
    
          ASSIGN COMPONENT '_ICON' OF STRUCTURE <row> TO <value>.
          IF <value> IS ASSIGNED.
            <value> = icon_yellow_light.
          ENDIF.
    
          ASSIGN COMPONENT '_CLICK' OF STRUCTURE <row> TO <value>.
          IF <value> IS ASSIGNED.
            <value> = '点击查看'.
          ENDIF.
    
        ENDLOOP.
    
      ENDMETHOD.
    *//********************************************************************
      METHOD display.
        WRITE space.
        DATA lv_style TYPE i.
        lv_style = cl_gui_control=>ws_child
                  + cl_gui_control=>ws_border
                  + cl_gui_control=>ws_visible.
        IF lo_docking IS INITIAL.
          CREATE OBJECT lo_docking
            EXPORTING
              parent                  = cl_gui_custom_container=>default_screen
              no_autodef_progid_dynnr = 'X'
              style                   = lv_style.
          CALL METHOD lo_docking->set_extension
            EXPORTING
              extension = 10000.
          lo_container ?= lo_docking.
        ENDIF.
    
        TRY.
            CALL METHOD cl_salv_table=>factory
              EXPORTING
                r_container  = lo_container
              IMPORTING
                r_salv_table = lo_salv
              CHANGING
                t_table      = it_table.
          CATCH cx_salv_msg INTO DATA(lo_err01).
        ENDTRY.
    
        DATA functions TYPE REF TO cl_salv_functions_list.
        functions = lo_salv->get_functions( ).
        functions->set_all( 'X' ).
    
        TRY.
            functions->add_function( EXPORTING
                name     = 'EXEC'
                icon     =  '@15@'
                text     = button_text
                tooltip  = button_text
                position = if_salv_c_function_position=>left_of_salv_functions  ).
          CATCH cx_salv_existing INTO DATA(lo_err02).
          CATCH cx_salv_wrong_call INTO DATA(lo_err03).
        ENDTRY.
    
        TRY.
            functions->add_function( EXPORTING
                name     = 'EXEC_TEST'
                icon     =  '@15@'
                text     = cnst_button_text_test
                tooltip  = cnst_button_text_test
                position = if_salv_c_function_position=>left_of_salv_functions  ).
          CATCH cx_salv_existing INTO DATA(lo_err04).
          CATCH cx_salv_wrong_call INTO DATA(lo_err05).
        ENDTRY.
    
        TRY.
            functions->add_function( EXPORTING
                name     = 'BACKGROUND'
                icon     =  '@M4@'
                text     = cnst_button_text_bg
                tooltip  = cnst_button_text_bg
                position = if_salv_c_function_position=>right_of_salv_functions ).
          CATCH cx_salv_existing INTO DATA(lo_err16).
          CATCH cx_salv_wrong_call INTO DATA(lo_err17).
        ENDTRY.
    
        TRY.
            functions->add_function( EXPORTING
                name     = 'JOB_INFO'
                icon     =  '@M5@'
                text     = cnst_button_text_job_info
                tooltip  = cnst_button_text_job_info
                position = if_salv_c_function_position=>right_of_salv_functions ).
          CATCH cx_salv_existing INTO DATA(lo_err18).
          CATCH cx_salv_wrong_call INTO DATA(lo_err19).
        ENDTRY.
    
        lo_events = lo_salv->get_event( ).
        SET HANDLER on_user_command FOR lo_events.
        SET HANDLER on_link_click FOR lo_events.
        SET HANDLER on_doubleclick FOR lo_events.
    
        lr_columns = lo_salv->get_columns( ).
        lr_columns_table ?= lr_columns.
        lr_columns_table->set_column_position( columnname = '_CLICK' position = 1 ).
        lr_columns_table->set_column_position( columnname = '_MSG' position = 1 ).
        lr_columns_table->set_column_position( columnname = '_ICON' position = 1 ).
        lr_columns_table->set_column_position( columnname = '_SEQ' position = 1 ).
        TRY.
            lr_column_table ?= lr_columns_table->get_column( '_SEQ' ).
            lr_column_table->set_long_text( '数据序号' ).
            lr_column_table->set_medium_text( '数据序号' ).
            lr_column_table->set_short_text( '数据序号' ).
          CATCH cx_salv_not_found INTO DATA(lo_err06).
        ENDTRY.
        TRY.
            lr_column_table ?= lr_columns_table->get_column( '_ICON' ).
            lr_column_table->set_long_text( '状态' ).
            lr_column_table->set_medium_text( '状态' ).
            lr_column_table->set_short_text( '状态' ).
            lr_column_table->set_icon( 'X' ).
          CATCH cx_salv_not_found INTO DATA(lo_err07).
        ENDTRY.
        TRY.
            lr_column_table ?= lr_columns_table->get_column( '_MSG' ).
            lr_column_table->set_long_text( '消息' ).
            lr_column_table->set_medium_text( '消息' ).
            lr_column_table->set_short_text( '消息' ).
          CATCH cx_salv_not_found INTO DATA(lo_err08).
        ENDTRY.
        TRY.
            lr_column_table ?= lr_columns_table->get_column( '_CLICK' ).
            lr_column_table->set_long_text( 'BAPI消息' ).
            lr_column_table->set_medium_text( 'BAPI消息' ).
            lr_column_table->set_short_text( 'BAPI消息' ).
            lr_column_table->set_cell_type( if_salv_c_cell_type=>hotspot ).
          CATCH cx_salv_not_found INTO DATA(lo_err09).
        ENDTRY.
        lr_columns_table->set_optimize( 'X' ).
    
        DATA lo_err TYPE REF TO cx_root.
        FIELD-SYMBOLS <component> TYPE LINE OF cl_abap_structdescr=>component_table.
        DATA fname TYPE lvc_fname.
        DATA txt_long TYPE scrtext_l.
        DATA txt_medium TYPE scrtext_m.
        DATA txt_short TYPE scrtext_s.
        DATA txt_tip TYPE lvc_tip.
        LOOP AT component_tab ASSIGNING <component>.
          fname = <component>-name.
          TRY.
              lr_column = lr_columns->get_column( fname ).
              txt_long = fname.
              txt_medium = fname.
              txt_short = fname.
              lr_column->set_long_text( txt_long ).
              lr_column->set_medium_text( txt_medium ).
              lr_column->set_short_text( txt_short ).
              txt_tip = fname && ''.
              lr_column->set_tooltip( txt_tip ).
            CATCH cx_salv_not_found INTO lo_err.
          ENDTRY.
        ENDLOOP.
    
        DATA: lr_display TYPE REF TO cl_salv_display_settings,
              ls_layout  TYPE        salv_s_layout_key,
              lr_layout  TYPE REF TO cl_salv_layout.
        DATA lv_header_text TYPE lvc_title.
        lv_header_text = 'Excel内容'.
        lr_display = lo_salv->get_display_settings( )..
        lr_display->set_striped_pattern( cl_salv_display_settings=>true ).
        lr_display->set_list_header( lv_header_text ).
        lr_layout = lo_salv->get_layout( ).
        ls_layout-report = sy-repid.
        lr_layout->set_key( ls_layout ).
        lr_layout->set_default( 'X' )..
        lr_layout->set_save_restriction( cl_salv_layout=>restrict_none ).
    
        DATA lo_selections TYPE REF TO cl_salv_selections.
        lo_selections = lo_salv->get_selections( ).
        lo_selections->set_selection_mode( if_salv_c_selection_mode=>row_column ).
    
        CALL METHOD lo_salv->display( ).
    
      ENDMETHOD.
    *//********************************************************************
      METHOD on_user_command.
    
        CASE e_salv_function.
          WHEN 'EXEC'.
            IF gv_background = abap_true.
              MESSAGE '已经提交后台,不能重复提交' TYPE 'S' DISPLAY LIKE 'W'.
            ELSE.
              gv_test_run = ''.
              PERFORM frm_exec IN PROGRAM (sy-repid) IF FOUND.
            ENDIF.
          WHEN 'EXEC_TEST'.
            IF gv_background = abap_true.
              MESSAGE '已经提交后台,不能重复提交' TYPE 'S' DISPLAY LIKE 'W'.
            ELSE.
              gv_test_run = 'X'.
              PERFORM frm_exec IN PROGRAM (sy-repid) IF FOUND.
            ENDIF.
          WHEN 'BACKGROUND'.
            IF gv_background = abap_true.
              IF zcl_xhl=>confirm( '已经提交后台任务,确定要再次提交?' ) = abap_true.
                PERFORM frm_prepare_2_bg.
              ENDIF.
            ELSE.
              PERFORM frm_prepare_2_bg.
            ENDIF.
          WHEN 'JOB_INFO'.
            PERFORM frm_display_job.
        ENDCASE.
    
      ENDMETHOD.
    *//********************************************************************
      METHOD on_doubleclick.
    
        CHECK row > 2.
        CHECK <gt_output> IS ASSIGNED.
        CHECK lines( <gt_output> ) > 2.
        READ TABLE <gt_output> ASSIGNING FIELD-SYMBOL(<ls_row>) INDEX 2.
        CHECK sy-subrc = 0.
    
        READ TABLE <gt_output> ASSIGNING FIELD-SYMBOL(<ls_currrent_row>) INDEX row.
        CHECK sy-subrc = 0.
    
        DATA lo_structdescr TYPE REF TO cl_abap_structdescr.
        lo_structdescr ?= cl_abap_structdescr=>describe_by_data( <ls_currrent_row> ).
        DATA(lt_components) = lo_structdescr->get_included_view( ).
        DATA lv_matnr TYPE char18.
        CLEAR lv_matnr.
        LOOP AT lt_components ASSIGNING FIELD-SYMBOL(<ls_comp>).
          ASSIGN COMPONENT <ls_comp>-name OF STRUCTURE <ls_row> TO FIELD-SYMBOL(<lv_mat>).
          IF <lv_mat> CS 'MATERIAL'.
            ASSIGN COMPONENT <ls_comp>-name OF STRUCTURE <ls_currrent_row> TO FIELD-SYMBOL(<lv_mat_value>).
            lv_matnr = <lv_mat_value>.
            EXIT.
          ENDIF.
        ENDLOOP.
        CHECK lv_matnr IS NOT INITIAL.
        DATA ls_return TYPE bapiret1.
        lv_matnr = |{ lv_matnr ALPHA = IN }|.
        CALL FUNCTION 'BAPI_MATERIAL_DISPLAY'
          EXPORTING
            material = lv_matnr
    *       MATERIAL_EVG        =
    *       MATERIAL_LONG       =
          IMPORTING
            return   = ls_return.
        .
    
      ENDMETHOD.
    *//********************************************************************
      METHOD on_link_click.
        CHECK row > 0.
        READ TABLE <gt_output> ASSIGNING FIELD-SYMBOL(<row>) INDEX row.
        CHECK <row> IS ASSIGNED.
        ASSIGN COMPONENT '_RETURN' OF STRUCTURE <row> TO FIELD-SYMBOL(<bapi>).
        CHECK <bapi> IS ASSIGNED.
        DATA lr_salv TYPE REF TO cl_salv_table.
        IF lr_salv IS INITIAL.
          TRY.
              CALL METHOD cl_salv_table=>factory
                IMPORTING
                  r_salv_table = lr_salv
                CHANGING
                  t_table      = <bapi>.
            CATCH cx_salv_existing INTO DATA(lo_err10).
            CATCH cx_salv_msg INTO DATA(lo_err11).
          ENDTRY.
        ENDIF.
        lr_salv->set_screen_popup(
          start_column = 15
          end_column = 120
          start_line = 1
          end_line = 10 ).
        DATA lr_columns TYPE REF TO cl_salv_columns.
        lr_columns = lr_salv->get_columns( ).
        lr_columns->set_optimize( 'X' ).
        lr_salv->display( ).
      ENDMETHOD.
    *//********************************************************************
      METHOD refresh.
        IF lo_salv IS NOT INITIAL.
          lr_columns = lo_salv->get_columns( ).
          lr_columns->set_optimize( 'X' ).
          CALL METHOD lo_salv->refresh( ).
        ENDIF.
      ENDMETHOD.
    *//********************************************************************
      METHOD prepare_field_relation_logic.
        DATA lt_dfies TYPE TABLE OF dfies.
        CLEAR lt_dfies.
        CALL FUNCTION 'DDIF_FIELDINFO_GET'
          EXPORTING
            tabname   = tabname
            langu     = sy-langu
          TABLES
            dfies_tab = lt_dfies.
        CLEAR gwa_field_relation.
    
        DATA ls_dd02v TYPE dd02v.
        CALL FUNCTION 'DDIF_TABL_GET'
          EXPORTING
            name     = tabname
            state    = 'A'
            langu    = '1'
          IMPORTING
            dd02v_wa = ls_dd02v.
    
        LOOP AT lt_dfies ASSIGNING FIELD-SYMBOL(<dfies>).
          MOVE-CORRESPONDING <dfies> TO gwa_field_relation.
          gwa_field_relation-tab_desc = ls_dd02v-ddtext.
          APPEND gwa_field_relation TO gt_field_relation.
          CLEAR gwa_field_relation.
        ENDLOOP.
    
      ENDMETHOD.
    *//********************************************************************
      METHOD prepare_field_relation.
        CLEAR gt_field_relation.
        prepare_field_relation_logic( 'BAPIMATHEAD' ).
        prepare_field_relation_logic( 'BAPI_MAKT' ).
        prepare_field_relation_logic( 'BAPI_MARA' ).
        prepare_field_relation_logic( 'BAPI_MARC' ).
        prepare_field_relation_logic( 'BAPI_MPOP' ).
        prepare_field_relation_logic( 'BAPI_MPGD' ).
        prepare_field_relation_logic( 'BAPI_MARD' ).
        prepare_field_relation_logic( 'BAPI_MBEW' ).
        prepare_field_relation_logic( 'BAPI_MLGN' ).
        prepare_field_relation_logic( 'BAPI_MVKE' ).
        prepare_field_relation_logic( 'BAPI_MLGT' ).
        prepare_field_relation_logic( 'BAPI_MEAN' ).
        prepare_field_relation_logic( 'BAPI_MLAN' ).
        prepare_field_relation_logic( 'BAPI_MFHM' ).
      ENDMETHOD.
    
    ENDCLASS.
    
    *//***************************************************************************
    *//***************************************************************************
    FORM download_template USING it_table TYPE STANDARD TABLE
                                 iv_file_name TYPE string.
    
    *  DATA(lv_path) = zcl_excel_tools=>set_download_path( '物料主数据导入模板' ).
    *  CHECK lv_path IS NOT INITIAL.
    *  zcl_excel_tools=>download_template( EXPORTING iv_path = lv_path
    *                                                id_data = it_table
    *                                                iv_fields_desc = ''
    **                                                IT_FIELDS_DESC
    *                                                 ).
    *  RETURN.
    
      DATA lo_salv TYPE REF TO cl_salv_table.
      DATA lo_columns TYPE REF TO cl_salv_columns_table.
      DATA lo_column TYPE REF TO cl_salv_column_table.
      DATA l_columns TYPE salv_t_column_ref.
      FIELD-SYMBOLS <l_column> TYPE LINE OF salv_t_column_ref.
      DATA: lo_result_data TYPE REF TO cl_salv_ex_result_data_table.
      DATA e_xstring TYPE xstring.
      DATA it_sort TYPE lvc_t_sort.
      DATA it_filt TYPE lvc_t_filt.
      DATA is_layout TYPE lvc_s_layo.
      DATA lo_aggreg TYPE REF TO cl_salv_aggregations.
      DATA lt_fcat TYPE lvc_t_fcat.
      FIELD-SYMBOLS <fcat> TYPE lvc_s_fcat.
    
      DATA: l_size TYPE i.
      DATA: lt_bintab TYPE solix_tab.
      DATA: l_filename TYPE string.
      IF iv_file_name IS INITIAL.
        CONCATENATE cnst_template_name  '-'  sy-datum  '-'  sy-uzeit INTO l_filename.
      ELSE.
        CONCATENATE iv_file_name '-' sy-datum '-' sy-uzeit INTO l_filename.
      ENDIF.
      DATA: l_path TYPE string.
      DATA: f_path TYPE string.
    
      DATA: mt_data TYPE REF TO data.
      FIELD-SYMBOLS <mt_data> TYPE STANDARD TABLE.
      CREATE DATA mt_data LIKE it_table.
      ASSIGN mt_data->* TO <mt_data>.
    
      <mt_data> = it_table.
      DELETE <mt_data> INDEX 2.
    
      TRY.
          CALL METHOD cl_salv_table=>factory
            IMPORTING
              r_salv_table = lo_salv
            CHANGING
              t_table      = <mt_data>.
        CATCH cx_salv_msg INTO DATA(lo_err15).
      ENDTRY.
      CHECK lo_salv IS NOT INITIAL.
      DATA lr_columns TYPE REF TO cl_salv_columns.
      DATA lr_column TYPE REF TO cl_salv_column.
      DATA lr_salv_error TYPE REF TO cx_salv_not_found.
      lr_columns = lo_salv->get_columns( ).
    
      DEFINE coltext.
        TRY.
          lr_column = lr_columns->get_column( &1 ).
          lr_column->set_short_text( &2 ).
          lr_column->set_medium_text( &2 ).
          lr_column->set_long_text( &2 ).
        CATCH cx_salv_not_found INTO lr_salv_error.
        ENDTRY.
      END-OF-DEFINITION.
    
      FIELD-SYMBOLS <row> TYPE any.
      READ TABLE it_table ASSIGNING <row> INDEX 2.
      DATA lo_struct TYPE REF TO cl_abap_structdescr.
      DATA component_tab TYPE cl_abap_structdescr=>component_table.
      lo_struct ?= cl_abap_structdescr=>describe_by_data( <row> ).
      component_tab = lo_struct->get_components( ).
      DATA fname TYPE lvc_fname VALUE IS INITIAL.
    
      DATA txt_long TYPE scrtext_l.
      DATA txt_medium TYPE scrtext_m.
      DATA txt_short TYPE scrtext_s.
    
      DEFINE ctext.
        TRY.
          lr_column = lr_columns->get_column( &1 ).
          lr_column->set_short_text( &2 ).
          lr_column->set_medium_text( &3 ).
          lr_column->set_long_text( &4 ).
        CATCH cx_salv_not_found INTO lr_salv_error.
        ENDTRY.
      END-OF-DEFINITION.
    
      LOOP AT component_tab ASSIGNING FIELD-SYMBOL(<comp>).
        ASSIGN COMPONENT <comp>-name OF STRUCTURE <row> TO FIELD-SYMBOL(<fvalue>).
        fname = <comp>-name.
        txt_short = <fvalue>.
        txt_medium = <fvalue>.
        txt_long = <fvalue>.
        ctext fname txt_short txt_medium txt_long .
      ENDLOOP.
    
      lo_columns ?= lo_salv->get_columns( ).
      l_columns = lo_columns->get( ).
    
      lo_aggreg = lo_salv->get_aggregations( ).
      lt_fcat = cl_salv_controller_metadata=>get_lvc_fieldcatalog( r_columns      = lo_columns
                                                                   r_aggregations =  lo_aggreg ).
    
      LOOP AT l_columns ASSIGNING <l_column>.
        IF <l_column>-columnname(1) = '_'.
          DELETE lt_fcat WHERE fieldname = <l_column>-columnname.
          CONTINUE.
        ENDIF.
        IF <fcat> IS ASSIGNED.
          UNASSIGN <fcat>.
        ENDIF.
        READ TABLE lt_fcat ASSIGNING <fcat>
          WITH KEY fieldname = <l_column>-columnname.
        IF <fcat> IS ASSIGNED.
          <fcat>-reptext = <l_column>-r_column->get_short_text( ).
        ENDIF.
      ENDLOOP.
    
      lo_result_data = cl_salv_ex_util=>factory_result_data_table(
           r_data                      = mt_data
           s_layout                    = is_layout
           t_fieldcatalog              = lt_fcat
           t_sort                      = it_sort
           t_filter                    = it_filt ).
      CALL METHOD cl_salv_bs_tt_util=>if_salv_bs_tt_util~transform
        EXPORTING
    *     xml_type      = if_salv_bs_xml=>c_type_excel_xml
          xml_type      = if_salv_bs_xml=>c_type_xlsx
          "老系统中没有c_type_xlsx这个类型,只能使用c_type_excel_xml了。
    *     xml_version   = if_salv_bs_xml=>version_21 "没感觉到区别和下面
          xml_version   = if_salv_bs_xml=>version_26 "老系统没有26版本
          r_result_data = lo_result_data
          xml_flavour   = if_salv_bs_c_tt=>c_tt_xml_flavour_export
    *     gui_type      = if_salv_bs_xml=>c_gui_type_gui
          gui_type      = if_salv_bs_xml=>c_gui_type_wd
        IMPORTING
          xml           = e_xstring.
    
      IF e_xstring IS NOT INITIAL.
        CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
          EXPORTING
            buffer        = e_xstring
          IMPORTING
            output_length = l_size
          TABLES
            binary_tab    = lt_bintab.
        cl_gui_frontend_services=>file_save_dialog(
          EXPORTING
            window_title         = '保存导入模板'
    *        default_extension    = 'XLS' "c_type_excel_xml时需要这个。
            default_extension    = 'xlsx'
            default_file_name    = l_filename
    *      with_encoding        = with_encoding
    *      file_filter          = file_filter
    *      initial_directory    = initial_directory
          prompt_on_overwrite  = 'X'
          CHANGING
             filename             = l_filename
             path                 = l_path
             fullpath             = f_path
    *      user_action          = user_action
    *      file_encoding        = file_encoding
          EXCEPTIONS
            cntl_error           = 1
            error_no_gui         = 2
            not_supported_by_gui = 3
            OTHERS               = 4
               ).
        CHECK f_path IS NOT INITIAL.
        CALL METHOD cl_gui_frontend_services=>gui_download(
          EXPORTING
            bin_filesize = l_size
            filename     = f_path
            filetype     = 'BIN'
          CHANGING
            data_tab     = lt_bintab
          EXCEPTIONS
            OTHERS       = 24 ).
      ENDIF.
    
    ENDFORM.
    *//***************************************************************************
    *//***************************************************************************
    FORM frm_view_templates.
    
      SELECT DISTINCT srtfd,aedat, pgmid FROM indx
        WHERE usera = 'MAT_MAINTAIN'
        ORDER BY aedat DESCENDING
        INTO TABLE @DATA(lt_list).
    *  IF sy-subrc = 0 AND lt_list IS NOT INITIAL.
    *  ELSE.
    *    MESSAGE '没有模板历史' TYPE 'S' DISPLAY LIKE 'W'.
    *  ENDIF.
      "//不用判断,如果没有,也许是需要导入,从其它系统。
      zcl_tabbed=>display_once(
        iv_popup = abap_true
        it_top = VALUE #(
          ( io_tabbed = zcl_tabbed=>new( lt_list )
            iv_alv_except_fields = 'SRTFD'
            iv_alv_with_toolbar = abap_true
            iv_alv_fields_desc = |aedat:模板生成日期,PGMID:模板名称|
            iv_alv_dclick_callback = |template_callback_dclick|
            iv_alv_toolbar = |GENERATE:@DJ@-生成模板,UPLOAD:@48@-上载模板|
            iv_alv_toolbar_callback = |TEMPLATE_CALLBACK_TOOLBAR|
          )
        )
      ).
    
    ENDFORM.
    *//***************************************************************************
    *//***************************************************************************
    FORM template_callback_toolbar USING sender TYPE REF TO cl_gui_alv_grid
                                       e_ucomm TYPE syst_ucomm
                         CHANGING ct_top TYPE zcl_tabbed=>ttyp_tab
                                  ct_bottom TYPE zcl_tabbed=>ttyp_tab
                                   cs_pop TYPE zcl_tabbed=>typ_tab
                                   cv_no_leave TYPE abap_bool. "D20211025 新增参数,
      "为了控制CLOSE LEAVE等在特殊情况下不CLOSE LEAVE<br>
      "2021-10-28 新增,还可以处理ALV自定义上下文菜单功能<br><br><br><br>
      READ TABLE ct_top ASSIGNING FIELD-SYMBOL(<ls_top>) WITH KEY ro_alv = sender.
      CHECK sy-subrc = 0.
      FIELD-SYMBOLS <lt_alv_table> TYPE STANDARD TABLE.
      ASSIGN <ls_top>-io_tabbed->gt_table->* TO <lt_alv_table>.
      CHECK sy-subrc = 0.
    
      CASE e_ucomm.
        WHEN 'GENERATE'.
          IF lines( <ls_top>-rt_alv_selected_rows ) <> 1.
            MESSAGE |请只选中一行进行模板生成| TYPE 'I' DISPLAY LIKE 'W'.
            RETURN.
          ENDIF.
          DATA ls_indx TYPE indx.
          CLEAR ls_indx.
          READ TABLE <lt_alv_table> ASSIGNING FIELD-SYMBOL(<ls_alv_row>)
          INDEX <ls_top>-rt_alv_selected_rows[ 1 ]-index.
          CHECK sy-subrc = 0.
          MOVE-CORRESPONDING <ls_alv_row> TO ls_indx.
          CHECK ls_indx-srtfd IS NOT INITIAL.
          DATA lt_fields_list LIKE gt_fields_list.
          CLEAR lt_fields_list.
          TRY.
              IMPORT itab = lt_fields_list FROM DATABASE indx(zx) ID ls_indx-srtfd.
            CATCH cx_root INTO DATA(lx_error).
              MESSAGE |获取模板字段失败:{ lx_error->get_text( ) }| TYPE 'I' DISPLAY LIKE 'E'.
              RETURN.
          ENDTRY.
    
          DATA(lv_counter) = 0.
          CLEAR gt_components.
          go_datadescr ?= cl_abap_datadescr=>describe_by_name( 'STRING' ).
          DO lines( lt_fields_list ) TIMES.
            lv_counter = lv_counter + 1.
            APPEND INITIAL LINE TO gt_components ASSIGNING FIELD-SYMBOL(<ls_comp>).
            <ls_comp>-name = 'COL' && lv_counter.
            <ls_comp>-type = go_datadescr.
          ENDDO.
          go_structdescr = cl_abap_structdescr=>create( gt_components ).
          go_tabledesc = cl_abap_tabledescr=>create( go_structdescr ).
          DATA lt_template TYPE REF TO data.
          CREATE DATA lt_template TYPE HANDLE go_tabledesc.
          FIELD-SYMBOLS <lt_template> TYPE STANDARD TABLE.
          ASSIGN lt_template->* TO <lt_template>.
          APPEND INITIAL LINE TO <lt_template> ASSIGNING FIELD-SYMBOL(<ls_row1>).
          APPEND INITIAL LINE TO <lt_template> ASSIGNING FIELD-SYMBOL(<ls_row2>).
          lv_counter = 0.
          LOOP AT lt_fields_list ASSIGNING FIELD-SYMBOL(<ls_field_list>).
            lv_counter = lv_counter + 1.
            ASSIGN COMPONENT lv_counter OF STRUCTURE <ls_row1> TO FIELD-SYMBOL(<lv_field1>).
            ASSIGN COMPONENT lv_counter OF STRUCTURE <ls_row2> TO FIELD-SYMBOL(<lv_field2>).
            <lv_field1> = <ls_field_list>-fieldname.
            <lv_field2> = <ls_field_list>-fielddesc.
          ENDLOOP.
    
          DATA lv_file_name TYPE string.
          lv_file_name = ls_indx-pgmid.
          PERFORM download_template USING <lt_template> lv_file_name .
          RETURN.
    
          DATA(lv_path) = zcl_excel_tools=>set_download_path( |{ ls_indx-pgmid }| ).
          CHECK lv_path IS NOT INITIAL.
          zcl_excel_tools=>download_excel( iv_path = lv_path
                                           it_table = <lt_template>
                                           iv_fields_desc = '' ).
        WHEN 'UPLOAD'.
          DATA(lv_path_upload) = zcl_excel_tools=>get_upload_path( ).
          CHECK lv_path_upload IS NOT INITIAL.
          FIELD-SYMBOLS <lt_excel_template> TYPE STANDARD TABLE.
          DATA(lo_excel) = zcl_excel_tools=>upload_by_fdt( iv_path = lv_path_upload ).
          ASSIGN lo_excel->gt_excel->* TO <lt_excel_template>.
          CHECK sy-subrc = 0.
          CHECK lines( <lt_excel_template> ) > 2.
          READ TABLE <lt_excel_template> ASSIGNING FIELD-SYMBOL(<ls_row1upload>) INDEX 1.
          READ TABLE <lt_excel_template> ASSIGNING FIELD-SYMBOL(<ls_row2upload>) INDEX 2.
          go_tabledesc ?= cl_abap_tabledescr=>describe_by_data( <lt_excel_template> ).
          go_structdescr ?= go_tabledesc->get_table_line_type( ).
          DATA(lt_components) = go_structdescr->get_included_view( ).
          CLEAR gt_fields_list.
          LOOP AT lt_components ASSIGNING FIELD-SYMBOL(<ls_component>).
            ASSIGN COMPONENT <ls_component>-name OF STRUCTURE <ls_row1upload> TO FIELD-SYMBOL(<lv_value1upload>).
            ASSIGN COMPONENT <ls_component>-name OF STRUCTURE <ls_row2upload> TO FIELD-SYMBOL(<lv_value2upload>).
            APPEND INITIAL LINE TO gt_fields_list ASSIGNING <ls_field_list> .
            <ls_field_list>-fieldname = <lv_value2upload>.
            <ls_field_list>-fielddesc = <lv_value1upload>.
          ENDLOOP.
          CHECK lines( gt_fields_list ) > 0.
          "//弹出框,输入模板名称
          DATA ls_name TYPE j_3gbelk.
          CLEAR ls_name.
          zcl_xhl=>get_input_values( EXPORTING iv_structure_name = 'J_3GBELK'
                                               iv_fields = 'J_3GVVCOM1'
                                     CHANGING cs_structure = ls_name ).
          IF ls_name-j_3gvvcom1 IS INITIAL.
            ls_name-j_3gvvcom1 = |物料主数据导入模板-{ sy-datum }-{ sy-uzeit }|.
          ENDIF.
    *      DATA ls_indx TYPE indx.
          CLEAR ls_indx.
          TRY.
              ls_indx-srtfd = cl_system_uuid=>create_uuid_c22_static( ).
            CATCH cx_root.
          ENDTRY.
          ls_indx-relid  = 'ZX'.
          ls_indx-usera = 'MAT_MAINTAIN'.
          ls_indx-aedat = sy-datum.
          ls_indx-pgmid = ls_name-j_3gvvcom1.
          EXPORT itab = gt_fields_list TO DATABASE indx(zx) FROM ls_indx ID ls_indx-srtfd.
          COMMIT WORK.
          DATA ls_row TYPE REF TO data.
          CREATE DATA ls_row LIKE LINE OF <lt_alv_table>.
          ASSIGN ls_row->* TO <ls_alv_row>.
          MOVE-CORRESPONDING ls_indx TO <ls_alv_row>.
          INSERT <ls_alv_row> INTO <lt_alv_table> INDEX 1.
          TRY.
              sender->refresh_table_display( ).
            CATCH cx_root.
          ENDTRY.
      ENDCASE.
    
    ENDFORM.
    *//***************************************************************************
    *//***************************************************************************
    FORM template_callback_dclick USING sender TYPE REF TO cl_gui_alv_grid
                               row TYPE int4
                               column TYPE char30
                               cs_current_row TYPE data
                CHANGING ct_top TYPE zcl_tabbed=>ttyp_tab
                        ct_bottom TYPE zcl_tabbed=>ttyp_tab
                        cs_pop TYPE zcl_tabbed=>typ_tab
                         co_tabbed TYPE REF TO zcl_tabbed.
    
      DATA lt_fields_list LIKE gt_fields_list.
      CLEAR lt_fields_list.
      CLEAR ct_bottom.
      DATA ls_indx TYPE indx.
      MOVE-CORRESPONDING cs_current_row TO ls_indx.
      CHECK ls_indx-srtfd IS NOT INITIAL.
      IMPORT itab = lt_fields_list FROM DATABASE indx(zx) ID ls_indx-srtfd.
      ct_bottom = VALUE #(
        ( io_tabbed = zcl_tabbed=>new( lt_fields_list )
        )
      ).
      co_tabbed->show_tabbed_alvs( ct_bottom ).
    
    ENDFORM.
    *//***************************************************************************
    *//***************************************************************************
    """""""""""""""""""""""""""""""""""
    "BAPI相关变量定义
    """""""""""""""""""""""""""""""""""
    DATA:
      headdata             LIKE bapimathead,
      clientdata           LIKE bapi_mara,
      clientdatax          LIKE bapi_marax,
      plantdata            LIKE bapi_marc,
      plantdatax           LIKE bapi_marcx,
      forecastparameters   LIKE bapi_mpop,
      forecastparametersx  LIKE bapi_mpopx,
      planningdata         LIKE bapi_mpgd,
      planningdatax        LIKE bapi_mpgdx,
      storagelocationdata  LIKE bapi_mard,
      storagelocationdatax LIKE bapi_mardx,
      valuationdata        LIKE bapi_mbew,
      valuationdatax       LIKE bapi_mbewx,
      warehousenumberdata  LIKE bapi_mlgn,
      warehousenumberdatax LIKE bapi_mlgnx,
      salesdata            LIKE bapi_mvke,
      salesdatax           LIKE bapi_mvkex,
      storagetypedata      LIKE bapi_mlgt,
      storagetypedatax     LIKE bapi_mlgtx.
    
    DATA:
      materialdescription    TYPE TABLE OF     bapi_makt WITH HEADER LINE,
      unitsofmeasure      TYPE TABLE OF  bapi_marm WITH HEADER LINE,
      unitsofmeasurex        TYPE TABLE OF     bapi_marmx WITH HEADER LINE,
      internationalartnos    TYPE TABLE OF     bapi_mean WITH HEADER LINE,
      materiallongtext    TYPE TABLE OF  bapi_mltx WITH HEADER LINE,
      taxclassifications  TYPE TABLE OF  bapi_mlan WITH HEADER LINE,
      returnmessages      TYPE TABLE OF  bapi_matreturn2 WITH HEADER LINE,
      prtdata                TYPE TABLE OF     bapi_mfhm WITH HEADER LINE,
      prtdatax            TYPE TABLE OF  bapi_mfhmx WITH HEADER LINE.
    
    DATA: extensionin TYPE TABLE OF bapiparex WITH HEADER LINE.
    DATA: extensioninx TYPE TABLE OF bapiparexx WITH HEADER LINE.
    """""""""""""""""""""""""""""""""""
    """""""""""""""""""""""""""""""""""
    FORM init_variables.
      CLEAR:
      headdata,
      clientdata,
      clientdatax,
      plantdata,
      plantdatax,
      forecastparameters,
      forecastparametersx,
      planningdata,
      planningdatax,
      storagelocationdata,
      storagelocationdatax,
      valuationdata,
      valuationdatax,
      warehousenumberdata,
      warehousenumberdatax,
      salesdata,
      salesdatax,
      storagetypedata,
      storagetypedatax,
    
      materialdescription,
      materialdescription[],
      unitsofmeasure,
      unitsofmeasure[],
      unitsofmeasurex,
      unitsofmeasurex[],
      internationalartnos,
      internationalartnos[],
      materiallongtext,
      materiallongtext[],
      taxclassifications,
      taxclassifications[],
      returnmessages,
      returnmessages[],
      prtdata,
      prtdata[],
      prtdatax,
      prtdatax[],
    
      extensionin,
      extensionin[],
      extensioninx,
      extensioninx[]
      .
    ENDFORM.
    *//***************************************************************************
    *//***************************************************************************
    FORM frm_prepare_2_bg.
    
      CLEAR gt_fields.
      go_tabledesc ?= cl_abap_tabledescr=>describe_by_data( <gt_output> ).
      go_structdescr ?= go_tabledesc->get_table_line_type( ).
      CLEAR gt_components.
      DATA(lt_components) = go_structdescr->get_included_view( ).
      LOOP AT lt_components ASSIGNING FIELD-SYMBOL(<ls_comp>).
    *    CHECK <ls_comp>-name(1) <> '_'.
        APPEND INITIAL LINE TO gt_fields ASSIGNING FIELD-SYMBOL(<ls_field>).
        <ls_field>-fieldname = <ls_comp>-name.
      ENDLOOP.
      DATA lv_srtfd TYPE indx_srtfd.
      DATA lv_srtfd1 TYPE indx_srtfd.
      TRY.
          lv_srtfd = cl_system_uuid=>create_uuid_c22_static( ).
          lv_srtfd = |{ lv_srtfd CASE = UPPER }|.
        CATCH cx_root.
          MESSAGE 'Oh GOD' TYPE 'X'.
      ENDTRY.
      TRY.
          lv_srtfd1 = cl_system_uuid=>create_uuid_c22_static( ).
          lv_srtfd1 = |{ lv_srtfd1 CASE = UPPER }|.
        CATCH cx_root.
          MESSAGE 'Oh GOD' TYPE 'X'.
      ENDTRY.
    
      EXPORT itab_structure = gt_fields TO DATABASE indx(zx) ID lv_srtfd1.
      EXPORT itab = <gt_output> TO DATABASE indx(zx) ID lv_srtfd.
      COMMIT WORK AND WAIT.
      DATA(lv_okgo) = abap_false.
      SELECT SINGLE @abap_true FROM indx WHERE srtfd = @lv_srtfd INTO @DATA(lv_result).
      IF sy-subrc <> 0.
        DO 500 TIMES.
          SELECT SINGLE @abap_true FROM indx WHERE srtfd = @lv_srtfd INTO @lv_result.
          IF sy-subrc <> 0.
            WAIT UP TO 1 SECONDS.
          ELSE.
            lv_okgo = abap_true.
            EXIT.
          ENDIF.
        ENDDO.
      ELSE.
        lv_okgo = abap_true.
      ENDIF.
      IF lv_okgo = abap_false.
        MESSAGE |数据准备失败,无法提交后台执行| TYPE 'S' DISPLAY LIKE 'E'.
      ELSE.
        gs_job-intreport = sy-repid.
        gv_background = abap_true.
        gv_test_run = abap_false.
        go_job = zcl_job=>new( ).
        gs_job_return = go_job->create_job( EXPORTING it_sel_table = VALUE #(
                                                          ( selname = 'P_BG'
                                                            kind = 'P'
                                                            sign = 'I'
                                                            option = 'EQ'
                                                            low = abap_true )
                                                          ( selname = 'P_SRTFD'
                                                            kind = 'P'
                                                            sign = 'I'
                                                            option = 'EQ'
                                                            low = lv_srtfd )
                                                          ( selname = 'P_SRTFD1'
                                                            kind = 'P'
                                                            sign = 'I'
                                                            option = 'EQ'
                                                            low = lv_srtfd1 )
                                                        )
                                              CHANGING cs_job_info = gs_job ) .
        IF gs_job_return-type = 'S'.
          MESSAGE |提交后台执行成功,后台job信息| TYPE 'S' .
        ENDIF.
      ENDIF.
    
    ENDFORM.
    *//***************************************************************************
    *//***************************************************************************
    FORM frm_display_job.
      IF gs_job IS NOT INITIAL.
        zcl_tabbed=>display_once(
          iv_popup = abap_true
          iv_top_alvs_mode = zcl_tabbed=>gs_alvs_mode-tab
          it_top = VALUE #(
            ( io_tabbed = zcl_tabbed=>new( gs_job )
              iv_tab_name = '后台任务相关信息'
              iv_alv_dclick_callback = 'job_callback_dclick'
            )
            ( io_tabbed = zcl_tabbed=>new( gs_job_return )
              iv_tab_name = '后台任务创建信息'
            )
          )
         ).
      ENDIF.
    ENDFORM.
    *//***************************************************************************
    *//***************************************************************************
    FORM job_callback_dclick USING sender TYPE REF TO cl_gui_alv_grid
                               row TYPE int4
                               column TYPE char30
                               cs_current_row TYPE data
                CHANGING ct_top TYPE zcl_tabbed=>ttyp_tab
                        ct_bottom TYPE zcl_tabbed=>ttyp_tab
                        cs_pop TYPE zcl_tabbed=>typ_tab
                         co_tabbed TYPE REF TO zcl_tabbed.
    
      DATA ls_job TYPE tbtcjob.
      CLEAR ls_job.
      MOVE-CORRESPONDING cs_current_row TO ls_job.
      CHECK ls_job IS NOT INITIAL.
      go_job->call_sm37( ).
    
    ENDFORM.
    *//***************************************************************************
    *//***************************************************************************
    FORM frm_exec.
    
      lcl_process=>prepare_field_relation( ).
    
      CHECK <gt_output> IS ASSIGNED.
      CHECK lines( <gt_output> ) > 2.
    
      READ TABLE <gt_output> ASSIGNING FIELD-SYMBOL(<row>) INDEX 2.
    
      DATA lo_struct TYPE REF TO cl_abap_structdescr.
      DATA components_tab TYPE cl_abap_structdescr=>component_table.
    
      DATA lv_tabname TYPE char30.
      DATA lv_fieldname TYPE char30.
      DATA lv_counter TYPE i VALUE IS INITIAL.
    
      lo_struct ?= cl_abap_structdescr=>describe_by_data( <row> ).
      components_tab = lo_struct->get_components( ).
    
      CLEAR:lcl_process=>gs_bapi_ext_relation.
      CLEAR:lcl_process=>gt_bapi_ext_relation.
    
      LOOP AT components_tab ASSIGNING FIELD-SYMBOL(<comp>).
        IF <comp>-name(1) = '_'.
          CONTINUE.
        ENDIF.
    
        lv_counter = lv_counter + 1.
    
        ASSIGN COMPONENT <comp>-name OF STRUCTURE <row> TO FIELD-SYMBOL(<tabfield>).
        CLEAR: lv_tabname, lv_fieldname.
    
        SPLIT <tabfield> AT '-' INTO lv_tabname lv_fieldname IN CHARACTER MODE.
        READ TABLE lcl_process=>gt_field_relation ASSIGNING FIELD-SYMBOL(<relation>)
        WITH KEY tabname = lv_tabname fieldname = lv_fieldname.
        IF <relation> IS ASSIGNED.
          <relation>-excel_original_text = <comp>-name.
          <relation>-excel_fieldname = '' && lv_counter && ''.
        ENDIF.
    
        IF lv_fieldname IS NOT INITIAL.
    
          DATA field1 TYPE char30 VALUE IS INITIAL.
          DATA field2 TYPE char30 VALUE IS INITIAL.
          IF lv_fieldname(1) = 'Z'.
            CLEAR:field1,field2.
            SPLIT lv_tabname AT '_' INTO field1 field2 IN CHARACTER MODE.
            IF field2 IS NOT INITIAL.
              field2 = 'BAPI_TE_' && field2.
              CONDENSE field2 NO-GAPS.
    
              lcl_process=>gs_bapi_ext_relation-tabname = lv_tabname.
              lcl_process=>gs_bapi_ext_relation-tabname_bapi_ext = field2.
              lcl_process=>gs_bapi_ext_relation-tabname_bapi_extx = field2 && 'X'.
    
              SELECT SINGLE fieldname INTO field1 FROM dd03l WHERE tabname = field2 AND fieldname = lv_fieldname.
              IF sy-subrc = 0.
                field2 = field2 && 'X'.
                CONDENSE field2 NO-GAPS.
                SELECT SINGLE fieldname INTO field1 FROM dd03l WHERE tabname = field2 AND fieldname = lv_fieldname.
                IF sy-subrc = 0.
                  APPEND lcl_process=>gs_bapi_ext_relation TO lcl_process=>gt_bapi_ext_relation.
                ELSE.
                  CLEAR: lcl_process=>gs_bapi_ext_relation.
                ENDIF.
              ELSE.
                CLEAR: lcl_process=>gs_bapi_ext_relation.
              ENDIF.
            ENDIF.
          ENDIF.
    
        ENDIF.
    
      ENDLOOP.
    
      SORT lcl_process=>gt_bapi_ext_relation.
      DELETE ADJACENT DUPLICATES FROM lcl_process=>gt_bapi_ext_relation.
    
      DATA lo_data TYPE REF TO cl_abap_datadescr.
      DATA components_bapi TYPE cl_abap_structdescr=>component_table.
      DATA component_bapi TYPE LINE OF cl_abap_structdescr=>component_table.
      DATA lt_dd03m TYPE TABLE OF dd03m WITH HEADER LINE.
      CLEAR:lt_dd03m,lt_dd03m[].
      LOOP AT lcl_process=>gt_bapi_ext_relation ASSIGNING FIELD-SYMBOL(<bapi_ext>).
        CLEAR: component_bapi,components_bapi.
        SELECT * FROM dd03m INTO TABLE lt_dd03m WHERE tabname = <bapi_ext>-tabname_bapi_ext AND ddlanguage = sy-langu.
        SORT lt_dd03m BY position.
        LOOP AT lt_dd03m.
          component_bapi-name = lt_dd03m-fieldname.
          lo_data ?= cl_abap_datadescr=>describe_by_name( lt_dd03m-tabname && '-' && lt_dd03m-fieldname ).
          component_bapi-type = lo_data.
          APPEND component_bapi TO components_bapi.
          CLEAR component_bapi.
        ENDLOOP.
        lo_struct = cl_abap_structdescr=>create( components_bapi ).
        CREATE DATA <bapi_ext>-bapi_ext_row TYPE HANDLE lo_struct.
    
        CLEAR: component_bapi,components_bapi.
        SELECT * FROM dd03m INTO TABLE lt_dd03m WHERE tabname = <bapi_ext>-tabname_bapi_extx AND ddlanguage = sy-langu.
        SORT lt_dd03m BY position.
        LOOP AT lt_dd03m.
          component_bapi-name = lt_dd03m-fieldname.
          lo_data ?= cl_abap_datadescr=>describe_by_name( lt_dd03m-tabname && '-' && lt_dd03m-fieldname ).
          component_bapi-type = lo_data.
          APPEND component_bapi TO components_bapi.
          CLEAR component_bapi.
        ENDLOOP.
        lo_struct = cl_abap_structdescr=>create( components_bapi ).
        CREATE DATA <bapi_ext>-bapi_ext_rowx TYPE HANDLE lo_struct.
    
      ENDLOOP.
    
    
      DATA fm_name TYPE rs38l_fnam.
      DATA excel_value_temp TYPE string.
      DATA len TYPE i.
    
      DATA counter TYPE i VALUE IS INITIAL.
      DATA counter_msg TYPE char40 VALUE IS INITIAL.
      DATA msg TYPE string.
    
      DATA(check_match) = ''.
      LOOP AT lcl_process=>gt_field_relation ASSIGNING FIELD-SYMBOL(<ls_relation1>) WHERE excel_fieldname IS NOT INITIAL.
        check_match = 'X'.
        EXIT.
      ENDLOOP.
    
      IF check_match IS INITIAL.
        MESSAGE '模板有问题,请确认后再执行!' TYPE 'I' DISPLAY LIKE 'E'.
        RETURN.
      ENDIF.
    
      LOOP AT <gt_output> ASSIGNING FIELD-SYMBOL(<ls_output>).
        CHECK sy-tabix > 2.
        ASSIGN COMPONENT '_ICON' OF STRUCTURE <ls_output> TO FIELD-SYMBOL(<temp_icon>).
        ASSIGN COMPONENT '_MSG' OF STRUCTURE <ls_output> TO FIELD-SYMBOL(<temp_msg>).
        IF <temp_icon> = icon_green_light AND <temp_msg> = '导入成功' .
          CONTINUE.
        ENDIF.
    
        PERFORM init_variables.
    
        LOOP AT lcl_process=>gt_field_relation ASSIGNING FIELD-SYMBOL(<ls_relation>) WHERE excel_fieldname IS NOT INITIAL..
          ASSIGN COMPONENT <ls_relation>-excel_original_text OF STRUCTURE <ls_output> TO FIELD-SYMBOL(<excel_value>).
    
          """""""""""""""""""""""""""""""""""""""""""""
          CASE <ls_relation>-tabname.
            WHEN 'BAPIMATHEAD'. "不需要更改参数
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE headdata TO FIELD-SYMBOL(<record_value>).
            WHEN 'BAPI_MARA'. "需要更改参数
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE clientdata TO <record_value>.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE clientdatax TO FIELD-SYMBOL(<record_valuex>).
              <record_valuex> = 'X'.
            WHEN 'BAPI_MARC'.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE plantdata TO <record_value>.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE plantdatax TO <record_valuex>.
              <record_valuex> = 'X'.
            WHEN 'BAPI_MPOP'.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE forecastparameters TO <record_value>.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE forecastparametersx TO <record_valuex>.
              <record_valuex> = 'X'.
            WHEN 'BAPI_MPGD'.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE planningdata TO <record_value>.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE planningdatax TO <record_valuex>.
              <record_valuex> = 'X'.
            WHEN 'BAPI_MARD'.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE storagelocationdata TO <record_value>.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE storagelocationdatax TO <record_valuex>.
              <record_valuex> = 'X'.
            WHEN 'BAPI_MBEW'.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE valuationdata TO <record_value>.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE valuationdatax TO <record_valuex>.
              <record_valuex> = 'X'.
            WHEN 'BAPI_MLGN'.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE warehousenumberdata TO <record_value>.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE warehousenumberdatax TO <record_valuex>.
              <record_valuex> = 'X'.
            WHEN 'BAPI_MVKE'.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE salesdata TO <record_value>.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE salesdatax TO <record_valuex>.
              <record_valuex> = 'X'.
            WHEN 'BAPI_MLGT'.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE storagetypedata TO <record_value>.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE storagetypedatax TO <record_valuex>.
              <record_valuex> = 'X'.
              "以上是输入参数,结构。
    
            WHEN 'BAPI_MAKT'.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE materialdescription TO <record_value>.
            WHEN 'BAPI_MARM'.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE unitsofmeasure TO <record_value>.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE unitsofmeasurex TO <record_valuex>.
              <record_valuex> = 'X'.
            WHEN 'BAPI_MEAN'.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE internationalartnos TO <record_value>.
            WHEN 'BAPI_MLTX'.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE materiallongtext TO <record_value>.
            WHEN 'BAPI_MLAN'.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE taxclassifications TO <record_value>.
            WHEN 'BAPI_MFHM'.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE prtdata TO <record_value>.
              ASSIGN COMPONENT <ls_relation>-fieldname OF STRUCTURE prtdatax TO <record_valuex>.
              <record_valuex> = 'X'.
          ENDCASE.
          """""""""""""""""""""""""""""""""""""""""""""
    
          DATA lo TYPE REF TO cl_abap_datadescr.
          CLEAR lo.
          IF <record_valuex> IS ASSIGNED.
            lo ?= cl_abap_datadescr=>describe_by_data( <record_valuex> ).
          ENDIF.
    
          IF <ls_relation>-convexit IS NOT INITIAL.
            CONCATENATE 'CONVERSION_EXIT_' <ls_relation>-convexit '_INPUT' INTO fm_name.
            CONDENSE fm_name NO-GAPS.
            excel_value_temp = <excel_value>.
            len = strlen( excel_value_temp ).
            IF len > <ls_relation>-intlen / 2  .
              <record_value> = ''.
              ASSIGN COMPONENT '_ICON' OF STRUCTURE <ls_output> TO FIELD-SYMBOL(<temp>).
              <temp> = icon_red_light.
              ASSIGN COMPONENT '_MSG' OF STRUCTURE <ls_output> TO FIELD-SYMBOL(<temp1>).
              <temp1> = '【该值' && <excel_value> && '长度太长,无法执行转换!' && fm_name && '' .
            ELSE.
              CALL FUNCTION fm_name
                EXPORTING
                  input  = <excel_value>
                IMPORTING
                  output = <record_value>.
            ENDIF.
            IF lo IS NOT INITIAL.
              IF lo->length > 2.
                <record_valuex> = <record_value>.
              ENDIF.
            ENDIF.
          ELSE.
            TRY.
                <record_value> = <excel_value>.
                IF lo IS NOT INITIAL.
                  IF lo->length > 2.
                    <record_valuex> = <record_value>.
                  ENDIF.
                ENDIF.
              CATCH  cx_sy_conversion_no_number.
                <record_value> = ''.
                ASSIGN COMPONENT '_ICON' OF STRUCTURE <ls_output> TO FIELD-SYMBOL(<temp3>).
                <temp> = icon_red_light.
                ASSIGN COMPONENT '_MSG'  OF STRUCTURE <ls_output> TO FIELD-SYMBOL(<temp4>).
                CONCATENATE '【该值' <excel_value> '无法转换为数字' INTO <temp4> .
            ENDTRY.
          ENDIF.
    
          "==========================================================================
          " 自定义字段的处理逻辑 开始
          "==========================================================================
          FIELD-SYMBOLS <bapi_ext_row> TYPE any.
          FIELD-SYMBOLS <bapi_ext_rowx> TYPE any.
    
          LOOP AT lcl_process=>gt_bapi_ext_relation ASSIGNING FIELD-SYMBOL(<bapi_relation>).
    
            ASSIGN <bapi_relation>-bapi_ext_row->* TO <bapi_ext_row>.
    
            ASSIGN COMPONENT  <ls_relation>-fieldname OF STRUCTURE <bapi_ext_row> TO FIELD-SYMBOL(<value_ext>).
            IF <value_ext> IS ASSIGNED.
              <value_ext> = <record_value>.
            ENDIF.
            IF <value_ext> IS ASSIGNED.UNASSIGN <value_ext>.ENDIF.
    
            ASSIGN <bapi_relation>-bapi_ext_rowx->* TO <bapi_ext_rowx>.
            ASSIGN COMPONENT  <ls_relation>-fieldname OF STRUCTURE <bapi_ext_rowx> TO FIELD-SYMBOL(<value_extx>).
            IF <value_extx> IS ASSIGNED.
              lo_data ?= cl_abap_datadescr=>describe_by_data( <value_extx> ).
              IF lo_data->length > 2 . "这个是内部长度,所以CHAR1 在这里是2.
                <value_extx> =  <record_value>.
              ELSE.
                <value_extx> = 'X'.
              ENDIF.
            ENDIF.
            IF <value_extx> IS ASSIGNED.UNASSIGN <value_extx>.ENDIF.
    
          ENDLOOP.
          "==========================================================================
          "自定义字段的处理逻辑 结束
          "==========================================================================
    
          IF <record_value> IS ASSIGNED.UNASSIGN <record_value>.ENDIF.
          IF <record_valuex> IS ASSIGNED.UNASSIGN <record_valuex>.ENDIF.
    
        ENDLOOP.
    
        IF materialdescription IS NOT INITIAL.
          APPEND: materialdescription.
        ENDIF.
        IF unitsofmeasure IS NOT INITIAL.
          APPEND  unitsofmeasure.
          APPEND unitsofmeasurex.
        ENDIF.
    
        IF internationalartnos IS NOT INITIAL.
          APPEND internationalartnos.
        ENDIF.
        IF materiallongtext IS NOT INITIAL.
          APPEND materiallongtext.
        ENDIF.
    
        IF taxclassifications IS NOT INITIAL.
          APPEND taxclassifications.
        ENDIF.
        IF prtdata IS NOT INITIAL.
          APPEND prtdata.
          APPEND prtdatax.
        ENDIF.
    
        IF lo IS NOT INITIAL.
          CLEAR lo.
        ENDIF.
    
        LOOP AT lcl_process=>gt_bapi_ext_relation ASSIGNING <bapi_relation>.
          ASSIGN <bapi_relation>-bapi_ext_row->* TO <bapi_ext_row>.
          IF <bapi_ext_row> IS NOT INITIAL.
            extensionin-structure = <bapi_relation>-tabname_bapi_ext.
            extensionin-valuepart1 = <bapi_ext_row>.  "未考虑超过240个字符,后续优化
            APPEND extensionin.
          ENDIF.
    
          ASSIGN <bapi_relation>-bapi_ext_rowx->* TO <bapi_ext_rowx>.
          IF <bapi_ext_rowx> IS NOT INITIAL.
            extensioninx-structure = <bapi_relation>-tabname_bapi_extx.
            extensioninx-valuepart1 = <bapi_ext_rowx>.
            APPEND extensioninx.
          ENDIF.
        ENDLOOP.
    
        "按照Excel中的每一行进行处理,每行字段处理完,即调用BAPI提交。
        DATA return TYPE bapiret2 VALUE IS INITIAL.
        CALL FUNCTION 'BAPI_MATERIAL_SAVEDATA'
          EXPORTING
            headdata             = headdata
            clientdata           = clientdata
            clientdatax          = clientdatax
            plantdata            = plantdata
            plantdatax           = plantdatax
            forecastparameters   = forecastparameters
            forecastparametersx  = forecastparametersx
            planningdata         = planningdata
            planningdatax        = planningdatax
            storagelocationdata  = storagelocationdata
            storagelocationdatax = storagelocationdatax
            valuationdata        = valuationdata
            valuationdatax       = valuationdatax
            warehousenumberdata  = warehousenumberdata
            warehousenumberdatax = warehousenumberdatax
            salesdata            = salesdata
            salesdatax           = salesdatax
            storagetypedata      = storagetypedata
            storagetypedatax     = storagetypedatax
          IMPORTING
            return               = return
          TABLES
            materialdescription  = materialdescription
            "unitsofmeasure       = unitsofmeasure
            "unitsofmeasurex      = unitsofmeasurex
            internationalartnos  = internationalartnos
            "materiallongtext     = materiallongtext
            taxclassifications   = taxclassifications
            returnmessages       = returnmessages
            prtdata              = prtdata
            prtdatax             = prtdatax
            extensionin          = extensionin[]
            extensioninx         = extensioninx[].
    
        DATA(return_ok) = 'X'.
    
        LOOP AT returnmessages TRANSPORTING NO FIELDS WHERE type CA 'AEX'.
          return_ok = abap_false.
        ENDLOOP.
    
        ASSIGN COMPONENT '_ICON' OF STRUCTURE <ls_output> TO FIELD-SYMBOL(<temp5>).
        ASSIGN COMPONENT '_MSG'  OF STRUCTURE <ls_output> TO FIELD-SYMBOL(<temp6>).
        IF return_ok = ''.
          CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
          <temp5> = icon_red_light.
          <temp6> = '导入失败'.
        ELSE.
          <temp5> = icon_green_light.
          IF gv_test_run IS NOT INITIAL.
            <temp6> = '测试导入成功'.
            CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
          ELSE.
            CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
              EXPORTING
                wait = 'X'.
            <temp6> = '导入成功'.
          ENDIF.
        ENDIF.
        ASSIGN COMPONENT '_RETURN' OF STRUCTURE <ls_output> TO FIELD-SYMBOL(<temp7>).
        <temp7> = returnmessages[].
    
        counter = counter + 1.
        counter_msg = counter.
        CONDENSE counter_msg NO-GAPS.
        CONCATENATE '已经处理' counter_msg '' INTO counter_msg.
        CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
          EXPORTING
            text = counter_msg.
        IF p_bg IS NOT INITIAL.
          MESSAGE |{ repeat( val = '*' occ = 80 ) }| TYPE 'S'.
          MESSAGE |{ counter_msg } 当前处理的物料号 { headdata-material }| TYPE 'S'.
        ENDIF.
    
        DATA lt_enq TYPE TABLE OF seqg3 WITH HEADER LINE.
        CLEAR: lt_enq,lt_enq[].
        DATA garg TYPE seqg3-garg.
        CLEAR garg.
        CONCATENATE sy-mandt headdata-material INTO garg.
        DATA num TYPE sy-tabix.
    
        CLEAR num.
    
        CALL FUNCTION 'ENQUE_READ'
          EXPORTING
            gclient = sy-mandt
            guname  = '' " sy-uname
            garg    = garg
          IMPORTING
            number  = num
          TABLES
            enq     = lt_enq[].
        IF num > 0.
          DO 100 TIMES.
            CONCATENATE headdata-material
             '被锁定,正在尝试释放,最多尝试100次,耗时100秒'
             INTO msg.
            CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
              EXPORTING
                text = msg.
            CALL FUNCTION 'BUFFER_REFRESH_ALL'.
            WAIT UP TO 1 SECONDS.
            CALL FUNCTION 'BUFFER_REFRESH_ALL'.
            CLEAR: lt_enq,lt_enq[],num.
            CALL FUNCTION 'ENQUE_READ'
              EXPORTING
                gclient = sy-mandt
                guname  = '' "sy-uname
                garg    = garg
              IMPORTING
                number  = num
              TABLES
                enq     = lt_enq[].
            IF num > 0.
            ELSE.
              EXIT.
            ENDIF.
          ENDDO.
        ENDIF.
    
      ENDLOOP. "//循环 <GT_OUTPUT>
    
      TRY.
          CALL METHOD lcl_process=>lo_salv->refresh( ).
        CATCH cx_root INTO DATA(lx_alv_error).
          MESSAGE |{ repeat( val = '*' occ = 80 ) }| TYPE 'S'.
          MESSAGE |ALV相关错误,后台执行可忽略: { lx_alv_error->get_text( ) }| TYPE 'S' DISPLAY LIKE 'E'.
      ENDTRY.
    
    ENDFORM.
  • 相关阅读:
    StringBuild
    String 字符串
    win7 64位支持的最大内存
    Spring获取对象与java new对象区别
    生成随机数
    java String转base64
    java时间格式
    Bash Scripting Learn Notes
    Linux parent process and child process when 'sudo'
    Linux services, runlevels, and rc.d scripts
  • 原文地址:https://www.cnblogs.com/ckstock/p/15708041.html
Copyright © 2020-2023  润新知