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