{"id":14070813,"url":"https://github.com/ws-garcia/VBA-CSV-interface","last_synced_at":"2025-07-30T08:33:18.187Z","repository":{"id":43268706,"uuid":"293627158","full_name":"ws-garcia/VBA-CSV-interface","owner":"ws-garcia","description":"The power you need to cleanse, filter, sort, reshape, manage and analyze data from CSV files.","archived":false,"fork":false,"pushed_at":"2024-07-26T22:46:59.000Z","size":172841,"stargazers_count":63,"open_issues_count":0,"forks_count":7,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-07-26T23:48:43.325Z","etag":null,"topics":["cleansing-data","csv","csv-parser","csv-reader","csv-writer","data-management","filtering","hacktoberfest","queries","sniffer","utf-8","vba"],"latest_commit_sha":null,"homepage":"https://ws-garcia.github.io/VBA-CSV-interface/","language":"VBA","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ws-garcia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/contributing.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2020-09-07T20:34:33.000Z","updated_at":"2024-07-26T22:47:02.000Z","dependencies_parsed_at":"2024-02-24T22:37:06.063Z","dependency_job_id":null,"html_url":"https://github.com/ws-garcia/VBA-CSV-interface","commit_stats":null,"previous_names":[],"tags_count":54,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ws-garcia%2FVBA-CSV-interface","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ws-garcia%2FVBA-CSV-interface/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ws-garcia%2FVBA-CSV-interface/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ws-garcia%2FVBA-CSV-interface/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ws-garcia","download_url":"https://codeload.github.com/ws-garcia/VBA-CSV-interface/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":215155197,"owners_count":15836926,"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":["cleansing-data","csv","csv-parser","csv-reader","csv-writer","data-management","filtering","hacktoberfest","queries","sniffer","utf-8","vba"],"created_at":"2024-08-13T07:08:06.584Z","updated_at":"2025-07-30T08:33:18.162Z","avatar_url":"https://github.com/ws-garcia.png","language":"VBA","funding_links":[],"categories":["VBA"],"sub_categories":[],"readme":"# ![VBA-CSV interface](/docs/assets/img/CSVinterface.png)\n[![GitHub](https://img.shields.io/github/license/ws-garcia/VBA-CSV-interface?style=plastic)](https://github.com/ws-garcia/VBA-CSV-interface/blob/master/LICENSE) [![GitHub release (latest by date)](https://img.shields.io/github/v/release/ws-garcia/VBA-CSV-interface?style=plastic)](https://github.com/ws-garcia/VBA-CSV-interface/releases/latest)\n[![DOI](https://zenodo.org/badge/DOI/10.3233/DS-240062.svg)](https://doi.org/10.3233/DS-240062)\n[![Github All Releases](https://img.shields.io/github/downloads/ws-garcia/VBA-CSV-interface/total.svg)]()\n[![Follow](https://img.shields.io/github/followers/ws-garcia.svg?style=social\u0026label=Follow\u0026maxAge=2592000)](https://github.com/ws-garcia/VBA-CSV-interface/watchers) [![Mentioned in Awesome VBA](https://awesome.re/mentioned-badge.svg)](https://github.com/sancarn/awesome-vba)\n\n## Introductory words\n\nThe most powerful and comprehensive CSV/[TSV](https://www.iana.org/assignments/media-types/text/tab-separated-values)/[DSV](https://www.linuxtopia.org/online_books/programming_books/art_of_unix_programming/ch05s02.html) data management library for VBA, providing parsing/writing capabilities compliant with RFC-4180 specifications and a complete set of tools for manipulating records and fields: [dedupe](https://ws-garcia.github.io/VBA-CSV-interface/api/methods/dedupe.html), [sort](https://ws-garcia.github.io/VBA-CSV-interface/api/methods/sort.html) and [filter](https://ws-garcia.github.io/VBA-CSV-interface/api/methods/filter.html) records; [rearrange](https://ws-garcia.github.io/VBA-CSV-interface/api/methods/rearrangefields.html), [shift](https://ws-garcia.github.io/VBA-CSV-interface/api/methods/shiftfield.html), [merge](https://ws-garcia.github.io/VBA-CSV-interface/api/methods/mergefields.html) and [split](https://ws-garcia.github.io/VBA-CSV-interface/api/methods/splitfield.html) fields. Is your data spread over two or more CSV files? Don't worry, here you will find [Left, Right and Inner](https://ws-garcia.github.io/VBA-CSV-interface/api/methods/tJoin.html) joins, and much more!\n\n## Advantages\n* __RFC-4180 specs compliant__.\n* __Stable__. Fully Test Driven Developed (TDD) library, ([69/69 test passed](https://github.com/ws-garcia/VBA-CSV-interface/blob/master/testing/tests/results/)), that includes 650+ line of code for testing. See [VBA test library by Tim Hall](https://github.com/ws-garcia/vba-test).\n* __Fast__. Writes and reads files at the highest speed.\n* __Memory-friendly__. Files are processed using a custom stream technique, only 0.5MB are in memory at a time.\n* __Robust__. The library is not just a simple parser and writer, it is also a CSV data editor/manager.\n* __[UTF-8](https://www.unicode.org/faq/utf_bom.html#UTF8) encoding support__. Do you have a CSV file, perhaps in chinese or some other foreign cyrillic language, downloaded from the Internet? This library is made to help you deal with it! You will be able to read and write UTF-8 encoded files in an easy way. \n* __Easy to use__. A few lines of code can do the work!\n* __Automatic delimiter sniffer__. Don't worry if you forgot the file configuration. The interface has a state-of-the-art methodology for sniffing delimiters. It is [based on science](https://content.iospress.com/articles/data-science/ds240062)!\n* __Highly Configurable__. User can configure the parser to work with a wide range of CSV files.\n* __CSV data subsetting__. Split CSV data into a set of files with related data.\n* __Like SQL queries on CSV files__. Use complex patterns to mimic SQL queries and filter data by criteria (=, \u003c\u003e, \u003e=, \u003c=, \u0026 (AND), |(OR)).\n* __Flexible__. Import only certain range of records from the given file, import fields (columns) by indexes or names, read records in sequential mode. \n* __Dynamic Typing support__. Turn CSV data field to a desired VBA data type.\n* __Multi-level data sorting__. Sort CSV imported data over multiple columns using the hyper-fast(100k records per second) [Yaroslavskiy Dual-Pivot Quicksort](https://web.archive.org/web/20151002230717/http://iaroslavski.narod.ru/quicksort/DualPivotQuicksort.pdf) like Java and also other methods like: IntroSort, HeapSort and Merge sort.\n* __Microsoft Access compatible__. The library has a version for those who feel in comfort working through DAO databases, [download from here](https://github.com/ws-garcia/VBA-CSV-interface/raw/master/src/Access_version.zip).\n\n## Getting started\n\nIf you don't know how to get started with VBA-CSV Interface class, visit the [documentation repo](https://ws-garcia.github.io/VBA-CSV-interface/) for code hints, basic and more in-depth use of the library.\n\nVisit the [frequently asked questions section](https://ws-garcia.github.io/VBA-CSV-interface/home/FAQ.html) for the most common questions.\n\n### Using the Code\n\nThis section will attempt to analyze all the capabilities of the CSV interface\n\nImport whole CSV file:\n\n```\nSub CSVimport()\n    Dim CSVint As CSVinterface\n\n    Set CSVint = New CSVinterface\n    With CSVint.parseConfig\n        .path = \"C:\\Sample.csv\"                ' Full path to the file, including its extension.\n        .dialect.fieldsDelimiter = \",\"         ' Columns delimiter\n        .dialect.recordsDelimiter = vbCrLf     ' Rows delimiter\n    End With\n    With CSVint\n        .ImportFromCSV .parseConfig             ' Import the CSV to internal object\n    End With\nEnd Sub\n```\n\nNow suppose from the file *\"Sample.csv\"* the user only requires to import a specific range of records. It is possible to write a code like the one shown below:\n\n```\nSub CSVimportRecordsRange()\n    Dim CSVint As CSVinterface\n\n    Set CSVint = New CSVinterface\n    With CSVint.parseConfig\n        .path = \"C:\\Sample.csv\"                ' Full path to the file, including its extension.\n        .dialect.fieldsDelimiter = \",\"         ' Columns delimiter\n        .dialect.recordsDelimiter = vbCrLf     ' Rows delimiter\n        .startingRecord = 10                   ' Start import on the tenth record\n        .endingRecord = 20                     ' End of importation in the 20th record\n    End With\n    With CSVint\n        .ImportFromCSV .parseConfig             ' Import the CSV to internal object\n    End With\nEnd Sub\n```\n\nIf the user wants to sort the imported data, a code like the following can be written:\n\n```\nSub CSVimportAndSort()\n    Dim CSVint As CSVinterface\n\n    Set CSVint = New CSVinterface\n    With CSVint.parseConfig\n        .path = \"C:\\Sample.csv\"               ' Full path to the file, including its extension.\n        .dialect.fieldsDelimiter = \",\"                ' Columns delimiter\n        .dialect.recordsDelimiter = vbCrLf            ' Rows delimiter\n    End With\n    With CSVint\n        .ImportFromCSV .parseConfig           ' Import the CSV to internal object\n        .Sort SortingKeys:=-1                 ' Sort imported data on first column is descending order\n    End With\nEnd Sub\n```\n\nCSV data are mainly treated as text strings, what if the user wants to do some calculations on the data obtained from a given file? In this situation, the user can change the behavior of the parser to work in dynamic typing mode. Here's an example:\n\n```\nSub CSVimportAndTypeData()\n    Dim CSVint As CSVinterface\n\n    Set CSVint = New CSVinterface\n    With CSVint.parseConfig\n        .path = \"C:\\Sample.csv\"                       ' Full path to the file, including its extension.\n        .dialect.fieldsDelimiter = \",\"                ' Columns delimiter\n        .dialect.recordsDelimiter = vbCrLf            ' Rows delimiter\n        .dynamicTyping = True                         ' Enable dynamic typing mode\n        '@---------------------------------------------------------\n        ' Configure dynamic typing\n        .DefineTypingTemplate TypeConversion.ToDate, _\n                                TypeConversion.ToLong, _\n                                TypeConversion.ToDouble\n        .DefineTypingTemplateLinks 6, _\n                                    7, _\n                                    10\n        ' The dynamic typing mode will perform the following:\n        '      * Over column 6 ---\u003e String To Date data Type conversion\n        '      * Over column 7 ---\u003e String To Long data Type conversion\n        '      * Over column 10 ---\u003e String To Double data Type conversion\n    End With\n    With CSVint\n        .ImportFromCSV .parseConfig             ' Import the CSV to internal object\n    End With\nEnd Sub\n```\n\nThe quote character, used for escape fields, can be defined as one of them, according to an enumeration:\n\n```\nSub SetQuoteChar()\n    Dim CSVint As CSVinterface\n\n    Set CSVint = New CSVinterface\n    With CSVint.parseConfig.dialect\n        .quoteToken = QuoteTokens.DoubleQuotes  ' 2 = [\"] (Default)\n        '.quoteToken = QuoteTokens.Apostrophe   ' 1 = [']\n        '.quoteToken = QuoteTokens.Tilde        ' 3 = [~]\n    End With\nEnd Sub\n```\n\nOnce the data is imported and saved to the internal object, the user can access it in the same way as a standard VBA array. An example would be:\n\n```\nSub LoopData(ByRef CSVint As CSVinterface)\n    With CSVint\n        Dim iCounter As Long\n        Dim cRecord() As Variant              ' Records are stored as a one-dimensional array.\n        Dim cField As Variant\n        \n        For iCounter = 0 To CSVint.count - 1\n            cRecord() = .item(iCounter)       ' Retrieves a record\n            cField = .item(iCounter, 1)       ' Retrieves the 2nd field of the current record\n        Next\n    End With\nEnd Sub\n```\n\nIn addition, the user can use the [`CSVArrayList`](https://ws-garcia.github.io/VBA-CSV-interface/api/csvarraylist.html) class to access the contents using code like this:\n\n```\nSub LoopData2(ByRef CSVint As CSVinterface)\n    With CSVint\n        Dim iCounter As Long\n        Dim cRecord() As Variant                    ' Records are stored as a one-dimensional array.\n        Dim cField As Variant\n        \n        For iCounter = 0 To CSVint.count - 1\n            cRecord() = .items.item(iCounter)       ' Retrieves a record\n            cField = .items.item(iCounter)(1)       ' Retrieves the 2nd field of the current record\n        Next\n    End With\nEnd Sub\n```\n\nHowever, it is sometimes disadvantageous to store data in containers other than VBA arrays. This becomes especially noticeable when it is required to write the information stored in Excel's own objects, such as spreadsheets, or VBA user forms, the case of list boxes, which allow to be filled in a single instruction using arrays. Then, the user can copy the information from the internal object using code like this:\n\n```\nSub DumpData(ByRef CSVint As CSVinterface)\n    Dim oArray() As Variant\n    With CSVint\n        .DumpToArray oArray            ' Dump the internal data into a two-dimensional array\n        .DumpToJaggedArray oArray      ' Dump the internal data into a jagged array\n        oArray = .items.items          ' Dump the internal data into a jagged array\n        .DumpToSheet                   ' Dump the internal data into a new sheet\n                                       ' using ThisWorkbook\n        '@-------------------------------------------------------------------\n        ' *NOTE: ONLY AVAILABLE FOR THE ACCESS VERSION OF THE CSV INTERFACE\n        ' Dump the internal data into the Table1 in oAccessDB database.\n        ' The method would create indexes in the 2nd and 3th fields.\n        .DumpToAccessTable oAccessDB, _\n                           \"Table1\", _\n                            2, 3\n    End With\nEnd Sub\n```\n\nSo far, in the examples addressed, the user has been allowed to choose between two actions:\n\n\u003col\u003e\n\t\u003cli\u003eImport \u003cem\u003eALL records\u003c/em\u003e contained in a CSV file.\u003c/li\u003e\n\t\u003cli\u003eImport a \u003cem\u003erecordset\u003c/em\u003e, starting at record X and ending at record Y.\u003c/li\u003e\n\u003c/ol\u003e\n\nIn both options, the user is forced to import all fields (columns) present in the file. Most CSV file parsers only offer the first option, but what if the user wants to save only the information that is relevant for a particular purpose, and what if user wants to store in memory only the records that meet a certain set of requirements?\n\nAn user may need to import 2 of X columns from a CSV file, in this case, the user can use something like:\n\n```\nSub CSVimportDesiredColumns()\n    Dim CSVint As CSVinterface\n\n    Set CSVint = New CSVinterface\n    With CSVint.parseConfig\n        .path = \"C:\\Sample.csv\"              ' Full path to the file, including its extension.\n        .dialect.fieldsDelimiter = \",\"       ' Columns delimiter\n        .dialect.recordsDelimiter = vbCrLf   ' Rows delimiter\n    End With\n    With CSVint\n        .ImportFromCSV .parseConfig, _\n                        1, \"Revenue\"         ' Import 1st and \"Revenue\" fields ONLY\n    End With\nEnd Sub\n```\n\nSo, OK, let's imagine now that an user wants to apply some logic before saving the data, in which case they can step through the records in the CSV file one by one, using the sequential reader, as shown in the following example:\n\n```\nSub CSVsequentialImport()\n    Dim CSVint As CSVinterface\n    Dim csvRecord As CSVArrayList\n    \n    Set CSVint = New CSVinterface\n    With CSVint.parseConfig\n        .path = \"C:\\Sample.csv\"             ' Full path to the file, including its extension.\n        .dialect.fieldsDelimiter = \",\"      ' Columns delimiter\n        .dialect.recordsDelimiter = vbCrLf  ' Rows delimiter\n    End With\n    With CSVint\n        .OpenSeqReader .parseConfig, _\n                        1, \"Revenue\"        ' Import the 1st and \"Revenue\" fields using\n                                            ' seq. reader\n        Do\n            Set csvRecord = .GetRecord\n            '//////////////////////////////////////////////\n            'Implement your logic here\n            '//////////////////////////////////////////////\n        Loop While Not csvRecord Is Nothing   ' Loop until the end of the file is reached\n    End With\nEnd Sub\n```\n\nIs there a way to sequentially fetch a set of records at a time instead of a single record? Currently, there is no built-in method to do that with a single instruction, as in the examples above, but with a few extra lines of code and the tools provided by the library, it is possible to achieve that goal. This is illustrated in the following example where the CSV file is streamed:\n\n```\nSub CSVimportChunks()\n    Dim CSVint As CSVinterface\n    Dim StreamReader As CSVTextStream\n            \n    Set CSVint = New CSVinterface\n    With CSVint.parseConfig\n        .dialect.fieldsDelimiter = \",\"                      ' Columns delimiter\n        .dialect.recordsDelimiter = vbCrLf                  ' Rows delimiter\n    End With\n    Set StreamReader = New CSVTextStream\n    With StreamReader\n        .endStreamOnLineBreak = True                        ' Instruct to find line breaks\n        .OpenStream \"C:\\Sample.csv\"                         ' Connect to CSV file\n        Do\n            .ReadText                                       ' Read a CSV chunk\n            CSVint.ImportFromCSVString .bufferString, _\n                                    CSVint.parseConfig, _\n                                    1, \"Revenue\"            ' Import a set of records\n            '//////////////////////////////////////\n            'Implement your logic here\n            '//////////////////////////////////////\n        Loop While Not .atEndOfStream                       ' Continue until reach\n                                                            ' the end of the CSV file.\n    End With\n    Set CSVint = Nothing\n    Set StreamReader = Nothing\nEnd Sub\n```\n\nSo far, it has been outlined the way in which you can import the records from a CSV file sequentially, the following example shows how to filter the records, in a like SQL way, according to whether they meet a criterion set by the user:\n\n```\nSub QueryCSV()\n    Dim CSVint As CSVinterface\n    Dim path As String\n    Dim FilteredData As CSVArrayList\n    \n    Set CSVint = New CSVinterface\n    path = Environ(\"USERPROFILE\") \u0026 \"\\Desktop\\Demo_100000records.csv\"\n    CSVint.parseConfig.Headers = False                                      \t\t'The file has no header record/row\n    CSVint.parseConfig.path = path\n    If path \u003c\u003e vbNullString Then\n        Set FilteredData = CSVint.Filter(\"f1='Asia' \u0026 f9\u003e20 \u0026 f9\u003c=50\", path) \t\t'Select \"Units sold\" greater than 20 and less or \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'equal to 50 from Asian customers\n        Set CSVint = Nothing\n        Set FilteredData = Nothing\n    End If\nEnd Sub\n```\n\nIn some situations, we may encounter a CSV file with a combination of `vbCrLf`, `vbCr` and `vbLf` as record delimiters. This can happen for many reasons, but the most common is by adding data to an existing CSV file without checking the configuration of the previously stored information. These cases will break the logic of many robust CSV parsers, including the demo of the 737K weekly downloaded [Papa Parse](https://www.papaparse.com/demo). The next example shows how an user can import CSV files with mixed line break as record delimiter, an option that uses the `multiEndOfLineCSV` property of the [`parseConfig`](https://ws-garcia.github.io/VBA-CSV-interface/api/properties/parseconf.html) object to work with these special CSV files.\n\n```\nSub ImportMixedLineEndCSV()\n    Dim CSVint As CSVinterface\n            \n    Set CSVint = New CSVinterface\n    With CSVint.parseConfig\n        .path = \"C:\\Mixed Line Breaks.csv\"\n        .dialect.fieldsDelimiter = \",\"        ' Columns delimiter\n        .dialect.recordsDelimiter = vbCrLf    ' Rows delimiter\n        .multiEndOfLineCSV = True             ' All delimiters will be turned into vbLf\n    End With\n    With CSVint\n        .ImportFromCSV .parseConfig\n    End With\n    Set CSVint = Nothing\nEnd Sub\n```\n\nIn all the above examples, an implicit assumption has been made, and that is that the user knows the configuration of the CSV file to be imported, so the question arises: can it be possible that the user does not know the configuration of the file to be imported? It is certainly possible, so how can the CSV interface help in these cases?\n\nThe tool includes a utility to sniff/guess field delimiters, record delimiters and quote character. This can be done with code like the following:\n\n```\nSub DelimitersGuessing()\n    Dim CSVint As CSVinterface\n\n    Set CSVint = New CSVinterface\n    With CSVint.parseConfig\n        .path = \"C:\\Sample.csv\"           ' Full path to the file, including its extension.\n    End With\n    With CSVint\n        Set .parseConfig.dialect = .SniffDelimiters(.parseConfig)    ' Try to guess delimiters and save to internal\n                                                                     ' parser configuration object.\n        '@--------------------------------------------------------------\n        ' *NOTE: the user can also create a custom configuration object\n        '        and try to guess the delimiter with it.\n    End With\nEnd Sub\n```\n\nWith VBA CSV interface, many things can be done, for example, an user can perform like SQL joins such as:\n\n```\nSub JoinTwoCSV()\n    Dim csv1 As CSVinterface\n    Dim csv2 As CSVinterface\n    Dim rTable As CSVArrayList\n    \n    '@--------------------------------------------------\n    ' Import data from CSV files\n    Set csv1 = New CSVinterface\n    With csv1\n        .parseConfig.delimitersGuessing = True\n        .parseConfig.path = Environ(\"USERPROFILE\") \u0026 \"\\Desktop\\Sales details.csv\"\n        .ImportFromCSV .parseConfig\n    End With\n    Set csv2 = New CSVinterface\n    With csv2\n        .parseConfig.delimitersGuessing = True\n        .parseConfig.path = Environ(\"USERPROFILE\") \u0026 \"\\Desktop\\Sales revenues.csv\"\n        .ImportFromCSV .parseConfig\n    End With\n    '@--------------------------------------------------\n    ' Perform a like SQL Left join on imported data.\n    With csv1.items\n    \t ' Join 1st, \"Region\", and 3th to 5th fields of left table with \"Total_Revenue\" field from the right table,\n\t ' on \"Order_ID\" of both tables if Total_Revenue is  greater than 3000000\n\t ' and Region is equal to \"Central America and the Caribbean\"\n        Set rTable = .LeftJoin(csv1.items, csv2.items, _\n                   \t\"{1,Region,3-5};{Total_Revenue}\", _\n                \t\"Order_ID;Order_ID\", _\n                \t\"t2.Total_Revenue\u003e3000000 \u0026 t1.Region='Central America and the Caribbean'\")\n\t\t\t\n        ' The \"*\" symbol can be used to retrieve all fields\n        ' from a given table like this.\n        \n            'Set rTable = .LeftJoin(csv1.items, csv2.items, _\n                        \"{*};{Total_Revenue}\", _\n                        \"Order_ID;Order_ID\", _\n                        \"t2.Total_Revenue\u003e3000000 \u0026 t1.Region='Central America and the Caribbean'\")\n                        \n    End With\n    '@--------------------------------------------------\n    ' Write the result in a spreadsheet.\n    csv1.DumpToSheet DataSource:=rTable\nEnd Sub\n```\n\n## Contributing\n\nIn order to contribute within this project, please see the [guidance for contributing](https://ws-garcia.github.io/VBA-CSV-interface/contributing.html).\n\n## Benchmark\n\nThe benchmark results for VBA-CSV Interface are available at [this site](https://ws-garcia.github.io/VBA-CSV-interface/home/getting_started.html#benchmark).\n\n## Dependencies\n\nThe library is composed of the following class modules:\n* `CSVArrayList`\n* [`CSVcallBack`](https://github.com/ws-garcia/VBA-Expressions)\n* `CSVdialect`\n* [`CSVexpressions`](https://github.com/ws-garcia/VBA-Expressions)\n* [`CSVexpressionsScope`](https://github.com/ws-garcia/VBA-Expressions)\n* `CSVinterface`\n* `CSVparserConfig`\n* `CSVSniffer`\n* `CSVTextStream`\n* [`CSVudFunctions`](https://github.com/ws-garcia/VBA-Expressions)\n\nAll dependencies are written in pure VBA.\n\n## Limitations\n\nVisit [this site](https://ws-garcia.github.io/VBA-CSV-interface/limitations/csv_file_size.html) in order to known around CSV file size considerations.\n\n## Licence\n\nCopyright (C) 2020-2025  [W. García](https://github.com/ws-garcia/).\n\nThis program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License along with this program.  If not, see \u003chttps://www.gnu.org/licenses/gpl-3.0.html\u003e.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fws-garcia%2FVBA-CSV-interface","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fws-garcia%2FVBA-CSV-interface","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fws-garcia%2FVBA-CSV-interface/lists"}