> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abbyy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Special features of ABBYY FlexiLayout Studio for creating additional FlexiLayouts

> Build additional invoice FlexiLayouts with ABBYY FlexiLayout Studio: query data sets with functions like RecordOfFCDataset and use XML parameter files.

ABBYY FlexiLayout Studio has several special features for developing additional FlexiLayouts for invoice projects:

* You can specify the locations of elements relative to the regions of fields that were detected when the main FlexiLayout from the invoice project was applied.
* Identifiers of vendors and business units can be used in requests to the data set of the Document Definition.
* Lists of keywords and other parameters of a FlexiLayout can be exported to an XML file, allowing you to edit them without editing the FlexiLayout or the Document Definition.

## Create an additional FlexiLayout

<Steps>
  <Step title="Open a batch in FlexiCapture">
    Open a batch with recognized invoices in FlexiCapture.
  </Step>

  <Step title="Create a FlexiLayout Studio project">
    Create a new project in ABBYY FlexiLayout Studio. On the main menu, select **Tools → Export Batch to FlexiLayout Studio → Create New FlexiLayout Studio Project...**.
  </Step>
</Steps>

<Note>
  This command is only available for FlexiCapture projects that are stored on your computer. If you are using the Distributed version of FlexiCapture and the project is stored on the server, first download it to your computer by clicking **Export Project...** on the **Project** menu.
</Note>

<Note>
  The suffix of the ABBYY FlexiLayout Studio project indicates the version of the Document Definition at the time of the project's creation.
</Note>

The ABBYY FlexiLayout Studio project you just created contains all the documents from the FlexiCapture batch, plus the field regions detected during recognition, in the form of a **reference layout**.

| Tree               | Node                     | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ------------------ | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **SearchElements** | **CommonBlockRegions**   | This node contains elements that correspond to all fields of the Document Definition. The coordinates of all regions of blocks that were detected when FlexiLayouts were applied to each document in FlexiCapture are saved in the ABBYY FlexiLayout Studio project. By default, regions with these coordinates are assigned to elements that have the same name as fields in the Document Definition. This allows them to be used to specify relative locations of elements and for creating new elements. |
| **SearchElements** | **CustomSearchElements** | This node contains sample elements. They are disabled by default to avoid interference when the FlexiLayout is applied.<br /><br />**DataSetRequestSample** — An example of a request to the data set of vendors and business units stored in the Document Definition. This data set includes identifiers of vendors and business units.                                                                                                                                                                    |

## Add a field to an additional FlexiLayout

To add a field to an additional FlexiLayout, create a block for this field and specify its search element.

Fields in the Document Definition must have unique names. This means that:

* To describe the search logic for a field, create a block with a unique name.
* To change the search logic for a field that already exists in the Document Definition, create a block with the same name.

## Add pages to an additional FlexiLayout

If you want to test the changes you have made to an additional FlexiLayout on new images, you can export your FlexiCapture batches into an existing invoice project in ABBYY FlexiLayout Studio. To export your batches, click **Tools → Export Batch to FlexiLayout Studio → Add to Existing FlexiLayout Studio Project...**.

* You can export FlexiCapture batches only into ABBYY FlexiLayout Studio projects that were created by selecting **Tools → Export Batch to FlexiLayout Studio → Create New FlexiLayout Studio Project...**.
* When you export a FlexiCapture batch to ABBYY FlexiLayout Studio, a new batch is created in ABBYY FlexiLayout Studio for that batch.
* If the new Document Definition has more fields than the Document Definition used for the ABBYY FlexiLayout Studio project, the export log contains a warning for each extra field.
* To make the program export the extra fields, for each extra field add a block with the same name in the **CommonBlockRegions** node of the **SearchElements** tree.

## Make requests to data sets from the Document Definition

You can find a sample request in the **DataSetRequestSample** element. This element is disabled by default.

| Type                                                | Description                                          |
| --------------------------------------------------- | ---------------------------------------------------- |
| **NamedValue**                                      | A named value.                                       |
| *Constructor*                                       |                                                      |
| `NamedValue( String, String )`                      |                                                      |
| *Methods*                                           |                                                      |
| `String Name()`                                     | Returns the name of a named value.                   |
| `String Value()`                                    | Returns the value of a named value.                  |
| **NamedValueArray**                                 | An array of named values.                            |
| *Constructors*                                      |                                                      |
| `NamedValueArray()`                                 |                                                      |
| `NamedValueArray( NamedValue namedValue )`          |                                                      |
| *Methods*                                           |                                                      |
| `Int Count()`                                       | Returns the total number of elements in the array.   |
| `NamedValue GetAt( Int index )`                     | Returns the element with the specified index number. |
| `Void Add( NamedValue namedValue )`                 | Adds a named value to the array.                     |
| `Void Add( NamedValueArray namedValueArray )`       | Adds a named value array to a named value array.     |
| `Void InsertAt( Int index, NamedValue namedValue )` | Inserts the named value into the position index.     |
| `Void DeleteAll()`                                  | Deletes all elements in an array.                    |
| `Void DeleteAt( Int index )`                        | Deletes an element in the position index.            |
| `Int FindByName( String name )`                     | Returns the position of the value named name.        |

### Functions

Syntax:

* The path to the Document Definition and the name of the data set are used to access the data set when working with a FlexiLayout in ABBYY FlexiLayout Studio.
* After a compiled FlexiLayout is added to a Document Definition in FlexiCapture, only its name is used when accessing the data set.
* **connectionString** format:

  ```
  "dbtype=FCDataset;fcTemplate=path_to_Document_Definition;datasetName=name_of_Data_Set;"
  ```

  **Note:** Separate parts of the path with double backslashes (`\\`).
* **searchFields** — Array of names of columns from which values need to be retrieved.
* **searchCriteria** — Array of **Column-Entry** pairs; returns all values if empty.
  * If a request contains multiple values for one field, use the **OR** operator.
  * If a request contains multiple values each of which corresponds to only one field, use the **AND** operator.
  * If a request contains multiple values for one field and values for multiple fields, use the **OR** operator to distinguish multiple values for one field and the **AND** operator to conjoin values for various fields.

| Definition                                                                                                                                                                                                                            | Description                                                                                                                                                                                                                                                                                        |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Logic TestAccessToFCDataSet( String connectionString )`                                                                                                                                                                              | Tests the connection to the data set.                                                                                                                                                                                                                                                              |
| `Logic TestFCDataSetSearchCriteria( String connectionString, StringArray searchFields, NamedValueArray searchCriteria )`                                                                                                              | Tests search conditions for the data set.                                                                                                                                                                                                                                                          |
| `StringArray FieldNamesOfFCDataset( String connectionString )`                                                                                                                                                                        | Returns a list of all fields from the data set, sorted in ascending order of their index numbers.                                                                                                                                                                                                  |
| `StringArray FieldNamesOfFCDataset( String connectionString, StringArray searchFields )`                                                                                                                                              | Returns a list of data set fields from the specified data set in ascending order of their index numbers. Should be used in conjunction with the RecordOfFCDataset function when there are complex columns.                                                                                         |
| `Int RecordCountOfFCDataset( String connectionString, StringArray searchFields, NamedValueArray searchCriteria )`                                                                                                                     | Returns the number of entries from the data set that are specified in the search conditions. Used to find out how many entries may be returned using the RecordOfFCDataset function.                                                                                                               |
| `Void PrepareRecordsetOfFCDataset( String connectionString, StringArray searchFields, NamedValueArray searchCriteria, Int maxRecordsCount = DefaultMaxRecordsCount )`                                                                 | Prepares data for a query to the data set. This needs to be performed for every new set of search conditions before calling the RecordOfFCDataset function.                                                                                                                                        |
| `StringArray RecordOfFCDataset( String connectionString, StringArray searchFields, NamedValueArray searchCriteria, Int rowIndex )`                                                                                                    | Returns an array of values from the entry with the number *rowIndex* from results returned by a query to the data set. The number of values is equal to the number of fields passed in searchFields (this includes the case of complex columns).                                                   |
| `Quality ValidateByFCDataSet( String word, String connectionString, Int fieldIndex, NamedValueArray searchCriteria, Int maxErrors, Rational maxErrorsPart, Logic ignoreSpaces = true, Int maxRecordsCount = DefaultMaxRecordsCount )` | Returns the quality of the string *word*. Accepts index numbers of fields. You can get index numbers by indexing the output of the FieldNamesOfFCDataset function.                                                                                                                                 |
| `Void SearchTextFromFCDataSet( String connectionString, Int fieldIndex, NamedValueArray searchCriteria, Int maxRecordsCount = DefaultMaxRecordsCount )`                                                                               | Used to specify search conditions for words for the Static Text function. When this function is called, existing search conditions are replaced with new ones. Accepts field index numbers. You can get index numbers by indexing the output of the FieldNamesOfFCDataset function.                |
| `Void RegularExpressionFromFCDataSet( String connectionString, Int fieldIndex, NamedValueArray searchCriteria, Int maxRecordsCount = DefaultMaxRecordsCount )`                                                                        | Used to specify search conditions using regular expressions for the CharString function. When this function is called, existing search conditions are replaced with new ones. Accepts field index numbers. You can get index numbers by indexing the output of the FieldNamesOfFCDataset function. |

### Search for rows from a column in an external database on an image

<Steps>
  <Step title="List the columns">
    Use FieldNamesOfFCDataset to get a list of columns sorted in ascending order of their index numbers.
  </Step>

  <Step title="Find the column index">
    Determine the index number of the column from which you need to find data.
  </Step>

  <Step title="Build the filter">
    Create an array of conditions for filtering data from the data set.
  </Step>

  <Step title="Run the search">
    Pass the index numbers of the column and the filter conditions to SearchTextFromFCDataSet (or RegularExpressionFromFCDataSet, if you need to use regular expressions).
  </Step>
</Steps>

This code is automatically generated when a recognized batch is exported from FlexiCapture.

### Search an image for entries from multiple columns

Since search parameters are replaced each time you call the **SearchTextFromFCDataSet** function, calling it repeatedly has no effect. As a workaround, get strings from an external database and pass them to the **SearchText** function, which adds each string to the existing search parameters instead of replacing them.

<Steps>
  <Step title="List the columns">
    Create an array of names of columns from which you need to find data.
  </Step>

  <Step title="Build the filter">
    Create an array of filter conditions for filtering data from the data set.
  </Step>

  <Step title="Count the entries">
    Determine the number of entries that are returned using the **RecordCountOfFCDataset** function.
  </Step>

  <Step title="Prepare the query">
    Prepare query data using the **PrepareRecordsetOfFCDataset** function.
  </Step>

  <Step title="Read each record">
    Go through all records and get the array for each record using the **RecordOfFCDataset** method.
  </Step>

  <Step title="Pass the values to SearchText">
    Pass the value of each element in the array to the **SearchText** function.
  </Step>
</Steps>

### Additional considerations for complex columns

* The **FieldNamesOfFCDataset** function returns an array that contains multiple occurrences of the name of the complex column. The number of occurrences is the same as the number of column instances in an encoded external database.

  *Example*: `{VendorId, VATID, Name, Name, Name, City}`. In this case, the external database contains three columns for the one complex column **Name** in the data set.
* If **SearchCriteria** contains a condition for a field that corresponds to a complex column (like in the example above), this condition is used to check all of these column instances.
* If **searchFields** contains a condition for a field that corresponds to a complex column (like in the example above), the result contains the array of values from each column instance.

  For example, if you request the following for `{VendorId, VATID, Name, Name, Name, City}`:

  ```
  searchFields = { VATID, Name, City}, you will receive
  {VATID_value, Name_valueInColumn1, Name_valueInColumn2, Name_valueInColumn3, City_value}
  ```
* You can get a list of columns that are returned by passing the **searchFields** array to the **FieldNamesOfFCDataset** function.

## Make a request to an XML file that contains FlexiLayout settings

You can make requests to an XML file with FlexiLayout settings using two standard functions that are described in the documentation for ABBYY FlexiLayout Studio:

```
StringArray ReadFromXML(String filename, String xPathQuery)
String ReadSingleStringFromXML(String filename, String xPathQuery)
```

To use this file when working on a FlexiLayout in ABBYY FlexiLayout Studio, place it in the project folder or one of its subfolders. The path to the file is relative to the ABBYY FlexiLayout Studio project file.

If you load a compiled FlexiLayout to a Document Definition in FlexiCapture and use it as an additional FlexiLayout, the XML file is placed in the **Templates** folder and you can edit it. When the FlexiLayout is applied, the program manages access to this file automatically.
