Understanding CSV files and their handling in ABAP

Understanding CSV files and their handling in ABAP

112749,017

In many ABAP developments, we use CSV files and sometimes there is confusion regarding CSV itself. Is it just a text file with values separated by commas ?

Let’s look at semantics of the various components involved so we have a vocabulary to work with.

Separator: Demarcates between two fields – so it will be a comma ‘,’ for CSVs.

Delimiter: It signifies limits of things, where it begins and ends. e.g. “Test String” has two delimiters, both double quote characters. Many CSVs can have double quotes as delimiters when comma values are to be placed as text.

Terminator : Indicates end of sequence. For CSV, we can think of newline as the terminator.

So if we have confusion about whether commas or double quotes are allowed inside data, looking at the CSV specification:

The de facto standard for CSV is here in case you want to read the full standard.

http://tools.ietf.org/html/rfc4180

Definition of the CSV Format ( points 1 – 7 are from CSV standard )

1.  Each record is located on a separate line, delimited by a line break.

2. The last record in the file may or may not have an ending line break.

3.  There maybe an optional header line appearing as the first line of the file with the same format as normal record lines.

4.  Within the header and each record, there may be one or more fields, separated by commas.  Each line should contain the same

number of fields throughout the file.  Spaces are considered part of a field and should not be ignored.  The last field in the

record must not be followed by a comma.

5.  Each field may or may not be enclosed in double quotes (however some programs, such as Microsoft Excel, do not use double quotes

at all).  If fields are not enclosed with double quotes, then double quotes may not appear inside the fields.

6.  Fields containing line breaks (CRLF), double quotes, and commas should be enclosed in double-quotes.

7. If double-quotes are used to enclose fields, then a double-quote appearing inside a field must be escaped by preceding it with

another double quote.

In my experience, point 7 is where we get tripped the most. CSV stands as comma separated values leading to the impression that commas are the separator and given that excel doesn’t put commas, it can start to get confusing.

So looking at some examples

Basic Example:

10, Vikas , Sydney

Data with separator / delimiter inside them.

“11”, “Vikas”, “Sydney, AU”      <– Data containing comma

“12”, “Vikas”, “Sydney, “NSW” AU”   <– Data containing comma and quotes in data

Handling in ABAP:

I’m focusing on reading the files as that’s where we face issues. The file can be uploaded from user’s desktop or read from the application server.

1)  Write your own code:

This can be easiest to start with but can start to get complicated with time.

Get data as a string, split at comma.

split lv_data at ‘,’ into lw_struct-test1 lw_struct-test2 lw_struct-test3.

Drawbacks:

a) This won’t work if we have data with separator, terminator or delimiter ( so no commas, double-quotes or newline within data ).

b)  The code will need to be updated if the file format changes – say we need to add another field test4. The code then changes to :

split lv_data at ‘,’ into lw_struct-test1 lw_struct-test2 lw_struct-test3 lw_struct-test4.

2) Read the file using KCD_CSV_FILE_TO_INTERN_CONVERT

CALL FUNCTION ‘KCD_CSV_FILE_TO_INTERN_CONVERT’

EXPORTING

i_filename      = ‘C:\Temp\Upload.csv’

i_separator     = ‘,’

TABLES

e_intern        = gt_intern

EXCEPTIONS

upload_csv      = 1

upload_filetype = 2.

Drawbacks

a) The file can be read only from presentation server/ desktop.

b) If a CSV file exists with double quotes, the last field is left with double quotes.

c) In case the file is to be read from application server, we need to read the code inside this FM and write some custom logic.

3) Use RTTI and dynamic programming along with FM RSDS_CONVERT_CSV .

It works but has lots of code . You can have a look at the code in this GIST.

CSV_Upload_long_process

In summary the steps are :

– Get structre of destination table using RTTI

– Create field catalog

– Create a dynamic table for field catalog values

– Create dynamic table lines

– Process Raw CSV data

– Store CSV files into dynamic table

Drawback:

a) Relatively long code leading to results especially if you have to program it from scratch.

Advantage:

a) Code is free from the target table format. If a new field is to be added, just update the structure for table type z_data_tty

4) Use class CL_RSDA_CSV_CONVERTER .

So the call becomes very straight forward – Instantiate the class with the separator and delimiter values. For a normal CSV, leave them as default .

* Instantiate the CSV object

call method cl_rsda_csv_converter=>create

*  EXPORTING

*    i_delimiter = C_DEFAULT_DELIMITER

*    i_separator = C_DEFAULT_SEPARATOR

receiving

r_r_conv    = lo_csv

* Process records

loop at lt_upload_data into lv_data.

CALL METHOD lo_csv->csv_to_structure

EXPORTING

i_data   = lv_data

IMPORTING

e_s_data = lw_struct.

That’s It !

Advantages:

a) The code is very small – less chances of us making an error compared to the one in 3) above.

b) The code is decoupled with file structure – we get to keep the benefit from the above point .

c) It can be used for both application server / presentation server files – of course file reading will need to be done before the call.

d) The developer has documented the examples exhaustively in method CSV_TO_STRUCTURE . Big thank to him/her !

e) It’s part of package RSDA which is present in ABAP trial environments as well such as NSP .

If you feel lazy to type the full program, here is the whole source code:

CSV_Reading_option_4

Former Member

September 10, 2014 at 3:45 pm

Thanks for sharing.

For converting CSV to internal table I often use TEXT_CONVERT_CSV_TO_SAP which is also pretty straight forward (raw data in, structured data out).

Regards

Jan

Like 0

Share

Vikas Singh

Blog Post Author

September 10, 2014 at 11:57 pm

Jan - I tried using TEXT_CONVERT_CSV_TO_SAP but it doesn't seem to work .

Look at this GIST:

https://gist.github.com/viksingh/2d0a685e0a1306240aee

Like 0

Share

Former Member

September 12, 2014 at 10:51 am

For me it works. Maybe Your CSV file has a header line? In that case you need to set i_line_header  = 'X'.

Like 0

Share

Eng Swee Yeoh

October 20, 2014 at 3:00 am

Hi Vikas

Nice blog detailing the comparison between different approaches to reading CSV files in ABAP.

I just completed a requirement using option 3, but will definitely try out option 4 next time I have a similar requirement.

However, my approach to option 3 was not as lengthy. There was no need to create field catalogs and dynamic table. I just created a data reference LIKE LINE of the output table. Below are snippets of my code.

Rgds

Eng Swee

Like 0

Share

Bruno Esperança

December 28, 2014 at 12:35 pm

Hi Eng,

What happens if your output table has a date field or an amount field? Are the values converted automatically?

Thanks,

Bruno

Like 1

Share

Eng Swee Yeoh

January 2, 2015 at 10:10 pm

Hi Bruno

If I remember correctly, it did handle date and amount fields correctly. Unfortunately, I've moved to a different project and no longer have access to that system to verify.

I do think it is handled automatically by the ABAP engine in line 54 of my screenshot above.

ABAP automatically performs type conversion when the assigning values from one field to another. So, line_content (which is CLIKE) will go through conversion to whatever the current type for <ddic_column> is, i.e. date type, amount type.

Do give it a try and let me know how it goes.

Rgds

Eng Swee

Like 0

Share

Matthew Billingham

January 3, 2015 at 6:40 am

1) Parts of this blog as copied from the linked standard for CSV. You must make it clear which parts are being quoted. (Or I'll have to reject the blog, and I actually don't want to do that).

2) While CSV has a standard definition, this is often not followed. For example, from Excel, as CSV file may well be semi-colon (;) separated. You should edit your blog to reflect this. Also, whether it affects any of the solutions you've given.

3) End of line markers may be Line Feed, but may also be Carriage Return, Line Feed. It depends on the source system and the program used to generate the file.

Like 3

Share

Alexey Sadovoy

May 30, 2016 at 8:10 am

Disadvange  (error) of method 4 - if needs structure contain field 'string' typed and CSV containts double quoted text - exception ocurs.

Like 0

Share

Juwin Pallipat Thomas

July 11, 2016 at 7:40 pm

Parsing CSV - this is not a problem just for ABAP language. Hence, rather than just thinking of an ABAP solution, think out of the box. Have a look at this post: http://www.kimgentes.com/worshiptech-web-tools-page/2008/10/14/regex-pattern-for-parsing-csv-files-with-embedded-commas-dou.html

This is the easiest method I have found till now. Just use SPLIT command, with the REGEX from this blog. I have used it several successfully.

Thanks,

Juwin

Like 1

Share

Derek Ren

August 18, 2016 at 4:07 am

it really help with a complete information

Like 0

Share

Loyd Enochs

August 18, 2016 at 12:02 pm

Excellent briefing, Vikas, and thank you for sharing!

Like 0

Share

Pages

…

Wordwrap in reports

Skip to end of banner

Go to start of banner

upload csv files into internal table

Skip to end of metadata

Created by Venkateswara Rao Appikonda on Sep 17, 2013

Go to start of metadata

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'

*--------------------------------------------------*

* report name

*-------------------------------------------------*

REPORT zupload_csv_file.

*--------------------------------------------------*

* data declarations

*-------------------------------------------------*

TYPES: BEGIN OF ttab,

rec(1000) TYPE c,

END OF ttab.

TYPES: BEGIN OF tdat,

fld1(10) TYPE c,

fld2(10) TYPE c,

fld3(10) TYPE c,

END OF tdat.

DATA: itab TYPE TABLE OF ttab WITH HEADER LINE.

DATA: idat TYPE TABLE OF tdat WITH HEADER LINE.

DATA: file_str TYPE string.

*--------------------------------------------------*

* selection screen design

*-------------------------------------------------*

PARAMETERS: p_file TYPE localfile.

*--------------------------------------------------*

* at selection screen for field

*-------------------------------------------------*

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.

CALL FUNCTION 'KD_GET_FILENAME_ON_F4'

EXPORTING

static = 'X'

CHANGING

file_name = p_file.

*--------------------------------------------------*

* start of selection

*-------------------------------------------------*

START-OF-SELECTION.

file_str = p_file.

CALL FUNCTION 'GUI_UPLOAD'

EXPORTING

filename = file_str

TABLES

data_tab = itab

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.

*--------------------------------------------------*

* process and display output

*-------------------------------------------------*

LOOP AT itab.

CLEAR idat.

SPLIT itab-rec AT ',' INTO idat-fld1

idat-fld2

idat-fld3.

APPEND idat.

ENDLOOP.

LOOP AT idat.

WRITE:/ idat-fld1, idat-fld2, idat-fld3.

ENDLOOP.

No labels

1 Comment

Former Member

Dear , if we add one or more field in internal table we are unable to append in itab please suggest

Roshan K

July 4, 2019 3 minute read

Excel Data to Internal table using ALSM_EXCEL_TO_INTERNAL_TABLE(obsolete) without additional code.

5113,626

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

WARNING: This post is intended to Excel upload FM which is now obsolete. Follow this, only if you are working on older systems to maintain the code where you’ve already used ‘ALSM_EXCEL_TO_INTERNAL_TABLE’.

Also this post will help you grasp concept of Field symbols with below application.

*************************************************************************************************************** This blog post will help you avoid extraneous code every time you create Excel upload program by creating a simple Interface and a structure.

For ALSM_EXCEL_TO_INTERNAL_TABLE, explicitly we need to write code to transfer output of this FM into internal table of desired format. For this we have to map column number of FM output with columns of required internal table using

Refer below example.

CALL FUNCTION ‘ALSM_EXCEL_TO_INTERNAL_TABLE’ EXPORTING filename            = p_file i_begin_col        = 1 i_begin_row      = 1 i_end_col          = 9 i_end_row        = 65536 TABLES intern                  = t_file EXCEPTIONS inconsistent_parameters = 1 upload_ole                      = 2 OTHERS                        = 3.

Output is in below format.

Further based on column number, work area is filled using CASE-ENDCASE and then Appending work area into required internal table in AT END OF ROW block.

LOOP

CASE (column)

when 1. wa_itab-col1 = value

when 2. wa_itab-col2 = value.

….and so on depending upon number of columns in Excel

ENDCASE

AT _END OF_ROW

APPEND wa_itab to itab.

END AT

ENDLOOP.

In order to avoid extraneous code when it comes to uploading Excel File with huge number of columns, create a FM with below code. Once you create Z FM, for every Excel File you’ll just need to create a structure in SE11  and you’re good to go.

Pass Desktop File path, Structure name in p_File and STR as input Parameters respectively.

First Create Structure in SE11 similar to the Excel File format.

FUNCTION zxls_into_it_2. *”———————————————————————- *”*”Local interface: *”  IMPORTING *”     REFERENCE(P_FILE) TYPE  RLGRAP-FILENAME *”     REFERENCE(HEADER) TYPE  CHAR1 DEFAULT ‘X’ *”     REFERENCE(STR) TYPE  CHAR30 *”  TABLES *”      IT_XLS_DATA TYPE  STANDARD TABLE *”———————————————————————- TYPE-POOLS: abap,slis. FIELD-SYMBOLS:<dy_table> TYPE STANDARD TABLE, <fs_current_field>, <wa_str>,<wa_temp> . DATA:new_line    TYPE REF TO data, new_line2 TYPE REF TO data, li_fieldcat TYPE lvc_t_fcat, dy_table    TYPE REF TO data, t_file      TYPE STANDARD TABLE OF alsmex_tabline, wa_file     TYPE alsmex_tabline, v_col       TYPE i, begin_row   TYPE i.

********This will provide Fields in Row format of Structure created(which should be similar to Excel Format). CALL FUNCTION ‘LVC_FIELDCATALOG_MERGE’ EXPORTING i_structure_name       = str CHANGING ct_fieldcat                  = li_fieldcat EXCEPTIONS inconsistent_interface = 1 program_error            = 2 OTHERS                    = 3. IF sy–subrc EQ 0.

********This will create internal table which will have fields as per the Excel Format. CALL METHOD cl_alv_table_create=>create_dynamic_table EXPORTING it_fieldcatalog           = li_fieldcat i_length_in_byte          = ‘X’ IMPORTING ep_table                  = dy_table EXCEPTIONS generate_subpool_dir_full = 1 OTHERS                    = 2. IF sy–subrc EQ 0. ASSIGN dy_table->* TO <dy_table>. ENDIF.

******V_col will hold the number of Columns inside Excel File which is later passed to ALSM_EXCEL_TO_INTERNAL_TABLE’ .

DESCRIBE TABLE li_fieldcat LINES v_col.

******Logic to skip Header IF header = ‘X’. begin_row = 2. ELSE. begin_row = 1. ENDIF.

******Core FM which will provide excel data in  t_file with row/coumn/value format

CALL FUNCTION ‘ALSM_EXCEL_TO_INTERNAL_TABLE’ EXPORTING filename              = p_file i_begin_col          = 1 i_begin_row        = begin_row i_end_col            = v_col i_end_row            = 65536 TABLES intern                  = t_file EXCEPTIONS inconsistent_parameters = 1 upload_ole              = 2 OTHERS                  = 3.

IF sy–subrc EQ 0. LOOP AT t_file INTO wa_file.

******This Block will create new area to store column wise data.<wa_temp> acts as a work area which is completely blank at start of new row AT NEW row. CREATE DATA new_line2 LIKE LINE OF <dy_table>. ASSIGN new_line2->* TO <wa_temp>. ENDAT.

*******for every iteration, wa_file-col will have increment till number of columns in Excel file and then reset to 1 when there’s new row i.e row = 1. (Refer example at end of blog)

ASSIGN COMPONENT wa_file–col OF STRUCTURE <wa_temp> TO <fs_current_field>. IF sy–subrc EQ 0.

<fs_current_field> = wa_file–value. UNASSIGN <fs_current_field>. ENDIF.

*****Finally once all Columns are processed and new row is about to start, append the workarea into Internal table

AT END OF row. APPEND <wa_temp> TO it_xls_data. UNASSIGN <fs_current_field>. UNASSIGN <wa_temp>. ENDAT.

ENDLOOP. ENDIF. ENDIF. ENDFUNCTION.

Explanation with example:

Now simply create a structure in SE11, define Internal table of that type in report and call above FM and pass the structure name and file path and its done.

Sandra Rossi

July 4, 2019 at 12:00 pm

There are many drawbacks with ALSM_EXCEL_TO_INTERNAL_TABLE:

First, the limits explained in the SAP note 933420 - ALSM_EXCEL_TO_INTERNAL_TABLE:

It's not released for customers

It's only available in a R/3 or S/4 system (i.e. doesn't work on all other ABAP-based softwares)

The output structure is limited to 9999 rows and columns

The output structure is limited to 50 characters per cell.

Second, the limits because it's based on OLE:

It's very slow (especially because it doesn't use Desktop Office Integration)

It cannot run in background (or any process not connected to a SAP GUI)

Workaround ---> use abap2xlsx (it's been discussed a lot in the forum)

Like 5

Share

Paul Hardy

July 4, 2019 at 12:50 pm

It would not be a normal week on the SAP Community if at least one person did not post a blog with some code they have come up with to do the same thing as ABAP2XLSX.

Like 5

Share

Peter Inotai

July 4, 2019 at 1:12 pm

#YAA2XB

(yet another ABAP to XLS blog)

Like 1

Share

y xg

July 4, 2019 at 3:52 pm

very good , very helpfull for us.

Like 0

Share

春 余

May 19, 2021 at 7:07 am

This is very useful, but in a call in "do while", the task manager will have multiple Excel.exe processes with the number of calls.I tried using "CALL METHOD OF workbook 'CLOSE' " before the "FREE object", but it didn't work. How can I kill the Excel.exe process?

Like 0

Share

返回ABAP参考资料列表