ABAP上传数据到任意数据库表

2023-07-12 14:05发布

*&---------------------------------------------------------------------*
*& Report  ZUPLOAD_DATA
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zupload_data.


*&---------------------------------------------------------------------*
*&     全局变量定义
*&---------------------------------------------------------------------*
"存放 ZDATA 表中的 data 字段信息
DATA: table_ref_data TYPE REF TO data,    "Create object
     wa_ref_data    TYPE REF TO data.

FIELD-SYMBOLS:
     <fs_tab_zdata> TYPE STANDARD TABLE,
     <fs_wa_zdata>  TYPE ANY.

"创建跟DB table一样的结构
DATA: table_ref      TYPE REF TO data,    "Create object
     wa_ref         TYPE REF TO data.

FIELD-SYMBOLS:
     <fs_table>     TYPE STANDARD TABLE,"Internal table
     <fs_wa>        TYPE ANY,
     <fs_field>     TYPE ANY.

DATA: gv_fail        TYPE c.

*&---------------------------------------------------------------------*
*&     选择屏幕
*&---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK bk1 WITH FRAME.
PARAMETERS p_fname TYPE rlgrap-filename .
PARAMETERS p_table TYPE dd02l-tabname.

SELECTION-SCREEN BEGIN OF BLOCK bk2 WITH FRAME.
PARAMETERS: r1 RADIOBUTTON GROUP rg1,
           r2 RADIOBUTTON GROUP rg1,
           r3 RADIOBUTTON GROUP rg1.
PARAMETERS:p_leng TYPE i DEFAULT 3000.
SELECTION-SCREEN END OF BLOCK bk2.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(79) com1.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(79) com2.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(79) com3.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(79) com4.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(79) com5.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(79) com6.
SELECTION-SCREEN END OF LINE.



SELECTION-SCREEN END OF BLOCK bk1.

INITIALIZATION.

 DELETE FROM ZSDT_SO_ZBLK WHERE Zblock = 'Z0B'.

 %_p_fname_%_app_%-text = '文件路径'.
 %_p_table_%_app_%-text = '数据库表名'.

 %_r1_%_app_%-text = '插入数据'.
 %_r2_%_app_%-text = '更新数据'.
 %_r3_%_app_%-text = '删除数据'.
 %_p_leng_%_app_%-text = '单行最大长度'.

 com1 = '文件要求:'.
 com2 = '1) 文件为txt' .
 com3 = '2) 字段间用tab键分隔符' .
 com4 = '3) 需要client MANDT字段' .
 com5 = '4) 无需标题行'.
 com6 = '注:如果模板中字段较多,可以增加“单行最大长度”,不然会dump)'.


*&---------------------------------------------------------------------*
*&     F4 帮助
*&---------------------------------------------------------------------*
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_fname.
* 取得文件名
 PERFORM open_file.


*&---------------------------------------------------------------------*
*& 运行程序
*&---------------------------------------------------------------------*
START-OF-SELECTION.


*-Create internal table
 CREATE DATA table_ref TYPE STANDARD TABLE OF (p_table).
 ASSIGN table_ref->* TO <fs_table>.
*-Create work area

 CREATE DATA wa_ref TYPE (p_table).
 ASSIGN wa_ref->* TO <fs_wa>.

*----------------------------------------------------------------------*
 "检查一些通用信息
 PERFORM check_general_things.


 CHECK gv_fail IS INITIAL.
*----------------------------------------------------------------------*
 "通过 GUI UPLOAD 将文件中数据上传到内表,
 "同时该function会进行数量,金额字段的检查
 PERFORM gui_upload.

 CHECK gv_fail IS INITIAL.
*----------------------------------------------------------------------*
 "用 GUI_UPLOAD导入数据,并且检查D , T , P , F, I 数据格式
 PERFORM check_data_format.

 CHECK gv_fail IS INITIAL.
*----------------------------------------------------------------------*
 "开始数据更新

 PERFORM update_table_data.


*&---------------------------------------------------------------------*
*&      Form  open_file
*&---------------------------------------------------------------------*
*       open_file
*----------------------------------------------------------------------*
FORM open_file.

 DATA: lc_lname  TYPE string,
       lc_txt    TYPE string,
       lc_txtfl  TYPE string,
       lt_filet  TYPE TABLE OF file_table,
       lw_filet  LIKE LINE  OF lt_filet,
       lc_rc     TYPE i,
       lc_usera  TYPE i.

 lc_lname = '文件名'.                        "本地文件名
 lc_txt   = '*.xlsx'.                        "'*.xls'
 lc_txtfl = '*.xls|*.xlsx|*.txt'.            "'MS EXCEL|*.xls|'
* 打开对话框
 CALL METHOD cl_gui_frontend_services=>file_open_dialog
   EXPORTING
     window_title            = lc_lname      "本地文件名
     default_extension       = lc_txt        "'*.xls'
     file_filter             = lc_txtfl      "'MS EXCEL|*.xls|'
   CHANGING
     file_table              = lt_filet      "文件名表
     rc                      = lc_rc         "文件数
     user_action             = lc_usera      "用户命令
   EXCEPTIONS
     file_open_dialog_failed = 1
     cntl_error              = 2
     error_no_gui            = 3
     not_supported_by_gui    = 4
     OTHERS                  = 5.
 IF sy-subrc <> 0.
   MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
             WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
 ENDIF.
 IF lc_usera = 0.
   READ TABLE lt_filet INTO lw_filet INDEX 1.
   p_fname = lw_filet-filename.
 ENDIF.

ENDFORM.                    " open_file
*----------------------------------------------------------------------*
*       CLASS create_demo DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS create_data DEFINITION.
 PUBLIC SECTION.
   CLASS-METHODS main IMPORTING
                                value(type)     TYPE c
                                value(length)   TYPE i
                                value(decimals) TYPE i
                      RETURNING value(dref)     TYPE REF TO data.
 PROTECTED SECTION.
   DATA dref TYPE REF TO data.
 PRIVATE SECTION.
   CLASS-METHODS create_data IMPORTING
                                       value(typ)  TYPE c
                                       value(len)  TYPE i
                                       value(dec)  TYPE i
                             RETURNING
                                       value(dref) TYPE REF TO data
                             RAISING   cx_sy_create_data_error.

ENDCLASS.                    "create_demo DEFINITION
*----------------------------------------------------------------------*
*       CLASS create_demo IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS create_data IMPLEMENTATION.
 METHOD main.
   FIELD-SYMBOLS <fs> TYPE ANY.
   TRY.
       dref = create_data( typ = type
                           len = length
                           dec = decimals ).
     CATCH cx_sy_create_data_error.
       WRITE: 'Error creating'(005), type, length, decimals.
       RETURN.
   ENDTRY.
 ENDMETHOD.                    "main
 METHOD create_data.
   TRANSLATE typ TO LOWER CASE.
   CASE typ.
     WHEN 'd' OR 'decfloat16' OR 'decfloat34' OR 'f' OR 'i'
              OR 'string' OR 't' OR 'xstring'.
       CREATE DATA dref TYPE (typ).
     WHEN 'c' OR 'n' OR 'x'.
       CREATE DATA dref TYPE (typ) LENGTH len.
     WHEN 'p'.
       CREATE DATA dref TYPE p LENGTH len DECIMALS dec.
     WHEN OTHERS.
       RAISE EXCEPTION TYPE cx_sy_create_data_error.
   ENDCASE.
 ENDMETHOD.                    "create_data
ENDCLASS.                    "create_demo IMPLEMENTATION
*&---------------------------------------------------------------------*
*&      Form  CHECK_GENERAL_THINGS
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM check_general_things .

 CHECK p_table <> space AND
       p_fname <> space.

 TABLES:dd02l.
 SELECT SINGLE * FROM dd02l
   WHERE tabname = p_table.
 IF sy-subrc NE 0.
   MESSAGE s001(00) DISPLAY LIKE 'E' WITH '数据库表不存在!'.
   LEAVE  LIST-PROCESSING.
   EXIT.
 ENDIF.

ENDFORM.                    " CHECK_GENERAL_THINGS
*&---------------------------------------------------------------------*
*&      Form  GET_DATA
*&---------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
FORM check_data_format.

 TYPE-POOLS: slis.

 DATA: lv_varchar_ref TYPE REF TO data,"char3000." HANA char22015
       lv_field       TYPE REF TO data.
 FIELD-SYMBOLS:
       <lv_varchar>   TYPE ANY.

 DATA: lv_dcpfm       TYPE usr01-dcpfm.
*  DATA: ls_dfies    LIKE dfies.
 DATA: lv_string_n     TYPE string.
 DATA: c_number        TYPE string VALUE '0123456789'.
 DATA: lv_start_pos    TYPE i VALUE 0,
       lv_offset       TYPE i.
 DATA:
       lv_err_line(10) TYPE n,
       lv_msg          TYPE char600,
       lv_msg_part     TYPE char50.
 DATA:
       lv_length       TYPE i,
       lv_decimals     TYPE i,
       lv_index        TYPE sy-tabix.
 FIELD-SYMBOLS
       <lfs_field>     TYPE ANY.

 DATA:p_fcat           TYPE slis_t_fieldcat_alv.
 DATA:wa_fcat          LIKE LINE OF p_fcat.


 CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
   EXPORTING
     percentage = 50
     text       = '正在检查数据格式......'.

 CLEAR lv_decimals.
 " create field dynamically
 CALL METHOD create_data=>main(
   EXPORTING
     type     = 'C'
     length   = p_leng
     decimals = lv_decimals
   RECEIVING
     dref     = lv_varchar_ref
                ).

 "创建字符串
 ASSIGN lv_varchar_ref->* TO <lv_varchar>.

*-Create internal table
 CREATE DATA table_ref_data LIKE STANDARD TABLE OF <lv_varchar>.
 ASSIGN table_ref_data->* TO <fs_tab_zdata>.
*-Create work area
 CREATE DATA wa_ref_data LIKE <lv_varchar>.
 ASSIGN wa_ref_data->* TO <fs_wa_zdata>.


 PERFORM get_field_catalog
                          CHANGING p_fcat.


*  CALL FUNCTION 'HR_KR_XSTRING_TO_STRING'
*    EXPORTING
**     FROM_CODEPAGE = '8500'
*      in_xstring = '09'
*      out_len    = 1
*    IMPORTING
*      out_string = lv_separator.


 LOOP AT <fs_table> ASSIGNING <fs_wa>.

   lv_err_line  = sy-tabix.

   CLEAR:lv_start_pos,lv_offset.

   lv_index = 1.

   DO .
     ASSIGN COMPONENT sy-index OF STRUCTURE <fs_wa> TO <fs_field>.

     IF sy-index EQ 1.
       IF <fs_field> NE sy-mandt.
         lv_msg = '客户端字段没有输入或输入错误!'.
         CONCATENATE '第' lv_err_line '行:'
                     lv_msg INTO lv_msg
                     SEPARATED BY space.
         CALL FUNCTION 'POPUP_TO_INFORM'
           EXPORTING
             titel = '@0A@错误提醒:'
             txt1  = lv_msg+0(80)
             txt2  = lv_msg+80(80)
             txt3  = lv_msg+160(80)
             txt4  = lv_msg+240(80).
         gv_fail = 'X'.
         EXIT.
       ENDIF.
     ENDIF.

     IF sy-subrc EQ 0.

       READ TABLE p_fcat INTO wa_fcat
                              INDEX lv_index.

       lv_index    = lv_index + 1.
       lv_length   = wa_fcat-intlen.
       lv_decimals = wa_fcat-decimals_out.

       " create field dynamically
       CALL METHOD create_data=>main(
         EXPORTING
           type     = wa_fcat-inttype
           length   = lv_length
           decimals = lv_decimals
         RECEIVING
           dref     = lv_field
                      ).

       lv_offset = wa_fcat-outputlen.
       <lv_varchar>+lv_start_pos(lv_offset) = <fs_field>.
       ASSIGN lv_field->* TO <lfs_field>.


       "CHECK 'date' consistent or not
       IF wa_fcat-inttype EQ 'D'.
         <lfs_field> = <lv_varchar>+lv_start_pos(lv_offset).
         CALL FUNCTION 'DATE_CHECK_PLAUSIBILITY'
           EXPORTING
             date                      = <lfs_field>
           EXCEPTIONS
             plausibility_check_failed = 1
             OTHERS                    = 2.
         IF sy-subrc <> 0.
*          Implement suitable error handling here
           lv_msg_part = 'date!'.
           PERFORM popup_to_inform
                   USING lv_err_line
                         wa_fcat-fieldname
                         <lv_varchar>
                         lv_start_pos
                         lv_offset
                         lv_msg_part
                   CHANGING lv_msg.

           gv_fail = 'X'.
           EXIT.
         ENDIF.
         DATA: lv_date_internal TYPE sy-datum.
         lv_date_internal = <lv_varchar>+lv_start_pos(lv_offset).
         CALL FUNCTION 'CONVERT_DATE_TO_EXTERNAL'
           EXPORTING
             date_internal            = lv_date_internal
           IMPORTING
             date_external            =
             <lv_varchar>+lv_start_pos(lv_offset)
           EXCEPTIONS
             date_internal_is_invalid = 1
             OTHERS                   = 2.
         IF sy-subrc <> 0.
* Implement suitable error handling here
         ENDIF.
       ELSEIF wa_fcat-inttype EQ 'T'.

         <lfs_field> = <lv_varchar>+lv_start_pos(lv_offset).
         CALL FUNCTION 'TIME_CHECK_PLAUSIBILITY'
           EXPORTING
             time                      = <lfs_field>
           EXCEPTIONS
             plausibility_check_failed = 1
             OTHERS                    = 2.
         IF sy-subrc <> 0.
*           MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*                   WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
*          Implement suitable error handling here
           lv_msg_part = 'time!'.
           PERFORM popup_to_inform
                   USING lv_err_line
                         wa_fcat-fieldname
                         <lv_varchar>
                         lv_start_pos
                         lv_offset
                         lv_msg_part
                   CHANGING lv_msg.
           gv_fail = 'X'.
           EXIT.
         ENDIF.

       ENDIF.

       "check numeric string
       IF wa_fcat-inttype EQ 'N'.
         lv_string_n = <lv_varchar>+lv_start_pos(lv_offset).
         IF lv_string_n CO c_number.
         ELSE.
           lv_msg_part = 'numeric string!'.
           PERFORM popup_to_inform
                   USING lv_err_line
                         wa_fcat-fieldname
                         <lv_varchar>
                         lv_start_pos
                         lv_offset
                         lv_msg_part
                   CHANGING lv_msg.
           gv_fail = 'X'.
           EXIT.
         ENDIF.
       ENDIF.
       "check 'number' consistent or not

       IF wa_fcat-inttype EQ 'P' OR
          wa_fcat-inttype EQ 'F' OR
          wa_fcat-inttype EQ 'I'.
         TRY .
             <lfs_field> = <lv_varchar>+lv_start_pos(lv_offset).

             SELECT SINGLE dcpfm FROM usr01        "#EC CI_SEL_NESTED.
               INTO lv_dcpfm WHERE bname = sy-uname.
             IF lv_dcpfm EQ 'X'.
               "do nothing
             ELSEIF ( lv_dcpfm EQ '' OR
                      lv_dcpfm EQ 'Y' ).
               IF wa_fcat-inttype EQ 'P' OR
                  wa_fcat-inttype EQ 'F'.
                 REPLACE ALL OCCURRENCES OF '.'
                         IN <lv_varchar>+lv_start_pos(lv_offset)
                                    WITH ','.
               ELSEIF wa_fcat-inttype EQ 'I'.
                 REPLACE ALL OCCURRENCES OF '.'
                       IN <lv_varchar>+lv_start_pos(lv_offset)
                                  WITH ''.
               ENDIF.
             ENDIF.
           CATCH  cx_sy_conversion_no_number.

             lv_msg_part = 'number!'.
             PERFORM popup_to_inform
                     USING lv_err_line
                           wa_fcat-fieldname
                           <lv_varchar>
                           lv_start_pos
                           lv_offset
                           lv_msg_part
                     CHANGING lv_msg.
             gv_fail = 'X'.
             EXIT.
         ENDTRY.
       ENDIF.

       IF wa_fcat-inttype EQ 'P' OR
          wa_fcat-inttype EQ 'F' OR
          wa_fcat-inttype EQ 'I'.
         WRITE <lv_varchar>+lv_start_pos(lv_offset)
            TO <lv_varchar>+lv_start_pos(lv_offset)
               RIGHT-JUSTIFIED.
       ENDIF.

       lv_start_pos = lv_start_pos + lv_offset.
     ELSE.
       EXIT.
     ENDIF.
*    ENDLOOP.
   ENDDO.

   <fs_wa_zdata> = <lv_varchar>.

   APPEND <fs_wa_zdata> TO <fs_tab_zdata>.
   CLEAR <fs_wa_zdata>.

 ENDLOOP.

ENDFORM.                    " GET_DATA
*&---------------------------------------------------------------------*
*&      Form  update_table_data
*&---------------------------------------------------------------------*
*       主处理
*----------------------------------------------------------------------*
FORM update_table_data.

 "cx_sy_sql_error . "cx_sy_open_sql_db.
 DATA: lcx_error TYPE REF TO cx_root.
 DATA err_text TYPE c LENGTH 1000.


 CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
   EXPORTING
     percentage = 80
     text       = '正在更新DB table......'.

 TRY.
     IF r1 EQ 'X'.
       INSERT (p_table) FROM TABLE <fs_table>.
     ELSEIF r2 EQ 'X'.
       MODIFY (p_table) FROM TABLE <fs_table>.
     ELSEIF r3 EQ 'X'.
       DELETE (p_table) FROM TABLE <fs_table>.
     ENDIF.

   CATCH cx_sy_open_sql_db INTO lcx_error.
     err_text = lcx_error->get_text( ). "得到错误信息
     sy-subrc = 4. "改变系统变量
 ENDTRY.

 IF sy-subrc = 0.
   COMMIT WORK.
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
   "操作成功,则记录操作日志

   CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
     EXPORTING
       percentage = 99
       text       = '更新马上完成......'.

*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
   MESSAGE s001(00) WITH '@08@更新表成功!'.
 ELSE.
   ROLLBACK WORK.
*    MESSAGE i001(00) WITH '@0A@更新表失败!'
*                          err_text.
   DATA: lv_msg1 TYPE char80,
         lv_tabix TYPE char6.
   lv_tabix = sy-tabix.
   CONCATENATE '操作第' lv_tabix '行数据时候发生数据库异常!'
               INTO lv_msg1.

   CALL FUNCTION 'POPUP_TO_INFORM'
     EXPORTING
       titel = '@0A@错误提醒:'
       txt1  = err_text+0(80)
       txt2  = err_text+80(80)
       txt3  = err_text+160(80)
       txt4  = lv_msg1.

 ENDIF.

ENDFORM.                    "update_table_data
*&---------------------------------------------------------------------*
*&      Form  POPUP_TO_INFORM
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_LV_ERR_LINE  text
*      -->P_WA_FCAT_FIELDNAME  text
*      -->P_<lv_varchar>  text
*      -->P_LV_START_POS  text
*      -->P_LV_OFFSET  text
*      -->P_LV_MSG_PART  text
*----------------------------------------------------------------------*
FORM popup_to_inform  USING lv_err_line TYPE n
                           wa_fcat-fieldname TYPE slis_fieldname
                           lv_char3000 TYPE char3000
                           lv_start_pos TYPE i
                           lv_offset TYPE i
                           lv_msg_part TYPE char50
                     CHANGING
                           lv_msg TYPE char600.

 CONCATENATE 'Line:' lv_err_line
             'field' wa_fcat-fieldname
             ':'
             lv_char3000+lv_start_pos(lv_offset)
             'is not a valid'
             lv_msg_part
            INTO lv_msg SEPARATED BY space.
*            MESSAGE lv_msg TYPE 'E'.
 CALL FUNCTION 'POPUP_TO_INFORM'
   EXPORTING
     titel = '@0A@错误提醒:'
     txt1  = lv_msg+0(80)
     txt2  = lv_msg+80(80)
     txt3  = lv_msg+160(80)
     txt4  = lv_msg+240(80).

ENDFORM.                    " POPUP_TO_INFORM
*&---------------------------------------------------------------------*
*&      Form  GET_FIELD_CATALOG
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_P_FCAT  text
*----------------------------------------------------------------------*
FORM get_field_catalog  CHANGING p_fcat TYPE slis_t_fieldcat_alv.
 "插入正确名称 <...>.
 DATA: et_fieldcat  TYPE lvc_t_fcat,
       ewa_fieldcat TYPE lvc_s_fcat,
       wa_fcat      TYPE LINE OF slis_t_fieldcat_alv.

 DATA:   l_alvbuffer(70) TYPE c,
         l_date TYPE sy-datum,
         wa_t002 TYPE t002.

 l_alvbuffer = sy-datum + 1.
 SET PARAMETER ID 'ALVBUFFER' FIELD l_alvbuffer.


 REFRESH p_fcat[].
 CALL FUNCTION 'REUSE_ALV_FIELDCATALOG_MERGE'
   EXPORTING
     i_program_name         = sy-repid
     i_structure_name       = p_table
     i_inclname             = sy-repid
     i_bypassing_buffer     = 'X'
   CHANGING
     ct_fieldcat            = p_fcat
   EXCEPTIONS
     inconsistent_interface = 1
     program_error          = 2
     OTHERS                 = 3.

 " just use mara, make no sense
 DATA: it_data     TYPE TABLE OF mara.

 CALL FUNCTION 'LVC_TRANSFER_FROM_SLIS'
   EXPORTING
     it_fieldcat_alv = p_fcat
*     IT_SORT_ALV     =
*     IT_FILTER_ALV   =
*     IS_LAYOUT_ALV   =
   IMPORTING
     et_fieldcat_lvc = et_fieldcat
*     ET_SORT_LVC     =
*     ET_FILTER_LVC   =
*     ES_LAYOUT_LVC   =
   TABLES
     it_data         = it_data
   EXCEPTIONS
     it_data_missing = 1
     OTHERS          = 2.
 IF sy-subrc <> 0.
* Implement suitable error handling here
 ENDIF.

 DATA: ls_dfies    LIKE dfies,
       l_tabname   LIKE dcobjdef-name,
       l_fieldname LIKE dfies-lfieldname,
       l_dummy     LIKE dfies-lfieldname.

 LOOP AT p_fcat INTO wa_fcat.
*   *** <field_n>(<length>)
   CLEAR ls_dfies.
   CLEAR l_fieldname.
   CLEAR l_tabname.

   IF wa_fcat-fieldname IS NOT INITIAL.
     l_fieldname = wa_fcat-fieldname.
   ELSEIF wa_fcat-ref_fieldname IS NOT INITIAL.
     l_fieldname = wa_fcat-ref_fieldname.
   ENDIF.

   IF wa_fcat-tabname IS NOT INITIAL.
     l_tabname = wa_fcat-tabname.
   ELSEIF wa_fcat-ref_tabname IS NOT INITIAL.
     l_tabname = wa_fcat-ref_tabname.
   ENDIF.

   CALL FUNCTION 'DDIF_FIELDINFO_GET'
     EXPORTING
       tabname        = l_tabname
*         fieldname      = l_fieldname
       langu          = sy-langu
       lfieldname     = l_fieldname
       all_types      = 'X'
     IMPORTING
*         X030L_WA       =
*         ddobjtype      =
       dfies_wa       = ls_dfies
*          TABLES
*         DFIES_TAB      =
     EXCEPTIONS
       not_found      = 1
       internal_error = 2
       OTHERS         = 3.
*if it is in ddic use ddic info in the field catalog
   IF sy-subrc = 0.
*      WRITE: /'DDIC Field', str_right.             " for debugging only
     IF wa_fcat-ref_tabname IS NOT INITIAL.
       wa_fcat-tabname      = wa_fcat-ref_tabname.
     ENDIF.
     IF wa_fcat-ref_fieldname IS NOT INITIAL.
       wa_fcat-fieldname      = wa_fcat-ref_fieldname.
     ENDIF.
     wa_fcat-inttype        = ls_dfies-inttype.
     wa_fcat-outputlen      = ls_dfies-outputlen.
     wa_fcat-seltext_l      = ls_dfies-scrtext_l. " long key word
     wa_fcat-seltext_m      = ls_dfies-scrtext_m. " middle key word
     wa_fcat-seltext_s      = ls_dfies-scrtext_s. " short key word
     wa_fcat-ddictxt        = 'S'.           " (S)hort (M)iddle (L)ong
     wa_fcat-rollname       = ls_dfies-rollname.
     wa_fcat-datatype       = ls_dfies-datatype.
     wa_fcat-inttype        = ls_dfies-inttype.
     wa_fcat-intlen         = ls_dfies-intlen.
     wa_fcat-lowercase      = ls_dfies-lowercase.
*      wa_fcat-ref_fieldname  = ls_dfies-fieldname.
*      wa_fcat-ref_tabname    = ls_dfies-tabname.
     wa_fcat-decimals_out   = ls_dfies-decimals.  " decimals in write
     wa_fcat-reptext_ddic   = ls_dfies-reptext.   " heading (ddic)
     wa_fcat-ddic_outputlen = ls_dfies-outputlen.

     MODIFY p_fcat FROM wa_fcat.
     CLEAR wa_fcat.
*        APPEND ls_dfies TO it_dfies.
     CLEAR ls_dfies.
   ENDIF.

 ENDLOOP.


 LOOP AT p_fcat INTO wa_fcat.
*    IF wa_fcat-inttype NE 'C'.
*      wa_fcat-intlen   = wa_fcat-outputlen * 2.
*    ENDIF.
*    wa_fcat-intlen     = wa_fcat-intlen / 2.
*    wa_fcat-inttype    = 'C'.
*    wa_fcat-datatype   = 'CHAR'.
*    wa_fcat-ref_tabname  = ''.
*    wa_fcat-ref_fieldname  = ''.
*    wa_fcat-rollname   = ''.
   MODIFY p_fcat FROM wa_fcat.
   CLEAR wa_fcat.
 ENDLOOP.
ENDFORM.                    " GET_FIELD_CATALOG
*&---------------------------------------------------------------------*
*&      Form  GUI_UPLOAD
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM gui_upload .
 DATA: lc_fname TYPE string.
*  DATA: IT_TABLE TYPE INDEX TABLE .
 lc_fname = p_fname.

 CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
   EXPORTING
     percentage = 30
     text       = '正在从文件Upload数据到内表......'.

 CALL FUNCTION 'GUI_UPLOAD'
   EXPORTING
     filename                = lc_fname"文件名
     filetype                = 'ASC'
     has_field_separator     = 'X'     "TAB分割
     codepage                = '4110'
   TABLES
     data_tab                = <fs_table>
   EXCEPTIONS
     file_open_error         = 1
     file_read_error         = 2
     no_batch                = 3
     gui_refuse_filetransfer = 4
     invalid_type            = 5
     no_authority            = 6
     unknown_error           = 7
     bad_data_format         = 8
     header_not_allowed      = 9
     separator_not_allowed   = 10
     header_too_long         = 11
     unknown_dp_error        = 12
     access_denied           = 13
     dp_out_of_memory        = 14
     disk_full               = 15
     dp_timeout              = 16
     OTHERS                  = 17.
 IF sy-subrc <> 0.
   DATA: lv_msg1 TYPE char80,
         lv_tabix TYPE char6.
   lv_tabix = sy-tabix.
   CONCATENATE '应该是第' lv_tabix '行“数量”或“金额”字段格式不正确!'
               INTO lv_msg1.

*    CALL FUNCTION 'POPUP_TO_INFORM'
*      EXPORTING
*        titel = '@0A@错误提醒:'
*        txt1  = lv_msg1.
   CALL FUNCTION 'POPUP_TO_INFORM'
     EXPORTING
       titel = '@0A@错误提醒:'
       txt1  = lv_msg1
       txt2  = ' '
       txt3  = ' '
       txt4  = ' '.
   gv_fail = 'X'.
   MESSAGE ID sy-msgid TYPE 'I' NUMBER sy-msgno
           WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
 ENDIF.
ENDFORM.                    " GUI_UPLOAD


赞赏支持