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
該程序執行的結果:
完整代碼如下:
*&---------------------------------------------------------------------*
*& 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.