Batch input data for any table

*&---------------------------------------------------------------------*
*&*** Author: Edward Kang         Date: 20100425 ***
*&Example:
*&Batch input file format: (exclude MANDT Field)
*&  CARRID`CONNID`FLDATE`PRICE`CURRENCY`PLANETYPE`SEATSMAX`SEATSOCC`PAYMENTSUM`SEATSMAX_B`SEATSOCC_B`SEATSMAX_F

`SEATSOCC_F`
*&Table name:
*&  SFLIGHT
*&---------------------------------------------------------------------*

REPORT zbatch_input_for_tab.

*"==============================变量声明区域============================*
*"---------------------------------------------------------------------*
*" 变量声明
*"---------------------------------------------------------------------*
TYPES: BEGIN OF l_str_text,                                             "存放文本字符串
    line(1000) TYPE c ,
END OF l_str_text.

DATA: l_tab_text        TYPE TABLE OF l_str_text ,                      "存放从文本文件里取出的数据
      l_str_text        TYPE l_str_text.                                "文件字段值

DATA: l_gui_file        TYPE string,                                    "文件地址变量
      l_itab            TYPE TABLE OF string.                           "分解字符串数组
DATA: con_split         TYPE c VALUE '`'.
TYPES: str_tab          TYPE STANDARD TABLE OF  string.                 "字符串组(内表)

*DATA:l_str_wnlog        TYPE zcms_log_for_wn.
DATA:l_tab_ret          TYPE bapiret2_t,
     l_str_ret          TYPE bapiret2,
     e_tab_return       TYPE bapiret2_t.
DATA:prc_result         TYPE c.
DATA:l_text             TYPE string.
DATA:l_one_mandt        TYPE i.
*******************************************************************************

DATA:l_tabname          TYPE objname.

SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-003.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE text-004.
PARAMETERS: file        TYPE text128."rterm-file .                      "文件路径
SELECTION-SCREEN END OF BLOCK b2.
SELECTION-SCREEN BEGIN OF BLOCK b3 WITH FRAME TITLE text-005.
PARAMETERS p_name TYPE rsrd1-tbma_val DEFAULT 'SFLIGHT'. "objname
SELECTION-SCREEN END OF BLOCK b3.
SELECTION-SCREEN END OF BLOCK b1.

*******************************Dynamic Table define****************************
TYPE-POOLS:abap.

DATA lt_table TYPE TABLE OF dfies.
DATA ls_table TYPE dfies.

l_tabname = p_name.   "for type conversion
CALL FUNCTION 'DDIF_NAMETAB_GET'
  EXPORTING
    tabname   = l_tabname "p_name
  TABLES
*   X031L_TAB =
    dfies_tab = lt_table
  EXCEPTIONS
    not_found = 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.
ENDIF.

DATA lr_struc TYPE REF TO cl_abap_structdescr.
DATA lr_table TYPE REF TO cl_abap_tabledescr.
DATA lr_type  TYPE REF TO cl_abap_typedescr.
DATA l_string TYPE string.
DATA lt_comp  TYPE abap_component_tab.
DATA ls_comp  LIKE LINE OF  lt_comp.
DATA e_wa     TYPE REF TO data.
DATA e_table  TYPE REF TO data.

FIELD-SYMBOLS <fs_table> TYPE STANDARD TABLE.
FIELD-SYMBOLS <fs_struc> TYPE any.

*****************
l_one_mandt = 1.
LOOP AT lt_table INTO ls_table.
  IF sy-tabix = 1 AND ls_table-fieldname <> 'MANDT'.
    l_one_mandt = 0.
  ENDIF.
  CONCATENATE ls_table-tabname '-' ls_table-fieldname INTO l_string.
*  L_STRING = LS_COMP-NAME.
  ls_comp-name = ls_table-fieldname.
  CALL METHOD cl_abap_datadescr=>describe_by_name
    EXPORTING
      p_name         = l_string
    RECEIVING
      p_descr_ref    = lr_type
    EXCEPTIONS
      type_not_found = 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.
  ENDIF.

  ls_comp-type ?= lr_type.
  APPEND ls_comp TO lt_comp.
  CLEAR ls_comp.
ENDLOOP.

CALL METHOD cl_abap_structdescr=>create
  EXPORTING
    p_components = lt_comp
  RECEIVING
    p_result     = lr_struc.

*CALL METHOD cl_abap_tabledescr=>create
*  EXPORTING
*    p_line_type = lr_struc
*  RECEIVING
*    p_result    = lr_table.

CREATE DATA e_wa    TYPE HANDLE lr_struc.
*CREATE DATA e_table TYPE HANDLE lr_table.

ASSIGN e_wa->*    TO <fs_struc>.
*ASSIGN e_table->* TO <fs_table>.

***************

*******************************Dynamic Table define****************************

*"=============================程序逻辑区域============================*

*"---------------------------------------------------------------------*
*" 1.选择屏幕
*"---------------------------------------------------------------------*
*SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-003.
*SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE text-004.
*PARAMETERS: file        TYPE text128."rterm-file .                      "文件路径
*SELECTION-SCREEN END OF BLOCK b2.
*SELECTION-SCREEN BEGIN OF BLOCK b3 WITH FRAME TITLE text-005.
*PARAMETERS p_name TYPE objname.
*SELECTION-SCREEN END OF BLOCK b3.
*SELECTION-SCREEN END OF BLOCK b1.

*"---------------------------------------------------------------------*
*" 2.初始化
*"---------------------------------------------------------------------*
INITIALIZATION .
  CLEAR:
      file.                                                             "文件路径

* 2.1文件选择F4
AT SELECTION-SCREEN ON VALUE-REQUEST FOR file.
  PERFORM lfile_open_dialog CHANGING file.

*"---------------------------------------------------------------------*
*" 3.执行程序
*"---------------------------------------------------------------------*
START-OF-SELECTION.
  l_gui_file = file.
  CLEAR: l_text.
  prc_result = cl_gui_frontend_services=>file_exist( l_gui_file ).      "判断本地文件是否存在
  IF prc_result IS INITIAL.
    l_text = |File { file } doesn't exist!|.
*    MESSAGE e208(00) WITH l_text.
    CALL FUNCTION 'BUS_MESSAGE_STORE'
      EXPORTING
        arbgb = '00'
        msgty = 'E'
        txtnr = '208'
        msgv1 = l_text.
  ENDIF.
  "本地文件数据上传至内表
  CALL FUNCTION 'GUI_UPLOAD'
    EXPORTING
      filename = l_gui_file                                             "更新文件地址
      filetype = 'ASC'                                                  "文件类型
      codepage = '8400'                                                 "字符类型
    TABLES
      data_tab = l_tab_text.                                            "更新文件内容内表

  LOOP AT l_tab_text INTO l_str_text.                                   "循环更新文件内容内表
    SPLIT l_str_text AT con_split INTO TABLE l_itab.                    "字段分解
    "for any
    DATA: l_total TYPE i.
    l_total  = lines( l_itab ).                                         "对输入字段个数进行检查
    "匹配输入内表的字段个数与结构体字段个数
    PERFORM match_field_number
      USING    <fs_struc>                                               "结构体
               l_total                                                  "批量输入的每行字段个数
      CHANGING l_tab_ret.

    PERFORM fill_structure
      USING    l_itab                                                   "
      CHANGING <fs_struc>                                               "
               l_tab_ret.                                               "返回信息

    IF l_tab_ret IS NOT INITIAL.
      APPEND LINES OF l_tab_ret TO e_tab_return.                        "填充返回信息内表
      CLEAR:l_tab_ret.
      CONTINUE.
*      BREAK-POINT.
*      RETURN.
    ENDIF.
    MODIFY (p_name) FROM <fs_struc>.

  ENDLOOP.

*  BREAK-POINT.
  IF e_tab_return IS NOT INITIAL.
    WRITE : / 'Error list!'.
    LOOP AT e_tab_return INTO l_str_ret.
      WRITE /.
      WRITE :
               (4) 'type',
               (6) 'id',
               (6) 'number',
               (100) 'message'.

      WRITE /.

      WRITE :  l_str_ret-type    UNDER 'type',
               l_str_ret-id      UNDER 'id',
               l_str_ret-number  UNDER 'number',
               l_str_ret-message UNDER 'message'.

      WRITE /.
    ENDLOOP.

  ELSE.
    CALL FUNCTION 'BUS_MESSAGE_STORE'
      EXPORTING
        arbgb = '00'
        msgty = 'S'
        txtnr = '208'
        msgv1 = text-001.

  ENDIF.

*************************************
* Form
*************************************
FORM lfile_open_dialog
  CHANGING c_lfile.

  DATA: l_initial_directory TYPE string.
  DATA: l_title             TYPE string.
  DATA: lt_file_table       TYPE filetable.
  DATA: l_rc                TYPE i.

  l_initial_directory = c_lfile.
  l_title = text-009.

  CALL METHOD cl_gui_frontend_services=>file_open_dialog
    EXPORTING
      window_title            = l_title
      default_extension       = '.TXT'
*     DEFAULT_FILENAME        =
      file_filter             = 'Text Files (*.TXT)|*.TXT|'
*     WITH_ENCODING           =
      initial_directory       = l_initial_directory
*     MULTISELECTION          =
    CHANGING
      file_table              = lt_file_table
      rc                      = l_rc
*     USER_ACTION             =
*     FILE_ENCODING           =
    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.

  ELSE.

    IF lt_file_table IS NOT INITIAL.

      READ TABLE lt_file_table INTO c_lfile INDEX 1.

    ENDIF.

  ENDIF.
ENDFORM.                    " LFILE_OPEN_DIALOG

FORM fill_structure
  USING    u_itab             TYPE str_tab                              "输入的字段内表
  CHANGING c_structure        TYPE any                                  "结构体
           c_tab_return       TYPE bapiret2_t.

  DATA:    l_tab              TYPE TABLE OF string,
           l_str_ret          TYPE bapiret2,                            "返回信息结构体
           exc                TYPE REF TO cx_sy_conversion_error,       "全局异常类
           l_tabix            TYPE i.
  FIELD-SYMBOLS: <fs_comp>.                             "#EC FS_UNTYPED
  FIELD-SYMBOLS: <fs_tabline> LIKE LINE OF l_tab.

  l_tab = u_itab.
*  TRY.
  "将字符串内表的值赋给结构体
  LOOP AT l_tab ASSIGNING <fs_tabline>.
    l_tabix = sy-tabix + l_one_mandt." don't input mandt field !!! (all table field except mandt)
    ASSIGN COMPONENT l_tabix OF STRUCTURE c_structure TO <fs_comp>.
    IF sy-subrc <> 0.
      EXIT.
    ENDIF.

    TRY.

        <fs_comp> = <fs_tabline> .

      CATCH cx_sy_conversion_error INTO exc.
        l_str_ret-message = exc->get_longtext( ).
        l_str_ret-type    = 'E'.
        APPEND l_str_ret  TO c_tab_return.

    ENDTRY.

  ENDLOOP.
  UNASSIGN: <fs_comp>,
            <fs_tabline>.
*    CATCH cx_sy_conversion_error INTO exc.
*      l_str_ret-message = exc->get_longtext( ).
*      l_str_ret-type    = 'E'.
*      APPEND l_str_ret  TO c_tab_return.
*  ENDTRY.

ENDFORM.                    " FILL_CRT_STRUCTURE

FORM match_field_number
  USING    value(u_structure) TYPE any                                  "结构体
           value(u_total)     TYPE i                                    "输入内表的字段总个数
  CHANGING c_tab_return       TYPE bapiret2_t.                          "返回信息内表

*"=============================变量声明区域============================*
*"---------------------------------------------------------------------*
*" 内表声明
*"---------------------------------------------------------------------*
  DATA:
        l_field_number        TYPE i.                                   "结构体的字段个数
  DATA: l_temp_num            TYPE i.

*"=============================程序逻辑区域============================*
  PERFORM describe_line                                                 "取结构体的字段个数
    USING    u_structure                                                "结构体
    CHANGING l_field_number.                                            "结构体的字段个数
  l_temp_num = l_field_number - l_one_mandt.   "不把MANDT Field计算在内
  IF u_total <> l_temp_num.          "l_field_number                    "字段个数比较
*    MESSAGE text-008 TYPE 'E'.
    CALL FUNCTION 'BUS_MESSAGE_STORE'
      EXPORTING
        arbgb = '00'
        msgty = 'E'
        txtnr = '208'
        msgv1 = text-008.
  ENDIF.


ENDFORM.                    " MATCH_FIELD_NUMBER

FORM describe_line                                                      "取结构体的字段个数
  USING    value(u_structure) TYPE any                                  "结构体
  CHANGING value(c_line) TYPE i.                                        "结构体的字段个数

  DATA:   l_line TYPE i.
  CLEAR : l_line, c_line.
  FIELD-SYMBOLS: <fs_comp>.                             "#EC FS_UNTYPED
  "取结构体的字段个数
  DO .
    ASSIGN COMPONENT sy-index OF STRUCTURE u_structure TO <fs_comp>.
    IF sy-subrc <> 0.
      EXIT.
    ENDIF.
    l_line = l_line + 1.
  ENDDO.
  c_line = l_line.
  UNASSIGN: <fs_comp>.

ENDFORM.                    " DESCRIBE_LINE

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值