首页 > 代码库 > 一步步实现ABAP后台导入EXCEL到数据库【2】

一步步实现ABAP后台导入EXCEL到数据库【2】

前文:http://www.cnblogs.com/hhelibeb/p/5912330.html

  既然后台作业只能在应用服务器运行,那么,我们可以先将要上传的数据保存在应用服务器中,之后再以后台作业的形式导入数据库。这里需要使用的关键字是OPEN DATASET。

1. OPEN DATASET 

Syntax

OPEN DATASET dset
  FOR { INPUT | OUTPUT | APPENDING | UPDATE }
  IN { { BINARY MODE }
     | { TEXT MODE ENCODING { DEFAULT
                           | {UTF-8 [SKIPPING|WITH BYTE-ORDER MARK]}
                            | NON-UNICODE }
                   [WITH {NATIVE|SMART|UNIX|WINDOWS} LINEFEED]  }
     | { LEGACY BINARY MODE [{BIG|LITTLE} ENDIAN]
                           [CODE PAGE cp] }
     | { LEGACY TEXT MODE [{BIG|LITTLE} ENDIAN]
                         [CODE PAGE cp]
                         [WITH {NATIVE|SMART|UNIX|WINDOWS} LINEFEED] } }
  [AT POSITION pos]
  [TYPE attr]
  [FILTER opcom]
  [MESSAGE msg]
  [IGNORING CONVERSION ERRORS]
  [REPLACEMENT CHARACTER rc].

效果

  打开由dset指定的应用服务器上的文件。

附加项

    • FOR { INPUT | OUTPUT | APPENDING | UPDATE }
      以输入、输出、追加、更新模式打开文件.

 

    • IN [LEGACY] { BINARY | TEXT } MODE
      以普通的二进制或者文本模式打开文件, 或者以LEGACY二进制或文本模式. LEGACY模式可以指定字节顺序和内码表。在Unicode系统中,LEGACY关键字可能会影响到以东亚文字写入的字段的内容。因此,建议只在没有使用LEGACY附加项的打开的文本中写入内容。

 

    • ENCODING {DEFAULT|UTF-8|NON-UNICODE}
      决定了使用何种字符表现形式来操作文件的内容:

      DEFAULT -Unicode系统中的UTF-8; 非Unicode系统则不转换.

      UTF-8 - UTF-8.

      NON-UNICODE -在Unicode系统中,内码表与非Unicode系统文本环境(text evirionment)一致; 非Unicode系统则不转换.

tips: text evirionment

text evirionment是ABAP程序的运行时环境的一部分,由语言、locale和系统内码表组成。同一个内部会话中的所有程序有一个共同的文本环境。默认情况下,内部会话的text environment由登录语言决定,并且也可以被语句set locale指定。当前的text environment包含在系统字段sy-langu中

 

    • WITH {NATIVE|SMART|UNIX|WINDOWS} LINEFEED
      决定文本文件的行尾选项.

 

    • SKIPPING|WITH BYTE-ORDER MARK
      控制UTF-8文件中的字节顺序标记(BOM)操作.

 

    • {BIG|LITTLE} ENDIAN
      决定文件中数值型数据对象被操作的顺序.

 

    • CODE PAGE cp
      决定文件中字符型数据对象以指定的内码表cp操作.

 

    • AT POSITION pos
      将文件指针设置到指定的位置pos.

 

    • TYPE attr
      为文件设置操作系统参数,或者控制文本文件的行尾选项.

 

    • FILTER opcom
      将一个语句转换给操作系统.

 

    • MESSAGE msg
      如果发生了错误,可以在msg中返回操作系统信息.

 

    • IGNORING CONVERSION ERRORS
      如果会话错误发生,该语句可以阻止异常.

 

    • REPLACEMENT CHARACTER rc
      指定一个字符rc替换无法转换的字符。如果未指定rc,则使用“#”.

   使用OPEN DATASET来实现上传数据到应用服务器,即程序中的output_data子进程:

*&---------------------------------------------------------------------**&      Form  OUTPUT_DATA*&---------------------------------------------------------------------**       将数据写入到Applacation Server*----------------------------------------------------------------------**  -->  p1        text*  <--  p2        text*----------------------------------------------------------------------*FORM output_data .  DATA s_file TYPE rlgrap-filename.  PERFORM generate_filename_in_server USING s_file.  OPEN DATASET s_file FOR INPUT IN TEXT MODE ENCODING DEFAULT.  IF sy-subrc = 0 .    LOOP AT itab INTO wa.      TRANSFER wa TO s_file.      IF sy-subrc <> 0 .        MESSAGE ERROR!! TYPE E.      ENDIF.    ENDLOOP.    CLOSE DATASET s_file.    WRITE: /写入服务器文件成功.    PERFORM submit_insert_program USING s_file.  "调用导入程序  ELSE.    WRITE: /写入服务器文件失败 .  ENDIF.ENDFORM.*&---------------------------------------------------------------------**&      Form  GET_file_name_in_server*&---------------------------------------------------------------------**       text*----------------------------------------------------------------------**  -->  p1        text*  <--  p2        text*----------------------------------------------------------------------*FORM generate_filename_in_server USING s_file .  DATA s_name TYPE string.  CALL FUNCTION SO_SPLIT_FILE_AND_PATH    EXPORTING      full_name     = p_source    IMPORTING      stripped_name = s_name*     FILE_PATH     =    EXCEPTIONS      x_error       = 1      OTHERS        = 2.  IF sy-subrc <> 0.* Implement suitable error handling here  ENDIF.  GET TIME.  CONCATENATE /tmp/ sy-datum  sy-uzeit s_name  .txt INTO s_file.  TRANSLATE s_file TO LOWER CASE.ENDFORM.

 

2,实现导入程序

  上传到服务器的程序已经实现,现在新建一个程序ztest_import,实现导入到数据库的功能。同样使用OPEN DATASET语句来实现:

REPORT ztest_import.SELECTION-SCREEN: BEGIN OF BLOCK blk.PARAMETERS: s_file TYPE rlgrap-filename .SELECTION-SCREEN END OF BLOCK blk.DATA: BEGIN OF wa,        col1(30) TYPE c,        col2(30) TYPE c,        col3(30) TYPE c,      END OF wa.FIELD-SYMBOLS: <hex_container> TYPE c.TRANSLATE s_file TO LOWER CASE.OPEN DATASET s_file FOR INPUT IN TEXT  MODE ENCODING DEFAULT.IF sy-subrc = 0.  ASSIGN wa TO <hex_container> CASTING.  DO.    "由于没有使用MAXIMUM LENGTH选项,所以每次读取的最大字节数    "由<hex_container>所占字节数决定    READ DATASET s_file INTO <hex_container>.    IF sy-subrc = 0.*"ztestly是在SE11中新建的表,结构和上传的excel相符,过程省略      INSERT ztestly FROM wa.      WRITE wa.    ELSE.      EXIT.    ENDIF.  ENDDO.  CLOSE DATASET s_file.  DELETE DATASET s_file.  "成功执行导入后,删除服务器上的文件ELSE.  MESSAGE open failed TYPE I

3,在上传程序中调用导入程序

  如果你看过我博客中有关submit的文章,可能会记得,submit语句是可以安排程序作为后台作业进行的。下面我们就使用这个特性,在上传程序ztest_upload的子程序submit_insert_program中调用导入程序ztest_import,代码如下:

*&---------------------------------------------------------------------**&      Form  SUBMIT_INSERT_PROGRAM*&---------------------------------------------------------------------**       text*----------------------------------------------------------------------**  -->  p1        text*  <--  p2        text*----------------------------------------------------------------------*FORM submit_insert_program USING s_file.  DATA: w_jobid  TYPE tbtcjob-jobcount,        w_stepnm TYPE tbtcjob-stepcount,        p_job_nm TYPE tbtcjob-jobname VALUE  ZTEST_IMPORT.  CLEAR:w_jobid.  CALL FUNCTION JOB_OPEN    EXPORTING*     DELANFREP        = ‘ ‘*     JOBGROUP         = ‘ ‘      jobname          = p_job_nm*     SDLSTRTDT        = NO_DATE*     SDLSTRTTM        = NO_TIME    IMPORTING      jobcount         = w_jobid    EXCEPTIONS      cant_create_job  = 1      invalid_job_data = 2      jobname_missing  = 3      OTHERS           = 4.  SUBMIT ztest_import WITH s_file = s_file VIA JOB p_job_nm NUMBER w_jobid  AND RETURN.  IF sy-subrc = 0.    CALL FUNCTION JOB_CLOSE      EXPORTING        jobcount             = w_jobid        jobname              = p_job_nm        strtimmed            = X      EXCEPTIONS        cant_start_immediate = 1        invalid_startdate    = 2        jobname_missing      = 3        job_close_failed     = 4        job_nosteps          = 5        job_notex            = 6        lock_failed          = 7        OTHERS               = 8.    IF sy-subrc <> 0.      WRITE: /后台作业发布失败.    ELSE.      WRITE: /后台作业发布成功.    ENDIF.  ENDIF.ENDFORM.

  运行zterst_upload,上传一个有效的excel文件,我们便可以在上一篇文章提到的自有作业界面看到后台作业执行成功,并且在SE16中查到自建表zestly中已经插入了相关数据。如果要改变后台作业的计划时间,可以在JOB_OPEN函数中设置相关参数。

一步步实现ABAP后台导入EXCEL到数据库【2】