---
url: /flow/guide/scripting-reference/functions/database/getcustomdataset.md
---

# GetCustomDataSet

## Declaration

`procedure GetCustomDataSet(const aDataSet : TFloClientDataSet; const aFieldNames : array of string);`

`procedure GetCustomDataSet(const aDataSet : TFloClientDataSet; const aFieldDefinitions : array of string);`

## Description

Creates an empty dataset with either:

* Columns with names as specified in aFieldNames, and default field type and size of string(255); or
* Columns with names, types, and sizes as specified in aFieldDefinitions.

aDataSet should be one of the [Global Datasets](/flow/guide/scripting-reference/variables/global-datasets) (if within a Map), or a local dataset created with [TFloClientDataset.Create](/flow/guide/scripting-reference/classes/data-set/tfloclientdataset.create) (if within a Custom Script or a Map).

The dataset starts empty and you can add records to it as necessary. Refer to [Data Set](/flow/guide/scripting-reference/classes/data-set/) class for information on what you can do with the dataset.

The accepted values for column type are: string, integer, boolean, memo, date, time, datetime. See Example 3 below.

(This page expanded in September 2018 to include aFieldDefinitions option and additional examples.)

### Example 1 - Insert and Retrieve Data (Column Names only)

```pascal
procedure ScriptEvent (var Value : variant);
var
// Data1, Data2, etc are pre-declared within a Map but must be explicitly declared for Custom Scripts
Data1: TFloClientDataSet;
begin
// Data1, Data2, etc are pre-initialised within a Map but must be explicitly initialised for Custom Scripts
Data1 := TFloClientDataSet.Create(nil);
// define the column structure of the dataset ...
GetCustomDataSet(Data1,['ID','Name']); // create the dataset, with columns named 'ID' and 'Name'
// add some data into the custom dataset ...
Data1.Insert; // insert a new row into the dataset
Data1['ID'].Value := '1'; // set the value of the ID field
Data1['Name'].Value := 'Cameron'; // set the value of the Name field
Data1.Post; // save the changes to this row
Data1.Insert; // insert another new row into the dataset
Data1['ID'].Value := '2';
Data1['Name'].Value := 'Dave';
Data1.Post;
Data1.Insert;
Data1['ID'].Value := '10';
Data1['Name'].Value := 'Eddie';
Data1.Post;
// optional: sort the dataset (on the ID column) ...
Data1.IndexFieldNames := 'ID';
// retrieve data from the custom dataset ...
// Note: custom dataset columns are string(255) by default, so the sort returns '1', '10', '2'
Data1.First;
while (not Data1.EOF) do
begin
LogInfo('ID:' + Data1['ID'].AsString + ';Name:' + Data1['Name'].AsString); // read values from the dataset
Data1.Next;
end;
// Data1, Data2, etc are cleaned up automatically by a Map but must be explicitly removed for Custom Scripts
if (Assigned(Data1)) then
Data1.Free;
end;
```

### Example 2 - List default Column Types (when defined with Names only)

```pascal
procedure ScriptEvent (var Value : variant);
var
// Data1, Data2, etc are pre-declared within a Map but must be explicitly declared for Custom Scripts
Data1: TFloClientDataSet; f: integer; vField: TField; vInfoStr: string;
begin
// Data1, Data2, etc are pre-initialised within a Map but must be explicitly initialised for Custom Scripts
Data1 := TFloClientDataSet.Create(nil);
// define the column structure of the dataset - specify Names and accept default Type(Size) of string(255) ...
GetCustomDataSet(Data1,['ID','Name']); // create the dataset, with columns named 'ID' and 'Name'
for f := 0 to (Data1.Fields.Count - 1) do
begin
vField := Data1.Fields.Fields[f];
vInfoStr := 'Field/column ' + IntToStr(f) + ': ';
vInfoStr := vInfoStr + 'Name=' + vField.FieldName + ';';
vInfoStr := vInfoStr + 'Type=' + IntToStr(Ord(vField.DataType)) + ';'; // see note below
vInfoStr := vInfoStr + 'Size=' + IntToStr(vField.Size) + ';';
vInfoStr := vInfoStr + IfThen(vField.Required, 'Reqd=Yes', 'Reqd=No') + '.';
LogInfo(vInfoStr);
end;
// Data1, Data2, etc are cleaned up automatically by a Map but must be explicitly removed for Custom Scripts
if (Assigned(Data1)) then
Data1.Free;
end;
```

Note: The list of column Type index values and codes is set out in [TFieldType](/flow/guide/scripting-reference/data-types/enumerations/tfieldtype).

### Example 3 - Specify Column Names, Types, Sizes, and whether Required

When the aFieldDefinitions option is used, then in addition to the Name of each column you can specify:

* The Type of each column
* The Size of each string column
* Whether or not a value is Required in each of the columns.

A column definition is of the form:

* '\<name>,string,\<stringsize>,\<reqcode>' (for string columns), or
* '\<name>,\<type>,\<reqcode>' for non-string columns

Valid values for column Type are: string, integer, boolean, memo, date, time, datetime.

To specify that a column is Required use one of: required, req, true, yes; to specify that a column is not Required use one of: optional, opt, false, no.

The Type will default to string if not specified; the Required flag will default to optional if not specified.

Example from script below: GetCustomDataSet(Data1,\['ID,integer,req','Name,string,50']);

```pascal
procedure ScriptEvent (var Value : variant);
var
// Data1, Data2, etc are pre-declared within a Map but must be explicitly declared for Custom Scripts
Data1: TFloClientDataSet; f: integer; vField: TField; vInfoStr: string;
begin
// Data1, Data2, etc are pre-initialised within a Map but must be explicitly initialised for Custom Scripts
Data1 := TFloClientDataSet.Create(nil);
// define the column structure of the dataset ...
GetCustomDataSet(Data1,['ID,integer,req','Name,string,50']); // create the dataset, with columns named 'ID' and 'Name'
for f := 0 to (Data1.Fields.Count - 1) do
begin
vField := Data1.Fields.Fields[f];
vInfoStr := 'Field/column ' + IntToStr(f) + ': ';
vInfoStr := vInfoStr + 'Name=' + vField.FieldName + ';';
vInfoStr := vInfoStr + 'Type=' + IntToStr(Ord(vField.DataType)) + ';';
if (vField.Size > 0) then
vInfoStr := vInfoStr + 'Size=' + IntToStr(vField.Size) + ';';
vInfoStr := vInfoStr + IfThen(vField.Required, 'Reqd=Yes', 'Reqd=No') + '.';
LogInfo(vInfoStr);
end;
// add some data into the custom dataset ...
Data1.Insert; // insert a new row into that dataset
Data1['ID'].Value := 1; // set the value of the ID field
Data1['Name'].Value := 'Cameron'; // set the value of the Name field
Data1.Post; // save the changes to this row
Data1.Insert; // insert another new row into the dataset
Data1['ID'].Value := 2;
Data1['Name'].Value := 'Dave';
Data1.Post;
Data1.Insert;
Data1['ID'].Value := 10;
Data1['Name'].Value := 'Eddie';
Data1.Post;
// optional: sort the dataset (on the ID column) ...
Data1.IndexFieldNames := 'ID';
// retrieve data from the custom dataset ...
// Note: ID custom column is now type integer, so the sort returns 1, 2, 10
Data1.First;
while (not Data1.EOF) do
begin
LogInfo('ID:' + Data1['ID'].AsString + ';Name:' + Data1['Name'].AsString); // read values from the dataset
Data1.Next;
end;
// Data1, Data2, etc are cleaned up automatically by a Map but must be explicitly removed for Custom Scripts
if (Assigned(Data1)) then
Data1.Free;
end;
```
