{"id":13698747,"url":"https://github.com/zenrosadira/abap-tbox-csvman","last_synced_at":"2025-07-14T00:38:03.561Z","repository":{"id":171885002,"uuid":"607577018","full_name":"zenrosadira/abap-tbox-csvman","owner":"zenrosadira","description":"ABAP CSV Manager - An easy-to-use and highly configurable tool to read and create CSV in ABAP","archived":false,"fork":false,"pushed_at":"2023-06-12T12:40:55.000Z","size":305,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"cloud-main","last_synced_at":"2025-04-06T21:51:45.296Z","etag":null,"topics":["abap","abap-development","abap-oo","sap"],"latest_commit_sha":null,"homepage":"","language":"ABAP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zenrosadira.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-02-28T08:55:04.000Z","updated_at":"2025-02-22T09:09:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"a6332ec6-4107-48b9-bc79-33e19ba34aba","html_url":"https://github.com/zenrosadira/abap-tbox-csvman","commit_stats":null,"previous_names":["zenrosadira/abap-tbox-csvman"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/zenrosadira/abap-tbox-csvman","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zenrosadira%2Fabap-tbox-csvman","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zenrosadira%2Fabap-tbox-csvman/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zenrosadira%2Fabap-tbox-csvman/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zenrosadira%2Fabap-tbox-csvman/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zenrosadira","download_url":"https://codeload.github.com/zenrosadira/abap-tbox-csvman/tar.gz/refs/heads/cloud-main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zenrosadira%2Fabap-tbox-csvman/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265228153,"owners_count":23731067,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["abap","abap-development","abap-oo","sap"],"created_at":"2024-08-02T19:00:52.480Z","updated_at":"2025-07-14T00:38:03.537Z","avatar_url":"https://github.com/zenrosadira.png","language":"ABAP","funding_links":[],"categories":["Categories"],"sub_categories":["📔 Data Formatting"],"readme":"# ABAP CSV Manager\n\n![Example](/docs/img/cover.png)\n\n## Requirement\n:cloud: ABAP for Cloud Development edition\n\nLooking for *On-Premise* edition? Switch to *onprem-main* branch.\n\n## Quick Start\n\n:office_worker: **I need to read a CSV, how can I do it?**\n\n:mage: Create a *reader* instance and call `read` method.\n```abap\nDATA(csv_reader) = zcl_tbox_csvman=\u003eget_reader( ).\ncsv_reader-\u003eread(\n  EXPORTING i_csv   = csv_data\n  IMPORTING e_table = tab_data ).\n```\n\n:office_worker: **I need to create a CSV, how can I do it?**\n\n:mage: Create a *writer* instance and call `write` method.\n```abap\nDATA(csv_writer)  = zcl_tbox_csvman=\u003eget_writer( ).\nDATA(csv_data)    = csv_reader-\u003ewrite( tab_data ).\n\n* csv_data is a string, if you need the output as a string table:\nDATA(csv_data)    = csv_reader-\u003ewrite_to_string_table( tab_data ).\n```\n\n### Some remarks about reading a CSV\n\nWhen you call the `read` method of a *reader* instance,\n`csv_data` can be:\n  - a string\n  - a table of strings\n  - a table with one-component table line\n \n`tab_data` must be a *flat* table: a table whose table line is a structure, whose components are simple elements.\n\nSometimes 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:\n\n  - you can get a reference variable to a table whose fields (of type string) are named F1, F2, ..., FN and so on; \n```abap\nDATA(csv_ref) = csv_reader-\u003eread_with_reference( csv_data ).\n\nFIELD-SYMBOLS \u003ctab\u003e TYPE STANDARD TABLE.\nASSIGN csv_ref-\u003e* TO \u003ctab\u003e.\n\nLOOP AT \u003ctab\u003e ASSIGNING FIELD-SYMBOL(\u003crow\u003e).\nDATA(row_index) = sy-tabix.\n  DO.\n    ASSIGN COMPONENT sy-index OF STRUCTURE \u003crow\u003e TO FIELD-SYMBOL(\u003cval\u003e). \n    IF sy-subrc \u003c\u003e 0.\n      EXIT.\n    ENDIF.\n    DATA(info) = |The value at row { row_index } and column { sy-index } is { \u003cval\u003e }| ).\n  ENDDO.\nENDLOOP.\n\n* You can always get a statically typed table using dereference method\ncsv_reader-\u003edereference( EXPORTING i_reference = csv_ref IMPORTING e_table = safe_data ).\n```\n\n  - 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.\n\n```abap\nDATA(csv_tab_t) = csv_reader-\u003eread_with_transposition( csv_data ).\n\nLOOP AT csv_tab_t INTO DATA(csv_row).\n  LOOP AT csv_row-row INTO DATA(row_values).\n    \n    DATA(info) = |The value at row { csv_row-row_index } and column { row_values-column_index } is { row_values-value }| ).\n    \n  ENDLOOP.\nENDLOOP.\n\n* You can always get a standard table, if you have a suitable variable, using detranspose method\ncsv_reader-\u003edetranspose( EXPORTING i_transposed = csv_tab_t IMPORTING e_table = safe_data ).\n```\n\n## General Configuration\n:office_worker: **Can I decide which character to use as delimiter, quotechar, and line terminator? And what about escaping special characters?**\n\n:mage: Once instantiated you can configure the csv management object:\n- ``csv_man-\u003edelimiter( `;` ).``  *fields delimiter, default is semicolon:* `;`*. Here \"delimiter\" is a synonym of \"separator\".*\n- ``csv_man-\u003equotechar( `\"` ).``  *to quote fields, default is none.\n- ``csv_man-\u003eend_of_line( `|` ).`` *line-terminator char, default is Carriage Return and Line Feed* `%_CR_LF` *.*\n- ``csv_man-\u003eescapechar( `/` ).`` *to escape special characters, both in read and write mode.*\n- ``csv_man-\u003edoublequote( ).`` *to escape a quotechar character with a quotechar character.*\n- `csv_man-\u003equoting( ztbox_cl_csvman=\u003ec_quote_minimal ).` *to restrict quoting application, with these options:*\n  - `zcl_tbox_csv_writer=\u003ec_quote_all` *to apply quotechar character to all fields (this is default behaviour if a quotechar is set);*\n  - `zcl_tbox_csv_writer=\u003ec_quote_minimal` *to apply quotechar character only to fields containing special characters;*\n  - `zcl_tbox_csv_writer=\u003ec_quote_nonnumeric` *to apply quotechar character only to non-numeric fields;*\n  - `zcl_tbox_csv_writer=\u003ec_quote_none` *to never quote fields (this is the default behaviour if no quotechar is set).*\n- `csv_man-\u003eheader( ).` *to write/expect an header line in write/read mode. Default is* `abap_true` *.*\n- `csv_man-\u003eheader_desc( ).` *to use field name as header text field. You can column text by calling* `-\u003elabel( )` *method on fields level, see below for details.*\n\n## Output Format\n:office_worker: **Nice, but I want also control fields output format, especially for date/time/numeric fields.**\n\n:mage: Sure, you can use these configurations:\n- ``csv_man-\u003edate_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`.\n- ``csv_man-\u003etime_format( `hh:mm:ss` ).`` *same as above, but for time fields. Default is* `hh:mm:ss`.\n- `csv_man-\u003enumber_format( ).` *three options here:*\n  - ` ` *(blank) to output numbers like* `1.234.567,89`\n  - `X` *to output numbers like* `1,234,567.89`\n  - `Y` *to output numbers like* `1 234 567,89`\n- ``csv_man-\u003ecountry( `US` ).`` *to output date, time and numbers according to a country rules (less specific than previous methods).*\n- `csv_man-\u003edecimals( 3 ).` *to write numerical fields with the specified decimals precision.*\n- `csv_man-\u003econdense_values( ).` *to remove leading and trailing spaces. Default is* `abap_false`.\n- `csv_man-\u003ekeep_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`.\n- `csv_man-\u003ealignment( cl_abap_format=\u003ea_right ).` *to align fields content according to the following options:*\n  - `cl_abap_format=\u003ea_left` *to justify text on the left (default option);*\n  - `cl_abap_format=\u003ea_right` *to justify text on the right.*\n\n## Fields Properties\n:office_worker: **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?**\n\n:mage: You can restrict the application of the previous methods to a single field by calling `field( )` method first, also chaining other methods, e.g.:\n\n```abap\ncsv_man-\u003efield( `AMOUNT_USD` )-\u003enumber_format( `X` ).\ncsv_man-\u003efield( `AMOUNT_EUR` )-\u003ecountry( `IT` )-\u003edecimals( 2 ).\n```\nYou can also exclude some fields from the CSV generation/reading process using `exclude( )` method:\n\n```abap\ncsv_man-\u003efield( `MANDT` )-\u003eexclude( ).\n```\n\nViceversa, 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.\n\n```abap\ncsv_man-\u003efield( `MATNR` )-\u003einclude( ).\ncsv_man-\u003efield( `WERKS` )-\u003einclude( ).\n```\n\nIf 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:\n\n```abap\ncsv_man-\u003eheader_desc( abap_true ).\ncsv_man-\u003efield( `MATNR` )-\u003eposition( 2 )-\u003elabel( `Material!!!` ).\ncsv_man-\u003efield( `WERKS` )-\u003eposition( 1 )-\u003elabel( `THE Plant` ).\n```\nIn this way, the following table:\n| MATNR  | WERKS |\n| ------- | ------ |\n| AAAA01  | US01  |\n| BBBB02  | US02  |\n\ngives this CSV as output:\n```csv\nTHE Plant,Material!!!\nUS01,AAAA01\nUS02,BBBB02\n```\n\n`label( )` method set a custom header text when `header_desc( )` is used.\n\n## Validations\n:office_worker: **Regarding reading the csv, is there an automatism to help identify errors in the data?**\n\n:mage: 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( )`.\n\nSuppose you read this CSV:\n\n```csv\n31/02/2023,10:45:19,\"1900,20\"\n28/02/2023,25:00:00,\"-894,23\"\n31/12/2022,00:00:01,\"12A4,43\"\n```\n\ninto a table with structure `DATE [D(8)] | TIME [T(6)] | AMOUNT [P(7) DEC(2)]`. The output will be\n| DATE  | TIME | AMOUNT |\n| ------- | ------ | ------ |\n| 00000000 | 104519 | 1900.20 |\n| 20230228 | 000000 | -894.00 |\n| 20221231 | 000001 | 0.00 |\n\nAnd the `get_validation_fails( )` output is this table:\n| ROW  | COL | TABLE_FIELD | CSV_VALUE | SAP_VALUE | CHECK_FAILED |\n| ------- | ------- | ------- | ------- | ------- | ------- |\n| 1 | 1 | DATE | 31/02/2023 | 20230231 | DATE_PLAUSIBILITY |\n| 2 | 2 | TIME | 25:00:00 | 250000 | TIME_PLAUSIBILITY |\n| 3 | 3 | AMOUNT | 12A4,43 | 12A4.43 | VALID_NUMB |\n\nYou can add also custom validation checks: it must be an instance method with the following signature\n\n```abap\nMETHODS sample_check IMPORTING i_value TYPE string RETURNING VALUE(r_fail) TYPE flag.\n```\nIf, e.g., an object `sample_object` implements method `sample_check`, you can add this check to a field:\n\n```abap\ncsv_man-\u003efield( `FIELD_NAME` )-\u003eadd_post_validation(\n  check_object  = sample_object\n  check_method  = `SAMPLE_CHECK` ).\n```\n\nin two ways: as a *pre validation* by calling method `add_pre_validation( )`, and as a *post validation* by calling method `add_post_validation( )`.\n- Pre-validation checks are applied to raw data: parameter `value` is a string containing exactly the content of the field in the CSV;\n- 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.\n\n`fail = abap_true` means the check has not been passed.\n\n## Installation\nInstall this project using [abapGit](https://abapgit.org/) ![abapGit](https://docs.abapgit.org/img/favicon.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzenrosadira%2Fabap-tbox-csvman","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzenrosadira%2Fabap-tbox-csvman","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzenrosadira%2Fabap-tbox-csvman/lists"}