ICsv interface
ICsv interface is used to work with csv
files.
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.
The interface has been added in QM 2.3.0.
Csv files also can be manipulated using Database
class, but it is slower.
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)
FromString($s)
ToString(str*so)
FromFile($file)
ToFile($file [append])
FromQmGrid(hwnd [flags])
ToQmGrid(hwnd [flags])
Clear()
[g]#ColumnCount()
[g]#RowCount()
[g]$Cell(row col)
[p]Cell(row col $value)
RemoveRow(row)
#AddRowMS(row ncells $cells)
#AddRowLA(row ncells lpstr*cells)
#AddRowSA(row ncells str*cells)
{3426CF3C-F7C1-4322-A292-463DB8729B54}
dll "qm.exe" ICsv'CreateCsv
CreateCsv - creates a csv object and returns ICsv
interface pointer. Since it is a COM object, it is destroyed automatically when
goes out of scope.
Separator - changes default separator that is used
when parsing and composing csv. Example: v.Separator=";".
Default separator on most computers is comma, but somewhere it is semicolon.
It can be changed in Control Panel -> Regional and Language Options ->
Customize... -> List Separator.
FromString - parses a csv string and creates table
in memory. The table is managed by the csv object.
ToString - composes a csv string from the table.
FromFile - parses a csv file and creates table in
memory.
ToFile - saves the table to a csv file. flags:
1 - append.
FromQmGrid - creates table from a QM_Grid
control. flags: 1 - except first column; 2 - trim spaces.
The control is available only in QM, but not in exe.
C++ definitions:
//About QM_Grid control
//This control is based on SysListView32. You can use its messages, notifications and styles.
//In addition to SysListView32 control functionality, QM_Grid control allows user to edit all
//or some cells, and can also show other controls, such as combo box, check box and button.
//By default, this control can be used to enter text, like with edit control but where each
//line is divided into columns. It also can be used to enter values of multiple properties,
//instead of dialog with multiple controls, similarly as in Microsoft programming IDEs.
//By default, to edit cells, is displayed temporary single-line edit control. You can use
//LVM_QG_SETCELLTYPE and/or LVM_QG_SETCOLUMNTYPE to set other control types and styles. These
//control types/styles are supported: single-line edit (default), multiline edit, combo box
//(edit with drop-down list), sorted combo box, check box (sets item text to Yes or empty),
//and noneditable. In addition, button can be displayed at right.
//Specific styles
//By default, all cells are editable, and user can easily add, delete and move rows.
//QG_NOEDITFIRSTCOLUMN does not allow user to edit cells in first column.
//QG_NOAUTOADD does not allow user to add, delete, insert and move rows.
//A. Initializing
//1. Create control of QM_Grid class. Optionally use listview styles.
//2. Optionally set listview extended styles, imagelists.
//3. Optionally send LVM_QG_SETSTYLE.
//4. Add columns (LVM_INSERTCOLUMN).
//5. Optionally send LVM_QG_SETCOLUMNTYPE to set default cell type for columns (initially it is QG_EDIT).
//6. Add items and subitems. You can use listview messages (LVM_INSERTITEM, etc). Or, use LVM_QG_SETALLCELLS to add all cells. Or, add items only (use LVM_INSERTITEM or LVM_QG_SETALLCELLS), and then use LVM_QG_SETALLCELLS to set subitems.
//7. Optionally send LVM_QG_SETCELLTYPE to set styles of separate cells.
//Notes
//Multistring is array of strings where all strings are in same buffer, each string is terminated with null, and last string is terminated with two null. Must be in CStr variable, whose address is passed as lParam. Multistring can be stored in registry with REG_MULTI_SZ type.
//To initialize checkbox cells, use "Yes" or leave empty.
//B. Receiving notifications.
//You can optionally process LVN_ and LVN_QG_ notifications.
//You must process LVN_QG_BUTTONCLICK for cells that have QG_BUTTONATRIGHT style. For example, show a dialog and set edit control text.
//You must process LVN_QG_COMBOFILL for cells that have QG_COMBO type. Use CB_ADDSTRING to add combo box items. This message is sent each time before showing dropdown list.
//You optionally can process LVN_QG_COMBOITEMCLICK for cells that have QG_COMBO type. If you don't process it, or process but return 0, combo box edit control text is set to selected item's text. This message allows you to override this behavior. You for example can show a dialog, set edit control text, and return 1.
//Also you can process LVN_ENDLABELEDIT to validate user input.
//C. Getting text from cells.
//Use LVM_GETITEMTEXT to get text from each cell you need. Or, use LVM_QG_GETALLCELLS to get all cells to multistring.
//D. Mouse and keyboard navigation.
//Click cell to edit it.
//Click-drag at right or left to select rows. Also, you can Ctrl+Click or Shift+Click.
//Right click or use App key to show context menu.
//In cell edit mode:
//Use Tab, Shift+Tab or arrows to edit next, prev, below or above.
//Use Enter to insert and edit new row.
//Use standard edit control navigation and context menu.
//Use Esc to deactivate cell edit mode.
//Not in cell edit mode:
//Use Spacebar to edit first editable cell of selected or first row.
//Use Ctrl+A to select all, Delete to delete selected, Ctrl+Up/Down to move selected cell.
////////////////////////////////////////////////////
//Public definitions
//Messages
#define LVM_QG_FIRST (LVM_FIRST+240)
#define LVM_QG_SETSTYLE (LVM_QG_FIRST) //Sets grid style. Use values from QM_GRID_STYLES enum. wParam is styles, lParam is mask.
#define LVM_QG_SETCELLTYPE (LVM_QG_FIRST+1) //Sets control type, style, and other flags of specified cell. Use values from QM_GRID_ITEM_FLAGS enum. wParam is item, lParam is MAKELPARAM(column, flags).
#define LVM_QG_SETCOLUMNTYPE (LVM_QG_FIRST+2) //Sets default control type, style and flags for all cells of specified column. wParam is column, lParam is flags from QM_GRID_ITEM_FLAGS enum.
#define LVM_QG_SETALLCELLS (LVM_QG_FIRST+3) //Populates all cells from CStr variable containing multistring. wParam is flags from QM_GRID_SETGETALL enum, lParam is CStr*.
#define LVM_QG_GETALLCELLS (LVM_QG_FIRST+4) //Gets all cells to CStr variable as multistring. wParam is flags from QM_GRID_SETGETALL enum, lParam is CStr*.
//Notifications
#define LVN_QG_FIRST (LVN_LAST)
#define LVN_QG_BUTTONCLICK (LVN_QG_FIRST) //must return 0
#define LVN_QG_COMBOFILL (LVN_QG_FIRST+1) //must return 0
#define LVN_QG_COMBOITEMCLICK (LVN_QG_FIRST+2) //must return 0, or 1 to preserve edit control text
#define LVN_QG_CHANGE (LVN_QG_FIRST+3) //must return 0
//This struct is sent with each LVN_QG_ notification (some members are used only with certain notifications):
struct QM_NMLVDATA { NMHDR hdr; HWND hctrl, hcb; int ctrltype, item, subitem, cbindex; LPSTR txt; };
//hdr - notification code, grid control handle and id
//hctrl - edit control (not grid control)
//hcb - combo box control.
//ctrltype - cell flags from QM_GRID_ITEM_FLAGS.
//item and subitem - specifies the cell.
//cbindex - on LVN_QG_COMBOITEMCLICK it is index of selected combo box item.
//txt - edit control text.
//Also, extends these SysListView32 messages and notifications
//LVM_EDITLABEL //lParam specifies subitem
//LVN_BEGINLABELEDIT //LVITEM::iSubItem specifies subitem
//LVN_ENDLABELEDIT //LVITEM::iSubItem specifies subitem. Return 1 to leave old text.
//Styles
enum QM_GRID_STYLES { QG_NOEDITFIRSTCOLUMN=1, QG_NOAUTOADD=2};
//Item styles and flags
enum QM_GRID_ITEM_FLAGS
{
QG_EDIT, QG_COMBO, QG_CHECK, QG_NONE=7, QG_CONTROLTYPEMASK=7, //control type
QG_EDIT_MULTILINE=8, QG_COMBO_SORT=8, QG_BUTTONATRIGHT=16, //control style
};
//LVM_QG_SETALLCELLS and LVM_QG_GETALLCELLS flags
enum QM_GRID_SETGETALL { QG_GET_NOFIRST=1, QG_GET_TRIM=2, QG_SET_FIRST=1, QG_SET_NOFIRST=2};
ToQmGrid - populates a QM_Grid control. flags:
1 - only first column; 2 - except first column.
Clear - deletes all rows.
ColumnCount, RowCount -
gets the number of columns and rows in the table.
Cell - gets or sets cell value. See the above example.
Note that the returned value becomes invalid after calling a function that modifies
the table, and therefore you should assign it to a str variable, like in the
example.
RemoveRow - removes a row.
AddRowMS, AddRowLA, AddRowSA - add a row.
row - 0-based row index where the new row must be inserted. Use an invalid
index (e.g. -1) to add to the end.
ncells - number of cells to add. If the table is empty, it sets the
number of columns. Else it must not be more than the number of columns.
cells - cell values.
Each of these functions differs only by the format of values (cells).
With MS, cells must be a multistring, ie single buffer containing multiple
string separated by null character. With LA, cells must be address of
first variable in an array of lpstr variables. With SA - str variables. If cells
is omitted or 0, adds an empty row. You can use Cell
to set cell values.
Notes
ICsv functions are not thread-safe. Don't use a single
variable in multiple threads simultaneously. It can damage data. If needed to
use in multiple threads, use lock.
If a function generates an error, its description in most cases is "The
parameter is incorrect". For example, FromFile
generates error if the file does not exist, or cannot be opened, or it is not
a csv file, or contains errors, or uses different separator.