ICsv interface

ICsv interface is used to work with CSV files, CSV strings, or string tables in memory.

Csv files are used to store tables. It is text where rows are separated by new lines, cells by commas, values containing new lines, commas or double quotes are enclosed in double quotes, double quotes are doubled, spaces around commas and new lines are ignored. Example:

 

value1,value2, value3
11,22,33
"value, with, commas","value with ""quotes""","multiline
value"
,,
,rows with empty values,
,,

The CSV file format is supported by many programs including Microsoft Excel, and therefore can be used to exchange data between them. However it have become somewhat of a legacy format. The mainsteam format now is xml, which is more powerful but adds much overhead (slower parsing/composing, requires more space in file and in memory). To save tables, CSV format often is better and easier to use.

 

You can find more information about CSV on the Internet.

 

Csv files also can be manipulated using Database class, but it is slower.

 

Added in QM 2.3.0.

 

Use function CreateCsv to create a csv object. To work with it, use ICsv interface. Example:

 

str s ss
ICsv v=CreateCsv()
v.FromFile("$my qm$\test.csv")

int nr=v.RowCount
int nc=v.ColumnCount
int r c
for r 0 nr
	out "--- row %i ---" r
	for c 0 nc
		s=v.Cell(r c)
		out s
		s.trim
		v.Cell(r c)=s

v.ToString(ss)
out ss

 

Functions

 

interface# ICsv :IUnknown
	[p]Separator($sep)
	[g]$Separator()
	FromString($s)
	ToString(str*so)
	FromFile($file)
	ToFile($file [flags]) ;;flags: 1 append
	FromQmGrid(hwnd [flags]) ;;flags: 1 no first column, 2 no empty rows, 4 selected
	ToQmGrid(hwnd [flags]) ;;flags: 1 only first column, 2 no first column
	Clear()
	[g]#RowCount()
	[g]#ColumnCount()
	[p]ColumnCount(count)
	[g]$Cell(row col)
	[p]Cell(row col $value)
	RemoveRow(row)
	#AddRowMS(row [nCells] [$cells] [firstCell]) ;;use row -1 to add to the end. Returns row index. 
	#AddRowLA(row [nCells] [lpstr*cells] [firstCell]) ;;use row -1 to add to the end. Returns row index.
	#AddRowSA(row [nCells] [str*cells] [firstCell]) ;;use row -1 to add to the end. Returns row index.
	#ReplaceRowMS(row [nCells] [$cells] [firstCell])
	#ReplaceRowLA(row [nCells] [lpstr*cells] [firstCell])
	#ReplaceRowSA(row [nCells] [str*cells] [firstCell])
	GetRowMS(row str*cells)
	MoveRow(row to)
	InsertColumn(col)
	RemoveColumn(col)
	[p]RowDataSize(nBytes)
	[g]#RowDataSize()
	[g]!*RowData(row)
	Sort(flags [col]) ;;flags: 0 simple, 1 insens, 2 ling, 3 ling/insens, 4 number/ling/insens, 0x100 descending
	{3426CF3C-F7C1-4322-A292-463DB8729B54}
dll "qm.exe" ICsv'CreateCsv [flags] ;;flags: 1 separator is comma

 

 


ICsv'CreateCsv [flags] ;;flags: 1 separator is comma

 

Creates CSV object and returns ICsv interface pointer. Since it is a COM object, it is destroyed automatically when goes out of scope.

 

flags (QM 2.3.2):

1 use comma as separator. Same as var.Separator=",".

 


[p]Separator($sep)
[g]$Separator()

 

Sets or gets (QM 2.3.2) separator that is used when parsing and composing csv. Example: v.Separator=";". Default separator on most computers is comma, but somewhere it is semicolon or other character. It can be changed in Control Panel -> Regional and Language Options -> Customize... -> List Separator.

 

Info: Excel, when opening and saving csv files, also uses the separator that is set in Control Panel.

 


FromString($s)

 

Parses csv string and creates table in memory. The csv variable manages the table.

 

Error if the csv string contains errors or uses different separator.

 


ToString(str*so)

 

Composes csv string from the table.

 


FromFile($file)

 

Parses csv file and creates table in memory.

 

Error if the csv file contains errors or uses different separator.

 

Can use syntax ":resourceid filepath" to add the file to exe resources.

 


ToFile($file [flags]) ;;flags: 1 append

 

Saves the table to file.

 

flags:

1 append.

 


FromQmGrid(hwnd [flags]) ;;flags: 1 no first column, 2 no empty rows, 4 selected

 

Gets cells from QM_Grid control and creates table in memory.

 

flags:

1 don't get first column.
2 don't get empty rows.
4 (QM 2.3.2) get only selected or checked (depending on style) rows.

 

Does not change Separator and RowDataSize.

 


ToQmGrid(hwnd [flags]) ;;flags: 1 only first column, 2 no first column

 

Populates QM_Grid control.

 

flags:

1 only first column.
2 except first column.

 

If flag 2 used, does not clear the control. The control must already contain cells in the first column. Cells in other columns can be empty or not.

 

If flag 1 used, the csv table should contain 1 column. The grid can contain 1 or more columns.

If flag 2 used, the csv table should contain control's column count -1.

Else the csv table should contain control's column count.

 


Clear()

 

Deletes all rows.

 

Sets ColumnCount to 0.

Does not change Separator and RowDataSize.

 


[g]#RowCount()
[g]#ColumnCount()
[p]ColumnCount(count)

 

Gets the number of rows or columns.

 

QM 2.3.2. ColumnCount also can be used to set column count.

 


[g]$Cell(row col)
[p]Cell(row col $value)

 

Gets or sets cell value. See the example at the beginning.

 

The returned value is temporary. It becomes invalid after calling a function that modifies the table. To use it later, assign it to a str variable, like in the example.

 


RemoveRow(row)

 

Removes row.

 


#AddRowMS(row [nCells] [$cells] [firstCell]) ;;use row -1 to add to the end. Returns row index. 
#AddRowLA(row [nCells] [lpstr*cells] [firstCell]) ;;use row -1 to add to the end. Returns row index.
#AddRowSA(row [nCells] [str*cells] [firstCell]) ;;use row -1 to add to the end. Returns row index.

 

Adds or inserts row.

 

row - 0-based row index where to insert the new row. Use an invalid index (e.g. -1) to add to the end.

nCells - number of cells to add.

cells - cell values.

firstCell (QM 2.3.2) - 0-based column index where to insert the cells.

 

If the number of columns is still not set (is 0) this function sets it to nCells+firstCell. You can also set it with ColumnCount before adding rows. If it is already set, nCells must not be bigger.

 

Each of these functions differs only by the format of the values array (cells).

 

Function cells type Comments
AddRowMS lpstr cells must be in multistring format, ie multiple null-terminated strings following each other, like "string1[0]string2[0]string3[0]".
AddRowLA lpstr* cells must be address of first variable in an array of lpstr variables.
AddRowSA str* cells must be address of first variable in an array of str variables.

 

If cells or nCells is omitted or 0, adds 1 empty row. You can use Cell to set cell values.

 

nCells cannot be 0 if column count is 0.

 

Cells that are outside the range specified by firstClell and nCells will be "". If some strings in cells are null, the cells will be "". If RowDataSize is nonzero, the functions fill row data with 0.

 

Example.

out
ICsv x=CreateCsv(1)
x.ColumnCount=3

 ------------

 add empty row and use Cell
int r=x.AddRowMS(-1)
x.Cell(r 0)="c1"; x.Cell(r 1)="c2"; x.Cell(r 2)="c3"

 MS
lpstr multistring="ms1[0]ms2[0]ms3"
x.AddRowMS(-1 3 multistring)

 LA with array
str st="a1 a2 a3"
ARRAY(lpstr) a
int nt=tok(st a 3 "" 1)
x.AddRowLA(-1 nt &a[0])

 SA with array
ARRAY(str) as="as1[]as2[]as3"
x.AddRowSA(-1 as.len &as[0])

 LA with local variables
lpstr s1("s1") s2("s1") s3("s1")
x.AddRowLA(-1 3 &s1)

 SA with local variables
str ss1("ss1") ss2("ss1") ss3("ss1")
x.AddRowSA(-1 3 &ss1)

 ------------

str s
x.ToString(s)
out s

 


#ReplaceRowMS(row [nCells] [$cells] [firstCell])
#ReplaceRowLA(row [nCells] [lpstr*cells] [firstCell])
#ReplaceRowSA(row [nCells] [str*cells] [firstCell])

 

Replaces row.

 

These functions replace nCells strings of row row, starting from firstCell. They don't change other cells and row data. If row does not exist, they add new row to the end like the AddRowX functions.

 

Everything else is as with the AddRowX functions.

 

Added in QM 2.3.2.

 


GetRowMS(row str*cells)

 

Stores all row cells into a str variable in multistring format.

 

Added in QM 2.3.2.

 


MoveRow(row to)

 

Moves row.

 

row - index of row to move.

to - new index of the row.

 

Added in QM 2.3.2.

 


InsertColumn(col)
RemoveColumn(col)

 

InsertColumn - inserts 1 empty column. If col is invalid (e.g. -1), adds to the end.

RemoveColumn - removes 1 column.

 

Alternatively you can use ColumnCount to add or remove columns.

 

Added in QM 2.3.2.

 


[p]RowDataSize(nBytes)
[g]#RowDataSize()
[g]!*RowData(row)

 

RowDataSize - sets or gets size of extra memory to allocate for each row.

RowData - returns address of extra memory of a row.

 

Allows to place any data in each row. It simplifies using ICsv as base of new table-based classes. The data exists only in memory.

 

Added in QM 2.3.2.

 


Sort(flags [col]) ;;flags: 0 simple, 1 insens, 2 ling, 3 ling/insens, 4 number/ling/insens, 0x100 descending

 

Sorts rows using text of one of columns.

 

flags:

0 Simple, case sensitive. Uses StrCompare to compare strings.
1 Simple, case insensitive. Uses StrCompare to compare strings.
2 Linguistic, case sensitive. Uses StrCmp to compare strings.
3 Linguistic, case insensitive. Uses StrCmpI to compare strings.
4 Number, linguistic, case insensitive. Uses StrCmpLogicalW to compare strings. It compares numbers in strings as number values, not as strings. On Windows 2000 uses flag 3 instead.
0x100 Sort descending.

col - 0-based column index.

 

Added in QM 2.3.2.

 

Notes

ICsv functions are not thread-safe. Don't use a single variable in multiple threads simultaneously. It can damage data. If need to use in multiple threads, use lock.