---
url: >-
  /statelake/scripting-reference/functions-and-procedures/database-functions/getcustomdataset/specify-column-names-types-sizes-and-whether-required.md
---

# Specify Column Names, Types, Sizes, & Whether Required

When the **aFieldDefinitions** option is used, 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.

Data1, Data2, Data3 etc are pre-declared within a **Map**, but must be explicitly declared within a Custom Script.

Data1, Data2, Data3 etc are pre-initialised within a **Map**, but must be explicitly initialised within a Custom Script.

Data1, Data2, Data3 etc are cleaned up automatically by a **Map**, but must be explicitly removed for Custom Script.

Example of script below.

```pascal
procedure ScriptEvent (var Value : variant);
var
  Data1: TFloClientDataSet; f: integer; vField: TField; vInfoStr: string;
begin
  Data1 := TFloClientDataSet.Create(nil);
 // define the column structure of the dataset ...
 // create the dataset, with columns named 'ID' and 'Name'
  GetCustomDataSet(Data1,['ID,integer,req','Name,string,50']);

 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 := 'Betty';        // 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 := 'Nigel';
  Data1.Post;

  Data1.Insert;                         // insert another new row into the dataset
  Data1['ID'].Value := 10;
  Data1['Name'].Value := 'Roger';
  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
 // read values from the dataset
    LogInfo('ID:' + Data1['ID'].AsString + ';Name:' + Data1['Name'].AsString);
    Data1.Next;
 end;

 if (Assigned(Data1)) then
  Data1.Free;

end;
```
