abap读取csv文件到内表

abap读取csv文件到内表

在 ABAP 中,可以使用字符串函数和逻辑处理来分割 CSV 文件。

由于某些字段值可能包含逗号,按照分割符分割出来的数据列就会出现对不齐的现象,也就是某些数据被拆分成了两列或者多列,你需要在处理时考虑这种情况。

上传的csv文件内容:

ID,姓名,年龄,地址
1,张三,25,"北京,中国"
2,李四,30,"上海,中国"
3,王五,28,"广州,中国"

一、选择屏幕-参数设定

首先进入se38创建一个程序,创建一个程序名为ztest_split_csv01程序。

设定好上传文件的参数。

*& Report ZTEST_SPLIT_CSV01
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ztest_split_csv01.

*--------------------------------------------------------------------*
* 选择屏幕
*--------------------------------------------------------------------*
PARAMETERS:p_path TYPE localfile.

* F4值帮助
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_path.
  CALL FUNCTION 'F4_FILENAME'
*   EXPORTING
*     PROGRAM_NAME        = SYST-CPROG
*     DYNPRO_NUMBER       = SYST-DYNNR
*     FIELD_NAME          = ' '
    IMPORTING
      file_name = p_path.

二、获取csv文件数据 (按行)

自定义的csv文件,编码格式是utf-8,但是使用gui_upload函数读取文件数据,会出现中文乱码,因此需要给形参codepage指定编码格式。

2.1 获取codepage

三种方式获取codepage:

  • 使用语言编码维护表

    DATA:lv_codepage     TYPE abap_encoding.
    SELECT SINGLE lv_codepage INTO codepage FROM tcp00a WHERE cpattr = 'UTF-8'.
    
  • 使用SCP_CODEPAGE_BY_EXTERNAL_NAME函数

    DATA:lv_codepage     TYPE abap_encoding.
    CALL FUNCTION 'SCP_CODEPAGE_BY_EXTERNAL_NAME'
        EXPORTING
          external_name       = 'UTF-8'
    *     KIND                = 'H'
        IMPORTING
          SAP_CODEPAGE        = lv_codepage
    *   EXCEPTIONS
    *     NOT_FOUND           = 1
    *     OTHERS              = 2
                .
    
  • 使用cl_abap_codepage=>sap_codepage类方法

    DATA:lv_codepage     TYPE abap_encoding.
    lv_codepage = cl_abap_codepage=>sap_codepage( 'UTF-8' ).
    

2.2 gui_upload

*  定义类型
  DATA: lt_csv_lines TYPE STANDARD TABLE OF string,  "保存读取的数据行
        lv_csv_data  TYPE string,
        lv_filename  TYPE string,
        lv_codepage     TYPE abap_encoding.  "编码



  lv_filename = p_path.

*--------------------------------------------------------------------*
* 主程序
*--------------------------------------------------------------------*
START-OF-SELECTION.
  "获取数据行
  PERFORM get_csv_lines.

FORM get_csv_lines .
  " 1. 获取utf-8编码格式
  "SELECT SINGLE lv_codepage INTO codepage FROM tcp00a WHERE cpattr = 'UTF-8'.
  lv_codepage = cl_abap_codepage=>sap_codepage( 'UTF-8' ).
  " 2. 获取数据行
  CALL FUNCTION 'GUI_UPLOAD'
    EXPORTING
      filename = lv_filename
*     FILETYPE = 'ASC'
*     HAS_FIELD_SEPARATOR           = ' '
*     HEADER_LENGTH                 = 0
*     READ_BY_LINE                  = 'X'
*     DAT_MODE = ' '
      codepage = lv_codepage
*     IGNORE_CERR                   = ABAP_TRUE
*     REPLACEMENT                   = '#'
*     CHECK_BOM                     = ' '
*     VIRUS_SCAN_PROFILE            =
*     NO_AUTH_CHECK                 = ' '
*   IMPORTING
*     FILELENGTH                    =
*     HEADER   =
    TABLES
      data_tab = lt_csv_lines
*   CHANGING
*     ISSCANPERFORMED               = ' '
*   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.
* Implement suitable error handling here
  ENDIF.


ENDFORM.

三、转换csv数据行 (csv_to_structure)

  • 1、声明一个cl_rsda_csv_converter对象;
  • 2、调用cl_rsda_csv_converter=>create创建一个实例lo_csv
  • 3、通过实例对象lo_csv调用实例方法csv_to_structure,将csv文本数据行转换成定义的数据类型(结构体)。
 "分割行数据中的值
  PERFORM converter_csv_data.
  
* 子程序
FORM converter_csv_data .
  "实例csv转换器
  DATA:lo_csv TYPE REF TO cl_rsda_csv_converter.
  CALL METHOD cl_rsda_csv_converter=>create
*    EXPORTING
*      i_delimiter      = C_DEFAULT_DELIMITER
*      i_separator      = C_DEFAULT_SEPARATOR
*      i_escape         =
*      i_line_separator = CL_ABAP_CHAR_UTILITIES=>NEWLINE
    RECEIVING
      r_r_conv = lo_csv.
  LOOP AT lt_csv_lines INTO lv_csv_data.
    "跳过第一次循环
    AT FIRST.
       CONTINUE.
    ENDAT.
   "将csv转abap数据结构
    CALL METHOD lo_csv->csv_to_structure
      EXPORTING
        i_data   = lv_csv_data
      IMPORTING
        e_s_data = wa_user.
    "分割好的数据结构插入内表
    APPEND wa_user TO it_user.
    WRITE: / wa_user-id, wa_user-name, wa_user-age, wa_user-address.
    CLEAR wa_user.
  ENDLOOP.

ENDFORM.

四、完整的demo

该程序执行的结果:

image

完整代码如下:

*&---------------------------------------------------------------------*
*& Report ZTEST_SPLIT_CSV01
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ztest_split_csv01.


*  定义类型
DATA: lt_csv_lines TYPE STANDARD TABLE OF string,  "保存读取的数据行
      lv_csv_data  TYPE string,
      lv_filename  TYPE string,
      lv_codepage  TYPE abap_encoding.  "编码

TYPES:BEGIN OF ty_user,
        id      TYPE i,
        name    TYPE string,
        age     TYPE i,
        address TYPE string,
      END OF ty_user.

DATA:it_user TYPE STANDARD TABLE OF ty_user,
     wa_user TYPE ty_user.

*--------------------------------------------------------------------*
* 选择屏幕
*--------------------------------------------------------------------*
PARAMETERS:p_path TYPE localfile.

* F4值帮助
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_path.
  CALL FUNCTION 'F4_FILENAME'
*   EXPORTING
*     PROGRAM_NAME        = SYST-CPROG
*     DYNPRO_NUMBER       = SYST-DYNNR
*     FIELD_NAME          = ' '
    IMPORTING
      file_name = p_path.

  lv_filename = p_path.


*--------------------------------------------------------------------*
* 主程序
*--------------------------------------------------------------------*
START-OF-SELECTION.
  "获取数据行
  PERFORM get_csv_lines.
  "分割行数据中的值
  PERFORM converter_csv_data.

*&---------------------------------------------------------------------*
*& Form get_csv_lines
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM get_csv_lines.
  " 1. 获取utf-8编码格式
*  SELECT SINGLE cpcodepage INTO lv_codepage FROM tcp00a WHERE cpattr = 'UTF-8'.
  lv_codepage = cl_abap_codepage=>sap_codepage( 'UTF-8' ).
  " 2. 获取数据行
  CALL FUNCTION 'GUI_UPLOAD'
    EXPORTING
      filename = lv_filename
*     FILETYPE = 'ASC'
*     HAS_FIELD_SEPARATOR           = ' '
*     HEADER_LENGTH                 = 0
*     READ_BY_LINE                  = 'X'
*     DAT_MODE = ' '
      codepage = lv_codepage
*     IGNORE_CERR                   = ABAP_TRUE
*     REPLACEMENT                   = '#'
*     CHECK_BOM                     = ' '
*     VIRUS_SCAN_PROFILE            =
*     NO_AUTH_CHECK                 = ' '
*   IMPORTING
*     FILELENGTH                    =
*     HEADER   =
    TABLES
      data_tab = lt_csv_lines
*   CHANGING
*     ISSCANPERFORMED               = ' '
*   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.
* Implement suitable error handling here
  ENDIF.


ENDFORM.
*&---------------------------------------------------------------------*
*& Form converter_csv_data
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM converter_csv_data .
  "实例csv转换器
  DATA:lo_csv TYPE REF TO cl_rsda_csv_converter.
  CALL METHOD cl_rsda_csv_converter=>create
*    EXPORTING
*      i_delimiter      = C_DEFAULT_DELIMITER
*      i_separator      = C_DEFAULT_SEPARATOR
*      i_escape         =
*      i_line_separator = CL_ABAP_CHAR_UTILITIES=>NEWLINE
    RECEIVING
      r_r_conv = lo_csv.
  LOOP AT lt_csv_lines INTO lv_csv_data.
    "跳过第一次循环
    AT FIRST.
       CONTINUE.
    ENDAT.
   "将csv转abap数据结构
    CALL METHOD lo_csv->csv_to_structure
      EXPORTING
        i_data   = lv_csv_data
      IMPORTING
        e_s_data = wa_user.
    APPEND wa_user TO it_user.
    WRITE: / wa_user-id, wa_user-name, wa_user-age, wa_user-address.
    CLEAR wa_user.
  ENDLOOP.

ENDFORM.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章