PackagePackagetypeA library you install and call yourself.See every one →What this type is →independently maintainedindependently maintainedoriginPublished by one person or a small company outside SAP. Says nothing about quality; the readings say that.See every one →

ABAP CSV Manager

A configurable CSV reader and writer for ABAP, with per-field format, validation and column-mapping options, reading into a flat or a dynamically typed internal table.

Reading a CSV into ABAP normally means fixing a target structure up front; a reader here turns CSV data into a flat internal table with read, or into a dynamically typed table with read_with_reference when the columns are not known beforehand, and a writer turns a table back into a CSV string. Delimiter, quote character, line terminator, escape character and quoting mode are configurable, along with per-country date, time and number formats, and individual fields can be included, excluded, reordered or given a custom header label. Reading also validates each field against its target type, for example flagging an implausible date such as 31 February, and collects the failures for get_validations_fails() instead of silently discarding them; custom validation methods can be registered per field, run before or after the value is converted.

Facts

Last pushLicenceMIT

Where it sits

Lives in
Provides
SerialisationABAPSerialisationcapabilityTurning typed in-memory data into a text or binary format such as JSON, CSV or protobuf and reading it back, including the mapping of names and types the language does not do for you. The protocol that carries the payload is a separate concern: an HTTP or OData client moves the bytes, and serialisation decides what they say.

Who is behind it

Marco MarroneMarco MarronePersonMaintains this
In the atlas: maintains 2, contributes to 2
@zenrosadira
maintainer

What it declares

Every artifact

Type
Package
Origin
Independently maintained

As a package

Where it runs
does not say
Distributed through
abapGit

Connections1

README

quoted from zenrosadira/abap-tbox-csvman under MIT, read
zenrosadira/abap-tbox-csvman/README.mdOn GitHub

ABAP CSV Manager

Example

Requirement

☁️ ABAP for Cloud Development edition

Looking for On-Premise edition? Switch to onprem-main branch.

Quick Start

🧑‍💼 I need to read a CSV, how can I do it?

🧙 Create a reader instance and call read method.

DATA(csv_reader) = zcl_tbox_csvman=>get_reader( ).
csv_reader->read(
  EXPORTING i_csv   = csv_data
  IMPORTING e_table = tab_data ).

🧑‍💼 I need to create a CSV, how can I do it?

🧙 Create a writer instance and call write method.

DATA(csv_writer)  = zcl_tbox_csvman=>get_writer( ).
DATA(csv_data)    = csv_reader->write( tab_data ).

* csv_data is a string, if you need the output as a string table:
DATA(csv_data)    = csv_reader->write_to_string_table( tab_data ).
Some remarks about reading a CSV

When you call the read method of a reader instance, csv_data can be:

  • a string
  • a table of strings
  • a table with one-component table line

tab_data must be a flat table: a table whose table line is a structure, whose components are simple elements.

Sometimes you need to read a CSV but you don't know a priori how many and which columns it contains. In these cases you still have two ways to read it:

  • you can get a reference variable to a table whose fields (of type string) are named F1, F2, ..., FN and so on;
DATA(csv_ref) = csv_reader->read_with_reference( csv_data ).

FIELD-SYMBOLS <tab> TYPE STANDARD TABLE.
ASSIGN csv_ref->* TO <tab>.

LOOP AT <tab> ASSIGNING FIELD-SYMBOL(<row>).
DATA(row_index) = sy-tabix.
  DO.
    ASSIGN COMPONENT sy-index OF STRUCTURE <row> TO FIELD-SYMBOL(<val>). 
    IF sy-subrc <> 0.
      EXIT.
    ENDIF.
    DATA(info) = |The value at row { row_index } and column { sy-index } is { <val> }| ).
  ENDDO.
ENDLOOP.

* You can always get a statically typed table using dereference method
csv_reader->dereference( EXPORTING i_reference = csv_ref IMPORTING e_table = safe_data ).
  • or you can get a transposed version of the CSV, that is, a table with two fields: the row index and a table containing the list of its values, for each column.
DATA(csv_tab_t) = csv_reader->read_with_transposition( csv_data ).

LOOP AT csv_tab_t INTO DATA(csv_row).
  LOOP AT csv_row-row INTO DATA(row_values).
    
    DATA(info) = |The value at row { csv_row-row_index } and column { row_values-column_index } is { row_values-value }| ).
    
  ENDLOOP.
ENDLOOP.

* You can always get a standard table, if you have a suitable variable, using detranspose method
csv_reader->detranspose( EXPORTING i_transposed = csv_tab_t IMPORTING e_table = safe_data ).

General Configuration

🧑‍💼 Can I decide which character to use as delimiter, quotechar, and line terminator? And what about escaping special characters?

🧙 Once instantiated you can configure the csv management object:

  • csv_man->delimiter( `;` ). fields delimiter, default is semicolon: ;. Here "delimiter" is a synonym of "separator".
  • csv_man->quotechar( `"` ). *to quote fields, default is none.
  • csv_man->end_of_line( `|` ). line-terminator char, default is Carriage Return and Line Feed %_CR_LF .
  • csv_man->escapechar( `/` ). to escape special characters, both in read and write mode.
  • csv_man->doublequote( ). to escape a quotechar character with a quotechar character.
  • csv_man->quoting( ztbox_cl_csvman=>c_quote_minimal ). to restrict quoting application, with these options:
    • zcl_tbox_csv_writer=>c_quote_all to apply quotechar character to all fields (this is default behaviour if a quotechar is set);
    • zcl_tbox_csv_writer=>c_quote_minimal to apply quotechar character only to fields containing special characters;
    • zcl_tbox_csv_writer=>c_quote_nonnumeric to apply quotechar character only to non-numeric fields;
    • zcl_tbox_csv_writer=>c_quote_none to never quote fields (this is the default behaviour if no quotechar is set).
  • csv_man->header( ). to write/expect an header line in write/read mode. Default is abap_true .
  • csv_man->header_desc( ). to use field name as header text field. You can column text by calling ->label( ) method on fields level, see below for details.

Output Format

🧑‍💼 Nice, but I want also control fields output format, especially for date/time/numeric fields.

🧙 Sure, you can use these configurations:

  • csv_man->date_format( `yyyy/dd/mm` ). to decide output format for date fields in write mode, or to declare expected format for date fields in read mode. You can use any format containing "dd", "mm", "yy", "yyyy" and an optional separator. Default is dd.mm.yyyy.
  • csv_man->time_format( `hh:mm:ss` ). same as above, but for time fields. Default is hh:mm:ss.
  • csv_man->number_format( ). three options here:
    • (blank) to output numbers like 1.234.567,89
    • X to output numbers like 1,234,567.89
    • Y to output numbers like 1 234 567,89
  • csv_man->country( `US` ). to output date, time and numbers according to a country rules (less specific than previous methods).
  • csv_man->decimals( 3 ). to write numerical fields with the specified decimals precision.
  • csv_man->condense_values( ). to remove leading and trailing spaces. Default is abap_false.
  • csv_man->keep_init( ). to maintain initial values: if set to abap_false a numerical field containing only 0, as well as an initial date or initial time, became blank in write mode. Default is abap_true.
  • csv_man->alignment( cl_abap_format=>a_right ). to align fields content according to the following options:
    • cl_abap_format=>a_left to justify text on the left (default option);
    • cl_abap_format=>a_right to justify text on the right.

Fields Properties

🧑‍💼 Ok cool. These are global configuration, valid for all the fields, aren't they? What if I want to set some format property to one field and a different property to another?

🧙 You can restrict the application of the previous methods to a single field by calling field( ) method first, also chaining other methods, e.g.:

csv_man->field( `AMOUNT_USD` )->number_format( `X` ).
csv_man->field( `AMOUNT_EUR` )->country( `IT` )->decimals( 2 ).

You can also exclude some fields from the CSV generation/reading process using exclude( ) method:

csv_man->field( `MANDT` )->exclude( ).

Viceversa, if you work with a table having too many fields, you can generate or reading a CSV considering only a small subset of fields using include( ) method. Once you have called include for a field, only fields for which include has been called will be considered.

csv_man->field( `MATNR` )->include( ).
csv_man->field( `WERKS` )->include( ).

If the order of the fields in the table does not match the columns in the CSV to generate or read, you can map each field with the corresponding csv-column position:

csv_man->header_desc( abap_true ).
csv_man->field( `MATNR` )->position( 2 )->label( `Material!!!` ).
csv_man->field( `WERKS` )->position( 1 )->label( `THE Plant` ).

In this way, the following table:

MATNRWERKS
AAAA01US01
BBBB02US02

gives this CSV as output:

THE Plant,Material!!!
US01,AAAA01
US02,BBBB02

label( ) method set a custom header text when header_desc( ) is used.

Validations

🧑‍💼 Regarding reading the csv, is there an automatism to help identify errors in the data?

🧙 We have it. When a CSV is read, some validation checks are performed according to the data type of the target fields: date fields (if not blank) must be a valid and plausible date; time fields (if not blank) must contain a valid and plausible time, numerical fields (if not blank) must contain a valid number. Whenever any of these check fail, the contents are not transferred. You get a detailed report for the validation fails by calling get_validations_fails( ).

Suppose you read this CSV:

31/02/2023,10:45:19,"1900,20"
28/02/2023,25:00:00,"-894,23"
31/12/2022,00:00:01,"12A4,43"

into a table with structure DATE [D(8)] | TIME [T(6)] | AMOUNT [P(7) DEC(2)]. The output will be

DATETIMEAMOUNT
000000001045191900.20
20230228000000-894.00
202212310000010.00

And the get_validation_fails( ) output is this table:

ROWCOLTABLE_FIELDCSV_VALUESAP_VALUECHECK_FAILED
11DATE31/02/202320230231DATE_PLAUSIBILITY
22TIME25:00:00250000TIME_PLAUSIBILITY
33AMOUNT12A4,4312A4.43VALID_NUMB

You can add also custom validation checks: it must be an instance method with the following signature

METHODS sample_check IMPORTING i_value TYPE string RETURNING VALUE(r_fail) TYPE flag.

If, e.g., an object sample_object implements method sample_check, you can add this check to a field:

csv_man->field( `FIELD_NAME` )->add_post_validation(
  check_object  = sample_object
  check_method  = `SAMPLE_CHECK` ).

in two ways: as a pre validation by calling method add_pre_validation( ), and as a post validation by calling method add_post_validation( ).

  • Pre-validation checks are applied to raw data: parameter value is a string containing exactly the content of the field in the CSV;
  • Post-validation checks are applied to transformed data: parameter value is a string containing the field value interally formatted for the SAP data type field target, according to the format options configured.

fail = abap_true means the check has not been passed.

Installation

Install this project using abapGit abapGit

MIT, read

History

Latest

v1.0-cloud

Other 3

Notes

ABAP CSV Manager compatibile with ABAP for Cloud Development.

  • Code refactored and simplified
  • Totally Cloud-Ready
  • There is no longer automatic application of conversion exits: I can't find released API in Cloud Development that can do this job, suggestions are welcome
Serialisation
  1. ABAP JSON APIJSON renderer and parser for ABAP with camelCase conversionfrom ABAP
  2. zcl_mdp_jsonABAP library generating and parsing JSON stringsfrom ABAP
  3. JSON2ABAPTypeGenerator of ABAP type definitions from JSON structuresfrom ABAP
  4. abap-protobufProtocol Buffers (proto2) implementation in ABAPfrom ABAP
  5. ZASISRegex RuleSets that read barcode strings into named fieldsfrom ABAP
  6. ABAP ArchitectEclipse plug-in turning JSON or XML into ABAP types and DDIC objectsfrom ABAP
  7. ABAP to JSON serializer and deserializerOpen-source Z* version of /UI2/CL_JSON for ABAP to JSONfrom ABAP
  8. ajsonJSON parser and serialiser for ABAP with a node treefrom ABAP
  9. sbcgua/text2tabParser of TAB-delimited text into ABAP internal tables and backfrom ABAP
  10. ABAP JSON Encoder/DecoderJSON encoder and decoder for ABAP, modelled on Go's encoding/jsonfrom ABAP
  11. ZwdCSVRFC 4180 CSV parser and generator for ABAPfrom ABAP

Details

Sources3
Added by handdiscovered herechecked
github.com/zenrosadira/abap-tbox-csvmantree, pushes, contributors, CIchecked
README.mdquoted, and what the entry declareschecked

Sources are graph entities: the same page may back several entries, and an unreachable source flags every row that rests on it.

Compatibility and provenance
discovered viaAdded by hand
first seen in the atlas
ecosystem and domainabap, protocols-and-apis
abaplint
issues under its own abaplint configuration24
lines2,696
statements1,691
objects8
files16
analysed, cloud-main
abaplint version2.120.84
Flavors2
ABAP Cloud
“ABAP for Cloud Development edition” — zenrosadira/abap-tbox-csvman — READMEchecked
Standard ABAP
“Looking for *On-Premise* edition? Switch to *onprem-main* branch.” — zenrosadira/abap-tbox-csvman — READMEchecked
History in the atlas1
  1. First seen.
For your agent
Ref
artifact:zenrosadira-abap-tbox-csvman
JSON
/artifacts/zenrosadira-abap-tbox-csvman.json
MCP
Connecting an agent