---
url: /statelake/scripting-reference/events.md
---

# Events

The **Statelake** scripting engine is an event-based engine. These **Events** are points at which script code can be entered by the user.

The **Events** are provided against the destination **Data Definition** of the **Map**, although an **Event** is ignored if there is no script attached to it.

There are different **Events** for datasets and fields.

Since each dataset and its fields have **Events** which a user can attach script to, the engine executes based on this destination **Data Definition**, running through its datasets and fields executing the **Events** as it goes.

This happens in a pre-determined order, however it is possible for the user to control this order of execution with special functions in the script.

There are 3 main types of **Event** -

* Dataview Events (Dataset)
* Record-level Events
* Field-level Events

## Attaching A Script To An Event

You attach a script to an **Event** by selecting the **Event** and then clicking anywhere in the script editor area of the screen.

A skeleton code of the **Event** will display, and you can enter you script.

The following are a few examples of this skeleton script.

```pascal
procedure BeforeMapEvent(var Value:Variant);  //INVOICE
begin
  Value :=
end;
```

```pascal
procedure OnStartMapEvent;  //INVOICE
begin

end;
```

```pascal
procedure OnMapEvent(var Value:Variant);  //MASTER_NAME
begin
  Value :=
end;
```

You can then edit the script simply by selecting the **Event**, and the script code will display in the script editor area of the screen, allowing you to amend it as appropriate.

## Automatically Creating Event Scripts

Certain **Events** can have scripts created automatically by the drag-and-drop process. However, you will find that the drag-and-drop will have no effect if the **Event** already has a script attached to it.

In this case you will need to edit the **Event** by selecting it, or remove the **Event's** script and then perform the drag-and-drop process again.

**LinkedData** **Events** can be set by dragging a dataset from the source and dropping it on the destination dataset, and as a result you will see the script appear in the script editor area of the screen.

**OnMap** **Events** for fields can be set by dragging a field from the source and dropping it on the destination field.

## Removing A Script From An Event

Removing the script from an **Event** could not be easier.

Simply right-click on the **Event** name, select the only option which is clear.

## Event Execution

**Events** are fired in a pre-determined order.

With the program flow in mind, the **Events** are fired in the following loop example, containing a two-level hierarchy of datasets: parent, child.

The highlighted **Events** are those that are most commonly used.

| Process ORDER | Parent  dataset | Parent  record | Parent  field | Child  dataset | Child  record | Child  field |
|---|---|---|---|---|---|---|
| 1 | OnStartMap |   |   |   |   |   |
| 2 |   | BeforeMap |   |   |   |   |
| 3 |   |   | BeforeMap |   |   |   |
| 4 |   |   | OnMap |   |   |   |
| 5 |   |   | AfterMap |   |   |   |
| 6 |   |   | ### (All repeatable) |   |   |   |
| 7 |   | AfterMap |   |   |   |   |
| 8 |   |   |   | OnStartMap |   |   |
| 9 |   |   |   |   | BeforeMap |   |
| 10 |   |   |   |   |   | BeforeMap |
| 11 |   |   |   |   |   | OnMap |
| 12 |   |   |   |   |   | AfterMap |
| 13 |   |   |   |   |   | ### (All repeatable) |
| 14 |   |   |   |   | AfterMap |   |
| 15 |   |   |   |   | ### (All repeatable) |   |
| 16 |   |   |   | OnEndMap |   |   |
| 17 |   | AfterDetailMap |   |   |   |   |
| 18 |   | ### (All repeatable) |   |   |   |   |
| 19 | OnEndMap |   |   |   |   |   |
| 20 |   |   |   |   |   |   |

**LinkedData** is a special **Event**, and if it is set, then the section between **BeforeMap** to **AfterDetailMap** is repeated for each record in the linked dataset.

If **LinkedData** is not set, then that section is executed only once.

::: info
Although there are **BeforeMap** and **AfterMap** events at record-level, and there are **BeforeMap** and **AfterMap** events at field-level, these events react in different ways with distinct behaviour differences and should not be confused.
:::

There is another way to look at the order that a series of **Events** are executed in a **Map**, using the following example.

Joe from Timaru has placed an order for a pair of green socks and a pair of pink socks, one blue jersey in size XXL, and one pair of size 43 brown leather shoes.

There is one (1) record in the **ORD_HEADER** table for this order -

* record 1 - **Joe** and **Timaru** are fields

There are three (3) records in the **ORD_LINES** table for this order -

* record 1 - **two** and **socks** are fields
* record 2 - **one** and **jersey** are fields
* record 3 - **one** and **shoes** are fields

There are seven (7) records in the **LINE_MSG** table for this order -

* record 1 - **green** is the field (record **1** in **ORD_LINES**)
* record 2 - **pink** is the field (record **1** in **ORD_LINES**)
* record 3 - **blue** is the field (record **2** in ORD_LINES)
* record 4 - **size XXL** is the field (record **2** in ORD_LINES)
* record 5 - **brown** is the field (record **3** in ORD_LINES)
* record 6 - **leather** is the field (record **3** in ORD_LINES)
* record 7 - **size** **43** is the field (record **3** in ORD_LINES)

The **Events** for this particular order would be processed as follows, with the colours identifying the **Event** blocks -

* **OnStartMap**

* The order read from ORD_HEADER.

  * **OnStartMap**

  * The first line of the order read from ORD_LINES (socks),

    * **OnStartMap**
    * The first message for the current line read from LINE_MSG (green),
    * The next message for the current line read from LINE_MSG (pink),
    * **OnEndMap** (there are no more lines for the current order line in LINE_MSG)

  * The next line of the order read from ORD_LINES (jersey),

    * **OnStartMap**
    * The first message for the current line read from LINE_MSG (blue),
    * The next message for the current line read from LINE_MSG (size XXL),
    * **OnEndMap** (there are no more lines for the current order line in LINE_MSG)

  * The next line of the order read from ORD_LINES (shoes),

    * **OnStartMap**
    * The first message for the current line read from LINE_MSG (brown),
    * The next message for the current line read from LINE_MSG (leather),
    * The next message for the current line read from LINE_MSG (size 43),
    * **OnEndMap** (there are no more lines for the current order line in LINE_MSG)

  * **OnEndMap** (there are no more lines for the current order in ORD_LINES)

  * **AfterDetailMap**

* **OnEndMap** (there are no more records in ORD_HEADER)

To see how a procedure can produce a visual example of this **Event Execution** grid in a **Log File**, please refer to [Procedures And Include Files](/statelake/scripting-reference/functions-and-procedures/what-is-a-procedure/procedures-and-include-files).
