1. General information

  • A script is a programmatic code executed on the server side.
  • Scripts can be executed:
    • in server events of edit forms,
      • OnBeforeOpen – executed before opening an edit form after clicking “Save and new”,
      • OnAfterOpen – executed after an edit form is opened,
      • OnBeforeSave – executed before a record is saved to the database,
      • OnAfterSave – executed after a record is saved to the database,
      • OnBeforeDelete – executed before a record is deleted from the database,
      • OnAfterDelete – executed after a record is deleted from the database,
    • after clicking a button in an edit form,
    • after clicking a button on a view page,
    • when attempting to create a new record from the “TimeTable” or “Planner” controls,
    • when creating a document with the “New from template” item of the “File” control, if the “Run script” field is checked on the “Print to template” tab – the script is shared with the button of the control. A detailed description is provided in the separate guide Edit form – File.
  • A reference to a script is always part of the configuration dialog of a control.
    • Most commonly this is the “ActionButtons” control (edit form server events) or the “Button” control (buttons in edit forms and view pages).
    • The link labeled “Edit script (number of script lines)” opens the script designer.
  • A script consists of numbered lines evaluated sequentially from top to bottom.
  • Each script line represents a single instruction.
  • NET Genium evaluates scripts line by line. General-purpose code blocks are not supported, but the “Cycle” command uses a block delimited by the “Next...” command.

1.1. Core script commands

  • Variable declaration
    • Defines the data type of a script variable.
    • If the variable already exists or contains a value, its type is changed and its value is set to database “null”.
  • Loading a value from a database query
    • Loads a value from a database query into a script variable or a form control.
    • Existing variable type and value are overwritten.
    • If a column of an “AutoSum” control is loaded into a database control of the Date type, the value is converted from the binary representation of a date to a date; a zero or negative value is saved as the database value “null”. A variable takes over the data type of the column, so the value of an “AutoSum” control remains a number in it.
  • Saving variable values back to the database
    • Writes variable values back to the database source.
    • The variable must not change the number of values it contains.
  • Loading multiple values from a database query
    • Loads values from multiple columns into variables or form controls.
    • The same applies to a column of an “AutoSum” control as for the “Loading a value from a database query” command – the value is converted to a date for a control of the Date type, but only without an arithmetic operator; with one, the assignment ends with a data type mismatch error.
  • Cycle
    • Iterates over values of a controlling variable using the “Next...” delimiter.
    • A script in which a “Cycle” command has no paired “Next...” command, or a “Next...” command has no “Cycle” command of its own, does not start at all – not even the lines before the cycle are executed – and ends with an error.
    • If the variable contains no values, the cycle is skipped.
    • During iteration, the controlling variable behaves as a single-value variable and, if it was loaded from a database query, so do the variables loaded by the same command as the controlling variable. Other variables with an array of values remain arrays of values inside the cycle as well. A detailed description of the behaviour of variables in a cycle is provided in the separate guide Working with variables in scripts.
    • Null values are automatically skipped.
    • The primary key “id” is recommended as the controlling variable.
  • Assignment
    • Assigns a single value or a mathematical expression to a variable or control.
    • For value arrays, the operation is applied to all elements.
    • If the value of an “AutoSum” control is assigned to a control or variable of the Date type, it is converted from the binary representation of a date to a date; a zero or negative value is assigned as the database value “null”. This applies only without an arithmetic operator – with one, the assignment ends with a data type mismatch error.
  • Comparison
    • Compares variable values or user-entered values.
    • Conditions testing whether a value is (not) filled in must, for text values, take both forms of an empty value into account – an empty string as well as the database value “null” (a composed condition: value equals “” or value is not defined). A detailed description of testing for an empty value is provided in the separate guide Working with variables in scripts.
  • Additional commands
    • Jump to line
    • Throw exception
      • Next to the text of the interruption, a database control of the edit form can be selected. If the edit form with this control is displayed after the interruption and the control is visible, the form scrolls to it and places the cursor into a “TextBox” or “TextArea” control. If the control is on another tab or hidden, the form stays at its original position.
    • Send email
    • Delete database records – all records returned by the query are deleted except system records, which are skipped without an error message
    • Redirect to an edit form (available only in OnBeforeOpen, OnAfterSave, OnAfterDelete) – the command ends the script and the lines after it are not executed; it therefore belongs at the end of the script. In the “OnBeforeOpen” script the user is already opening a new record, so there the command only ends the script. In the “OnAfterSave” script the redirect is performed only after saving with the “Save” or “Save and continue editing” button; after saving in any other way (printing to a template, a button script, “Save and new”) it is not performed
    • Create new database records
      • The command can have a database query as its data source. If at least one assignment reads a column of this query, one new record is created for each record returned by the query; if the query returns no record, nothing is created. Otherwise the query is not run and a single record is created. A command without any assignment creates no record.
      • The owner of the new record is the user who ran the script. If the command does not assign the “pid” and “pform” values, the record stays without a link to a parent record.
      • Default values of controls are not filled in. The only exception is a text box of the Integer or Long type with the default value “Max + 1”, “Max + 1 (local)”, “Max + 1: uniform numerical series” or “Max + 1: uniform numerical series (local)” to which the command assigns no value or an empty value – it gets the next number of the series. All other values have to be assigned in the command.
      • An empty value assigned to a column of a data type other than String is saved as the database value “null”.
      • If the command assigns the value of an “AutoSum” control (from the edit form or from a column of the source query) to a column of the Date type, it converts the value from the binary representation of a date to a date; a zero or negative value is saved as the database value “null”. This makes sense only for an “AutoSum” control that calculates the Average, MAX or MIN function from a date column, and only without an arithmetic operator.
    • Save one or more values to the database
    • Comment (including calls to external functions)
      • Server and external functions written into the comment field are executed only by the “33. Comment” command. The comment field that the commands 1, 2, 4, 9 and 27–32 also have is only a descriptive note – functions written into it are not executed.

1.2. Nature of the scripting language

  • NET Genium scripting is a declarative, line-oriented language.
  • It supports declarative cycles and controlled conditional branching through conditional command variants and the “Jump to line” command.
  • A jump may only target any of the following (later) lines or the end of the script; backward jumps are not allowed. A jump from inside a cycle out of it, even out of several nested cycles at once, is allowed; a jump into the body of another cycle (past its “Cycle” command) is not supported. Logic that cannot be expressed using the available commands must be implemented using external functions written in C#.

1.3. Running scripts outside the web interface

  • Scripts assigned to buttons on view pages can be executed externally using the “RunScript.exe” utility.
  • The utility is located in the “NETGenium\bin” directory on the server.
  • The “RunScript.exe” utility is not available in NET Genium Online – the customer has no access to the directories of the cloud server.

1.4. Script errors and interruptions

  • Script execution may fail due to syntax errors, conversion errors, database write errors, or explicit interruptions.
  • In all cases, execution is terminated, control returns to the original context, and an error message is displayed.
  • For “OnBeforeSave” and “OnBeforeDelete” scripts, interruption prevents saving or deleting the record.
  • An interruption rolls back only the database changes that the script has not committed yet. Changes committed by the “COMMIT()” function, writes of external functions through their own database command and writes of server functions that write to the database themselves – for example “OBSOAS”, “DELETEDATA”, “DELETEHISTORY”, “UPDATEAUTOSUM”, “COPYATTACHMENT”, “CREATEATTACHMENT”, “RENAMEATTACHMENT”, “RESETUSERPASSWORD”, “SENDUSERPASSWORD” and “SENDCHATMESSAGE” – stay in the database.
  • An interruption does not take back the values that the script assigned to the controls of the current record before the interruption. If the edit form is displayed after the interruption, it contains these values, and the next saving of the record saves them.
  • The “Send email” command in the “OnBeforeSave” and “OnAfterSave” scripts queues the message, which is sent only after the record is saved. In other scripts the message is sent immediately, so a later interruption of the script does not take it back.
  • In NET Genium Online the duration of a script is limited to 10 seconds. Once the limit is exceeded, the script is terminated with the error “Timeout expired! The maximum duration of the script is 10 seconds.” The limit is checked before each next line of the script starts – a line that is already running is completed and the error occurs only before the following line; if the last line of the script exceeds the limit, no error occurs.

1.5. Scope of the scripting language

  • The NET Genium scripting language is a closed and limited language designed exclusively for controlling application logic on the server side. A script may use only the variables, commands, operators, server functions, and external functions explicitly described above. Any other constructs, functions, operators, data types, return values, code blocks, or language elements are not supported and cannot be used in scripts. If the required functionality cannot be implemented using the available script commands, variables, and server functions, it must be implemented as an external function written in the C# programming language.

1.6. The “Send email” command

  • If multiple recipients or a variable with a list of values are specified, the message is sent to all recipients as blind carbon copies; the “Do not use Bcc for multiple recipients” option keeps them in the recipient field.
  • An empty recipient specified by a variable or a control interrupts the script with the message “Message must contain a recipient.”. If a recipient written as text becomes empty only after the values are substituted and no copy remains, the message is sent to the service e-mail address from the NET Genium settings and “NG NO-RCPT:” is inserted into the subject.
  • Invalid recipient and copy addresses (for example a name instead of an e-mail address) are omitted. If all specified addresses are invalid, the message is not redirected to the service e-mail address and is not sent – it is saved into the “SMTP” directory and “ResendEmlFiles.exe” does not send it later either (error “No recipients”).
  • An empty sender interrupts the script with the message “Message must contain a sender.”; if the sender is written as text and is empty after the values are substituted, the default sender of all messages is used.
  • The “Send only when data changes” option applies only in the “OnBeforeSave” and “OnAfterSave” scripts: the message is not sent if no value of the record has changed. A value filled in by a default value before every save and a change of an empty value to an empty text do not count as a change.
  • The “Insert link to the record” option inserts the link only for a saved record.
  • The message is translated into the language of the recipients, including copies and blind copies; the language of a recipient is looked up in the user account by e-mail address and recipients without an account are not taken into account.
    • If all recipients with an account have the same language, the subject, the text above and below the message body, the names of the listed controls and their values are translated into it.
    • If none of the recipients has an account, the message is translated into the language of the user whose action sent the e-mail — usually the user whose action started the script.
    • If the recipients with an account have different languages, the subject, the text above and below the message body and the names of the listed controls contain only the versions of these languages separated by “ / ”; if any of them lacks its own version, they also contain the default text. The values of the controls are translated into the language of the user whose action sent the e-mail; the unit after a value follows the languages of the recipients in the same way as the names of the controls.
    • If any recipient has an account without a language set, the subject, the text above and below the message body and the names of the listed controls contain all language versions separated by “ / ”; the values of the controls are translated into the language of the user whose action sent the e-mail, the unit after a value follows the languages of the recipients in the same way as the names of the controls.
    • Texts that NET Genium adds to the message are not translated according to the language of the recipients: the link to the record and the label of an attached file are in the language of the user whose action sent the e-mail, the link to the record in a linked installation in the language set for the link.
  • If the subject contains a line break after the values are substituted (typically from a multi-line text field), the message is sent with an empty subject.
  • If the subject starts, after the values are substituted, with an exclamation mark followed by a character other than another exclamation mark, the exclamation mark is removed from the subject and the message requests a read receipt to the reply-to address or, if none is set, to the sender address.
  • In the “OnBeforeSave” and “OnAfterSave” scripts, messages are sent only after the transaction is committed. If the “OnAfterSave” script ends with an error, the messages it queued are not sent – except for the messages queued before the “COMMIT()” function was called; messages from the “OnBeforeSave” script are. If the “OnBeforeSave” script or the saving of the record itself ends with an error, the record is not saved and no message from this script is sent, not even a message queued before the “COMMIT()” function was called.

2. Script designer dialog

  • The text boxes on the script lines intended for a value, a column and a comment can be opened in a spacious multi-line input field on a new tab. Double-clicking a filled-in text box displays the link “Open ... in a new tab (in a new window)...” below it, which opens a separate window with a multi-line field; the value saved in this window is transferred back to the text box on the script line.

2.1. Drop-down list “Enter the command...”

  • A drop-down list with a selection of the type of command that will be inserted into the script at the selected location.
    • 1. Declare variable
    • 2. Assign value from query
    • 3. Save variable back to the database
    • 4. Assign more/multiple values from query
    • 5. Cycle
    • 6. Assign value
    • 7. If (expression) assign value
    • 8. If (composed expression) assign value
    • 9. Go to line
    • 10. If (expression) go to line
    • 11. If (composed expression) go to line
    • 12. Throw exception
    • 13. If (expression) throw exception
    • 14. If (composed expression) throw exception
    • 15. Send email
    • 16. If (expression) send email
    • 17. If (composed expression) send email
    • 18. Delete record
    • 19. If (expression) delete record
    • 20. If (composed expression) delete record
    • 21. Redirect to new record
    • 22. If (expression) redirect to new record
    • 23. If (composed expression) redirect to new record
    • 24. New record
    • 25. If (expression) new record
    • 26. If (composed expression) new record
    • 27. Save value to the database
    • 28. If (expression) save value ...
    • 29. If (composed expression) save value ...
    • 30. Save more/multiple values to the database
    • 31. If (expression) save more/multiple ...
    • 32. If (composed expression) save more/multiple ...
    • 33. Comment
  • The designer offers the commands 21–23 only in the “OnBeforeOpen”, “OnAfterSave” and “OnAfterDelete” scripts. In other scripts they are missing from the list and the numbers of the other commands stay the same.
  • Below the drop-down lists is a row of buttons with the numbers of the commands. Clicking a button inserts the command with this number at the selected location, in the same way as selecting it in the “Enter the command...” list.

2.2. Drop-down list of the range of variables

  • Drop-down list with a selection of the range of variables that the designer offers on individual lines of the script for storing values.
  • The range only determines the variables offered in the script designer – at run time the script has all variables available. The range cannot be narrowed below the highest variable used by the script – in that case the designer extends it automatically. Writing a script via the MCP server or the ai-model utility does not change the range; the designer adjusts it the next time the script is opened.
  • Above the list is the label “Variables and functions”, shared with the list described in chapter 2.3. Hovering the mouse over the label displays the variables of the selected range that the script does not use yet (“Free variables”).
  • A detailed description of the variables is provided in the separate guide Variables.

2.3. Drop-down list “Variables and functions”

  • Drop-down list with a selection of variables and functions that can be used on individual lines of the script – script variables of the selected range, system variables, external functions, functions creating a value or an array of values of a given data type (for example “String(...)” or “IntegerArray(...)”), aggregate functions and server functions.
  • A detailed description of the server functions is provided in the separate guide Server functions.

2.4. Drop-down list “Values”

  • A drop-down list with a selection of database control identifiers that can be used on individual lines of the script.

2.5. Link “Dictionary...”

  • The dictionary displays a list of comments and interrupts used across all scripts throughout the application that relate to the following types of commands:
    • The “message” parameter of the “SCHEDULEBACK” server function in the script comment
    • The “message” parameter of the “TEFUIG” server function in the script comment
    • The “message” parameter of the “TESUIG” server function in the script comment
    • The “message” parameter of the “THROWEXCEPTION” server function in the script comment
    • The “message” parameter of the “WRITEMESSAGE” server function in the script comment
    • Script abort
  • Dictionary search is used to design the correct form of user messages and to maintain the consistency of nomenclature throughout the application.

2.6. Link “Change tracking...”

  • Change tracking displays a detailed report with the script changes made by individual users. By default, the report displays the last 10 changes; this number can be changed with the “maxrows” parameter in the report URL. Consecutive saves by the same user on one day and saves that did not change the content are merged by the report into one change; the “full=true” parameter in the report URL turns the merging off.

2.7. Link “Statistics...”

  • The statistics display aggregated information about the usage of the control associated with this script across the entire application.
  • The link is displayed only for the scripts of controls; it is missing for the scripts of the server events of an edit form.
  • Using the “Statistics” link opens a detailed report of all places where the control is used or referenced, including the ability to open the settings of that location or control.

2.8. Link “Logging...”

  • Using the “Logging” link displays a detailed report containing records of the script execution. The report includes information on:
    • the date and time when the script was executed,
    • the user who executed the script,
    • the script processing time,
    • the start date and time of the processing, and
    • the end date and time of the processing.
  • For logging to function correctly, logging must be enabled in the NET Genium modify on the “Other” tab, either as “To database” or “To database and disk”, A detailed description is provided in the separate guide NET Genium settings.
  • The minimum displayed script-processing time is set by default to 0 milliseconds, meaning that all script-execution records are shown, including those whose processing time was 0 ms. This minimum time can be increased or decreased by modifying the “mintime” parameter in the report URL.
  • The number of displayed records is limited by default to 100 entries. This number can be manually increased or decreased by modifying the “maxrows” parameter in the report URL.

2.9. “Run script” button

  • The “Run script” button is used to run the script in test mode.
  • The current version of the script is saved before it is run.
  • Running a script simulates the progress of script processing, but does not store any values in the database or delete any records from the database.
  • Database queries of the script read the current data from the database. The “Send email” command is skipped in test mode and the “COMMIT()” and “OBSOAS” functions are not performed; an interruption of the script, on the other hand, is triggered just as in a real run.
  • A script of an edit form (a form event or a script of a control of the edit form) is evaluated in test mode over the values of the record from which the configuration dialog of the control was opened. If the dialog was opened for a new record or outside the edit form (for example from reports), the script runs over an empty record.
  • When the run finishes, the values of all script variables are displayed, together with a warning stating the line number and the number of returned records for each “Assign value from query” and “Assign more/multiple values from query” command whose query did not return exactly one record. If the script ends with an error, only the text of the error is displayed.
  • External functions are called in test mode with the value “true” in the “test” parameter and with the value “null” in the “cmd” parameter. Whether the function writes nothing in test mode is up to the function itself – it should therefore start with a condition on the “test” parameter:
using System;

namespace NETGenium
{
public class ExternalFunctions
{
public static string ngef(string id, string[] args, bool test, DbCommand cmd, DbConnection conn)
{
if (test) return "";

switch (id)
{
// case "MyFirstFunction": return MyFirstFunction();
default: return conn == null ? "" : conn.ExternalFunctionNotFound(id, cmd);
}
}
}
}

2.10. “Save” button

  • Save changes to the script.

2.11. “Save and continue editing” button

  • Save changes to the script and leave the script open for further editing.