Welcome to the C/SIDE Reference Guide

This guide contains Help on all the functions, data types, properties and triggers in C/SIDE. It also provides general descriptions of some of the features and functionality that C/SIDE supports.

In the Table of Contents, all the C/AL functions are grouped alphabetically according to the data type that they support or according to a category. Each data type volume also contains a description of the data type. Each category volume contains the data types and corresponding functions that fall into that category.

Properties and triggers are also listed alphabetically.

In the Index, the names of data types and functions are written in block capitals. Furthermore, function names are followed by the name of the data type that they can be used with, for example, GETFILTER (Record). Property and trigger names are written as one word in camel case, for example, BorderStyle.

For more information about the C/SIDE development environment, see Application Designer's Guide, the reference manual for C/AL developers.


AUTOMATION

The Automation data type is used to reference an automation server. In order to use an automation server in C/SIDE, define a variable of type Automation and give it a name.

Then click the AssistButton in the Subtype field. In the Automation Object List form that now opens, use the AssistButton in the Automation Server field to get a list of available automation servers. Select a server and click OK. When the lookup form closes, the table part of the Automation Object List form is filled in with the interfaces of the selected automation server. Select an interface and click OK.

This procedure has selected the GUID of the automation server, the version number and the GUID of the interface. It is immediately evaluated into a human-readable name as <name of server>.<name of interface>, as in:

'Microsoft Excel 8.0 Object Library'.Application

When you have defined an automation server as a variable, you must use CREATE to create an instance of the server. After that, you can use the server through the variable. You can browse its methods and properties in the Symbol Menu.

When you are using a server, you should know that there is not a one-to-one relationship between C/AL data types and COM data types. Click here to see an overview of the data type mapping.

C/SIDE can receive events from an Automation server.


CREATE (Automation)

Use this function to create an Automation object.

[Ok :=] CREATE(Automation [,NewServer])

Ok

Data type: boolean

The return value of CREATE is TRUE if the Automation object could be created, and FALSE if it could not be created. If the return is not tested, execution will terminate with a run-time error.

Automation

Data type: automation

A variable of type Automation that has previously been declared.

NewServer

Data type: boolean

If NewServer is FALSE (the default), CREATE will try to reuse an already running instance of the automation server referenced by Automation before creating a new instance. If NewServer is TRUE, CREATE will always create a new instance of the automation server.

Comments

CREATE creates (instantiates) the automation server referenced by the Automation variable. While an OCX (custom control) is instantiated implicitly, Automation variables must be created explicitly.

If you have an array of OCXs, each control will be created when its first member is accessed.

If you have an array of automation servers, you have to call CREATE on each element individually. The NewServer variable can be used independently on each element.

The automation object that is created can be explicitly destroyed by CLEAR. The object will be destroyed implictly when the Automation variable goes out of scope.

An Automation variable can only be created once. You will get a run-time error if you try to create an Automation a scecond time, without calling CLEAR first. You will also get a run-time error if you try to create an OCX variable.


ISCLEAR (Automation)

Use this variable function to check whether an automation object has been created or not.

Ok := ISCLEAR(Automation)

Ok

Data type: boolean

The return value of Ok is TRUE if:

  • the automation variable has not been created. See CREATE.

  • the automation variable has been cleared. See CLEAR.

  • the automation variable has been assigned NULL by an automation server.

Automation

Data type: automation

Example

Here is an example of how you can use the ISCLEAR function:

VAR

d:
 Automation "'Microsoft XML, version 2.0'.DOMDocument";
n: Automation "'Microsoft XML, version 2.0'.IXMLDOMNodeList";
b: boolean;

CODE

b := ISCLEAR(d);

b will be TRUE

CREATE(d);
b := ISCLEAR(d);

b will be FALSE

CLEAR(d);
b := ISCLEAR(d);

b will be TRUE


VARIABLEACTIVE (Automation)

Use this function to determine if a variable, such as field or a control, is active or inactive.

IsActive := VARIABLEACTIVE(Variable)

IsActive

Data type: boolean

The result.

If IsActive is... | It means the variable is...
TRUE | Active
FALSE | Inactive

Variable

Data type: any

The variable you want to investigate.


BINARY

Use this simple data type to store variable lengths of binary data in a record. The maximum length of a binary field is 250 bytes.


BLOB

A BLOB (Binary Large Object) is a complex data type. Variables of this data type differ from normal numeric and string variables in that BLOBs have a variable length.

The maximum size of a BLOB is normally determined by your system's disk storage capacity. However, the maximum size in C/SIDE is 2GB.

Comments

Use BLOBs to store memos (text), pictures (bitmaps) or user-defined types, but note that C/SIDE cannot display text stored in BLOBs.

You can read from and write to BLOBs by creating input and output streams, respectively. To do so, use CREATEINSTREAM and CREATEOUTSTREAM.

More information:

InStream and OutStream


CREATEINSTREAM (BLOB)

Use this function to create an InStream object for a BLOB (Binary Large Object). This enables you to stream data into the BLOB.

Blob.CreateInStream(Stream)

Blob

Data type: Variable

Stream

The InStream object type that has been created.

More information:

Code Example for Streams


CREATEOUTSTREAM (BLOB)

Use this function to create an OutStream object for a BLOB (Binary Large Object). This enables you to stream data out of the BLOB.

Blob.CreateOutStream(Stream)

Blob

Data type: Variable

Stream

The OutStream object type that has been created.

More information:

Code Example for Streams


EXPORT (BLOB)

Use this function to export a BLOB (Binary Large Object).

[ExportName :=] := Blob.EXPORT([Name [, CommonDialog]])

ExportName

Data type: text

The name and path of the file the system imported.

If ExportName is... | It means the BLOB was...
The file's name and path | Exported
Blank | Not exported

Blob

Data type: variable

The BLOB you want to export.

Name

Data type: text or code

The path and name of the BLOB you want to export. When you enter the path, keep in mind these shortcuts:

You can... | If the command is located...
Omit the drive designation | On the current drive
Omit the full path | In the current directory
Enter only the subdirectory name | In a subdirectory of the current directory

CommonDialog

Data type: boolean

This tells the system whether or not you want it to display a dialog before it exports the BLOB. This dialog window lets you select the file you want to export. Based on the SubType property, the system only lists the appropriate file type, such as a bitmap files (*.bmp), memo files (*.txt), or all files (*.*).

If CommonDialog is... | It means the system will...
TRUE | Display the confirmation dialog
FALSE (default) | Not display the confirmation dialog


HASVALUE (BLOB)

Use this function to determine if a BLOB (Binary Large Object) has a value.

HasValue := Blob.HASVALUE

HasValue

Data type: boolean

If HasValue is... | It means the BLOB...
TRUE | Has a value
FALSE | Does not have a value

Blob

Data type: BLOB

The BLOB you want to check.


IMPORT (BLOB)

Use this function to import a BLOB (Binary Large Object).

[ImportName :=] := Blob.IMPORT([Name [, CommonDialog]])

ImportName

Data type: filename

The name and path of the file the system imported.

If ImportName is... | It means the BLOB was...
The file's name and path | Imported
Blank | Not imported

Blob

Data type: variable

The BLOB you want to import.

Name

Data type: text or code

The path and name of the BLOB you want to import. When you enter the path, keep in mind these shortcuts:

You can... | If the command is located...
Omit the drive designation | On the current drive
Omit the full path | In the current directory
Enter only the subdirectory name | In a subdirectory of the current directory

CommonDialog

Data type: boolean

This tells the system whether or not you want it to display a dialog before it imports the BLOB. This dialog window lets you select the file you want to import. Based on the SubType property, the system only lists the appropriate file type, such as bitmap files (*.bmp), memo files (*.txt), or all files (*.*).

If CommonDialog is... | It means the system will...
TRUE | Display the confirmation dialog
FALSE (default) | Not display the confirmation dialog


BOOLEAN

Use this simple data type to indicate one of two values: TRUE or FALSE.

Comments

For usability reasons, boolean values are sometimes shown as Yes or No in the system. For instance, for the form property InsertAllowed, the two possible values are Yes or No.


CHAR

Use this simple data type to store a single character as a value in the range 0 to 255. You can easily convert this data type from a number to a character and vice versa. This means you can use mathematical operators on char variables as well as numeric variables.

Example

You an assign a constant string of the length 1 to a char variable:

C := 'A';

You can also assign a single char in a text, code, or binary variable to a char variable:

C := S[2];


CODEUNIT

Use this complex data type to store units of C/AL code. Codeunits contain a number of user-defined functions.


Codeunit.RUN

Use this function to load and execute the unit of C/AL code you specify. See also RUN (codeunit).

[Ok] := Codeunit.RUN(Number [, Record])

Ok

Data type: boolean

If you do not include the optional return value, and an error occurs while the system is executing the codeunit, it terminates the execution of the C/AL code that called this codeunit.

If you include the return value and there's an error, the system continues to execute the calling C/AL code. This means you must handle any errors. The possible values are shown below.

If Ok is... | It means that...
TRUE | No errors occurred
FALSE | An error occurred during the execution of the codeunit

If you include the return value, the system automatically clears the variables used in the codeunit object before and after it executes the object.

If you use the return value in an IF statement which is inside a write transaction, a run-time error occurs unless you commit your data updates before you call Codeunit.RUN.

Number

Data type: integer

This number identifies the unit of C/AL code. You can use the Symbols option on the View menu to choose from a list.

If the codeunit you specify does not exist, a run-time error occurs.

If the codeunit you specify does not exist, a compile error occurs.

If you run the codeunit with a record from a table other than the one it's associated with, you will get a run-time error.

Record

Data type: record

This optional parameter identifies a record.

Example

The following example shows how to use the Codeunit.RUN function.

Codeunit.RUN(4711, SomeRecord);


RUN (Codeunit)

Use this function to load and execute the unit of C/AL code you specify. To use this function, you can specify a C/SIDE table associated with the codeunit when you defined the codeunit properties. This lets you pass a variable with the function. The transaction that the codeunit contains is always committed due to the boolean return value.

[Ok] := Codeunit.RUN(VAR Record)

Ok

Data type: boolean

If you do not include the optional return value and an error occurs while the system is executing the codeunit, it terminates the execution of the C/AL code that called this codeunit.

If Ok is... | It means that...
TRUE | No errors occurred
FALSE | An error occurred during the execution of the codeunit

If you include the return value and an error occurs, the system continues to execute the calling C/AL code. This means you must handle any errors. If you include the return value, the system automatically clears the variables used in the codeunit object before and after it executes the object.

Codeunit

Data type: codeunit

This identifies the unit of code you want the system to execute.

VAR Record

Data type: record

This parameter is not always optional. If you specify a C/SIDE table associated with the codeunit, you can select a record. If you did not specify a table, you cannot specify a record. However, you must use this parameter to select a record if you attached a record to the codeunit when you defined its properties.

Example

The following example shows how to use the RUN (codeunit) function.

VAR
c : CodeUnit1,
c.XXX(expression1, ...); // any user-defined function
c.RUN(Rec)


Matrix Box

Contents

General Description

Navigating in a Matrix Box

Creating a Matrix Box

Programming Information

General Description

A matrix box is a composite control that can show information from several tables at the same time. The first two tables are the vertical and the horizontal table of the matrix box control. In the matrix part of the control, each cell can be used to display information that is calculated on basis of fields in these two tables, or information that is retrieved from other tables (with values from the first two tables being used to select records, for example by setting filters). Each cell in the matrix is the intersection of a record from the vertical and the horizontal table.

The part to the left of the vertical divider bar displays records from the vertical table, the table that is the source table of the form, in a way similar to an ordinary table box. To the right of the divider bar is the matrix itself. Above it, the records from the horizontal table are displayed (in the style that is normally used for the labels in a table box) - this is the matrix heading. The horizontal table is called the matrix source table.

Navigating in a Matrix Box

Navigating in a matrix box is a bit more complex than usual, since there are several tables and dimensions involved. The following describes how to move around, both by using the mouse and by using the keyboard.

Using the mouse

You can scroll the vertical table vertically by clicking the navigation buttons at the right of the matrix, and you can scroll the horizontal table horizontally by clicking the navigation buttons at the bottom of the matrix. If all columns of the vertical table do not fit in the "table box", a normal scroll bar will be added below, and you can scroll the columns horizontally, as in an ordinary table box.

You can resize any column by placing the cursor in the label area and then dragging when the cursor changes to the resize cursor (which it does when it is on top of a column divider). Dragging the vertical divider bar changes the relative proportions of the table box and matrix box parts.

The height of the headings, both in the table box and the matrix part of the control, can be adjusted by dragging, and the columns in the table box part can be resized vertically.

Using the keyboard

In order to use the keyboard for navigation, you will have to place the focus in the part of the control you want your keystrokes to affect.

You can move from one part of the control to another by pressing Ctrl+<arrow>. That is, to move from the table box to the matrix, press Ctrl+Right; to move from the matrix to the matrix heading, press Ctrl+Up; to move from the matrix heading back to the matrix, press Ctrl+Down; to move from the matrix to the table box, press Ctrl+Left. You cannot go directly from the matrix heading to the table box (you have to go via the matrix).

When you are placed in the matrix heading, PageUp and PageDown scrolls the horizontal table (that is, a horizontal scroll).

Ctrl+PageUp or Ctrl+PageDown in the matrix part (including the matrix heading) will also scroll the horizontal table.

Creating a Matrix Box

It can be confusing to create a matrix box for the first time. Here is a step-by-step instruction to guide you through the process (what will be created is a matrix box where both the vertical and the horizontal table are based on the Integer table, and the matrix cells display the product of the two integers in the records that intersect at that cell).

  1. Create a new form, and select the Integer table as the source table.

  2. Add a matrix box to the form. Give the matrix box control a name (by setting the Name property), and set the HorzGlue and VertGlue properties to Both.

  3. Insert a text box with the Number field from the Integer record as the source expression in the table part of the matrix box.

  4. In the property sheet of the matrix box control, select Integer as the MatrixSourceTable property.

  5. Add a text box without a source expression to the empty part of the matrix box control. Check the InMatrix property of this text box - it should be Yes.

  6. Add a text box without a source expression to the last empty part (the matrix heading) of the matrix box control. Check the InMatrixHeading property of this text box - it should be Yes.

  7. Add a source expression to the text box in the matrix heading (the last one added.) The source expression should point to a field from the MatrixSourceTable. If the matrix box was named Matrix, and the horizontal table is the Integer table, it could be:

    CurrForm.Matrix.MatrixRec.Number

  8. Add a source expression to the text box in the matrix. Here, it could be:

Number * CurrForm.Matrix.MatrixRec.Number

Programming Information

In order to access the horizontal table (the matrix source table), you must give the matrix box control a name (by setting the Name property of the control.

When the matrix box control has a name, the records of the table can be accessed as

CurrForm.<name of matrix box control>.MatrixRec.<field>

Triggers

A matrix box control has these triggers:

OnFindRecord, OnNextRecord, OnAfterGetRecord, OnAfterGetCurrRecord, OnBeforePutRecord, OnNewRecord, OnInsertRecord, OnModifyRecord and OnDeleteRecord.

Properties

A matrix box has these properties:

ID, Name, XPos, YPos, Width, Height, HorzGlue, VertGlue, Visible, Enabled, Editable, Focusable, ParentControl, InFrame, InPage, BackColor, Border, BorderColor, BorderStyle, BorderWidth, RowHeight, MatrixColumnWidth, HeadingHeight, ToolTip, InlineEditing, Description and MatrixSourceTable.

These text box properties are special for text boxes that are part of a matrix box control:

InMatrix and InMatrixHeading.

(% MAT_VERT "Vertical table")

This area contains records from the vertical table - the table that is the source table of the form.

(% MAT_HORZ "Horizontal table")

This area contains records from the horizontal table - the table that is the matrix source table. This area is also known as the matrix heading.

(% MAT_MAT "Matrix")

This area is the matrix itself. Each cell is at the intersection of a record from the vertical table and one from the horizontal table.

(% MAT_NV "Vertical navigation")

Use the navigation buttons in this area to scroll the vertical table.

(% MAT_NH "Horizontal navigation")

Use the navigation buttons in this area to scroll the horizontal table.

(% MAT_SCROLL "Scroll bar")

Use this scroll bar to see other records from the vertical table.


ACTIVATE (Form)

Use this function to make a form or control active. This function applies to command buttons, menu buttons, check boxes, option buttons, text boxes, picture boxes, indicators, subform controls, and forms.

[Ok := ] Form.ACTIVATE

Ok

Data type: boolean

Comments

A form or control can become active when the end user clicks on it or selects it by any other means such as through the keyboard. This function provides another way to make active a form or control that's already displayed on the screen.

When you call this function on a form, the system activates the form and places control on the active control on the form. If the form is locked by another form running modally, the system also activates the other form. A form can only be activated when it is running and visible.

When you call this function on a control, the system makes the control the active control on the form. If the control is already active, the system gives focus to the control. If the control is not active, the system gives it focus the next time the form is activated. You must load the form before you can activate its controls.


DECIMALPLACESMAX (Control)

Use this function to return the current setting of the maximum number of decimal places for a control (field or text box), and to set a new value. The function manipulates the maximum number-part of the setting of the DecimalPlaces property.

[CurrMaxDecimals] := DECIMALPLACESMAX([NewMaxDecimals])

CurrMaxDecimals

Data type: integer

The current setting of the maximum number of decimal places.

NewMaxDecimals

Data type: integer

The new setting of the maximum number of decimal places.

Comments

See the description of the DecimalPlaces property for details.


DECIMALPLACESMIN (Control)

Use this function to return the current setting of the minimum number of decimal places for a control (field or text box), and to set a new value. The function manipulates the minimum number-part of the setting of the DecimalPlaces property.

[CurrMinDecimals] := DECIMALPLACESMIN([NewMinDecimals])

CurrMinDecimals

Data type: integer

The current setting of the minimum number of decimal places.

NewMinDecimals

Data type: integer

The new setting of the minimum number of decimal places.

Comments

See the description of the DecimalPlaces property for details.


EDITABLE (Form & Control)

Use this function to return the current setting of the Editable property, and to change the setting of the property.

This function can be used on forms and controls.

[IsEditable] := From.EDITABLE([SetEditable])

IsEditable

Data type: boolean

The current value of the Editable property.

SetEditable

Data type: boolean

The new setting of the Editable property.

Comments

See the description of the Editable property for details.


ENABLED (Control)

Use this function to return the current setting of the Enabled property of a control, and to change the setting of the property.

[IsEnabled] := ENABLED([SetEnabled])

IsEnabled

Data type: boolean

The current value of the Enabled property.

SetEnabled

Data type: boolean

The new setting of the Enabled property.

Comments

See the description of the Enabled property for details.


HEIGHT (Form & Control)

Use this function to return the current setting of the Height property of a form or control, and to set this property to a new value.

[CurrHeight] := Form.HEIGHT([NewHeight])

CurrHeight

Data type: integer

The current setting of Height.

NewHeight

Data type: integer

The new setting of Height.

Comments

See the description of the Height property for details.


INLINEEDITING (Table Box & Matrix Box)

Use this function to return the current setting of the InlineEditing property of a table box or a matrix box, and to change the setting of the property.

[IsInLineEditing] := INLINEEDITING([SetInLineEditing])

IsInLineEditing

Data type: boolean

The current value of the InlineEditing property.

SetInLineEditing

Data type: boolean

The new setting of the InlineEditing property.

Comments

See the description of the InlineEditing property for details.


UPDATEEDITABLE (Form & Control)

Use this function to dynamically change the setting of the Editable property of a field, form or control.

UPDATEEDITABLE(Editable)

Editable

Data type: boolean

Possible values:

TRUE | Means that the control be editable.
FALSE | Means that the control should not be editable.

Comments

This function can only be called from the OnBeforeInput of the control. The property will only be changed temporarily, that is for the duration of this form.

Example

You can use this function to set the Editable property of a control dynamically, based on, for example, the current value of some other field, like this:

IF "On Hold" THEN
CurrForm.Address.UPDATEEDITABLE(FALSE);


UPDATESELECTED (Control)

Use this function to mark a control as selected (which will normally be displayed in reverse video, but this depends upon the Windows color scheme that the end user has chosen.)

UPDATESELECTED(Selected)

Selected

Data type: boolean

Possible values:

TRUE | Means that the control will be marked as selected.
FALSE | Means that the selection indication will be removed from the control.

Comments

This function can only be used in the OnFormat trigger.


UPDATEFONTBOLD (Control)

Use this function to dynamically change the setting of the FontBold property of a control.

UPDATEFONTBOLD(FontBold)

FontBold

Data type: boolean

Possible values:

TRUE | Means that the control will be shown in bold.
FALSE | Means that the control will not be shown in bold.

Comments

This function can only be called from the OnFormat trigger of the control. The property will only be changed temporarily, that is for the duration of this form.

Example

The intended use of this function is to display controls of selected records in a tabular form by using the bold font. If a repeated control in a table box has the FontBold property set to yes, then all rows will be using the bold font. By using this function, you can select individual records where the bold font should be used, based on, for example, the current value of some other field, like this:

IF Type = Type::Heading THEN
CurrForm.Name.UPDATEFONTBOLD(TRUE);


UPDATEFORECOLOR (Control)

Use this function to dynamically change the setting of the ForeColor property of a control.

UPDATEFORECOLOR(ForeColor)

ForeColor

Data type: integer

The ForeColor parameter is used to set the new foreground (text) color. The integer value identifies a color by using the RGB value of the color.

Comments

This function can only be called from the OnFormat trigger of the control.

Example

The intended use of this function is to display controls of selected records in a tabular form in a specific foreground (text) color. The color set by the ForeColor property causes all rows to be displayed in this color. By using this function, you can select individual records where the color should be used, based on, for example, the current value of some other field, like this:

IF Amount < 0
CurrForm.Amount.UPDATEFORECOLOR(255);

This would display the Amount control with red as the foreground color (see RGB for details on finding the integer value to use.)


UPDATEINDENT (Text Box)

Use this function set the Indent property of a text box.

UPDATEINDENT(Indent)

Indent

Data type: integer

The indentation in 1/100 mm.

Comments

The Indent property can only be set by using this function from the OnFormat trigger of the text box - it cannot be set from the property sheet.

The intended use is to provide some means of structuring information in a tabular form by indenting the contents of a text box, based on some notion of a hierarchy. See also the UPDATEFORECOLOR and UPDATEFONTBOLD functions which are meant to be used for similar purposes.

Example

You can use this function to indent a text box in a tabular form according to the value in some other field this:

CurrForm.Name.UPDATEINDENT(Level * 220);

The Level field is supposed to contain integer values from 0 and upwards. The higher this value is, the more indentation will be added to text box that displays the contents of the Name field.


VISIBLE (Form & Control)

Use this function to return the current setting of the Visible property of a form or control, and to change the setting of the property.

[IsVisible] := Form.VISIBLE([SetVisible])

IsVisible

Data type: boolean

The current value of the Visible property.

SetVisible

Data type: boolean

The new setting of the Visible property.

Comments

See the description of the Visible property for details.


WIDTH (Form & Control)

Use this function to return the current setting of the Width property of a form or control, and to set this property to a new value.

[CurrWidth] := Form.WIDTH([NewWidth])

CurrWidth

Data type: integer

The current setting of Width.

NewWidth

Data type: integer

The new setting of Width.

Comments

See the description of the Width property for details.


XPOS (Form & Control)

Use this function to return the current setting of the XPos property of a form or control, and to set this property to a new value.

[CurrXPos] := Form.XPOS([NewXPos])

CurrXPos

Data type: integer

The current setting of XPos property.

NewXPos

Data type: integer

The new setting of XPos property.

Comments

See the description of the XPos property for details.


YPOS (Form & Control)

Use this function to return the current setting of the YPos property of a form or control, and to set this property to a new value.

[CurrYPos] := Form.YPOS([NewYPos])

CurrXPos

Data type: integer

The current setting of YPos property.

NewXPos

Data type: integer

The new setting of YPos property.

Comments

See the description of the YPos property for details.


CHECKLICENSEFILE (Database)

Use this function to check a key in the license file of the system.

CHECKLICENSEFILE(KeyNumber)

KeyNumber

Data type: integer

The number of the key you want to check.

Comments

The system's license file turns on or off different system capabilities. Use this function to check a key in that file for the current user. If the user has no access rights to the object in question, the system displays a message and terminates the process.

If you omit this function, the user will have the ability to continue regardless of whether he or she has the appropriate license file or not.


COMMIT (Database)

Use this function to end the current write transaction.

COMMIT

Comments

When the system enters a C/AL codeunit, it automatically enables write transactions to be performed. When the system exits a C/AL code module, it automatically ends the write transaction by committing the updates made by the C/AL code.

This means that if you want the C/AL codeunit to perform a single write transaction, the system automatically handles it for you. However, if you want the C/AL codeunit to perform multiple write transactions, you must use the COMMIT function to end one write transaction before you can start the next. The COMMIT function separates write transactions in a C/AL code module.

Example

The metasyntax below contains two write transactions. As execution begins, a write transaction is automatically started. Using the COMMIT function, you tell the system that the first write transaction has ended and prepare the system for the second. Once execution has been completed, the system automatically ends the second write transaction.

BeginWriteTransactions

(C/AL Statements) // Transaction 1

COMMIT(...)

(C/AL Statements) // Transaction 2

EndWriteTransactions


COMPANYNAME (Database)

Use this function to return the current company name.

Name := COMPANYNAME

Name

Data type: text constant or code

The name of the company, or an empty string if no company has been selected.

Example

This example shows how to use the COMPANYNAME function to retrieve the name of the current company.

Name := COMPANYNAME;
MESSAGE(Text000, Name);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The name is: %1'


CURRENTTRANSACTIONTYPE (Database)

This function can be used both to return the current transaction type and set a new type to be assigned.

[TransactionType :=] CURRENTTRANSACTIONTYPE([TransactionType])

TransactionType

Data type: TransactionType

The type of transaction to be set for the next transaction, or retrieved.

Comments

This function sets the transaction type for the next transaction that begins when you are using SQL Server. The transaction type determines the extent of locking that is performed on data in SQL Server tables and indexes. It also determines whether or not modifications to data can occur within the transaction. The following basic transaction types are available:

Browse

Snapshot

UpdateNoLocks

Update

Report

The Report transaction type maps to one of the other basic transaction types. Click here for more information about the behavior of the transaction types.

Note that using CURRENTTRANSACTIONTYPE to set a transaction type from within a currently active transaction has no effect on the transaction type. You must set the transaction type before a transaction begins, which occurs at the first database call in a trigger or in a codeunit. If you set the current transaction type to a less isolated transaction behavior, for example, if you try to change an Update transaction to a Browse transaction, the system ignores the function call. If you try to change the current transaction type to a more isolated transaction behavior, for example, from Browse to Update, you will receive an error message.

Example 1

CURRENTTRANSACTIONTYPE can be used to set the required behavior of the next transaction in the database:

CURRENTTRANSACTIONTYPE := TRANSACTIONTYPE::UpdateNoLocks;

It can also be used to make the system return the transaction type setting for the current transaction.

IF CURRENTTRANSACTIONTYPE = TRANSACTIONTYPE::UpdateNoLocks THEN...

Example 2

The following examples show you how to use the CURRENTTRANSACTIONTYPE function to set the transaction type for two separate transactions.

When you set the transaction type in this way you will get an update (or write) transaction using SERIALIZABLE behavior, which means that modifications are allowed within this transaction. Furthermore, SQL Server will guarantee the serializability of the transaction by placing the appropriate locks when you read from the table in the database.

CURRENTTRANSACTIONTYPE := TRANSACTIONTYPE::Update;

When you set the transaction type in this way you will get a read-only, non-locking transaction. This means that no modifications are allowed within this transaction and that SQL Server does not place any locks. It is also possible to read any uncommitted data.

CURRENTTRANSACTIONTYPE := TRANSACTIONTYPE::Browse;

Example 3

Scenario 1

OnInsert

{The current transaction type is UpdateNoLocks. This is usually the default transaction type for a trigger.}

CURRENTTRANSACTIONTYPE := TRANSACTIONTYPE::Browse;

{When you try to change the transaction type from UpdateNoLocks to Browse, which is a less isolated transaction type, the system ignores the function call. The current transaction type remains UpdateNoLocks.}

Table.GET;
CURRENTTRANSACTIONTYPE := TRANSACTIONTYPE::Browse;

{Again, when you try to change to a less isolated transaction type, the system ignores the function call. The current transaction type remains UpdateNoLocks.}

CURRENTTRANSACTIONTYPE := TRANSACTIONTYPE::Update;

{When you try to change the transaction type from UpdateNoLocks to Update, which is a more isolated transaction type, the function call causes the system to generate an error message. The current transaction type remains UpdateNoLocks.}

COMMIT;
CURRENTTRANSACTIONTYPE := TRANSACTIONTYPE::Browse;
CURRENTTRANSACTIONTYPE := TRANSACTIONTYPE::Update;

{The system is now ready for the next transaction. You can therefore set a new transaction type and change it again if required.}

Table.GET;

{The current transaction type is Update.}

CURRENTTRANSACTIONTYPE := TRANSACTIONTYPE::Browse;

{The system ignores this function call.}

OnInsert.RETURN
COMMIT;

Scenario 2

CODEUNIT

{The current transaction type is UpdateNoLocks.}

CURRENTTRANSACTIONTYPE := TRANSACTIONTYPE::Snapshot;

{When you try to change to a less isolated transaction type, the system ignores the function call.}

Report 1

CURRENTTRANSACTIONTYPE := TRANSACTIONTYPE::Browse;

{When you try to change to a less isolated transaction type, the system ignores the function call.}

Report 2

CURRENTTRANSACTIONTYPE := TRANSACTIONTYPE::Update;

{When you try to change to a more isolated transaction message, the function call causes the system to generate an error message.}

See also Transaction Type


LOCKTIMEOUT (Database)

Use this function to find out whether or not the lock timeout setting is set to on. You can also use this function to override the default setting.

[LockTimeout :=] LOCKTIMEOUT([LockTimeout])

LockTimeout

Data type: Boolean

This value tells you whether or not to use a lock timeout.

This function has been specifically designed for use in long running processes that shouldn't be terminated because of a lock timeout, for example batch jobs that run overnight.

When the C/AL code is finished executing, the default setting is used again. This function does not alter the duration of a lock timeout.

To change the default setting in Microsoft Dynamics NAV, click File, Database, Alter to open the Alter Database window. Click the Advanced tab and enter or remove the check mark from the Lock timeout field.


SELECTLATESTVERSION (Database)

This function forces the latest version of the database to be used.

SELECTLATESTVERSION

Comments

Microsoft Dynamics NAV Database Server

Due to the version principle, you are guaranteed that the database version that you use is consistent, even if you do some time-consuming processing, for example in a report, and other users update the database while the report is running.

In a situation where this is not desirable, and you need to use the latest version of data, you can use SELECTLATESTVERSION to enforce a reloading of the version that the client is using.

SQL Server

This function ensures that the data displayed is the most current data in the database. The function clears all non-locked records from the client cache, thereby ensuring that you read the most recent data.


SERIALNUMBER (Database)

Use this function to return a string which contains the serial number of the license file for your Microsoft Dynamics NAV system.

String := SERIALNUMBER;

String

Data type: text constant or code

This string contains the serial number.

Example

The following C/AL code shows how to use the database.SERIALNUMBER function.

SN := SERIALNUMBER;
MESSAGE(Text000 + Text001, SN);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The serial number for this\'
Text001 | 'software package is: %1'

The serial number is, of course, dependent on your licensed version of Microsoft Dynamics NAV. The serial number shown here is just an example.

The serial number for this
software package is: W1-ZA-002-6R75A-7


TRANSACTIONTYPE

Use variables of this complex data type to store the current transaction type. You can then use the value to set the transaction type. You can only change the transaction type when there is no current transaction, in other words immediately after a commit.

For more information about transaction types, see TransactionType.

For more information about the rules governing transaction types, see CurrentTransactionType.


USERID (Database)

Use this function to have the system return the ID of the current user.

ID := USERID

ID

Data type: text constant or code

This string contains the ID of the current user.

Comments

Unless set up otherwise, the system prompts you for a user ID and password when you start the application. This function returns the user ID entered there.

Example

This example shows how to use the USERID function.

User := USERID;
MESSAGE(Text000, User);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The system was started by %1'

A typical result:

The system was started by: JOE


Dataport

Dataports are objects that are used for importing data from and exporting data to external text files.

For more information about dataports, see the manual Application Designer's Guide.


BREAK (Dataport, Report, XMLport)

Use this function to exit from a loop or a trigger in a data item trigger of a dataport, report or XMLport.

BREAK

Comments

When used inside a loop - such as a WHILE..DO or REPEAT..UNTIL construction - BREAK causes the execution of the loop to end, and control will return to the statement that immediately follows the loop.

When used outside a loop, BREAK causes the execution of the current trigger to end.

Compare also with the QUIT function.

Example

The following shows how to use the BREAK function:

REPEAT
Myvar := Myvar +1;
IF Myvar = 5 THEN
CurrReport.BREAK;
MESSAGE(Text000,Myvar);
UNTIL Myvar = 10

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Myvar is now %1'

When this code is run, the execution of the loop will end when MyVar is 5.


DATAPORT.RUN (Dataport)

Use this function to load and execute the dataport you specify. If, at design time, you do not know the specific dataport you want to run, use this function or the DATAPORT.RUNMODAL function. If you do know the specific dataport you want to run, you can use the RUN (Dataport) function or the RUNMODAL (Dataport) function.

DATAPORT.RUN(Number [, ReqWindow] [, Record])

Number

Data type: integer

The ID of the dataport you want to execute. You can use the Symbols option on the View menu to choose from a list.

If the dataport you specify does not exist, a run-time error occurs.

ReqWindow

Data type: boolean

Tells the system whether it should display the request window for the dataport. The request window is part of the dataport object.

To... | Enter...
Display the request window before running the dataport | TRUE (default)
Run the dataport without showing the request window | FALSE

Record

Data type: record

Tells the system which record to use in the dataport. The system will use any filters attached to the record you specify.


DATAPORT.RUNMODAL (Dataport)

Use this function to load and execute the dataport you specify. The system runs the dataport modally. If, at design time, you do not know the specific dataport you want to run, use this function or the DATAPORT.RUN function. If you do know the specific dataport you want to run, you can use the RUN (Dataport) function or the RUNMODAL (Dataport) function.

DATAPORT.RUNMODAL(Number [, ReqWindow] [, Record])

Number

Data type: integer

The ID of the dataport you want to execute. You can use the Symbols option on the View menu to choose from a list.

If the dataport you specify does not exist, a run-time error occurs.

ReqWindow

Data type: boolean

Tells the system whether it should display the request window for the dataport. The request window is part of the dataport object.

To... | Enter...
Display the request window before running the dataport | TRUE (default)
Run the dataport without showing the request window | FALSE

Record

Data type: record

Tells the system which record to use in the dataport. The system will use any filters attached to the record you specify.


FILENAME (Dataport)

Use this function to return the current setting of the FileName property of a dataport, and to set this property to a new value.

[CurrFileName] := FILENAME([NewFileName])

CurrFileName

Data type: text

The current setting of FileName property.

NewFileName

Data type: text

The new setting of FileName property.

Comments

See the description of the FileName property for details.


IMPORT (Dataport)

Use this function to return the current setting of the Import property, and to change the setting of the property.

[IsImport] := IMPORT([SetImport])

IsImport

Data type: boolean

The current value of the Import property.

SetImport

Data type: boolean

The new setting of the Import property.

Comments

See the description of the Import property for details.


QUIT (Dataport, Report, XMLport)

Use this function to abort the processing of a dataport, report or XMLport.

QUIT

Comments

When the QUIT function is used, the dataport, report or XMLport is left without committing any changes that were made during the execution to the database. The OnPostReport, OnPostDataPort or OnPostXMLport trigger will not be called.


RUN (Dataport)

Use this function to load and execute the dataport you specify. Use this function or the RUNMODAL (Dataport) function if you know at design time the exact dataport you want to run. Otherwise, use the DATAPORT.RUNMODAL or DATAPORT.RUN function.

Dataport.RUN

Dataport

Data type: dataport

Once you define this variable, you can run this function or the RUNMODAL function on the variable. The system automatically clears the variable after it executes this function.


RUNMODAL (Dataport)

Use this function to load and execute the dataport you specify. Use this function or the RUN (Dataport) function if you know at design time the exact report you want to run. Otherwise, use the DATAPORT.RUNMODAL or DATAPORT.RUN function.

Dataport.RUNMODAL

Dataport

Data type: dataport

Once you define this variable, you can run this function or the d.RUN function on the variable. As opposed to the d.RUN function, the system does not automatically clear the variable after it executes this function. You must handle clearing the variable after using it.

Comments

The request form is run modally.


SETTABLEVIEW (Dataport Form & Report)

Use this function to apply the Table View on the current record as the table view for the form, report or dataport.

SETTABLEVIEW(Record)

Record

Data type: record

The record whose table view you want to apply to the form or data item.

Comments

This function only narrows the view of the table that was set through the SourceTableView property of the form, or the DataItemTableView property of the data item.

If you use this function and the SaveTableView property of the form is set to "Yes", the system will not save the current table view in the setup file.


SKIP (Dataport, Report, XMLport)

Use this function to skip the current iteration of the current dataport, report or XMLport.

SKIP

Comments

While you can use SHOWOUTPUT to suppress printing the output from a section in a report, SKIP allows you to suppress any processing at all and move on.

Example

If you perform some processing in the OnAfterGetRecord trigger of a data item, and do not want this processing to take place in some situations, you can use SKIP in this way:

IF Balance = 0 THEN
CurrReport.SKIP
ELSE
... // some processing

A typical situation where you will use SKIP like this is when you want to retrieve records from a related table, using values in the current record for forming a filter. If the values in the current record already indicate that no records from the related table will be retrieved, there is no need to perform this processing - and you can use SKIP to avoid it.


DATEFORMULA

Use this data type to contain a date formula that has the same capabilities as an ordinary input string for the CALCDATE function. The DateFormula data type is used to provide multilanguage capabilities to the CALCDATE function.

Comments

When a date calculation formula is stored in a DateFormula field it is converted to a generic, nonlanguage dependent format. When a date calculation formula is retrieved from a DateFormula field, it is converted to a valid date conversion string for the currently selected language.


DATE

Use this simple data type to denote dates ranging from January 1, 0 (the year zero) to December 31, 9999. The system defines an undefined date as 0D.

Comments

All dates have a corresponding closing date. To the system, the closing date for a given date is defined as a period that follows a given date and precedes the next normal date. When sorted, the system places closing dates after their corresponding given date and before the next normal date.

August 1996 |  |  |  |  |
Monday | Tuesday | Wednesday |  |  |
1 |  | 2 |  | 3 |
(080196D) | (080196C) | (080296D) | (080296C) | (080396D) | (080396C)

xxxxxxD: Normal date

xxxxxxC: Closing date

The format of the date is determined by your Regional and Language Options in Windows.

SQL Server Option

SQL Server stores information about both date and time in columns of the DATETIME and SMALLDATETIME types. For date fields, Microsoft Dynamics NAV uses only the date part and places a constant value for the time. For a normal date, this contains 00:00:00:000. For a closing date, it contains 23:59:59:000 for a DATETIME and 23:59:00:000 for a SMALLDATETIME.

The Microsoft Dynamics NAV undefined date is represented by the earliest valid date in SQL Server: 01-01-1753 00:00:00:000 for a DATETIME, and 01-01-1900 00:00:00:000 for a SMALLDATETIME.

For time fields, only a SQL Server DATETIME type can be used. Microsoft Dynamics NAV uses only the time part and places a constant value for the date: 01-01-1754. The Microsoft Dynamics NAV undefined time is represented by the same value as an undefined date.

In order for Microsoft Dynamics NAV to interpret date and time values correctly, the formats mentioned above must be used when linking Microsoft Dynamics NAV table definitions to external tables or views.

To reformat a DATETIME or SMALLDATETIME column that is to be used as a date field in Microsoft Dynamics NAV, an UPDATE statement can be applied to the table data. Here is an example of such an update statement:

UPDATE [My Table] SET [My Date] = CONVERT(CHAR(10), [My Date], 102)

For a closing date, a CONVERT style of 120 can be used to set the appropriate time part. To reformat a time field a similar statement can be used:

UPDATE [My Table] SET [My Time] = CAST('1754-01-01 '+CONVERT(CHAR(8), [My Time], 108) AS DATETIME)

As an alternative to modifying the table data you can create a view that applies the necessary conversion to the column and gives the column an alias. However, views that are created in this way are not updateable, and it is more efficient to change the data than to apply conversions for every row.


DATETIME

Use this data type to denote the date and time of day.

The datetime is stored in the database as Coordinated Universal Time (UTC).

UTC is the international time standard (formerly Greenwich Mean Time, or GMT). Zero hours UTC is midnight at 0 degrees longitude.

The datetime is always displayed as local time in Microsoft Dynamics NAV.

Local time is determined by the time zone regional settings used by your computer.

You must always enter datetimes as local time. When you enter a datetime as local time, it is converted to UTC using the current settings for the time zone and daylight saving time.

Comments

There is only one constant available when you use this data type: undefined datetime.

DateTime := 0DT

Microsoft Dynamics NAV Database Server

The earliest permitted datetime is January 1, 0000, 00:00:00.000.
The latest permitted datetime is December 31, 9999, 23:59:59.999.

SQL Server

The earliest permitted datetime is January 1, 1754, 00:00:00.000.
The latest permitted datetime is December 31, 9999, 23:59:59.999.

Any datetimes that are not within this range and that you try to enter or construct by, for example, adding a datetime to a duration, are regarded as undefined datetimes and give an error message.

Undefined dates are stored as January 1, 1753, 00:00:00.000.

Note

The biannual change to and from daylight saving time affects the way in which datetimes are displayed. For example, if you are located in central Europe, you are in the central European time zone and are using Central European Time (CET). During the winter the difference between CET and UTC is 1 hour. When you change to daylight saving time for the summer the difference is 2 hours.

This means that the local time representation of a UTC will vary depending on the time zone you are located in and whether you are using daylight saving time or not. Therefore, any datetimes that were entered during the winter will be converted and displayed differently after you have changed to daylight saving time for the summer. In other words, datetimes will not necessarily be displayed the same as when they were entered.

The DateTime datatype does not support closing dates.

By default, datetimes are displayed using the standard display format. When you use the standard display format, seconds and milliseconds are not displayed until you select the datetime field. Furthermore, if you export your data using the standard dataport export, the User Portal dataport export or by writing it to a file, the seconds and milliseconds will not be exported unless you specify that datetime fields use another format and display this information. For more information about how datetimes are displayed and the formats that are available, see Format.


DURATION

Use this data type to represent the difference between two datetimes, in milliseconds. This value can be negative. It is a 64 bit integer.

DATETIME-DATETIME=DURATION

DATETIME-DURATION=DATETIME

DATETIME+DURATION=DATETIME


TIME

Use this simple data type to denote a time. The system defines an undefined time as 0T. Any time between 00:00:00 to 23:59:59 is valid.

Example

Here are some examples of times:

11:59:00 (11:59 am)

12:00:00 (12:00 noon)

12:01:00 (12:01 pm)

23:59:00 (11:59 pm)

00:00:00 (12:00 midnight)

00:01:00 (12:01 am)

The format of the time is determined by your Regional and Language Options in Windows.

SQL Server Option

To learn how the SQL Server Option handles times and dates, see DATE.


CALCDATE (Date)

Calculates a new date based on a date expression and a reference date.

NewDate := CALCDATE(DateExpression [, Date])

NewDate

Data type: date

The date the system computes from the reference date and the date expression.

DateExpression

Data type: text, code or dateformula

The date expression can be any length. The system interprets the string from left to right, one subexpression at a time. The following rules describe the valid syntax of date expressions:

DateExpression = | <SubExpression> |
<SubExpression> | [<Sign>] <Term> |
 | <Sign> | + | -
 | <Term> | (see below)

This is the syntax of <Term>:

<Term> = | <Number><Unit> | <Unit><Number> | <Prefix><Unit>
<Number> | Positive integer
<Unit> | D | WD | W | M | Q | Y (D=day, WD=Weekday, W=Week, M=Month, Q=Quarter, Y=Year)
<Prefix> | C(C=Current)

These production rules show that date expressions consist of zero or more subexpressions. Each subexpression is comprised of one to three possible terms. Here are some typical examples of terms:

30D (30 days) corresponds to <Number><Unit>

WD2 (weekday number 2) corresponds to <Unit><Number>

CW (current week) corresponds to <Prefix><Unit>

The internal calendar of C/SIDE starts on Monday and ends on Sunday. This means that Monday is weekday 1 and Sunday is weekday 7.

A run-time error occurs if the syntax of DateExpression is incorrect.

Date

Data type: date

Use this optional parameter to define a reference date. The default is the current system date.

Using the DateFormula data type

The DateExpression can be a field or variable of type Text or Code, and it can be a field or variable of type DateFormula. The benefit of using a DateFormula field or variable is that the date formula becomes language independent.

The user simply enters formulas in the currently selected language. The formula is stored in a generic format in field or variable. When the formula needs to be displayed, the actual string displayed will be converted to the currently selected language at this point in time.

For example, if a user with language set to ENG (English) enters the date formula "1W+1D" for one week and one day, a user with the language set to FRA (French) will see "1S+1J" and a user with the language set to ESP (Spanish) will see "1S+1D".

If a date formula is entered with < > delimiters surrounding it, the date formula will be stored in a generic, nonlanguage dependent format. This makes it possible to develop date formulas that are not dependent on the currently selected language.

Example

The first example shows how to use the production rules listed above.

Prefix | Unit | Sign | Number | Unit | Sign | Number | Unit
C | Q | + | 1 | M | - | 10 | D

This should be interpreted as: Current quarter + 1 month - 10 days.

The second example shows how to use the CALCDATE function.

Expr1
 := 'CQ+1M-10D'; // Current quarter + 1 month - 10 days
Expr2 := '-WD2'; // The last weekday no.2, (last Tuesday)
Expr3 := 'CM+30D'; // Current month + 30 days
RefDate := 052196D;
Date1 := CALCDATE(Expr1, RefDate);
Date2 := CALCDATE(Expr2, RefDate);
Date3 := CALCDATE(Expr3, RefDate);
MESSAGE(Text000 + Text001 + Text002 + Text003,
RefDate, Expr1, Date1, Expr2, Date2, Expr3, Date3);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The reference date is: %1 \'
Text001 | 'The expression: %2 returns %3\'
Text002 | 'The expression: %4 returns %5\'
Text003 | 'The expression: %6 returns %7'

The message window shows:

The reference date is: 05/21/96
The expression: CQ+1M-10D returns 07/20/96
The expression: -WD2 returns 05/14/96
The expression: CM+30D returns 06/30/96


CLOSINGDATE (Date)

Use this function to return the closing date for a Date.

ClosingDate := CLOSINGDATE(Date)

ClosingDate

Data type: date

The system returns the corresponding closing date for Date.

Date

Date type: date

The input date.

Comments

All dates have a corresponding closing date. To the system, a closing date is a period following the given date, but before the next normal date. Closing dates are sorted immediately after the corresponding normal date, but before the next normal date.

August 1996 |  |  |  |  |
Monday | Tuesday | Wednesday |  |  |
1 |  | 2 |  | 3 |
(080196D) | (080196C) | (080296D) | (080296C) | (080396D) | (080396C)

xxxxxxD: Normal date

xxxxxxC: Closing date

Example

These examples show how to use the CLOSINGDATE function. In the first example a normal date is given as input. In the second example a closing date is given as input.

With a normal date as input:

Date1
 := 040496D;
CloDate := CLOSINGDATE(Date1);
MESSAGE(Text000, Date1, CloDate);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The closing date for %1 is %2.'

This message appears:

The closing date for 04/04/96 is C04/04/96.

With a closing date as input:

Date1
 := CLOSINGDATE(040496C);
CloDate := CLOSINGDATE(Date1);
MESSAGE(Text001, Date1, CloDate);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text001 | 'The closing date for %1 is %2.'

This message appears:

The closing date for C04/04/96 is C04/04/96.


DATE2DMY (Date)

Returns the day, month, or year based on a date.

Number := DATE2DMY(Date, What)

Number

Data type: integer

The day, month, or year of Date.

Date

Data type: date

The input date.

What

Data type: integer

This tells the system what the function should return. The valid options are 1, 2, and 3.

This value... | Corresponds to...
1 | Day (1-31)
2 | Month (1-12)
3 | Year

Example

This example shows how to use the DATE2DMY function.

d
 := TODAY;
day := DATE2DMY(d,1);
month := DATE2DMY(d,2);
year := DATE2DMY(d,3);
MESSAGE(Text000,day,month,year);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Today is day %1 of month %2 of the year %3'

The message window could show:

Today is day 16 of month 2 of the year 1996


DATE2DWY (Date)

Returns the day of the week, week number, and year based on the input Date.

Number := DATE2DWY(Date, What)

Number

Data type: integer

The resulting day of the week, week number, or year.

Date

Data type: date

The input date.

What

Data type: integer

Tells the system what the function should return. The valid options are 1, 2, and 3.

This value... | Corresponds to...
1 | Day of the week (1-7, Monday equals 1)
2 | Week number (1-53)
3 | Year

Comments

If the input date to the DATE2DWY function is in a week which spans two years, the DATE2DWY function computes the output year as the year of the first day in the week. This situation is shown in the example below.

Example

This example shows a special case which occurs when you use the DATE2DWY function in a week which spans two years.

D
 := 010194D;
DayOfWeek := DATE2DWY(D, 1);
WeekNumber := DATE2DWY(D, 2);
Year := DATE2DWY(D, 3);
MESSAGE(Text000 + Text001 + Text002 + Text003, D, DayOfWeek, WeekNumber,
 Year);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The date %1 corresponds to:\'
Text001 | 'The day of the week: %2\'
Text002 | 'The week number: %3\'
Text003 | 'The year: %4'

The message window shows:

The date 01/01/94 corresponds to:
The day of the week: 6
The week number: 52
The year: 1993

This example shows that the system regards the date 01/01/94 as day number 6 (Saturday) in week number 52 in the year 1993.


DATI2VARIANT (Date & Variant)

Use this system date function to create a variant that contains a VT_DATE.

Variant := DATI2VARIANT(Date, Time)

Variant

Data type: variant

Date

Data type: date

Time

Data type: time

More information:

VARIANT


DMY2DATE (Date)

Use this function to return a Date based on a day, month, and year.

Date := DMY2DATE(Day [, Month] [, Year])

Date

Data type: date

The resulting date.

Day

Data type: integer

The number of the day in the month (1..31).

Month

Data type: integer

The number of the month in the year (1..12). If you omit this optional parameter, the system uses the current month as the default.

Year

Data type: integer

The four-digit number of the year. If you omit this optional parameter, the system uses the current year as the default.

Example

This C/AL code shows how to use the DMY2DATE function.

Day := 17;
Month := 2;
Year := 1996;
D := DMY2DATE(Day, Month, Year);
MESSAGE(Text000 + Text001 + Text002 + Text003, Day, Month, Year, D);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Day number %1,\'
Text001 | 'month number %2, and\'
Text002 | 'year number %3 \'
Text003 | 'corresponds to the date: %4'

The message window could show:

Day number 17
month number 2, and
year number 1996
corresponds to the date: 02/17/96


DWY2DATE (Date)

Use this function to return a Date based on a weekday, a week, and a year.

Date := DWY2DATE(WeekDay [, Week] [, Year]))

Date

Data type: date

The resulting date.

Weekday

Data type: integer

The number of the day in the week (1..7). Monday is day number 1.

Week

Data type: integer

The number of the week. January 1 falls in week number 1. If you omit this optional parameter, the system uses the current week as the default.

Year

Data type: integer

The four-digit number of the year. If you omit this optional parameter, the system uses the current year as the default.

Comments

A special situation occurs if the week (Week) that's input into DWY2DATE spans two years. Depending on Weekday, the year of the output Date can differ from the input year. This situation is shown in the following example.

Example

This example shows how to use the DWY2DATE function. Please note that the input week in this example spans two years.

DayOfWeek
 := 7;
Week := 52;
Year := 1993;
Date := DWY2DATE(DayOfWeek, Week, Year);

MESSAGE(Text000 + Text001 + Text002, DayOfWeek, Week, Year, Date);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Day %1 of week %2\'
Text001 | 'in the year %3,\'
Text002 | 'is the date: %4'

The message window will show:

Day 7 of week 52
in the year 1993,
is the date: 01/02/94

The example shows that the system regards the 7th day of the week in the 52nd week of the year 1993 as the date 01/02/94.


NORMALDATE (Date)

Use this function to return the normal date (as opposed to the closing date) for the argument Date.

NormalDate := NORMALDATE(Date)

NormalDate

Data type: date

The resulting normal date.

If Date is a... | Then NormalDate will be a...
Normal date | Normal date
Closing date | Normal date

Date

Data type: date

The input date. You can enter a closing date or a normal date. A run-time error occurs if the value of Date is set to the undefined date (0D).

Comments

All dates have a corresponding closing date. A closing date is regarded by the system as a period that follows the given date but comes before the next normal date. The system sorts closing dates immediately after the corresponding normal date and before the next normal date.

August 1996 |  |  |  |  |
Monday | Tuesday | Wednesday |  |  |
1 |  | 2 |  | 3 |
(080196D) | (080196C) | (080296D) | (080296C) | (080396D) | (080396C)

xxxxxxD: Normal date

xxxxxxC: Closing date

Example

These examples show how to use the NORMALDATE function.

With a normal date as input:

OldDate
 := 040496D;
NorDate := NORMALDATE(OldDate);
MESSAGE(Text000, OldDate, NorDate);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The normal date for %1 is %2.'

The message window shows:

The normal date for 04/04/96 is 04/04/96.

With a closing date as input:

OldDate
 := CLOSINGDATE(040496D);
NorDate := NORMALDATE(OldDate);
MESSAGE(Text001,OldDate, NorDate);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text001 | 'The normal date for %1 is %2.'

The message window shows:

The normal date for C04/04/96 is 04/04/96.


TIME (Time)

Use this function to retrieve the current time from the operating system.

Time := TIME

Time

Data type: time

The current time.

Comments

You can only use the TIME function to retrieve the time from the operating system. You cannot use it to set the time in the operating system.

Example

This example shows how to use the TIME function.

MESSAGE(Text000, TIME);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The current system time is: %1'

The message window could show:

The current system time is: 4:15:46 PM


TODAY (Date)

Use this function to return the current date set in the operating system.

Date := TODAY

Date

Data type: date

The current date defined by the operating system.

Comments

You can only use the TODAY function to retrieve the current date from the operating system. You cannot use it to set the date in the operating system.

Example

This example shows how to use the TODAY function.

MESSAGE(Text000, TODAY);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The current date is: %1'

The message window could show:

The current date is: 05/27/96


VARIANT2DATE (Date & Variant)

Use this system date function to return a date from a VT_DATE variant.

Date := VARIANT2DATE(Variant)

Date

Data type: date

The resulting date.

Variant

Data type: variant

More information:

VARIANT


VARIANT2TIME (Date & Variant)

Use this system date function to return a time from a VT_DATE variant.

Time := VARIANT2TIME(Variant)

Time

Data type: time

The resulting time.

Variant

Data type: variant

More information:

VARIANT


WORKDATE (Date)

Use this function to return the current work date or to set a new work date.

[WorkDate]:= WORKDATE([NewDate])

WorkDate

Data type: date

The current work date.

NewDate

Data type: date

The new work date you want to set.

Comments

This function returns the work date chosen using the Work Date option on the Tools menu. If the user did not choose a work date, the system returns the current system date.

Example

This example shows how to use the WORKDATE function:

MESSAGE(Text000, WORKDATE);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The work date is: %1'

A typical response could be:

The work date is: 05/27/96


CREATEDATETIME (Datetime)

Use this function to create a datetime from a date and a time.

DateTime := CREATEDATETIME(Date, Time)

DateTime

Data type: datetime

The concatenated datetime

Date

Data type: date

The date that you want to use to create a datetime.

You cannot use an undefined date to create a datetime.

Time

Data type: time

The time that you want to use to create a datetime.

You cannot use an undefined time to create a datetime.


CURRENTDATETIME (Datetime)

Use this function to return the current datetime.

Datetime := CURRENTDATETIME

Datetime

Data type: datetime

The current datetime.


DT2DATE (Datetime)

Use this function to return the date part of a datetime.

Date := DT2DATE(Datetime)

Date

Data type: date

The date part of the datetime.

Datetime

Data type: datetime

The datetime that you want to return the date part of.

Comments

If datetime is undefined, this function returns an undefined date.


DT2TIME (Datetime)

Use this function to return the time part of a datetime.

Time := DT2TIME(Datetime)

Time

Data type: time

The time part of the datetime.

Datetime

Data type: datetime

The datetime that you want to return the time part of.

Comments

If datetime is undefined, this function returns an undefined time.


ROUNDDATETIME (Datetime)

Use this function to round a datetime.

NewDateTime := ROUNDDATETIME(Datetime [, Precision][, Direction])

NewDateTime

Data type: datetime

The rounded result.

Datetime

Data type: datetime

The datetime that you want to round.

Precision

Data type: biginteger (only positive bigintegers can be used)

This optional parameter determines the precision used when rounding. The default value is 1000.

Direction

Data type: text or code

This optional parameter tells the system how to round Datetime. The default rounding method is '='. You can change the method by using these options:

Enter this... | To round...
'=' | To the nearest value (default)
'>' | Up
'<' | Down


DIALOG

Variables of this complex data type store dialog windows. These variables also give you access to a number of dialog functions, such as OPEN, CLOSE, and so on.


BEEP (Dialog)

Use this function to sound a tone through the computer's speaker. For example, you can use the function to signal that the wrong kind of data has been entered in a control or that your application is waiting for input from the user.

BEEP(Frequency, Duration)

Frequency

Data type: integer

The frequency of the beep (100Hz-10000Hz).

Duration

Data type: integer

The duration of the beep in milliseconds.


CLOSE (Dialog)

Use this function to close a dialog window which has been opened by OPEN (Dialog).

Dialog.CLOSE

Dialog

Data type: dialog

Comments

If CLOSE is used on a dialog window that is not open, a run-time error will occur.

The dialog windows of an object are automatically closed when the object terminates.


CONFIRM (Dialog)

Use this function to create a dialog box which prompts the user for a yes or no answer. The system centers the dialog box on the screen for you.

Ok := Dialog.CONFIRM(String [, Default] [, Value1] ,...)

Ok

Data type: boolean

This return parameter reflects the user's selection.

Ok will be... | If you entered...
TRUE | Yes
FALSE | No

String

Data type: code or text constant

The system displays this string in the dialog box. Use a back slash (\) to indicate a new line. The string can be a multilanguage enabled text constant.

Default

Data type: boolean

Describes what the computer should use as the default button. If you do not specify a default, the system uses No.

Comments

The system sizes the message window for you. The height of the window corresponds to the number of lines and the width corresponds to the length of the longest line.

Examples

In the following example, the Dialog.CONFIRM function prompts the user for a Yes or No answer:

Question
 := Text000;
Answer := Dialog.CONFIRM(Question, TRUE);
MESSAGE(Text001, Answer);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Leave without saving changes?'
Text001 | 'You selected %1.'


ERROR (Dialog)

Use this function to display an error message and end the execution of C/AL code.

ERROR(String [, Value1, ...])

String

Data type: text constant or code

This string contains the text of the error message you want to display to the user. Use a back slash (\) to start a new line. Use percent signs (%) or pound signs (#) to insert variable values into the string. Place the percent or pound signs where you want the system to substitute the variable value. The string can be a multilanguage enabled text constant.

Value1,...

Data type: any

Any variable or expression to be inserted in String. You can insert up to 10 values.

For '#'-type fields, the system truncates the value according to the total number of pound-sign characters in String. For '%'-type fields, the system prints the full length of the value.

Comments

The system automatically sizes the window to hold the longest line of text and total number of lines.

Example

This example shows how to use the ERROR function.

AccountNo
 := 1230;
// The execution stops when the error statement is executed,
// and the following statements will never be executed.
ERROR(Text000, AccountNo);
MESSAGE(Text001); // This line is not executed

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Finance Account #1#### must not be blocked.'
Text001 | 'Dummy message!'

The error window will show:

Finance Account 1230 must not be blocked.

The ERROR function causes the system to halt its execution of the C/AL so it never executes the MESSAGE function.


INPUT (Dialog)

Use this function to read what a user enters into a field in a window. The system returns the input in a variable. This function also returns a number which identifies the next input field in the window.

NewControlID := Dialog.INPUT([ControlID] [,Variable])

NewControlID

Data type: integer

The control ID of the next field in the window. If the user presses Esc to leave the window, the window will close and the calling C/AL code will terminate, and zero is returned.

ControlID

Data type: integer

This number identifies the field in the dialog window.

Variable

Data type: any

A variable that may be edited in the dialog window.


MESSAGE (Dialog)

Use this function to display a text string in a message window.

MESSAGE(String [, Value1, ...])

String

Data type: code or text constant

This string contains the text you want the system to display in the message window. Use a back slash (\) to start a new line. Use percent signs (%) to insert variable values into the string. Place the percent where you want the system to substitute the variable value. The string can be a multilanguage enabled text constant.

Value,1...

Data type: any

Any type of C/AL variable you want to insert into String. You can insert up to 10 values.

Comments

When the system executes a message statement in the C/AL code, it does not immediately display the message. Instead, it waits until the C/AL code is finished executing or until it pauses to wait for user interaction.

The system automatically sizes the window to hold the longest line of text and the total number of lines.

Example

This example shows how to use the MESSAGE function.

Create the following variables:

Variable | Data Type
Text | Text
Number | Decimal

Create the following text constants :

Text Constant | ENU Value
Text000 | You can use message windows to\
Text001 | display text and numbers:\
Text002 | The number:
Text003 | The text:

Use the following code to create the message:

Text := 'ABCDE';

Number := 12345.678;

// The back slash indicates a new line.

// You can concatenate strings using the + operator.

// You can insert variable values using the % symbol.

MESSAGE(Text000 + Text001 + Text002 + '%1\' +Text003 + '%2', Number, Text);

The message window reads:

You can use message windows to
display text and numbers:
The number: 12,345.678
The text: ABCDE


OPEN (Dialog)

Use this function to open a dialog window.

Dialog.OPEN(String [, Variable1], ...)

Dialog

Data type: dialog

Once you define this variable, you can open the dialog and then use other dialog functions.

String

Data type: text constant or code

This string contains the text you want the system to display in the window. Use a back slash (\) to start a new line. Use pound signs (#) to insert variable values into the string, Place the pound signs where you want the system to substitute the variable value.

If you use @ characters instead of #, the string can be used as an indicator. In this case, use @ characters only for the string, and let the variable be an integer. The limits of the indicator are 0 and 9999 - meaning that the integer you use for updating the indicator should have a value within this range.

Place a number in the part of the string where a variable value will be substituted (as, for example, #1####) in order to be able to reference this field for updating.

You can update the fields using the d.UPDATE or d.INPUT functions or by letting the user edit the values.

Variable1

Data type: any

Use these optional parameters to specify variables for field1, field2, and so on.

Comments

Dialog windows opened by an object are closed when the object terminates.

Dialog windows are automatically sized to hold the longest line of text and the total number of lines.

Example

This example shows how to use the dialog.OPEN function.

AccountInfo
 := Text000 +
Text001;
AccNo := 5634;
TotSum := 1000;
d.OPEN(AccountInfo, AccNo, TotSum);
// Opens a window with '#'-fields for Account no. and Total
d.UPDATE(); // Update the fields
d.CLOSE()

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Account no. #1######,\'
Text001 | 'shows a total of $ #2######'

The system will open the dialog window and show this text:

Account no. 5634
shows a total of $ 1000

This shows that the system has formatted the values of the variables AccNo and TotSum into the '#'-fields.


STRMENU (Dialog)

Use this function to create a menu window that displays a series of options.

OptionNumber := Dialog.STRMENU(OptionString [, DefaultNumber])

OptionNumber

Data type: integer

The number of the menu option the user selected. If the user presses Esc to exit the menu, the system returns zero (0).

OptionString

Data type: code or text constant

A comma-separated string. Each substring in OptionString denotes an option on the menu. The string can be a multilanguage enabled text constant.

DefaultNumber

Data type: integer

Use this optional parameter to determine a default option, which the system highlights. The system numbers the options 1, 2, 3, 4, and so on.

If you omit this optional parameter, the system uses the first option (1) as the default.

Example

This example shows how to use the Dialog.STRMENU function.

Options
 := Text000
// Sets the default to option 3
Selected := Dialog.STRMENU(Options, 3);
MESSAGE(Text001, Selected);

Create the following text constants and variables in the C/AL Globals window:

Text Constant | Const Value ENU Value |
Text000 | 'Save,Delete,Exit,Find ...' |
Text001 | 'You selected option %1.' |
Variable | Data Type | Length
Options | Text | 30
Selected | Integer |

The system shows the following text in the menu window:

Save
Delete
Exit
Find ...

and highlights option 3, Exit. The system stores the option the user selects in the variable Selected and displays a message similar to the one shown here:

You selected option 2.


UPDATE (Dialog)

Use this function to update the value of a '#'-or '@' field in the current window.

Dialog.UPDATE([Number] [, Value])

Dialog

Data type: dialog

The dialog you want to update.

Number

Data type: integer

Each '#' or '@' field has a specific number. The Number argument tells the system into which field it should insert Value. If you omit this parameter, the system updates all '#' or '@' fields in the current window.

Value

Data type: any

This value (or expression) can be any simple C/AL data type such as boolean, option, integer, decimal date, time, text and code. If you omit this value, the system uses the value from the variable in the Dialog.OPEN call.

Example

The following example shows how to update '#' field in a window.

.
.
.
AccountInfo := Text000 +
Text001;

AccNo := 5634;
TotSum := 1000;
// Opens a window with '#'-fields for Account no. and Total
dialog.OPEN(AccountInfo);
dialog.UPDATE(1, AccNo); // Fill in field no. 1
dialog.UPDATE(2, TotSum); // Fill in field no. 2
.
.
.

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Account no. #1######,\'
Text001 | 'shows a total of $ #2######'

The system shows this information:

Account no. 5634
shows a total of $ 1000

The values of the variables AccNo and TotSum have been inserted in the '#'-fields.

When you have a function that contains dialog.update(number,value) and the value is a variant, you must format the text constant to ensure that the variant type can understand the text constant.

In C/SIDE the text constant is read as type: AL_TEXTCONST, which cannot be interpreted by the variant.

Adding format(textconstant) converts the text constant to a string type, which can be interpreted and displayed by the variant.

Example

OnRun()
Win.OPEN('#1##################################\'+
        '#2##################################\'+
        '@3@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@');

UpdateWindow(1,Text000);//will
 not work
UpdateWindow(2,FORMAT(Text000));//will work
FOR I:= 1 TO 1000 DO
UpdateWindow(3,I);
Win.CLOSE();

UpdateWindow(Number : Integer;Value : Variant)
Win.UPDATE(Number,Value);


YIELD (Dialog)

Use this function to pass control to the operating system, specifically DOS/Windows 3.x, so it can process events. Once the operating system finishes, you regain control.

YIELD

Comments

If you do not want your C/AL code to completely tie up the system for long periods of time, you can insert this function periodically so other programs can run. For instance, if you are creating a report which must read a great number of records, you may want to occasionally use this function so others can continue to work.


CLEARLASTERROR

Use this function to remove the last error message from memory.

CLEARLASTERROR

Comments

You can set up Microsoft Dynamics NAV so that it keeps running even if a runtime error occurs. You can use the GETLASTERRORTEXT function to find out whether or not an error has occurred and to see the actual text in the last error message that was generated. You can then use the CLEARLASTERROR function to remove the last error message from memory. If you subsequently call the GETLASTERRORTEXT function, an empty string is returned.


GETLASTERRORTEXT

Use this function to return the text that was contained in the last error message displayed by the system.

String := GETLASTERRORTEXT

String

Data type: text

The text string that was contained in the last error message that was displayed by Microsoft Dynamics NAV.

The string cannot exceed the maximum string length specified in Microsoft Dynamics NAV. This is currently 1024.

If no error has occurred, the function returns an empty string.

Comments

You can set up Microsoft Dynamics NAV so that it keeps running even if a runttime error occurs. You can use this function to find out whether or not an error has occurred and to see the actual text in the last error message that was generated. You can also use the CLEARLASTERROR function to remove the last error message from memory. If you then call GETLASTERRORTEXT, an empty string is returned.


FIELDREF

This complex data type identifies a field in a table and gives you access to this field.

The fieldref object can refer to any field in any table in the database.


ACTIVE (FieldRef)

Use this function to check whether the field that is currently selected is enabled or not.

Ok := FieldRef.ACTIVE

Ok

Data type: boolean

This return value tells you if the field is marked as enabled or disabled.

If Ok is... | It means that the field is marked as...
TRUE | Enabled
FALSE | Disabled

FieldRef

Data type: fieldref

The fieldref that refers to the field that you want to check.

Comments

Each field in a record can be set as enabled or disabled in the table description. You cannot use a disabled field because disabled fields cannot contain data.

This function is similar to the Record.FIELDACTIVE function.


CALCFIELD (FieldRef)

Use this function to update a FlowField in a record.

[Ok :=] FieldRef.CALCFIELD

Ok

The optional return value.

If OK is... | It means that...
TRUE | The FlowField has been calculated.
FALSE | The FlowField could not be calculated.

Fieldref

Data type: fieldref

The fieldref of the FlowField that you want to update.

Comments

FlowFields are virtual fields. The values in these fields are not saved in the table. This means that you must use the CALCFIELDS function to update them. For example, if you retrieve a record using the RecordRef.FIND and RecordRef.NEXT functions, the system sets the FlowFields in those records to zero (0). Then, you can call FieldRef.CALCFIELD, to make the system calculate the value in one of the FlowFields.

When a FlowField is a direct source expression of a control on a form or a report, the calculation will be performed automatically by the system.

This function is similar to the Record.CALCFIELDS function.


CALCSUM (FieldRef)

Use this function to calculate the total of a SumIndexFields in a table.

[Ok:=] FieldRef.CALCSUM

Ok

Data type: boolean

If you omit this optional return value and if the field is not a SumIndexField, a run-time error occurs. If you include a return value, the system assumes you will handle any errors.

FieldRef

Data Type: fieldref

The fieldref that refers to the field.

This function is similar to the Record.CALCSUMS function.


CAPTION (FieldRef)

Use this function to return the current caption of a field referred to by a fieldref as a string.

Caption := FieldRef.CAPTION

Caption

Data type: text or code

The caption as a string.

FieldRef

Data type: fieldref

The fieldref that refers to the field for which you want to retrieve the caption.

Comments

CAPTION returns the caption of a field. CAPTION first looks for a CaptionML property. If it does not find one it will use the Name property. This means that FIELDCAPTION is multilanguage enabled.

This function is similar to the Record.FIELDCAPTION function.


CLASS (FieldRef)

Use this function to return the fieldclass of the field that is currently selected. This function returns an error if no field is selected.

Class := FieldRef.CLASS

Class

Data type: option

The return vale. The fieldclass of the field.

FieldRef

Data type: fieldref

The fieldref that refers to the field that you are interested in.


FIELDERROR (FieldRef)

Use this function to stop the execution of the code (cause a run-time error, in fact) and create an error message for a field.

FieldRef.FIELDERROR([Text])

FieldRef

Data Type: fieldref

The fieldref that refers to the field for which you want to create an error message.

Text

Data type: text or code

Use this optional parameter to include the text of the error message. If this parameter is not present, default texts will be used.

Comments

Like any other run-time error, this function causes the system to automatically abort any transaction.

This function is similar to the Record.FIELDERROR function.


GETFILTER (FieldRef)

Use this function to return the filter within the current filter group that are applied to a field.

String := FieldRef.GETFILTER

String

Data type: text

This string contains the filter that is applied to the field in the record.

FieldRef

Data type: fieldref

The fieldref that refers to the field for which you want to return the filter.

Comments

See also RecordRef.GETFILTERS, FieldRef.SETFILTER, and FieldRef.SETRANGE.

This function is similar to the Record.GETFILTER function.


GETRANGEMAX (FieldRef)

Use this function to return the maximum value in a range for a field.

Value := FieldRef.GETRANGEMAX

Value

Data Type: depends on the field referred to by the fieldref.

Contains the maximum value of the range set for the field referred to by the fieldref. The type of value must match the type of the field referred to by the fieldref.

FieldRef

Data Type: fieldref

This function is similar to the Record.GETRANGEMAX function.

See also FieldRef.GETRANGEMIN.


GETRANGEMIN (FieldRef)

Use this function to return the minimum value in a range for a field.

Value := FieldRef.GETRANGEMIN

Value

Data Type: text constant or code

Contains the minimum value of the range set for the field referred to by the fieldref. The data type of value must match the data type of the field referred to by the fieldref.

FieldRef

Data Type: fieldref

This function is similar to the Record.GETRANGEMIN function.

See also FieldRef.GETRANGEMAX.


LENGTH (FieldRef)

Use this function to return the maximum size of the field (the size specified in the DataLength property of the field). This function is usually used for finding the defined length of code and text fields.

Length := FieldRef.LENGTH

Length

Data Type: integer

The defined length of the field.

FieldRef

Data Type: fieldref

The fieldref that refers to the field that you want to know the length of.


NAME (FieldRef)

Use this function to return the name of a field as a string.

Name := FieldRef.NAME

Name

Data type: text constant or code

The name of the field given as input.

FieldRef

Data type: fieldref

The fieldref of the field in the record.

Comment

The FieldRef.CAPTION function retrieves the Caption property of a field. If you want to enable your application for multilanguage now or in the future, you must use the FIELDCAPTION function instead.

This function is similar to the Record.FIELDNAME function.


NUMBER (FieldRef)

No := FieldRef.NUMBER

No

Data type: Integer

The return value - the number of the table or of the field.

FieldRef

Data type: fieldref

The fieldref that refers to the field that you are interested in.

This function is similar to the Record.FIELDNO function.


OPTIONCAPTION (FieldRef)

Use this function to return the option caption of the field that is currently selected. This function returns an error if no field is selected.

OptionCaption := FieldRef.OPTIONCAPTION

OptionCaption

Data type: text

The option caption of the field.

FieldRef

Data type: fieldref

The fieldref that identifies the field that you are interested in.


OPTIONSTRING (FieldRef)

Use this function to return the list of options that are available in the field that is currently selected. This function returns an error if no field is selected.

OptionString := FieldRef.OPTIONSTRING

OptionString

Data type: text

The return value. The list of options that are available in the field.

FieldRef

Data type: fieldref

The fieldref that identifies the field that you are interested in.


RECORD (FieldRef)

Use this function to return the recordref of the field that is currently selected. This function returns an error if no field is selected.

RecordRef := FieldRef.RECORD

RecordRef

Data type: recordref

The recordref of the field that is currently selected.

FieldRef

Data type: fieldref

The fieldref that refers to the field.


RELATION (FieldRef)

Use this function to find out the table relationship of a given field.

TableNumber := FieldRef.RELATION

TableNumber

Data type: integer

The number of the table which has a relationship with the field referred to by fieldref. This relationship is set up through the properties.

FieldRef

Data Type: fieldref

The fieldref that refers to the field for which you want to find the table relationship.

Comments

You can use this function for several purposes such as to determine lookups or to check to see if you have permission to read from a table.

This function is similar to the Record.RELATION function.


SETFILTER (FieldRef)

Use this function to assign a filter to a field you specify.

FieldRef.SETFILTER(String [, Value],...)

FieldRef

Data type: fieldref

The fieldref that refers to the field that you want to place a filter on.

String

Data type: text or code

The filter expression. A valid expression consists of alphanumeric characters and one or more of the following operators: <, >, *, &, |, and =. You can use replacement fields (%1, %2, and so on) to insert values at run-time.

Value

Data type: any

Replacement values to insert in replacement fields in the filter expression. The data type of Value must match the type of Field.

Comments

If the function is called with a field for which a filter already exists, the system will remove that filter before it sets the new one. You can construct filters using these operators:

This operator... | Means...
.. | Range
& | And
| | Or
< | Less than
<= | Less than or equal to
> | Greater than
>= | Greater than or equal to
<> | Different from
* | Forms a part of value

This function is similar to the Record.SETFILTER function.


SETRANGE (FieldRef)

Use this function to set a simple filter, such as a single range or a single value, on a field.

FieldRef.SETRANGE([FromValue] [, ToValue])

FieldRef

Data type: fieldref

The fieldref that refers to the field that you want to place a filter on.

FromValue

Data type: -

The lower limit of the range. The data type of FromValue must match the data type of the field referred to by the fieldref.

ToValue

Data type: -

The upper limit of the range. If you omit this parameter, the system uses the value you specified for FromValue. The data type of ToValue must match the data type of the field referred to by the fieldref.

Comments

The FieldRef.SETRANGE function provides a quick way to set a simple filter on a field. If you call this function with a field that already has a filter, the system removes that filter before it sets the new one. If you omit all of the optional parameters, the system removes any and all filters set for the field.

The fieldref function fails if no field is selected.

This function is similar to the Record.SETRANGE function.


TESTFIELD (FieldRef)

Use this function to see if the contents of a field match a given value. If the contents differ from the given value, the system displays an error message.

FieldRef.TESTFIELD([Value])

FieldRef

Data Type: fieldref

The fieldref that refers to the field that you are interested in.

Value

Data type: any

The value that you want to compare with the contents of the field referred to by fieldref. The data type of Value must match the type of the field. If you include Value and the contents of the field do not match, the system displays an error message. If you omit Value and the content of the field is zero or blank (empty string), the system also displays an error message.

This function is similar to the Record.TESTFIELD function.


TYPE (FieldRef)

Use this function to return the data type of the field that is currently selected.

Type := FieldRef.TYPE

Type

Data type: The data type of the field.

FieldRef

Data type: fieldref

The fieldref that refers to the field that you are interested in.


VALIDATE (FieldRef)

Use this function to enter a new value into a field and have the new value validated by the properties and code that have been defined for that field.

FieldRef.VALIDATE([NewValue])

FieldRef

Data type: fieldref

The fieldref that refers to the field.

NewValue

Data type: must be compatible with the data type of the field referred to by the fieldref.

The value to insert in the field.

Comments

The VALIDATE function first checks any TableRelation, then executes the OnValidate trigger of the field.

This function is similar to the Record.VALIDATE function.


VALUE (FieldRef)

Use this function to set or get the value of the field that is currently selected. This function returns an error if no field is selected.

[CurrValue :=] FieldRef.VALUE([NewValue])

CurrValue

Data type: variant

FieldRef

Data type: fieldref

The fieldref that refers to the field that you are interested in.

NewValue

Data type: variant

The new value that you want to set for the field.

Comments

If you want to format the value of a fieldref you must use:

FORMAT(FieldRef)

instead of

FORMAT(FieldRef.VALUE)


FILE

Variables of this data type give you access to files. Files can be opened in text or binary mode (see File.TEXTMODE).

You can read from or write to a file by creating input and output streams, respectively. To do so, you use File.CREATEINSTREAM and File.CREATEOUTSTREAM.

More information:

InStream and OutStream


CLOSE (File)

Use this function to close a file which has been opened by OPEN (File).

File.CLOSE

File

Data type: file

Use this variable to refer to the file.

Comments

If the file is not open, a run-time error will occur.


COPY (File)

Use this function to copy a file.

[Ok :=] File.COPY(FromName, ToName)

Ok

Data type: boolean

This optional return parameter tells you whether or not the file was copied.

FromName

Data type: text or code

The name of the file you want to make a copy of, including its path. When you enter the path, keep in mind these shortcuts:

You can... | If the file is located...
Omit the drive designation | On the current drive
Omit the full path | In the current directory
Enter only the subdirectory name | In a subdirectory of the current directory

ToName

Data type: text or code

The name you want to assign to the copy, including its path. See the shortcuts outlined above concerning how to enter the path.

Comments

If you do not use the return value, and the file cannot be copied (for any reason at all), a run-time error will occur. If you do include the return value in your code, you are supposed to handle any errors yourself.

Examples

To copy a file on your c: drive named oldfile to a file called newfile on drive a:, you would use the function as shown below:

File.COPY('c:\data\oldfile','a:\newfile')

If the system cannot copy the file, a run-time error will occur. You avoid this by using the return value like this:

if File.COPY('c:\data\oldfile', 'a:\newfile') then

... // continue your program

else

... // else handle the error


CREATE (File)

Use this function to create and open an ASCII or binary file. If the file exists, the system will truncate it and then open it.

[Ok := ] File.CREATE(Name)

Ok

Data type: boolean

Tells you whether or not the file was created.

Ok will be... | If the file was...
TRUE | Created
FALSE | Not created

File

Data type: file

Use this variable to refer to the file.

Name

Data type: text or code

The name of the file, including the path. When you enter the path, keep in mind these shortcuts:

You can... | If the file is located...
Omit the drive designation | On the current drive
Omit the full path | In the current directory
Enter only the subdirectory name | In a subdirectory of the current directory

Comments

Always call the TEXTMODE (File) function before you use CREATE or OPEN (File). If TEXTMODE is true and you read or write to the file, the system places text in the buffer.

If TEXTMODE is false, the system places binary information in the buffer.


CREATEINSTREAM (File)

Use this function to create an InStream object for a file. This enables you to stream data into the file.

File.CreateInStream(Stream)

File

Data type: file

Use this variable to refer to the file.

Stream

The InStream object type that has been created.

More information:

Code Example for Streams


CREATEOUTSTREAM (File)

Use this function to create an OutStream object for a file. This enables you to stream data out of the file.

File.CreateOutStream(Stream)

File

Data type: File

Use this variable to refer to the file.

Stream

The OutStream object type that has been created.

More information:

Code Example for Streams


CREATETEMPFILE (File)

Use this function to create a temporary file. This enables you to save data of any format to a temporary file. This file has a unique name and will be stored in the temporary files folder.

File.CreateTempFile

File

Data type: File

Use this variable to refer to the file.

Comments

You can use this function with NAME (File) and CLOSE (File).

Example

FileName.CREATETEMPFILE:
Message('Hello');
FileName.CLOSE;

This example generates a temporary file with the text Hello and then deletes the file with the File.CLOSE function.


ERASE (File)

Use this function to erase a file.

[Ok] := File.ERASE(Name)

Ok

Data type: boolean

This optional return value tells you whether or not the system erased the file.

Ok will be... | If the system...
TRUE | Erased the file
FALSE | Did not erase the file

Name

Data type: text or code

The name of the file you want to erase, including the path. When you enter the path, keep in mind these shortcuts

You can... | If the file is located...
Omit the drive designation | On the current drive
Omit the full path | In the current directory
Enter only the subdirectory name | In a subdirectory of the current directory

Comments

If you do not use the return value, and the file cannot be erased (for any reason at all), a run-time error will occur. If you do include the return value in your code, you are supposed to handle any errors yourself.


EXISTS (File)

Use this function to determine if a file exists.

[Ok :=] File.EXISTS(Name)

Ok

Data type: boolean

This return value tells you whether or not the file exists.

Ok will be... | If the file...
TRUE | Exists
FALSE | Does not exist

Name

Data type: text or code

The name of the file you want to check, including the path. When you enter the path, keep in mind these shortcuts:

You can... | If the file is located...
Omit the drive designation | On the current drive
Omit the full path | In the current directory
Enter only the subdirectory name | In a subdirectory of the current directory


GETSTAMP (File)

Use this function to find out the time at which a file was last written to (return a time stamp).

[Ok]:= File.GETSTAMP(Name, Date [, Time])

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find the file. When you include the return value, the system assumes you will handle any errors. The return value can have these values:

If Ok is... | It means that the file...
TRUE | Exists
FALSE | Does not exist

Name

Data type: text or code

The name of the file, including the path. When you enter the path, keep in mind these shortcuts:

You can... | If the file is located...
Omit the drive designation | On the current drive
Omit the full path | In the current directory
Enter only the subdirectory name | In a subdirectory of the current directory

Date

Data type: date

The system will return the date that the file was last written to in this variable.

Time

Data type: time

If it is used, the system will return the time that the file was last written to in this variable.


LEN (File)

Use this function to return the length of an ASCII or binary file.

Length := File.LEN

Length

Data type: integer

This tells you the length of the file in bytes.

File

Data type: file

Use this variable to refer to the file.

Comments

This function is often used with POS (File) and SEEK (File).


NAME (File)

Use this function to return the name of an ASCII or binary file.

Name := File.NAME

Name

Data type: text or code

This string contains the name of the file, including its path.

File

Data type: file

Use this variable to refer the file.

Comments

You must use the File .OPEN to open the file before you can use this function.


OPEN (File)

Use this function to open an existing ASCII or binary file. As compared to CREATE (File) , this function does not create the file if it does not exist.

[Ok]:= File.OPEN

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find the file. If you include a return value, you must handle any errors. The possible values are:

If Ok is... | It means the file was...
TRUE | Opened
FALSE | Not opened (does not exist)

File

Data type: file

Use this variable to refer to the file.


POS (File)

Use this function to return the current position of the file pointer in an ASCII or binary file.

Position := File.POS

Position

Data type: integer

This tells you the current position of the file pointer in bytes.

File

Data type: file

Use this variable to refer to the file.

Comments

This function is often used with LEN (File) and SEEK (File).


QUERYREPLACE (File)

This function is used to determine whether the system should query the user before overwriting a file if it already exists. The function can also be used to determine what the current setting of this option is for a file.

[IsQueryreplace :=] File.QUERYREPLACE([SetQueryreplace])

IsQueryreplace

Data type: boolean

The current setting of the option for the file. The possible values are:

If IsQueryreplace is... | It means that...
TRUE | The user will be queried before the file is replaced
FALSE | The user will not be queried

File

Data type: file

Use this variable to refer to the file.

SetQueryreplace

Data type: boolean

Sets the option for the file. The possible values are:

If SetQueryreplace is... | It means that...
TRUE | The user will be queried before the file is replaced
FALSE | The user will not be queried


READ (File)

Use this function to read from an ASCII or binary file.

[Read] := File.READ(Variable)

Read

Data type: integer

This optional return value tells you the number of bytes read.

File

Data type: file

Use this variable to refer to the file.

Variable

Data type: any

The destination variable.

Comments

If TEXTMODE (File) is set to TRUE, the system reads a line of text from the file, evaluates it and sets the variable equal to the result.

If TEXTMODE is set to FALSE, the system determines the number of bytes to read based on the size of the variable.


RENAME (File)

Use this function to rename an ASCII or binary file.

[Ok:=] File.RENAME(OldName, NewName)

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find the file. When you include the return value, the system assumes you will handle any errors. The return value can have these values:

If Ok is... | It means the system...
TRUE | Renamed the file
FALSE | Did not rename the file

OldName

Data type: text or code

The current name of the file you want to change, including its path. When you enter the path, keep in mind these shortcuts:

You can... | If the file is located...
Omit the drive designation | On the current drive
Omit the full path | In the current directory
Enter only the subdirectory name | In a subdirectory of the current directory

NewName

Data type: text or code

The new name you want to assign to the file, including its path. See the shortcuts shown above.

Comments

Typically the system will return FALSE if the file does not exist or if the file is a system or hidden file.


SEEK (File)

Use this function to set a file pointer to a new position in an ASCII or binary file.

File.SEEK(Position)

File

Data type: file

Use this variable to refer to the file.

Position

Data type: integer

The position at which you want to place the pointer.

Comments

This function is often used with POS (File) and LEN (File).


SETSTAMP (File)

Use this function to set a time stamp for a file.

[Ok] := File.SETSTAMP(Name, Date [, Time])

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find the file. When you include the return value, the system assumes you will handle any errors. The return value can have these values:

If Ok is... | It means the time stamp...
TRUE | Was set
FALSE | Was not set

Name

Data type: text

The name of the file, including its path. When you enter the path, keep in mind these shortcuts:

You can... | If the file is located...
Omit the drive designation | On the current drive
Omit the full path | In the current directory
Enter only the subdirectory name | In a subdirectory of the current directory

Date

Data type: date

The date you want stamped on the file.

Time

Data type: time

The time you want stamped on the file.


TEXTMODE (File)

This function is used to set whether a file should be opened as an ASCII file or a binary file. The function can also be used to determine what the current setting of this option is for a file.

[IsTextmode] := File.TEXTMODE([SetTextmode])

IsTextmode

Data type: boolean

The current setting of this option for the file.

If IsTextmode is... | It means that file will be opened as...
TRUE | An ASCII file
FALSE | A binary file

File

Data type: file

Use this variable to refer to the file.

SetTextmode

Data type: boolean

This variable is used to set the mode that the file will be opened in when File.OPEN is called.

If SetTextmode is... | It means that file will be opened as...
TRUE | An ASCII file
FALSE | A binary file

Comments

This function should be used before File.OPEN is used to open the file.


TRUNC (File)

Use this function to truncate an ASCII or binary file to the current position of the file pointer.

File.TRUNC

File

Data type: file

Use this variable to refer to the file.

Comments

Typically, you use this function with SEEK (File). First, File.SEEK positions the pointer, then File.TRUNC truncates the file at that point.


WRITE (File)

Use this function to write to an ASCII or binary file.

File.WRITE(Value)

File

Data type: file

Use this variable to refer to the file.

Value

Data type: all simple, and records

The information you want the system to write to the file.

Comments

If TEXTMODE (File) is set to TRUE and Value is an integer, the system formats the integer into text and writes the result, followed by a new line character.

If Value is a record, the system separates each field with a tab character.

If TEXTMODE is FALSE and Value is an integer, the system writes the integer as an integer which is four bytes long.


WRITEMODE (File)

Use this function before you use OPEN (File) to set or test whether you can write to a file in later calls.

[IsWritemode :=] File.WRITEMODE([SetWritemode])

IsWritemode

Data type: boolean

The current setting of this option for the file.

If IsWritemode is... | It means that...
TRUE | You can read from and write to the file
FALSE | You can only read from the file

File

Data type: file

Use this variable to refer to the file.

SetWritemode

Data type: boolean

This variable is used to set the mode that the file will be opened in when File.OPEN is called.

If SetWritemode is... | It means that...
TRUE | The file will be opened for read and write.
FALSE | The file will be opened for reading only.

Comments

This function should be used before OPEN (File) is used to open the file.


FORM

Variables of this complex data type store forms. Forms contain simpler elements called controls. Controls are used to display information to the user or to receive information from the user.


ACTIVE (Form)

Use this function to find out if the current form is active or inactive.

IsActive := Form.ACTIVE

IsActive

Data type: boolean

The system returns one of these values:

If IsActive is... | It means the form is...
TRUE | Active
FALSE | Not active


CAPTION (Form)

Use this function to return the current caption of an object as a string, and to set a new caption for the object.

[CurrCaption] := Form.CAPTION([NewCaption])

CurrCaption

Data type: text or code

The current caption as a string.

NewCaption

Data type: text or code

A new caption for the object.

Comments

CAPTION returns or sets the caption of an object. CAPTION first looks for a CaptionML property; if it does not find one, it looks for a Caption property; if that also fails, it will use the Name property. This means that CAPTION is multilanguage enabled.

When CAPTION is used to set a new caption for an object, this new caption is not stored with the object. It is only effective for the instance of the object where it is set.

For tables and fields in tables, you must use TABLECAPTION or FIELDCAPTION.

Example

This example shows how to use the CAPTION function:

OriginalCaption
 := CurrForm.CAPTION;
MESSAGE(Text000, OriginalCaption);
CurrForm.CAPTION('Some New Caption');
NewCaption := CurrForm.CAPTION;
MESSAGE(Text001, NewCaption);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The original caption was %1'
Text001 | 'The new caption is %1'

The message windows could show this:

The original caption was Sales Order Lines

The new caption is Some New Caption


CLOSE (Form & Table)

Use this function to close the current form or table.

Form.CLOSE


FORM (Form)

Use this function to access a form that is a subform of the current form - that is, the form that is defined as the SubFormID of a subform control.

Subform := Form.FORM

Subform

Data type: form

Example

In order to execute a function that is a local function of a form that is used as a subform on the current form, use FORM like this:

CurrForm.NameOfSubformControl.FORM.LocalFunctionToExecute;


FORM.RUN (Form)

Use this function to create and launch a form object, which you specify. If, at design time, you do not know the specific form you want to run, use this function or the FORM.RUNMODAL function.

FORM.RUN(Number [, Record] [, Field])

Number

Data type: integer

A number which identifies a form object. If you enter zero (0), the system displays the default lookup window for the current form. You can use the Symbols option on the View menu to choose from a list.

If the form you specify does not exist, a run-time error occurs.

Record

Data type: record

The Form.RUN function shows, by default, the record last displayed on the form. For each object, the system stores information about the most recently shown record and the attached key and filters.

Use this optional parameter to select a specific record to display on the form. The record must be of the same type as the table attached to the window. When it displays the record, the system uses the key and filters attached to the record.

Field

Data type: field

Use this optional parameter to select a specific field on which focus will be placed.

Comments

When you want to close the form, use CurrForm.CLOSE. CurrForm is a predefined system variable.

Example

This example shows how to call form 4711.

FORM.RUN(4711);


FORM.RUNMODAL (Form)

Use this function to create, run, and close a form object, which you specify. The system runs the form modally. If, at design time, you do not know the specific form you want to run, use this function or the FORM.RUN function. If you do know the specific form you want to run, you can use the RUN (Form) or RUNMODAL (Form) function to specify a variable.

[Action] := Form.RUNMODAL(Number [, Record] [, Field])

Action

Data type: code

This return code tells you what action the user took. Here are the possible return values:

If Action is... | It means that the user...
OK | Pressed OK to exit the window
Cancel | Pressed Cancel to exit the window
LookupOK | Pressed OK on a lookup window
LookupCancel | Pressed Cancel on a lookup window
Yes | Pressed Yes
No | Pressed No
Close | Pressed Close, Esc, or closed the window using the title bar
FormHelp | Selected Help
RunObject | Selected an option that ran another object
RunSystem | Selected an option that ran an external program

Number

Data type: integer

A number which identifies a form object. If you enter zero (0), the system displays the default lookup window for the current form. You can use the Symbols option on the View menu to choose from a list.

If the form you specify does not exist, a run-time error occurs.

Record

Data type: record

This function shows, by default, the record last displayed on the form. For each object, the system stores information about the most recently shown record and the attached key and filters.

Use this optional parameter to select a specific record to display on the form. The record must be of the same type as the table attached to the form. When it displays the record, the system uses the key and filters attached to the record.

Field

Data type: field

Use this optional parameter to select a specific field on which focus will be placed.

Example

This example shows how to call form 4711.

IF FORM.RUNMODAL(4711, Rec, ...) = Action::LookupOK THEN...


GETRECORD (Form)

Use this function to retrieve the current record shown on the form.

Form.GETRECORD(Record)

Form

Data type: form

Record

Data type: record

The retrieved record will be placed here.


LOGHEIGHT (Form)

Use this function to return the current setting of the LogHeight property of a form, and to set this property to a new value.

[CurrLogHeight] := Form.LOGHEIGHT([NewLogHeight])

CurrLogHeight

Data type: integer

The current setting of LogHeight.

NewHeight

Data type: integer

The new setting of LogHeight.

Comments

See the description of the LogHeight property for details.


LOGWIDTH (Form)

Use this function to return the current setting of the LogWidth property of a form, and to set this property to a new value.

[CurrLogWidth] := Form.LOGWIDTH([NewLogWidth])

CurrLogWidth

Data type: integer

The current setting of LogWidth.

NewLogWidth

Data type: integer

The new setting of LogWidth.

Comments

See the description of the LogWidth property for details.


LOOKUPMODE (Form)

Use this function to return the current setting of the LookupMode property of a form, and to set this property to a new value.

[CurrLookupMode] := Form.LOOKUPMODE([NewLookupMode])

CurrLookupMode

Data type: boolean

The current setting of LookupMode.

NewLookupMode

Data type: boolean

The new setting of LookupMode.

Comments

See the description of the LookupMode property for details.


MAXIMIZEDONOPEN (Form)

Use this function to return the current setting of the MaximizedOnOpen property of a form, and to set this property to a new value.

[CurrMaximized] := Form.MAXIMIZEDONOPEN([NewMaximized])

CurrMaximized

Data type: boolean

The current setting of MaximizedOnOpen.

NewMaximized

Data type: boolean

The new setting of MaximizedOnOpen.

Comments

See the description of the MaximizedOnOpen property for details.


MINIMIZEDONOPEN (Form)

Use this function to return the current setting of the MinimizedOnOpen property of a form, and to set this property to a new value.

[CurrMinimized] := From.MINIMIZEDONOPEN([NewMinimized])

CurrMinimized

Data type: boolean

The current setting of MinimizedOnOpen.

NewMinimized

Data type: boolean

The new setting of MinimizedOnOpen.

Comments

See the description of the MinimizedOnOpen property for details.


OBJECTID (Form)

This function returns a string in the "form xxx" format, where xxx is the name or number of the application object.

String := Form.OBJECTID([UseNames])

String

Data type: text or code

Form

Data type: form

UseNames

Data type: boolean

The UseNames parameter is optional. If it is set to TRUE (default value) or if it is empty, the returned string contains references to field names in the table that the record is associated with. If the parameter is set to FALSE, field numbers are used instead.


RUN (Form)

Use this function to create and launch a form you specify. You can use CLEAR to remove the form. Use this function or the RUNMODAL (Form) function if you know at design time the exact form you want to run.

Otherwise, use the Form.RUNMODAL or Form.RUN function.

Form.RUN

Form

Data type: form

Once you define this variable, you can run these form functions on it: SETTABLEVIEW, SETRECORD, GETRECORD, RUN, and RUNMODAL. The system automatically clears the variable after it executes this function.

If the form you specify does not exist, a compile error occurs.

Comments

Once you define the variable f, you can use it before you run the form. If you use the RUNMODAL (form) function, you can use the variable before and after you run the form.

Example

This example shows how to use this function. Assume the variable f has been defined as Form 1.

Form.XXX;
 // any user-defined function
Form.SETTABLEVIEW(Rec);
Form.SETRECORD(Rec);
Form.RUN;


RUNMODAL (Form)

Use this function to create, launch, and close the form you specify. Use this function or the RUN (Form) function if you know at design time the exact form you want to run. Otherwise, use the Form.RUNMODAL or Form.RUN function.

[Action] := Form.RUNMODAL

Action

Data type: code

This optional return code tells you what action the user took. Here are the possible return values:

If Action is... | It means that the user...
OK | Pressed OK to exit the window
Cancel | Pressed Cancel to exit the window
LookupOK | Pressed OK on a lookup window
LookupCancel | Pressed Cancel on a lookup window
Yes | Pressed Yes
No | Pressed No
Close | Pressed Close, Esc, or closed the window using the title bar
Helpform | Selected Help
RunObject | Selected an option that ran another object
RunSystem | Selected an option that ran an external program

Form

Data type: variable

Once you define this variable, you can run these form functions on it: SETTABLEVIEW, SETRECORD, GETRECORD, RUN, and RUNMODAL. Unlike the Form.RUN function, the system does not automatically clear the variable after it executes this function.

If the form you specify does not exist, a compilation error occurs.

Comments

Once you define the variable f, you can use it before and after you run the form. If you use the Form.RUN function, you can only use the variable before you run the form.

Examples

This example shows how to use this function. Assume that the variable Form has been defined as Form 1.

CLEAR(f)
Form.XXX; // any user-defined function
Form.SETTABLEVIEW(Rec);
Form.SETRECORD(Rec);
IF Form.RUNMODAL = Action::LookupOK THEN Form.GETRECORD(Rec)...

Note that the code above includes the CLEAR function to make sure the variable has been cleared.


SAVERECORD (Form)

Use this function to save the current record shown on the form.

CurrForm.SAVERECORD

Comments

This function saves the current record to the table.

See also UPDATE.


SETRECORD (Form)

Use this function to select the current record shown on the form.

Form.SETRECORD(Record)

Form

Data type: form

Record

Data type: record

The record you want to select as the current record.

Comments

You can use this function to select a record to display when the user opens the form. If you use this function for this purpose, it will override the SourceTableRecord property "Saved" setting: the current record will not be saved in the setup file.


SETSELECTIONFILTER (Form)

Use this function to have the system note the records the user has selected on the form, mark those records in the table specified, and set the filter to "marked only".

CurrForm.SETSELECTIONFILTER(Record)

Record

Data type: record

A specific record or records.

Comments

If either all or no records are selected, marks will not be used.


UPDATE (Form)

Use this function to save the current record and then update the controls in the form. If you set the SaveRecord parameter to FALSE, this function will not save the record before the system updates the form.

CurrForm.UPDATE[(SaveRecord)]

SaveRecord

Data type: boolean

You have these options:

If you want the system to... | Set SaveRecord to...
Save the current record | TRUE
Update without saving the current record | FALSE

Comments

See also SAVERECORD (Form).


UPDATECONTROLS (Form)

Use this function to reload the captions of all controls on the current form. This is necessary when the user changes the caption class of a control after the form has been loaded.

CurrForm.UPDATECONTROLS


URL (Form)

This function returns a string that contains the full URL to a form.

String:=Form.URL([UseNames])

String

Data type: text or code

Form

Data type: form

UseNames

Data type: boolean

The UseNames parameter is optional. If it is set to TRUE (default value) or if it is empty, the returned string contains references to field names in the table that the record is associated with. If the parameter is set to FALSE, field numbers are used instead.

Comments

This function is equivalent to the functionality in the menu item Copy Link.

Example

For examples of how to format URLs, see Composing URLs.


GUID

Use this data type to give a unique identifying number to any database object.

The Globally Unique Identifier (GUID) data type is a 16 byte binary data type. This data type is used for the global identification of objects, programs, records and so on. The important property of a GUID is that each value is globally unique. The value is generated by an algorithm, developed by Microsoft, which assures this uniqueness.

The GUID is a 16 byte binary data type and can be logically grouped into the following subgroups:

4byte-2byte-2byte-2byte-6byte.

The standard textual representation is {12345678-1234-1234-1234-1234567890AB}.

The virtual table OLE Control (2000000042) does not use the GUID data type. It uses a textual representation of the GUID in a text field instead. It is easier to make operations and references to this text field using the GUID data type than it is using the textual representation. The GUID data type is compatible with the existing textual representation.

The GUID data type is useful when you want to uniquely identify some data, so that it can be exchanged with external applications. For example, if you want to transfer an item catalog to an external application, you add a GUID field to the record in the table and use this as the primary reference when you communicate with the external application.

Compatibility

You can assign and compare the TEXT data type and the GUID data type. Assigning a GUID to a TEXT can be done as follows:

MyTableRec.MyGuid  :=  MyTableRec.MyText;

Useful C/AL Functions and Properties

The following C/AL functions can be used with the GUID data type:

  • Guid:=CREATEGUID();

This function creates a new unique GUID value. The value can then be assigned to a field of the GUID data type or of the TEXT data type.

  • Ok:=ISNULLGUID(Guid);

This function is a convenient way to check if a value has already been assigned to a GUID or not. A NULL GUID (consisting only of zeroes) is valid, but should never be used for reference purposes.

  • CLEAR(Guid);

The standard CLEAR function can also be used on the GUID data type. It nullifies the GUID.

  • AutoSplitKey

A NULL GUID is valid but is not useful in a table. Therefore, the AutoSplitKey property is implemented for the GUID data type when it is used in a form. When GUID is selected as a primary key, AutoSplitKey is enabled for the form, and the GUID value remains NULL. When you create a new record, a valid GUID is created and assigned automatically.

The CREATEGUID and ISNULLGUID functions are available in the C/AL Symbol Menu under SYSTEM, Variables.

CREATEGUID takes no arguments and returns a valid 16 byte GUID value. If the result is assigned to a TEXT variable or field, the value is converted to a string and follows the syntax explained earlier. The algorithm that generates the new GUID value uses Microsoft's CoCreateGuid function.

ISNULLGUID takes a GUID value as a required argument and returns TRUE/FALSE depending on whether or not the GUID value is NULL. This function does not accept a TEXT value as an argument.

CLEAR is the standard CLEAR function and takes one required argument. It nullifies the GUID value in the same way as it resets any other value.

AutoSplitKey is a property, not a function and can be applied to forms. If you have defined a GUID field as part of the primary key, the AutoSplitKey property automatically generates a new valid GUID value. When a new record is created and the GUID field is left as NULL, the AutoSplitKey property ensures that a valid GUID value is automatically inserted into the field. If you then enter a NULL GUID into this record, for example, by using the CLEAR function, this new NULL GUID value is not automatically replaced by the AutoSplitKey property. The AutoSplitKey property only applies to new records.

Format

The GUID value can also be represented as text. You can use the standard C/AL functions FORMAT and EVALUATE to convert from GUID values to TEXT values. If you do not use the correct format when you edit a GUID value in its textual format, the following error message is displayed:

Invalid Format of GUID string. The correct format of the GUID string is
{CDEF7890-ABCD-1234-ABCD-1234567890AB}
where 0-9, A-F symbolizes hexadecimal digits.


CREATEGUID (GUID)

Use this function to create a new unique GUID. The value can then be assigned to a GUID data type or a text data type. Use the text data type if you want to compare the GUID to another text string.

Guid :=CREATEGUID();

Guid

Data type: guid


ISNULLGUID

Use this function to check whether or not a value has been assigned to a GUID. A null GUID that consists only of zeros is valid but must never be used for reference purposes.

Ok := ISNULLGUID(Guid);

Ok

Data type: boolean

If Ok is... | It means that...
TRUE | a value has been assigned to the GUID.
FALSE | a value has not been assigned to the GUID.


INSTREAM and OUTSTREAM

The InStream (input stream) and OutStream (output stream) data types are generic stream objects that you can use to read from or write to files and BLOBs. In addition, the InStream and OutStream data types enable data to be read from and sent to objects of the types Automation and OCX. The Microsoft XML DOM can read from an InStream object and write to an OutStream object.

You can define the internal structure of a stream as a flat stream of bytes. You can assign one stream to another. Reading from and writing to a stream occurs sequentially.

You can create a stream object using:

Blob.CREATEINSTREAM

Blob.CREATEOUTSTREAM

File.CREATEINSTREAM

File.CREATEOUTSTREAM

You can use InStream and OutStream in the following ways:

InStream.Read

InStream.EOS

InStream.ReadText

OutStream.WRITE

OutStream.WRITETEXT

More information:

Code Example for Streams


InStream.EOS

Use this function to find out whether or not an input stream has reached End of Stream (EOS).

IsEOS:= InStream.EOS()

IsEOS

Data type: boolean

This function has no parameters.

Return value: | Means:
Yes | The stream has reached End of Stream.
No | The stream has not reached End of Stream.

Comments

If you are reading data from an external component, EOS can return FALSE even though no more data is available. This may happen if you have not called READ first.

More information:

InStream and OutStream

Code Example for Streams

InStream.READ

InStream.READTEXT


InStream.READ

Use this function to read a specified number of bytes from an InStream object.

Data is read in binary format.

[{Read}:= ] InStream.Read(Variable, [Length])

Read

Data type: integer

where

Variable | is the variable that will receive the data that is read.
Length | is the number of characters that you requested to be read. If you don't specify Length, the size of the variable is used. In the case of data types other than string, code and binary, if you specify a length that differs from the size of the variable, an error message appears.

Return value

The number of characters that were read.

Comments

If the optional return value (READ) is not present and the data being read is less than the length requested to be read, an error message will appear.

If the return value is present, you must verify the validity of the data that has been read.

Example

recBinaries.FIND('-');
recBinaries.CALCFIELDS(Data);
recBinaries.CREATEINSTREAM(InStream);
InStream.READ(Title);
InStream.READ(Name);
InStream.READ(Surname);
InStream.READ(AltStartDate);

The above example is related to the example shown in OutStream.WRITE.

More information:

InStream and OutStream

Code Example for Streams

InStream.EOS

InStream.READTEXT


InStream.READTEXT

Use this function to read text from an InStream object. READTEXT reads the specified number of bytes, the maximum length of the string or until the end of the line.

Data is read in text format.

[{Read}:= ] InStream.ReadText(Text, [Length])

Read

Data type: integer

where

Text | is the variable of data type Text that receives the characters that were read.
Length | is the number of characters that you requested to be read. If you don't specify Length, the maximum length of the string is used.

Return value

The number of characters that were read.

Comments

If the optional return value (READ) is not present and the data being read is less than the length requested to be read, an error message will appear.

If the return value is present, you must verify the validity of the data that has been read.

Example

FileTest.OPEN('c:\XMLDocs\NewTest.txt');
FileTest.CREATEINSTREAM(streamInTest);
//Starting a loop
WHILE NOT (streamInTest.EOS()) DO
BEGIN
  Int:= streamInTest.READTEXT(Txt,100);
  MESSAGE(Txt + ' Size: ' + FORMAT(Int));
END;
FileTest.CLOSE();

More information:

InStream and OutStream

Code Example for Streams

InStream.READ

InStream.EOS


OutStream.WRITE

Use this function to write a specified number of bytes to the stream.

Data is written in binary format.

[{Written}:= ] OutStream.Write(Variable, [Length])

Written

Data type: integer

where

Variable | contains the data to be written.
Length | is the number of bytes that you requested to be written. In the case of data types other than string, code and binary, if you specify a length that differs from the size of the variable, an error message appears.

Return value

The number of bytes that were written.

Comments

If the optional return value (written) is not specified and it was not possible to write all the data, an error message appears.

If the return value is present, you must verify that all the data was streamed.

Example

recBinaries.FIND('-');
recBinaries.Data.CREATEOUTSTREAM(OutStream);
OutStream.WRITE('Secretary');
OutStream.WRITE('Alice');
OutStream.WRITE('Hart');
OutStream.WRITE(010696D);
recBinaries.MODIFY();

More information:

InStream and OutStream

Code Example for Streams

OutStream.WRITETEXT


OutStream.WRITETEXT

Use this function to write text to an OutStream object.

Data is written in text format.

[{Written} := ] OutStream.WriteText([Text, [Length]])

Written

Data type: integer

where

Text | is the text to write. If you do not specify this, a carriage return and a line feed are written.
Length | is the number of characters that you requested to be written.

Return value

The number of characters that were written.

Example

FileMyHTML.CREATE('main.html');
FileMyHTML.CREATEOUTSTREAM(OutStream);
OutStream.WRITETEXT('<html>');
OutStream.WRITETEXT();
utStream.WRITETEXT('<head>');
OutStream.WRITETEXT('<title>')My Page</title>);
OutStream.WRITETEXT('</head>');
OutStream.WRITETEXT();
OutStream.WRITETEXT('<P>Hello world!</p>');
OutStream.WRITETEXT();
OutStream.WRITETEXT('</html>');
FileMyHTML.CLOSE();

More information:

InStream and OutStream

Code Example for Streams

OutStream.WRITE


KEYGROUPDISABLE

Use this function to disable a key group.

[Ok :=] KEYGROUPDISABLE(GroupName)

Ok

Data type: boolean

This optional return value tells you whether or not the key group was enabled.

Ok returns... | If
TRUE | The key group was disabled.
FALSE | The key group was not disabled.

GroupName

Data type: string

The name of the key group that you want to disable.

Related Topics

Key Groups


KEYGROUPENABLE

Use this function to enable a key group.

[Ok :=] KEYGROUPENABLE(GroupName)

Ok

Data type: boolean

This optional return value tells you whether or not the key group was enabled.

Ok returns... | If
TRUE | The key group was enabled.
FALSE | The key group was not enabled.

GroupName

Data type: string

The name of the key group that you want to enable.

Related Topics

Key Groups


KEYGROUPENABLED

Use this function to check whether or not a specific key group is enabled.

[Ok :=] KEYGROUPENABLED(GroupName)

Ok

Data type: boolean

This optional return value tells you whether or not the key group is enabled.

Ok will be... | If
TRUE | The key group is enabled.
FALSE | The key group is not enabled.

GroupName

Data type: string

The name of the key group.

Related Topics

Key Groups


KEYREF

This complex data type identifies a key in a table and the fields in this key. This gives you access to the key and the fields it contains.

The keyref object can refer to any key in any table in the database


ACTIVE (KeyRef)

Use this function to find out if the key is enabled or not.

Ok := KeyRef.ACTIVE

Ok

Data type: boolean

The return value.

TRUE | The key is enabled.
FALSE | The key is not enabled.

KeyRef

Data type: keyref

The keyref that refers to a key.


FIELDCOUNT (KeyRef)

Use this function to return the number of fields that have been defined in a key. These functions returns an error if no key is selected.

No := KeyRef.FIELDCOUNT

No

Data type: integer

The number of fields that have been defined in the key.

KeyRef

Data type: keyref

The keyref that refers to the key.


FIELDINDEX (KeyRef)

Use this function to return the fieldref of the field that has this index in the key referred to by the keyref variable.

FieldRef := KeyRef.FIELDINDEX(Index)

Fieldref

Data type: fieldref

The fieldref that refers to the field with this index in the key.

KeyRef

Data type: keyref

The keyref that refers to the key.

Index

Data type: integer

Comments

The first field in the index must have index 1, the second index 2 and so on. The last field must have index = FIELDCOUNT. If the index is out of the range supplied or if no table is selected, the function returns an error.


RECORD (KeyRef)

Use this function to return the recordref of a key. This function returns an error if no key is selected.

RecordRef := KeyRef.RECORD

RecordRef

Data type: recordref

The recordref of the field that is currently selected.

KeyRef

Data type: keyref.

The keyref that refers to the key that is currently selected.


BIGINTEGER

Use this data type to store very large whole numbers. This data type is a 64 bit integer.

You must add an L to the constant definition to inform C/AL that the integer must be interpreted and treated as a BIGINTEGER.

Example

BI := 1L

BI := 455500000000L


DECIMAL

Use this simple data type to denote decimal numbers ranging from -10+E63 to +10+E63. The exponent ranges from -63 to +63. The system holds decimal numbers in memory with 18 significant digits.

Example

Here are some examples of decimal values:

546.88

3425.57

The following is not a decimal, but rather an integer:

342


INTEGER

Use this simple data type to store whole numbers with values that range from -2,147,483,647 to 2,147,483,647.

Comments

In addition to representing whole numbers in this range, you can use integers to represent boolean values. For boolean values, -1 represents TRUE and 0 represents FALSE.

Example

Here are some examples of integer values:

546

-3425

The following is not an integer, but rather a Decimal:

342.45


ABS (Numbers)

Use this function to calculate the absolute value of a number. ABS always returns a positive numeric value or zero.

NewNumber := ABS(Number)

NewNumber

Data type: integer

NewNumber is greater than or equal to 0 (zero).

Number

Data type: integer

The input value.

Comments

The system automatically converts all of the numeric data types for you.

Example

This example shows how to remove the sign from a negative numeric value.

x
 :=-10.235; // x is assigned a negative value
y := ABS(x);
 // y is assigned the value of x without sign
MESSAGE(Text000, x, y);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'x = %1, y = %2'

The system displays this message:

x = -10.235, y = 10.235


POWER (Numbers)

Use this function to raise a number to a power. For instance you can use this function to square the number 2 to get the result, 4.

NewNumber := POWER(Number, Power)

NewNumber

Data type: decimal

The result of raising Number by Power.

Number

Data type: integer

The number you want to raise exponentially. This number is the base in the exponential function.

Power

Data type: integer

The exponent in the exponential function.

Example

These examples show typical uses for the POWER function.

Compound Amounts

If a principal P is deposited at interest rate R and compounded annually, then at the end of N years the accumulated amount (A) is:

Suppose you placed $2800 into a bank account which pays 5%, compounded quarterly. To determine what the amount will be in eight years, you must consider:

N = 32 payment periods (8 years times 4 quarterly periods)

R = 0.0125 per period (5% divided by 4 quarterly periods)

So, the accumulated amount (A) is:

A = $2800(1 + 0.0125)32 =$2800(1.4881) = $4166.68

Annuity Amounts

If a principal P is deposited at the end of each year at interest rate R (in decimals) compounded annually, then at the end of N years the accumulated amount is:

This is often called an annuity.

Suppose you have an annuity in which a payment of $500 is made at the end of each year. The interest on this annuity is 4%, compounded annually. To determine what the annuity will be worth in 20 years you must consider:

R = 0.04

N = 20

So the amount of the annuity (A) will be:

A = $500((1 + 0.04)20 - 1)/0.04 = $14,889.05

Here's an example of the C/AL code you would use to make this calculation:

Number1
 := 2; Power1 := 8;
Number2 := 100; Power2 := 0;
Number3 := 5; Power3 := 0.5;

Res1
 := POWER(Number1, Power1);
Res2 := POWER(Number2, Power2);
Res3 := POWER(Number3, Power3);
MESSAGE(Text000, Number1, Power1, Res1)
MESSAGE(Text001, Number2, Power2, Res2);
MESSAGE(Text001, Number3, Power3, Res3);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | '%1 raised to the power of %2 = %3'
Text001 | '%1 raised to the power of %2 = %3'
Text002 | '%1 raised to the power of %2 = %3'

The message windows will show:

2 raised to the power of 8 = 256

100 raised to the power 0 = 1

5 raised to the power of 0.5 = 2,2360679775

The last message window shows that raising a number to the power of 0.5 corresponds to the square root of the number.


RANDOM (Numbers)

Use this function to return a pseudo-random number.

Number := RANDOM(MaxNumber)

Number

Data type: integer

A pseudo-random number between one (1) and the number you entered for MaxNumber.

MaxNumber

Data type: integer

The largest acceptable number. In effect, you are setting a range from one (1) to the number you enter here.

Comments

The system will always choose a number from the same set of numbers. Use RANDOMIZE to generate a new set of numbers.


RANDOMIZE (Numbers)

Use this function to generate a set of random numbers, from which RANDOM will select a random number.

RANDOMIZE([Seed])

Seed

Date type: integer

A number RANDOMIZE uses to create a unique set of numbers. If you use the same number as seed, you get the same set of numbers generated. If you omit this optional parameter, RANDOMIZE uses the current system time (total number of milliseconds since midnight).


ROUND (Numbers)

Use this function to round the value of a number variable.

NewNumber := ROUND(Number [, Precision] [, Direction])

NewNumber

Data type: decimal

The rounded result.

Number

Data type: decimal

The number you want to round.

Precision

Data type: decimal

This optional parameter determines the precision used when rounding. The default value is 0.01 for the US version. In other countries/regions, other default values may be used. Note that the default value is only used when you have not specified the rounding precision in the Amount Rounding Precision field in the General Ledger Setup table.

Direction

Data type: text or code

This optional parameter tells the system how to round Number. The default rounding method is '='. There are three different options for rounding.

Enter this... | To round...
'=' | To the nearest value (default)
'>' | Up
'<' | Down

Example

The following example shows how to use the ROUND function.

DN
 := 1234.56789;
Larger := '>';
Precision := 0.001;
Res := ROUND(DN,
 Precision, Larger);
MESSAGE(Text000,DN,
 Precision, Larger,Res);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'ROUND(%1, %2, %3) returns %4'

The message window shows:

ROUND(1,234.56789, 0.001, >) returns 1,234.568

This table shows some additional ROUND examples:

Number | Precision | Direction | New Number
1234.56789 | 100 | = | 1200
 | 0.1 | = | 1234.6
 | 0.001 | = | 1234.568
 | 0.001 | < | 1234.567
 | 0.001 | > | 1234.568
-1234.56789 | 100 | = | -1200
 | 0.1 | = | -1234.6
 | 0.001 | = | -1234.568
 | 0.001 | < | -1234.567
 | 0.001 | > | -1234.568

Note - Rounding Negative Numbers

When you round down ('<') a negative number, the following occurs: -1234.56789 is rounded down to -1234.567. However, -1234.567 is a mathematically greater value than -1234.56789.

When you round up ('>') a negative number, the following occurs: -1234.56789 is rounded up to -1234.568. However, -1234.568 is a mathematically smaller value than -1234.56789.


OCX

The OCX data type is used to reference a custom control (OCX, ActiveX Control). In order to use a control in C/SIDE, define a variable of type OCX and give it a name. Then use the lookup in the Subtype field to locate and select the control you want to use. You select from a list of installed controls, and when you select one, the GUID of the control is inserted. When the focus leaves the Subtype field, the name of the control is substituted for the GUID.

When you have defined a control as a variable, you can use the control through the variable, and you can browse its methods and properties in the Symbol Menu.

When you are using a control, you should know that there is not a one-to-one relationship between C/AL data types and COM data types. Click here to see an overview of the data type mapping.


OPTION

Use this simple data type to denote an option value. You can easily convert option data types to a number. The values range from -2,147,483,647 to 2,147,483,647.

Comments

In the OptionString property of the field or variable, you can enter the option values as a comma-separated list.

Example

Assume that Number is a numeric value and that Type denotes a field in the Purchase Header table. In the following statement, the system converts the option value into a number:

Number := "Purchase Header".Type

This example shows how you can use the possible values of an option field as constants in your C/AL code:

"Purchase Header".Type := "Purchase Header".Type::Invoice;


RECORD

This complex data type corresponds to a row in a table. Each record consist of fields (which form the columns of the table). A record is typically used to hold information about a fixed number of properties.

Comments

To access a field in a table in your C/AL code, use this syntax: TableName.FieldName


ADDLINK (Record)

Use this function to add a link to a record.

[ID := ]ADDLINK(URL[, Description])

ID

Data Type: Integer

The ID of the URL that you want to add to the record. Every time you add a link to a form or a table an entry is created in the Record Link system table. Each entry is given an ID.

URL, Description

Data Type: String

The link that you want to add to the record and an optional description of it.

Comments

The URL can be a link to a Web site, a file stored on the local or on a remote computer, or a link to a Navision form.


ASCENDING (Record)

Use this function to change or check the order in which the system will search through a C/SIDE table.

[IsAscending] := Record.ASCENDING([SetAscending])

IsAscending

Data type: boolean

This return value tells you the order in which a search will be made.

If IsAscending is... | It means the system will search in...
TRUE | Ascending order
FALSE | Descending order

SetAscending

Data type: boolean

Determines the order of the search.

To... | Enter...
Search in ascending order | TRUE
Search in descending order | FALSE
Check the search order | leave blank


CALCFIELDS (Record)

Use this function to update the FlowFields in a record.

[Ok :=] Record.CALCFIELDS(Field1, [Field2],...)

Ok

The optional return value.

Field1, Field2, ...

Data type: field

The FlowFields you want to update. Each field must be defined as a FlowField and must belong to the same record variable.

Comments

FlowFields are virtual fields. The values in these fields are not saved in the table. This means that you must use the CALCFIELDS function to update them. For example, if you retrieve a record using the FIND and NEXT functions, the system sets the FlowFields in those records to zero (0). Then, when you call CALCFIELDS, the system updates their values.

When a FlowField is a direct source expression of a control on a form or a report, the calculation will be performed automatically by the system.

Example

This example shows how to use the CALCFIELDS function to find the balance on December 31, 2003 and the net change for a customer in 2003:

Customer.SETRANGE("Date Filter",010103D,123103D);
Customer.CALCFIELDS(Balance, NetChange);

The first line sets up a filter for the date filter field in the customer record. This field is a FlowFilter field which the system uses when it calculates some of the FlowFields in the customer record. The system then calculates the FlowFields in the second line.


CALCSUMS (Record)

Use this function to calculate the total of a column of SumIndexFields in a C/SIDE table. Using parameters, you can tell the system exactly which fields to calculate.

[Ok :=] Record.CALCSUMS (Field1, [Field2],...)

Ok

Data type: boolean

If you omit this optional return value and if one of the fields is not a SumIndexField, a run-time error occurs. If you include a return value, the system assumes you will handle any errors.

Record

Data type: record

The record that contains the SumIndexFields you want to calculate.

Field1, Field2, ...

Data type: decimal

One or more decimal fields, which are defined as SumIndexFields, in the current key.

Comments

Use this function to total columns in a table. This function operates only on records that meet the conditions of any filters associated with the record.

Example

This example shows how to use the CALCSUMS function.

"Cust.
 Ledger Entry".SETCURRENTKEY("Customer No.","Date");
"Cust. Ledger Entry".SETRANGE("Customer No.", 'AAA
 1050');
"Cust. Ledger Entry".SETRANGE("Date", 010196D, 123196D);
"Cust. Ledger Entry".CALCSUMS("Amount");

The first line selects a key. The second and third lines set filters for the fields Customer No. and Date in the Cust. Ledger Entry record so the total is only calculated within the specified range. The CALCSUMS function then finds the net change in account AAA 1050 for 1996. The Amount field will show the result of the calculation.


CHANGECOMPANY (Record)

Use this function to redirect references to table data from one company to another.

[Ok :=] Record.CHANGECOMPANY([CompanyName])

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find the company. If you include the return value, you can handle any errors. The possible values are:

If Ok is... | It means that the company was...
TRUE | Found
FALSE | Not found

Record

Data type: record

The record you want to access from a table in another company.

CompanyName

Data type: text or code

The name of the company you want to change to. If you omit this parameter, the system changes back to the current company.

Comments

When executing this function, the system respects the user's access rights. For example, a user cannot access data in CompanyName unless he or she already has the necessary access rights.

The CHANGECOMPANY function is not affected by RESET (Record). You can deselect a company by making a new call to CHANGECOMPANY or by using CLEAR.

Global filters always belong to a specific company. If you use

Record.CHANGECOMPANY(NewCompany);

to select the company named NewCompany, any filters assigned to Record will be transferred to Record in the new company.

Example

This example shows how to use the CHANGECOMPANY function.

"G/L
 Account".CHANGECOMPANY('New Company');
"G/L Account".GET('1000');
"G/L Account".CALCFIELDS(Balance);// Calculates the balance
// for account no. 1000 in
// 'New Company'
"G/L Entry".CHANGECOMPANY('New Company');
"G/L Entry".SETCURRENTKEY("No.",LedgerEntry.Date);
"G/L Entry".SETRANGE("No.",'1000');
"G/L Entry".SETRANGE(Date,010196D,013196D);
"G/L Entry".CALCSUMS(NetAmount); // Sums NetAmount from
// all G/L entries on
// account no. 1000 within
// the specified range,
// for 'New Company'
"G/L Entry".RESET;
"G/L Entry".FIND('+'); // Finds the largest "No."
// in the G/L Entry table in
// 'New Company'
"G/L Entry".DELETE; // Deletes this entry in
// 'New Company'

This example shows that once the CHANGECOMPANY function has been called, all future references to the G/L Account and G/L Entry tables will refer to the table data in New Company.


CLEARMARKS (Record)

Use this function to remove all marks on a record.

Record.CLEARMARKS

Record

Data type: record

The record from which you want to remove all marks.

Example

This C/AL code removes all the marks from the Customer record.

Customer.CLEARMARKS


CONSISTENT (Record)

Use this function to mark a C/SIDE table as being consistent or inconsistent from an administrative point of view, which you define.

Record.CONSISTENT(Consistent)

Record

Data type: record

The table you want to mark.

Consistent

Data type: boolean

The mark to be set on the table.

To mark the table as... | Enter...
Consistent. | TRUE
Inconsistent. | FALSE

Comments

Normally this function is only used for accounting routines. If your accounts do not balance, the accounts are inconsistent. This function makes sure inconsistent changes are not made in your accounts.

If an attempt is made to commit a write transaction when a table is marked as inconsistent, the system displays a message and all updates made in the write transaction are aborted.

Example

A typical example of an inconsistency occurs when the sum of all the entries in a table containing general ledger entries does not balance (is not equal to zero).

Imagine that your application includes a function object called ChangeAmount. This function is used to withdraw amounts that were put into the General Ledger Entry table in your application. When an amount is withdrawn from an account, the system is inconsistent until a corresponding amount is put in. The pseudo-code below illustrates the ChangeAmount function:

FUNCTION
 ChangeAmount(DecimalNo.: Amount) BEGIN
GLEntry."G/L Account No." := '1000';
GLEntry.Amount := Amount;
GLEntry.INSERT;
Balance := Balance + Amount;
IF Balance = 0 THEN
Consistent := TRUE
ELSE
Consistent := FALSE;
GLEntry.CONSISTENT(Consistent);
END;

The function uses the variable Balance to express the change in balance. For example, when the function is used to withdraw $100, the Balance variable will reflect this as -$100.

When you use the function to put in one or more amounts whose total equals +$100, the Balance variable then equals zero and the table is marked as consistent. This means that if an attempt is made to put in an amount and end the write transaction (commit the change) without withdrawing a corresponding amount, an error occurs and the system cancels the write transaction.


COPY (Record)

Use this function to copy a record from a C/SIDE table. All filters, marks, and keys are included in the copy.

Record.COPY(FromRecord)

Record

Data type: record

The record where the copy should be placed.

FromRecord

Data type: record

The record you want to make a copy of.


COPYFILTER (Record)

Use this function to copy the filter set for one field and apply it to another field.

Record.COPYFILTER(FromField, ToRecord.ToField)

Record

Data type: record

The record to copy the filter from.

FromField

Data type: field

The system copies the filter set for this field.

ToRecord.ToField

Data type: record.field

The system applies the filter it copied (FromField) to the field you specify here.

Comments

The FromFields and ToFields must be of the same data type, but they do not have to belong to the same table.

Compare with COPYFILTERS.

Example

This C/AL code shows how to use the COPYFILTER function:

Customer.SETFILTER("No.", '<1000');
Customer.COPYFILTER("No.", Vendor."No.");
.
.
Count := Vendor.COUNT;

The system copies and applies the filter set for Customer."No." to Vendor."No.". This affects the result of the Record.COUNT function, which counts how many vendors have a number less than 1000.


COPYFILTERS (Record)

Use this function to copy all filters set by SETFILTER or SETRANGE from one record to another.

Record.COPYFILTERS(FromRecord)

Record

Data type: record

The record to copy filters to.

FromRecord

Data type: record

The system copies the filters from this record.

Comments

This function is used to apply filters defined for another record, as a basis for counting, searching, calculating, or similar operation.

Compare with Record.COPYFILTER.

Example

This C/AL code shows how to use the COPYFILTERS function:

Customer1.SETFILTER("No.", '<1000'); // Set filters
Customer1.SETRANGE(Group, 1); // on fields in a
Customer1.MARKEDONLY(TRUE); // Customer record
Customer2.COPYFILTERS(Customer1); // Apply filters
// to another record
Count := Customer2.COUNT;

The system copies the filters defined for Customer1 and applies them to Customer2. This affects the result returned by Record.COUNT in the last line.


COPYLINKS (Record)

Use this function to copy all the links from a particular record.

COPYLINKS(FromRecord)

Comments

You use this function to copy all the links from a specified record and paste the links to the current record.

The link can be a link to a Web site, a file stored on the local or on a remote computer, or a link to a Navision form.


COUNT (Record)

Use this function to count the number of records in a C/SIDE table.

Number := Record.COUNT

Record

Data type: record

Refers to the table to be counted.

Number

Data type: integer

The number of records in the table.

Comments

This function returns the number of records that meet the conditions of any filters associated with the records. If no filters are set, the function tells you the total number of records in the table.

Example

This example shows how to use the COUNT function. The statement:

Number := Customer.COUNT;

assigns the number of records in the Customer table to the Number variable. This statement is the same as:

Number := 0;
IF Customer.FIND('-') THEN
REPEAT
Number := Number + 1;
UNTIL Customer.NEXT = 0;

except the first example is much faster since only one command to the Database Management System (DBMS) is needed. The second example sends several commands to the DBMS.


COUNTAPPROX (Record)

Use this function to obtain an approximate count of the number of records in the table, for example, for updating progress bars or displaying informational messages.

Number := Record.COUNTAPPROX

Record

Data type: record

Refers to the table to be counted.

Number

Data type: integer

The number of records in the table.

If a filter has been set on the record, this function will behave exactly as the Record.COUNT function.

Comments

The count is approximate because it uses statistical information maintained by SQL Server, which is not kept precisely in synchronization with modifications to the table and is not under transaction control. However, it is much faster to use this information than to perform an accurate record count under transaction control, especially when there is a large number of records in the table.

Example

This example shows how to use the COUNTAPPROX function. The statement:

Number := Customer.COUNTAPPROX;

assigns the approximate number of records in the Customer table to the Number variable.


CURRENTKEY (Record)

Use this function to return the current key of a database table.

CurrentKey := Record.CURRENTKEY

CurrentKey

Data type: text or code

The name of the current key of Record.

Record

Data type: record

A record that refers to the table for which you want to find the key currently in use.


DELETE (Record)

Use this function to delete a record in a C/SIDE table. See also DELETEALL.

[Ok :=] Record.DELETE([RunTrigger])

Ok

Data type: boolean

The return value. If the record does not exist and you do not include a return value, the function will terminate with a run-time error.

If Ok is... | It means that the system...
TRUE | Deleted the record
FALSE | Did not delete the record because either it could not find it in the table, or the user did not have the correct permissions, or the C/AL code terminated

Record

Data type: record

The record to be deleted. Record itself does not change.

RunTrigger

Data type: boolean

This optional parameter lets you run the C/AL code in the OnDelete trigger.

To have the system... | Enter...
Execute the code in the OnDelete trigger | TRUE
Not execute the code in the OnDelete trigger | FALSE (default)

Comments

The current key and any filters on the record have no effect on this operation. The system identifies the record to delete by the values in its primary key.

In a multiuser environment, another application can delete the record from the table after you read the record and before you try to delete it. The Database Management System automatically detects such a situation, which causes the DELETE function to fail with a run-time error.

To prevent this situation, you can lock the table while you are using it with the LOCKTABLE function.

Example

These examples show how to use the DELETE function. The first example does not use the return value from the DELETE function. This means that a run-time error occurs if the system cannot find the record to be deleted. The second example shows how you can handle errors using the return value.

Without using the return value:

Customer."No." := '100':
Customer.DELETE;

Using the return value:

Customer."No." := '100';
IF Customer.DELETE THEN
MESSAGE(Text000)
ELSE
ERROR(Text001);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The customer has been deleted'
Text001 | 'The customer could not be found'


DELETEALL (Record)

Use this function to delete all records in a C/SIDE table that fall within a specified range. See also DELETE.

Record.DELETEALL([RunTrigger])

RunTrigger

Data type: boolean

This parameter lets you run the C/AL code in the OnDelete trigger.

To have the system... | Enter...
Execute the code in the OnDelete trigger | TRUE
Not execute the code in the OnDelete trigger | FALSE (default)

Record

Data type: record

Identifies the table in which the deletion will occur. The system only deletes those records selected by the filters set for Record.

Example

This C/AL code:

WHILE Customer.FIND('-') DO
Customer.DELETE;

performs the same operation as:

Customer.DELETEALL;

When the RunTrigger is FALSE (the default) the DELETEALL function is much faster because it requires only one call to the server, while the first method requires multiple calls. On the other hand, if RunTrigger is TRUE, there will not be any gain in performace because C/SIDE then has to load each record to the client anyway, in order to execute the OnDelete trigger.


DELETELINK (Record)

Use this function to delete a link that has been added to a record in a table.

DELETELINK(ID)

ID

Data Type: Integer

The ID of the link you want to delete.

Comments

Every time you add a link to a form or a table an entry is created in the Record Link system table. Each entry is given an ID.


DELETELINKS (Record)

Use this function to delete all of the links that have been added to a record.

DELETELINKS


FIELDACTIVE (Record)

Use this function to check whether a field is enabled or not.

Ok := Record.FIELDACTIVE(Field)

Ok

Data type: boolean

This return value tells you if the field is marked as enabled or disabled.

If Ok is... | It means that the field is marked as...
TRUE | Enabled
FALSE | Disabled

Field

Data type: field

The field you want to check.

Comments

Each field in a record can be set as enabled or disabled in the table description. You cannot use a disabled field because disabled fields cannot contain data.

Example

This example shows how to use the FIELDACTIVE function. The statement:

Customer."Address 2" := Text000;

causes a run-time error if the Address 2 field has not been marked as enabled. You can avoid this error by performing this test:

IF Customer.FIELDACTIVE("Address 2") THEN
Customer."Address" := Text000
ELSE
MESSAGE(Text000);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Atlanta'
Text001 | 'The field is not marked as enabled


FIELDCAPTION (Record)

Use this function to return the current caption of a field as a string.

Caption := Record.FIELDCAPTION(Field)

Caption

Data type: text or code

The caption as a string.

Field

Data type: field

The field for which you want to retrieve the caption.

Comments

FIELDCAPTION returns the caption of a field. FIELDCAPTION first looks for a CaptionML property. If it does not find one it will use the Name property. This means that FIELDCAPTION is multilanguage enabled.

See also TABLECAPTION and CAPTION.


FIELDERROR (Record)

Use this function to stop the execution of the code (cause a run-time error, in fact) and create an error message for a field.

Record.FIELDERROR(Field, [Text])

Record

Data type: record

The record that contains the field.

Field

Data type: field

The field for which you want to create an error message.

Text

Data type: text or code

Use this optional parameter to include the text of the error message. If this parameter is not present, default texts will be used as shown in the examples below. You can use backslashes (\) to break lines.

Comments

Like any other run-time error, this function causes the system to automatically abort any transaction.

Example

These examples show how to use the FIELDERROR function.

There is no Text parameter, and the field does not have a value:

Customer."No." := '';
Customer.FIELDERROR("No.");

This message appears:

You must specify No. in Customer No. = ''.

There is no Text parameter, and the field has a value: :

Customer."No." := 'NEW 3500';
Customer.FIELDERROR("No.");

This error message appears:

No. must not be NEW 3500 in Customer No. ='NEW 3500'

Using a non-empty string as Text parameter:

Customer."No." := 'NEW 3500';
Customer.FIELDERROR("No.", 'is not valid');

This error message appears:

No. is not valid in Customer No.='NEW 3500'


FIELDNAME (Record)

Use this function to return the name of a field as a string.

Name := Record.FIELDNAME(Field)

Name

Data type: text constant or code

The name of the field given as input.

Record

Data type: record

The name of the record that contains the field.

Field

Data type: field

The name of the field in the record.

Comment

The FIELDCAPTION function retrieves the Caption property of a field. If you want to enable your application for multilanguage now or in the future, you must use the FIELDCAPTION function instead.

Example

This example shows how to use the FIELDNAME function:

Name := Customer.FIELDNAME("No.");

The system stores the name of the field in a string. The advantage of this statement over

Name := 'No.';

is that the first statement dynamically adapts to any change to the field name made in the development system. The second statement performs a static assignment.


FIELDNO (Record)

Use this function to return the number assigned to a field in the table description.

Number := Record.FIELDNO(Field)

Number

Data type: integer

The number of the field you selected.

Record

Data type: record

The name of the record that contains the field.

Field

Data type: field

The name of the field in the record.

Example

This C/AL code shows how to use the FIELDNO function. The statement:

Number := Customer.FIELDNO("No.");

assigns the number of the No. field in the Customer record to the number variable.

Normally, this function is used to find out which field a variable, containing a field number, points to in a record:

CASE CurrentFieldNo OF
Customer.FIELDNO("No."): ...
Customer.FIELDNO(Name): ...
Customer.FIELDNO(Address): ...
ELSE ...
END;

This construct lets you tell the system to take actions based on the field number contained in the CurrentFieldNo variable.


FILTERGROUP (Record)

Use this function to change the filter group that is being applied to the table. You can also use this function to return the number of the current filtergroup. You cannot return the number of the filtergroup and set a new filtergroup at the same time.

A filtergroup can contain a filter for a Record that has been set earlier with SETFILTER or SETRANGE. The total filter applied is the combination of all the filters set in all the filtergroups.

[CurrGroup] := Record.FILTERGROUP([NewGroup])

CurrGroup

Data type: integer

The number of the current filter group.

Record

Data type: record

A record pointing to the table you want to work with.

NewGroup

Data type: integer

The number of the filter group you want to use.

Settings

There are filtergroups with numbers from 0 to 255.

Comments

When you select a FILTERGROUP, subsequent filter settings - by SETFILTER or SETRANGE - apply to that group.

All groups are active at all times. The only way to disable a group is to remove the filters set in that group.

Filters in different groups are all effective simultaneously; that is: if in one group, a filter is set on customer numbers 1000..2000, while in another group, a filter is set on customer numbers 1800..3000, the result will be that only numbers in the range 1800..2000 are visible.

C/SIDE uses 7 FILTERGROUPS internally:

Number | Name | Description
0 | Std | The default group where filters are placed when no other group has been selected explicitly. This group is used for filters that can be set from the filter dialogs by the end user. This group is also used for the filtering action that is the result of the RunFormLink property on a form.
1 | Global | Not used, but may be used in the future.
2 | Form | Used for the filtering actions that result from the SETTABLEVIEW function; from the SourceTableView property; and from the DataItemTableView property.
3 | Exec | Used for the filtering actions that result from the SubFormView and RunFormView properties.
4 | Link | Used for the filtering actions that result from the DataItemLink and SubFormLink properties.
5 | Temp | Not used, but may be used in the future.
6 | Security | Used for applying security filters for user permissions.

This means that a filter set in a group different from FILTERGROUP 0 cannot be changed by a user that uses a filter dialog to set a filter. If, for example, a filter has been set on customer numbers 1000..2000 in group 4, the user can set a filter that delimits this selection further, but cannot widen it to include customer numbers outside the range 1000..2000.

It is possible to use one of the internally used groups from C/AL. If you do this, keep in mind that in this way, you will replace the filter that C/SIDE assumes is in this group. If, for example, you use FILTERGROUP 4 in a form, you will replace the filtering that is actually the result of applying the SubFormLink property. This could seriously alter the way forms and subforms interact.


FIND (Record)

Use this function to find a record in a C/SIDE table based on the values stored in keys.

Ok := Record.FIND([Which])

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find the record. If you include a return value, the system assumes you will handle any errors. Ok can have these values:

If Ok is... | It means the record was...
TRUE | Found
FALSE | Not found

Record

Data type: record

On input, Record identifies the record you want the system to find. On output, there are two possibilities:

If the record was... | Then...
Found | The system returns the record in Record and sets any FlowField in the record to zero. You must update them using CALCFIELDS.
Not found | A run-time error occurs, if you omitted the return value Ok.

Which

Data type: text or code

Tells the system how to perform the search. The system searches through the table until either it finds the record or there are no more records. Each character in this string can be present only once. You can combine the '=', '<' and '>' characters.

This... | Tells the system to search for...
'=' | A record that equals the key values (default)
'>' | A record that is larger than the key values
'<' | A record that is less the key values
'+' | The last record in the table ('+' can only be used alone)
'-' | The first record in the table ('-' can only be used alone)

If SearchStr contains '=', '>' or '<', you must assign values to all fields of the current and primary keys before you call FIND.

Comments

FIND retrieves the first record that meets the conditions set by SearchStr and the filters associated with Record. The search path reflects the sort order defined by the current key. If the current key is not the primary key, there is a chance that several records might have the same values in current key fields. If this happens, the system uses the sort order defined by the primary key as the search path.

Example

This C/AL code shows how to use the FIND function:

dialog.OPEN('Search for customer number...\'
+ '#1##################');
dialog.INPUT(1, Customer."No.");

IF Customer.FIND THEN
MESSAGE(Text000 + Text001, Customer."No.", Customer.Name)

ELSE
MESSAGE(Text002);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The customer was found.\'
Text001 | 'Customer No. %1 is:\%2'
Text002 | 'Sorry, that customer could not be found...'

First, the system prompts you to enter a customer number to search for:

Search for customer number...

If the number you enter does not exist, the system displays this message:

Sorry, that customer could not be found...

If the system finds the number in the Customer table, it could display:

The customer was found.
Customer number AAA 1050 is:
AAA Furniture Manufacturing


FINDFIRST (Record)

Use this function to find the first record in a table based on the current key and filter.

Ok := Record.FINDFIRST

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find the record. If you include a return value, the system assumes you will handle any errors. Ok can have these values:

If Ok is... | It means the record was...
TRUE | Found
FALSE | Not found

Record

Data type: record

Contains the record if it was found.

If the record was... | Then...
Found | The system returns the record in Record and sets any FlowField in the record to zero. You must update them using CALCFIELDS.
Not found | A run-time error occurs, if you omitted the return value Ok.

Comment

This function should be used instead of FIND('-') when you only need the first record.

You should only use this function when you explicitly want to find the first record in a table/set. Do not use this function in combination with REPEAT .. UNTIL.

Example

The following C/AL code shows how to use the FINDFIRST function:

// Read the first record only

IF SalesSetup.FINDFIRST THEN BEGIN

  ConfigurePost(SalesSetup);

END;

Related Topics

FIND

FINDLAST

FINDSET


FINDLAST (Record)

Use this function to find the last record in a table based on the current key and filter.

Ok := Record.FINDLAST

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find the record. If you include a return value, the system assumes you will handle any errors. Ok can have these values:

If Ok is... | It means the record was...
TRUE | Found
FALSE | Not found

Record

Data type: record

If the record was... | Then...
Found | The system returns the record in Record and sets any FlowField in the record to zero. You must update them using CALCFIELDS.
Not found | A run-time error occurs, if you omitted the return value Ok.

Comment

This function should be used instead of FIND('+') when you only need the last record.

You should only use this function when you explicitly want to find the last record in a table/set. Do not use this function in combination with REPEAT .. UNTIL.

Example

The following C/AL code shows how to use the FINDLAST function:

// Read the last record only

IF GLEntry.FINDLAST THEN;

Related Topics

FIND

FINDFIRST

FINDSET


FINDSET (Record)

Use this function to find a set of records in a table based on the current key and filter. The records can only be retrieved in ascending order.

Ok := Record.FINDSET([ForUpdate][, UpdateKey])

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find a record. If you include a return value, the system assumes you will handle any errors. Ok can have these values:

If Ok is... | It means the record set was...
TRUE | Found
FALSE | Not found

Record

Data type: record

If the record was... | Then...
Found | The system returns the record in Record and sets any FlowField in the record to zero. You must update them using CALCFIELDS.
Not found | A run-time error occurs, if you omitted the return value Ok.

ForUpdate

Data type: boolean

Set this to FALSE if you don't intend to modify any records in the set.

Set this to TRUE if you want to modify some records in the set.

If you set this parameter to TRUE, a LOCKTABLE is immediately performed on the table before the records are read.

UpdateKey

Data type: boolean

This only applies if ForUpdate is set to TRUE.

If you are going to modify any field value within the current key, set this parameter to TRUE.

Comments

You should only use this function when you explicitly want to loop through a recordset. You should ONLY use this function in combination with REPEAT .. UNTIL.

Furthermore, FINDSET only supports descending loops. If you want to loop from the bottom up, you should use FIND(‘+’).

The general rules for using FINDSET are:

• FINDSET(FALSE,FALSE)- read-only. This uses no server cursors and the record set is read with a single server call.

• FINDSET(TRUE,FALSE)- is used to update non-key fields. This uses a cursor with a fetch buffer similar to FIND(‘-’).

• FINDSET(TRUE,TRUE)- is used to update key fields.

Note

This function is designed to optimize finding and updating sets. If you set any or both of the parameters to FALSE, you can still modify the records in the set but these updates will not be performed optimally.

Example

The following C/AL code examples show how to use the FINDSET function:

Example 1

// Looping through a set without updating it.

SalesLine.SETFILTER("Purch. Order Line No.",'<>0');

IF SalesLine.FINDSET THEN BEGIN

  REPEAT

    CopyLine(SalesLine);

  UNTIL SalesLine.NEXT = 0;

END;

Example 2

// Looping through a set  and updating a field that is not within the current key.

SalesLine.SETRANGE("Document Type",DocumentType);

SalesLine.SETRANGE("Document No.",DocumentNo);

IF SalesLine.FINDSET(TRUE, FALSE) THEN BEGIN

  REPEAT

    SalesLine."Location Code" := GetNewLocation(SalesLine);

    SalesLine.MODIFY;

  UNTIL SalesLine.NEXT = 0;

END;

Example 3

// Looping through a set and updating a field that is within the current key.

SalesShptLine.SETRANGE("Order No.",SalesLine."Document No.");

SalesShptLine.SETRANGE("Order Line No.",SalesLine."Line No.");

SalesShptLine.SETCURRENTKEY("Order No.","Order Line No.");

IF SalesShptLine.FINDSET(TRUE, TRUE) THEN BEGIN

  REPEAT

    SalesShptLine."Order Line No." := SalesShptLine."Order Line No." + 10000;

    SalesShptLine.MODIFY;

  UNTIL SalesShptLine.NEXT = 0;

END;

Related Topics

FIND

FINDFIRST

FINDLAST


GET (Record)

Use this function to find a record based on values stored in primary key fields.

[Ok :=] Record.GET([Value] ,...)

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find the record. When you include the return value, the system assumes you will handle any errors. The return value can have these values:

If Ok is... | It means that the record was...
TRUE | Found
FALSE | Not found

Record

Data type: record

The record in the table.

Value,...

Data type: any

Values in primary key fields. The data type of Value must match the data type of the corresponding primary key field. For example, if you enter an integer, the data type of the corresponding primary key field must also be an integer. The system assigns the value 0 (zero) or an empty string to unspecified fields.

Comments

This function always uses the primary key for the table and ignores any filters. The system does not change the current key and filters after you call this function.

Example

This C/AL code shows how to use the GET function. This statement

Customer.GET('1120');

causes a run-time error if the system cannot find customer 1120. To avoid this, use the following construct:

IF Customer.GET('1120') THEN
MESSAGE(Text000)
ELSE
MESSAGE(Text001);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The record was found'
Text001 | 'Sorry, the record could not be found...'


GETFILTER (Record)

Use this function to return a list of the filters within the current filter group that are applied to a field.

String := Record.GETFILTER(Field)

String

Data type: text constant or code

This string contains a list of the filters applied to the field in the record.

Record

Data type: record

The input record.

Field

Data type: field

The input field.

Comments

See also GETFILTERS, SETFILTER, and SETRANGE.

Example

This example shows how to use the GETFILTER function.

Write the following code in the OnRun trigger:

CustomerEntry.SETRANGE(Amount,
 -100, 100);
String := CustomerEntry.GETFILTER(Amount);
MESSAGE(Text000, String);

Create the following Global variables in the C/AL Globals window:

Variable
Name | Data Type | Subtype
String | Text |
CustomerEntry | Record | Cust. Ledger Entry

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The filter is:\%1'

The system displays this message:

The filter is:
-100..100


GETFILTERS (Record)

Use this function to return a string which contains a list of the filters within the current filter group for all fields in a record. In addition, this function also returns the state of MARKEDONLY.

String := Record.GETFILTERS

String

Data type: text constant or code

This string contains a list of the filters for all fields in Record.

Record

Data type: record

The record from which you want a list of filters.

Comments

See also GETFILTER, SETFILTER, and SETRANGE.

Example

This example shows how to use the GETFILTERS function.

"Cust.
 Ledger Entry".SETRANGE(Amount, -100, 100);
"Cust. Ledger Entry".SETRANGE(Date, 010196D, 123196D);
Str := "Cust. Ledger Entry".GETFILTERS;
MESSAGE(Text000 + '%1', Str);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The filters are:\'

The system displays this message:

The filters are:
Amount: -100..100, Date: 010196..123196


GETPOSITION (Record)

Use this function to return a string that contains the primary key of the current record.

String := Record.GETPOSITION([UseNames])

String

Data type: text or code

The string has the same format as the SourceTableRecord property on a form.

UseNames

Data type: boolean

Comments

The UseNames parameter is optional. If it is set to TRUE (default value) or if it is empty, the returned string contains references to field names in the table that the record is associated with. If the parameter is set to FALSE, field numbers are used instead.


GETRANGEMAX (Record)

Use this function to return the maximum value in a range for a field. Compare with GETRANGEMIN.

Value := Record.GETRANGEMAX(Field)

Value

Data type: depends on Field

Contains the maximum value of the range set for Field. The type of value must match the type of Field.

Record

Data type: record

The record which contains the field.

Field

Data type: field

The field you want to find the maximum value for. The current filter on Field must be a single range filter, otherwise a run-time error occurs.

Example

The following C/AL code shows how to use the GETRANGEMAX function.

With a filter which defines a single range:

Customer.SETFILTER("No.",'100..200');
Val := Customer.GETRANGEMAX("No.");
MESSAGE(Text000, Val);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The maximum value is: %1'

The message window shows:

The maximum value is: 200

With a filter which is a single value:

Customer.SETFILTER("No.",'100');
Val := Customer.GETRANGEMAX("No.");
MESSAGE(Text000, Val);

The message window shows:

The maximum value is: 100

With a filter which is not a single range:

Customer.SETFILTER("No.",'200|300');
Val := Customer.GETRANGEMAX("No.");

This causes a run-time error to occur.


GETRANGEMIN (Record)

Use this function to return the minimum value in a range for a field. Compare with GETRANGEMAX.

Value := Record.GETRANGEMIN(Field)

Value

Data type: text constant or code

Contains the minimum value of the range set for Field. The data type of value must match the type of Field.

Record

Data type: record

The record that contains the field.

Field

Data type: field

The field you want to find the minimum value for. The current filter on Field can only be a single range filter, otherwise a run-time error occurs.

Example

These examples show how to use the GETRANGEMIN function.

With a filter which is a single range:

Customer.SETFILTER("No.",'100..200');
Val := Customer.GETRANGEMIN("No.");
MESSAGE(Text000', Val);

The message window shows:

The minimum value is: 100

With a filter which is single value:

Customer.SETFILTER("No.",'100');
Val := Customer.GETRANGEMIN("No.");
MESSAGE(Text000, Val);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The minimum value is: %1'

The message window shows:

The minimum value is: 100

With a filter which is not a single range:

Customer.SETFILTER("No.",'200|300');
Val := Customer.GETRANGEMIN("No.");

This code causes a run-time error to occur.


GETVIEW (Record)

Use this function to return a string that describes the current sort order, key and filters on a table.

String := Record.GETVIEW([UseNames])

String

Data type: text or code

The string format is the same as the SourceTableView property on forms.

UseNames

Data type: boolean

Comments

The UseNames parameter is optional. If it is set to TRUE (default value) or if it is empty, the returned string contains references to field captions in the table that the record is associated with. If the parameter is set to FALSE, field numbers are used instead.

If the function SETVIEW has been executed, the String parameter will return the value set by SETVIEW.


HASFILTER (Record)

Use this function to determine if the system has attached a filter to a record within the current filter group.

Ok := Record.HASFILTER

Ok

Data type: boolean

The result.

If Ok is... | It means there...
TRUE | Is a filter
FALSE | Are no filters

Record

Data type: record

The record you want to check.


HASLINKS (Record)

Use this function to find out whether or not a record contains any links.

OK := HASLINKS

OK

Data Type: Boolean

The possible return values are:

If Ok is... | It means that...
TRUE | The record contains at least one link.
FALSE | The record does not contain any links.

Comments

The link can be a link to a Web site, a file stored on the local or on a remote computer, or a link to a Navision form.


INIT (Record)

Use this function to initialize a record in a C/SIDE table.

Record.INIT

Record

Data type: record

The record you want to initialize.

This function assigns default values to each field in the record. The values the system assigns in the record correspond to those defined when the table was created. If no value was assigned when the table was created, the system assigns values based on the data type, as shown in this table:

If the data type is... | The default value is...
Boolean | No
Option | 0
Integer | 0
Decimal | 0.0
Date | 0D (Undefined date)
Time | 0T (Undefined time)
Code | '' (empty string)
Text | '' (empty string)
BigText | <Empty>
Binary | <Empty>
BLOB | <Empty>
DateFormula | '' (empty string)
TableFilter | <Empty>
BigInteger | 0
Duration | 0
DateTime | 0DT (Undefined )
GUID | 00000000-0000-0000-0000-000000000000
RecordID | <Empty>

Comments

The system does not initialize primary key or timestamp fields.

After the system executes this function, you can change the values in any or all of the fields before you call the INSERT function to enter the record in the table. Be sure that the fields that make up the primary key contain values that make the total primary key unique. If the primary key is not unique (record already exists), the system rejects the record.

Example

These C/AL examples show how to use the INIT function. Assume that the primary key includes the "No." field:

Scenario 1

Customer.INIT;
Customer."No." := '1120';
Customer.INSERT;

Scenario 2

Customer."No."
 := '1120';
Customer.INIT;
Customer.INSERT;

Since INIT does not initialize the primary key fields, the order of the statements in situation 1 and 2 is not important. Situation 1 causes the same result as situation 2.


ISEMPTY (Record)

Use this function to find out whether a C/SIDE table or a filtered set of records is empty.

Empty := Record.ISEMPTY

Record

Data type: record

Refers to the table or the filtered set of records to be checked.

Empty

Data type: boolean

Comments

This function tells you whether the table is empty or not if you have not applied filters to the record. If you have applied filters, the function determines whether the filtered set of records is empty.

The number of filters that you have applied to the records affects the speed of the ISEMPTY function. The fewer the number of filters, the faster the system performs the operation.

When you are using SQL Server, this function is faster than using the Record.COUNT function and then testing the result for zero.


INSERT (Record)

Use this function to insert a record into a C/SIDE table.

[Ok :=] Record.INSERT([RunTrigger])

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot insert the record. If you include the return value, you must handle any errors. The return value can have the following values:

If Ok is... | It means that the record...
TRUE | Was inserted
FALSE | Was not inserted

Record

Data type: record

The record you want to insert.

RunTrigger

Data type: boolean

This parameter lets you run the C/AL code in the OnInsert trigger.

To have the system... | Enter...
Execute the code in the OnInsert trigger | TRUE
Not execute the code in the OnInsert trigger | FALSE (default)

Comments

The system uniquely identifies records using the values in primary key fields. The C/SIDE Database Management System (DBMS) checks the primary key for the table before it inserts a new record.

If the table contains an auto-increment field, the auto-increment feature is used if the record contains a zero value in that field. The auto-increment feature enters the new value into the field as part of the insert.

If the auto-increment field contains a non-zero value, that value is inserted into the table and the auto-increment feature is not used. If the value in the auto-increment field is greater that the last auto-increment value in the table, the next auto-increment value that is entered into the table will be greater than the value in the field that you just inserted. If the value in the auto-increment field already exists in the table, a runtime error occurs.

Example

These examples show how to use the INSERT function.

Without using the return value:

Customer.INIT
Customer."No." := '1120';
Customer.INSERT;

If customer 1120 already exists, a run-time error occurs. To avoid this, use the following construction:

Customer.INIT;
Customer."No." := '1120';
IF Customer.INSERT THEN
MESSAGE(Text000, Customer."No.")
ELSE
MESSAGE(Text001, Customer."No.");

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Customer no.: %1 inserted'
Text001 | 'Customer no: %1 already exists'


LOCKTABLE (Record)

Use this function to lock a C/SIDE table to protect it from write transactions that conflict with each other.

Record.LOCKTABLE([Wait] [, VersionCheck])

Record

Data type: record

The record from the table that you want to lock.

Wait

Data type: boolean

This parameter tells the system what to do if the table already is locked:

To make... | Enter...
The system wait until the table is unlocked, if another application already has locked the table | TRUE (or leave blank)
LOCKTABLE end with a run-time error, if another application already has locked the table | FALSE

VersionCheck

Data type: boolean

Use this optional parameter to do a version check.

To... | Enter...
Not check the version | FALSE (or leave blank)
Check the version | TRUE

The examples below show you how to use the VersionCheck parameter.

Comments

Because all write operations automatically lock the table in use, LOCKTABLE would appear unnecessary. Imagine, however, a transaction in which an application wants to inspect data and then only possibly change it, with a guarantee that the data being changed has not been modified by other applications since the read. The solution is to explicitly lock the table before the read operation. This makes sure no other application makes changes between the read and the possible write.

Example

The following examples show how to use the LOCKTABLE function.

Without the VersionCheck parameter:

This example uses pseudo-language to show the scope of write locks. Both an explicit lock and an automatic lock are illustrated.

The first line (1) explicitly locks table A. If this explicit lock was not set on table A, the DBMS would automatically lock this table when a record was inserted (3). Table B is not locked explicitly, but is locked automatically by the DBMS when a record is inserted (4). Both locks are active until the system exits the C/AL code module (5).

BeginWriteTransaction
LockTable(TableA) (1)
FindRec(TableA, ...) (2)
.
.
InsertRec(TableA,...) (3)
.
InsertRec(TableB) (4)
.
.
EndWriteTransaction (5)
With the VersionCheck parameter:

If a data update depends on a prior read and there is a relatively long time between the read and the write, you may not want to lock the table as you normally would during a transaction. In this way you would avoid preventing other users from updating the table until your transaction is committed. You can do this by using the VersionCheck parameter, which tells the system to compare time stamps to check if a record has been changed.

Consider this example:

Customer.GET('AAA 1050'); | {Reading at 10:00.Time stamp}
. | {automatically set to 10:00}
. |
. |
Customer.LOCKTABLE(TRUE, TRUE); | {Start write transaction at {10:15}
. |
. |
. |
. | {A run-time error occurs if}
Customer.MODIFY | {the time stamp on Customer}
. | {in the data version used in}
. | {the transaction differs}
. | {From the time stamp made}
. | {the last time you read the}
. | {record before the write}
. | {transaction started}
. |
{End write transaction} |

When the VersionCheck parameter is TRUE, the MODIFY function compares the time stamp of the record you modify within a transaction with the time stamp made the last time you read the record before the transaction started. If these time stamps differ, the record was changed after you read it and before you locked the table. If this occurs, the system displays an error message.

Using LOCKTABLE with SQL Server

The SQL Server Option for Microsoft Dynamics NAV only supports the default values for the parameters of the LOCKTABLE function – LOCKTABLE(TRUE,FALSE).

From the point where it takes effect, the LOCKTABLE function causes all operations on the table to be SERIALIZABLE.

If [Wait] is set to FALSE, it will be ignored. You must set [VersionCheck] to FALSE otherwise an error will occur.


MARK (Record)

Use this function to mark a record. You can also use this function to find out if a record is marked. See also MARKEDONLY.

[IsMarked] := Record.MARK([SetMarked])

IsMarked

Data type: boolean

This return value tells you whether Record is marked.

If IsMarked is... | It means that the record...
TRUE | Is marked
FALSE | Is not marked

The mark is effective until the system stops executing the application.

Record

Data type: record

The input record.

SetMarked

Data type: boolean

Mark this record, or remove a previously set mark..

To... | Enter...
Mark the record (already marked records remain marked) | TRUE
Remove any mark | FALSE

Example

This example shows how to use the MARK function. Assume that initially no records are marked:

Customer.SETCURRENTKEY("No.");
Customer."No." := 'NEW 3500';
Customer.FIND('=');
Customer.MARK(TRUE); // Mark a record
Customer.FIND('-'); // Find first record
REPEAT // Go through records
Marked := Customer.MARK; // Test if marked
MESSAGE(Text000, Customer."No.", Marked);
UNTIL Customer.NEXT = 0;

Create the following text constant in the C/AL Globals window:

Text Constant | ENU value
Text000 | 'Customer.No.:%1, Marked?:%2'

The example shows how to use MARK to explicitly mark a record and how to test whether or not a record is marked.

The message windows could show:

Customer No.: AAA 1050, Marked?: No

Customer No.: DEL 3500, Marked?: No

Customer No.: NEW 3500, Marked?: Yes

Customer No.: PEA 2500, Marked?: No

Customer No.: SOP 7500, Marked?: No

The next example shows how to use MARK with MARKEDONLY. Assume that initially none of the records are marked.

SETCURRENTKEY(Customer."No.");
Customer."No." := 'NEW 3500';
FIND(Customer, '=');
MARK(Customer, TRUE); //Mark a record
No1 := COUNT(Customer);
MARKEDONLY(Customer, TRUE);
No2 := COUNT(Customer);
MESSAGE(Text001 + Text002, No1, No2);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU value
Text001 | 'Number of records before MARKEDONLY: %1\'
Text002 | 'Number of records after MARKEDONLY: %2'

The message window could show:

Number of records before MARKEDONLY: 5
Number of records after MARKEDONLY: 1


MARKEDONLY (Record)

Use this function to tell the system to activate a special filter. After you use this function, your view of the table only includes records marked by this function.

[IsMarkedOnly] := Record.MARKEDONLY([SetMarkedOnly])

IsMarkedOnly

Data type: boolean

The return value reflects whether the special filter is activated.

If Ok is... | It means the special filter is...
TRUE | In use
FALSE | Not in use

Record

Data type: record

A record from the table for which you want to activate the special 'mark' filter.

SetMarkedOnly

Data type: boolean

This optional parameter changes the state of the special filter.

To include... | Enter...
Only marked records | TRUE
All records | FALSE

Example

This example shows how to use MARK and MARKEDONLY. You should assume that initially none of the records are marked.

Customer.SETCURRENTKEY("No.");
Customer."No." := 'NEW 3500';
Customer.FIND('=');
Customer.MARK(TRUE); // Mark a record

No1 := Customer.COUNT;
Customer.MARKEDONLY(TRUE);
No2 := Customer.COUNT;
MESSAGE(Text000 + Text001, No1, No2);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Number of records before MARKEDONLY: %1\'
Text001 | 'Number of records after MARKEDONLY: %2'

The message window could show:

Number of records before MARKEDONLY: 5
Number of records after MARKEDONLY: 1


MODIFY (Record)

Use this function to modify a record in a C/SIDE table. See also MODIFYALL.

[Ok :=] Record.MODIFY([RunTrigger])

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find the record. If you include the return value, you must handle any errors. The possible values are:

If Ok is... | It means that the system...
TRUE | Modified the record
FALSE | Could not find the record

Record

Data type: record

The record you want to modify. The system does not change the record.

RunTrigger

Data type: boolean

This parameter lets you run the C/AL code in the OnModify trigger.

To have the system... | Enter...
Execute the code in the OnModify trigger | TRUE
Not execute the code in the OnModify trigger | FALSE (default)

Comments

Select the record you want to replace using the primary key fields. The record's current key and filters do not affect the operation.

In multiuser environments, another application could modify the record between the time you read the record and when you attempt to modify it. The DBMS automatically watches for this and, if a conflict occurs, cancels the MODIFY function and displays an error message.

Example

This example shows how to use the MODIFY function.

Customer.FIND('='); |
MESSAGE(Text000 + | // Find customer
'%2', Customer."No.", Customer.Name); |
Customer.Name := 'Joe Raybon'; |
Customer.MODIFY; |
MESSAGE(Text001 + | // Display name
'%2', Customer."No.", Customer.Name); | // Modify customer name
 | // Display new name

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The customer no. %1 is:\'
Text001 | 'Now customer no. %1 is:\'

When the system locates a specific customer it displays a message similar to this:

The customer no. AAA 1050 is:
AAA Furniture Manufacturing

After the system modifies the information, the second message window could shows:

Now customer no. AAA 1050 is:
Joe Raybon


MODIFYALL (Record)

Use this function to modify a field in all records within a range you specify. See also MODIFY.

Record.MODIFYALL(Field, NewValue [, RunTrigger])

Record

Data type: record

The record that contains the field you want to modify.

Field

Data type: field

The field you want to modify.

NewValue

Data type: any

The value you want to assign to Field in all records. The data type of Value must match the type of Field.

RunTrigger

Data type: boolean

This parameter lets you run the C/AL code in the OnModify trigger.

To have the system... | Enter...
Execute the code in the OnModify trigger | TRUE
Not execute the code in the OnModify trigger | FALSE (default)

Comments

If no filter is set, the system modifies the field in all records in the table. If a filter is set, the system changes the fields only in the records which fall within the range specified by the filter.

Please note that the OnValidate trigger is never executed when MODIFYALL is used.

Example

This example shows how to use MODIFYALL. The result of the statement:

Customer.MODIFYALL(Group, 2);

is equivalent to:

IF
 Customer.FIND('-') THEN
REPEAT
Customer.Group := 2;
Customer.MODIFY;
UNTIL Customer.NEXT = 0;


NEXT (Record)

Use this function to step through a specified number of records and retrieve a record.

Steps := Record.NEXT([Steps])

Steps

Data type: integer

This function returns the number of records inspected which meet the criteria of any filters and the current key. This value can be less than Steps, depending on the number of records in the table. If the table is empty, the system returns zero and does not change Record.

Record

Data type: record

The record from which the system should begin the search.

Steps

Data type: integer

Used to define the direction of the search and how many records to step over.

This value... | Tells the system to...
> 0 | Search Steps records forwards in the table.
< 0 | Search Steps records backwards in the table.
= 0 | No effect

If you do not specify Steps, the system finds the next record.

Comments

This function locates a record positioned a given number of steps forward or backward from Record. Movement through the table is governed by the filters and the current key associated with the records. The fields in Record which will be compared with the current key fields must contain appropriate values before the function is called.

Example

This example shows how to use the NEXT function:

Count := 0;
IF Customer.FIND('-') THEN
REPEAT
Count := Count + 1;
UNTIL Customer.NEXT = 0;

This code uses a REPEAT UNTIL loop to count the number of entries in the Customer table. The FIND function finds the first entry in the table. Each time the system calls NEXT, it steps one record forward. When NEXT equals zero (0), there are no more entries in the table and the system exits the loop.


READCONSISTENCY (Record)

Use these functions to determine whether the table supports read consistency.

Ok := Record.READCONSISTENCY

Ok

Data type: boolean

This return value tells you whether or not read consistency is supported.

If Ok is... | It means that...
TRUE | The table supports read consistency.
FALSE | The table does not support read consistency.

Record

Data type: record

Refers to the table to be checked for this feature.

Comments

The advantage of read consistency is that a snapshot of the data can be used in situations where you do not want the data to change during the transaction. For example, you can print a report and be sure that other users have not updated the report data. Further, this function does not negatively affect the concurrency of the system in a multiuser environment.

The Microsoft Dynamics NAV Database Server supports read consistency as an integral part of the database architecture. At present, SQL Server does not support this feature. It implements a consistent snapshot by locking data as it is read to prevent other users from changing it. This significantly reduces concurrency for tables that are frequently accessed by multiple users.


READPERMISSION (Record)

Use this function to find out if you can read from a table. This function can test for both full read permission and a partial read permission that has been granted with a security filter.

This function uses the filter that is currently applied to the Record to determine whether or not you have read permission. If no filter is applied, the function tests for full read permission. If a filter has been set, the function only tests for read permission within the range of the filter.

To determine whether or not the user has a partial read permission, because a security filter has been applied, use the SETPERMISSIONFILTER (Record) function before testing the permission with READPERMISSION (Record)

Ok := Record.READPERMISSION

Ok

Data type: boolean

This return value tells you whether you have permission to read from the table.

If Ok is... | You can...
TRUE | Read from some or all of the table
FALSE | Not read from the table

Record

Data type: record

The record in the table from which you want to read.

Comments

If you do not have permission to read from a table and you attempt to read, the system generates a run-time error. This function lets you find out beforehand if you have read permission. When the permissions are checked, the combination of permissions in the license file and the user's permissions in the Permission table is considered.


RECORDLEVELLOCKING (Record)

Use these functions to find out whether the table supports record level locking.

Ok := Record.RECORDLEVELLOCKING

Record

Data type: record

Refers to the table to be checked for this feature.

Ok

Data type: boolean

The possible return values are:

If Ok is... | It means that...
TRUE | The table supports record level locking.
FALSE | The table does not support record level locking.

Comments

When you are using SQL Server, you can use record level locking.

When you are using the Microsoft Dynamics NAV Database Server, you cannot use record level locking.


RELATION (Record)

Use this function to find out the table relationship of a given field.

TableNumber := Record.RELATION(Field)

TableNumber

Data type: integer

The number of the table which has a relationship with Field. This relationship is set up through the properties.

Record

Data type: record

The record which contains Field.

Field

Data type: field

The field for which you want to find the table relationship.

Comments

You can use this function for several purposes such as to determine lookups or to check to see if you have permission to read from a table.


RENAME (Record)

Use this function to change a primary key in a C/SIDE table.

[Ok]:= Record.RENAME(Value1, [Value2],...)

Ok

Data type: boolean

This tells you whether the system was able to rename the primary key or not. Typically, the system will return FALSE if the record does not exist or if you do not have permission to write to the table.

Record

Data type: record

The record that contains the primary key that you want to change.

Value1, Value2, ...

Data type: text

The new values for the primary key.

Comments

For example, if you use the customer's phone number as the customer number, you can use this function to change the customer number if the phone number changes.


RESET (Record)

Use this function to remove all filters, including any special filters set by MARKEDONLY, and change the current key to the primary key. The system also removes any marks on the record and clears any C/AL variables on the record.

Record.RESET

Record

Data type: record

The record you want to reset.

Example

This code shows how to use the RESET function.

Customer.SETFILTER("No.",
 'NEW 3500');
Customer.SETRANGE("Salesperson Code",
 'J. JENSEN');
Customer.MARKEDONLY(TRUE);
Count := Customer.COUNT;
 // Count marked customers in the range
Customer.RESET;
Count1 := Customer.COUNT(Customer);
 // Count all customers
MESSAGE(Text000 + Text001, Count, Count1);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Before RESET: %1\'
Text001 | 'After RESET: %2'

The message window could show:

Before RESET: 0
After RESET: 5

The example shows that RESET removed all filters.


SETCURRENTKEY (Record)

Use this function to select a key for a table.

[Ok :=] Record.SETCURRENTKEY(Field1, [Field2],...)

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find the key. If you include a return value, you must handle any errors. The possible values are:

If Ok is... | It means the key was...
TRUE | Selected
FALSE | Not selected (does not exist)

Record

Data type: record

The record that contains the fields which identify the key you want to select.

Field1, Field2

Data type: field

One or more fields which identify the key you want to select.

Comments

SETCURRENTKEY is used to select a key for a record, and thereby set the sort order that is used for the table in question. This key becomes the current key and is used by FIND, NEXT, and other functions until another key is selected. Until this function is called, the system uses the table's primary key as the current key.

Remember the following points when you use SETCURRENTKEY:

  • Inactive fields are ignored - only active keys are scanned.

  • When searching for a key, C/SIDE selects the first occurrence of the specified field(s).

This means that:

  • if you specify only one field as a parameter when you call SETCURRENTKEY, the key that is actually selected may consist of more than one field.

  • if the field that you specify is the first component of several keys, the key that is selected may not be the key that you expect.

  • if no keys can be found that include the field(s) that you specify, a runtime error occurs unless you test the Boolean return value of SETCURRENTKEY in your code.

If you do test the return value, you must decide what the program should do if the function returns FALSE, because without a runtime error, the program will continue to run even though no key was found.

Example

These examples show to use the SETCURRENTKEY function.

Without using the return value:

Customer.SETCURRENTKEY(Name);

This statement selects the Name key for the Customer table. If the system cannot find the key, a run-time error occurs.

Using the return value:

By including a return value, you can avoid a run-time error if the system cannot find the key.

IF Customer.SETCURRENTKEY(Name) THEN
MESSAGE(Text000)
ELSE
MESSAGE(Text001);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The key was successfully selected!'
Text001 | 'Sorry, the key could not be found...'


SETFILTER (Record)

Use this function to assign a filter to a field you specify.

Record.SETFILTER(Field, String, [Value],...)

Record

Data type: record

The record that contains the field you want to filter.

Field

Data type: field

The field you want to filter.

String

Data type: text or code

The filter expression. A valid expression consists of alphanumeric characters and one or more of the following operators: <, >, *, &, |, and =. You can use replacement fields (%1, %2, and so on) to insert values at run-time.

Value

Data type: any

Replacement values to insert in replacement fields in the filter expression. The data type of Value must match the type of Field.

Comments

If the function is called with a field for which a filter already exists, the system will remove that filter before it sets the new one. You can construct filters using these operators:

This operator... | Means...
.. | Range
& | And
| | Or
< | Less than
<= | Less than or equal to
> | Greater than
>= | Greater than or equal to
<> | Different from
* | Forms a part of value

Example

This table shows examples of filters:

This example... | Means...
A..Z | A range from A to Z
A | G | A or G
F.. & *A/S | A range from F and A/S is included in the field.
<>B | All except B
<>'' | All not blank
<=200 | >500 | All less than or equal to 200 or greater than 500

Using a filter with replacement field:

This filter selects all accounts in the range from 100 to 200 and No. 300

"G/L Account".SETFILTER("No.", '%1..%2|%3', '100', '200', '300');

Using a filter entered directly in a string:

This filter, which is entered as a string, corresponds to the previous example. It too selects all accounts in the range from 100 to 200 and No. 300.

"G/L Account".SETFILTER("No.", '100..200|300');


SETPERMISSIONFILTER (Record)

Use this function to apply the user's security filter to a Record variable. The security filter is combined with any other filters that are placed on the Record variable with SETFILTER (Record) or SETRANGE (Record).

The combined filter will not include any records outside the range of the security filter and this will prevent a run-time permission error from occurring when you read the records. If SETPERMISSIONFILTER is not set a permission error can occur if you attempt to read a record that is outside the range of the user's security filter.

This C/AL function only applies to the SQL Server Option for Microsoft Dynamics NAV.

Record.SETPERMISSIONFILTER

Comments

Security filters are an essential part of record level security. Security filters limit the access that a user has so that they can only access the records, in the tables that they have permissions for, that match the criteria specified in the security filter.

For more information about record level security, see the manuals Installation & System Management: Microsoft SQL Server Option and Application Designer's Guide.

Examples

Scenario 1

This example finds the first record within your read permission security filter:

Customer.SETPERMISSIONFILTER;
Customer.FIND('-');

Scenario 1

This example determines whether or not you have any read permission by setting the current filter as your security filter:

Customer.SETPERMISSIONFILTER;

If Customer.READPERMISSION THEN

  MESSAGE('You have some read permissions to Customer.')

ELSE

  MESSAGE('You have no read permission to Customer.');


SETPOSITION (Record)

Use this function to set the fields in a primary key on a record to the values specified in the supplied string. The remaining fields are left untouched.

Record.SETPOSITION(String)

String

Data types: text or code


SETRANGE (Record)

Use this function to set a simple filter, such as a single range or a single value, on a field.

Record.SETRANGE(Field [,FromValue] [.ToValue])

Record

Data type: record

The record that contains the field you want to filter.

Field

Data type: field

The field you want to filter.

FromValue

Data type: -

The lower limit of the range. The data type of FromValue must match Field.

ToValue

Data type: -

The upper limit of the range. If you omit this parameter, the system uses the value you specified for FromValue. The data type of ToValue must match Field.

Comments

SETRANGE is a quick way to set a simple filter on a field.

SETRANGE removes any filters that were set earlier and replaces them with the From-Value/To-Value parameters that you specify.

If you use SETRANGE without setting the From-Value/To-Value parameters, the function removes any filters that are already set.

If you only set the From-Value, the To-Value is set to the same value as the From-Value.

Example

This example shows how to use the SETRANGE function to specify that you only want to see customers 100 through 200.

Customer.SETRANGE("No.", '100', '200');

The above statement is a quick way to set the same filter as:

Customer.SETFILTER("No.", '>=100&<=200');


SETRECFILTER (Record)

Use this function to set the values in the current key of the current record as a record filter.

Record.SETRECFILTER

Example

You can use this function to set a filter on a table before running a report. Enter C/AL code similar to the example shown below in the OnPush trigger of a command button or menu item on a form. When the code is triggered, the current key fields of the current record in the form will be used as a filter when the report is run.

Customer.SETRECFILTER;
REPORT.RUN(REPORT::"An Example Report",FALSE,FALSE,Customer);


SETVIEW (Record)

Use this function to set the current sort order, key and filters on a table.

Record.SETVIEW(String)

String

Data type: text or code

The string format is the same as the SourceTableView property on forms.

Comments

The value of the String parameter can be one returned by GETVIEW.

If the SETVIEW function is executed with an empty string, all filters are removed and the primary key is used.


TABLECAPTION (Record)

Use this function to return the current caption of a table as a string.

Caption := Record.TABLECAPTION

Caption

Data type: text or code

The caption as a string.

Comments

TABLECAPTION returns the caption of a table. TABLECAPTION first looks for an CaptionML property. If it does not find one it will use the Name property. This means that TABLECAPTION is multilanguage enabled.

See also FIELDCAPTION and CAPTION (Form).


TABLENAME (Record)

Use this function to return the name of a C/SIDE table.

Name := Record.TABLENAME

Name

Data type: text or code

The name of the table.

Record

Data type: record

The record in the table for which you want to find the table name.

Comments

The TABLECAPTION function retrieves the Caption property of the table. If you want to enable your application for multilanguage now or in the future, you must use the TABLECAPTION function instead.


TESTFIELD (Record)

Use this function to test to see if the contents of a field match a given value. If the contents differ from the given value, the system displays an error message.

Record.TESTFIELD(Field, [Value])

Record

Data type: record

The record that contains the field you want to test.

Field

Data type: field

The field you want to test.

Value

Data type: any

The value you want to compare to Field. The data type of Value must match the type of Field. If you include Value and the contents of Field do not match, the system displays an error message. If you omit Value and the content of Fields is zero or blank (empty string), the system also displays an error message.

Example

These examples show how to use the TESTFIELD function.

Without Value:

Customer."No." := '';
Customer.TESTFIELD("No.")

This code returns an error message:

You must specify No.in Customer No.=''

With Value:

Customer."No." := 'AAA 1050';
Customer.TESTFIELD("No.",'1000')

If No. is not 1000, the system displays this message:

No. must be 1000 in Customer No.='AAA 1050'


TRANSFERFIELDS (Record)

Use this function to copy all matching fields in one record to another record.

Record.TRANSFERFIELDS(FromRecord [, InitPrimaryKeyFields])

Record

Data type: record

The record to copy the contents of the fields in FromRecord to.

FromRecord

Data type: record

The record from which to copy.

InitPrimaryKeyFields

Data type: Boolean

Default value: True

Comments

TRANSFERFIELDS copies fields based on the Field No. property of the fields. For each field in Record (the destination), the contents of the field with the same Field No. in FromRecord (the source) will be copied, if such a field exists.

The fields must have the same data type for the copying to succeed (text and code are convertible, other types are not.) There must be room for the actual length of the contents of the field to be copied in the field to which it is to be copied. If any of these conditions are not fulfilled, a run-time error will occur.

If the InitPrimaryKeyFields parameter is set to false, the TRANSFERFIELDS function will not change the timestamp or the Primary Key fields of the destination record.

If the InitPrimaryKeyFields parameter is set to true, and the records are in the same table, the TRANSFERFIELDS function will change both the timestamp and the Primary Key fields of the destination record.

If the InitPrimaryKeyFields parameter is set to true, and the records are not in the same table, the TRANSFERFIELDS function will change the Primary Key fields of the destination record (if the fields fulfill the conditions specified above) but the timestamp of the destination record will not be changed.

BLOB Fields

If you are copying a record that contains a BLOB field, you must calculate the BLOB field before it can be copied with the rest of the record.

IF Mytable.BLOB.HASVALUE THEN
 Mytable.CALCFIELDS(BLOB);


VALIDATE (Record)

Use this function to call the triggers for the field you specify.

Record.VALIDATE(Field [, NewValue])

Field

Data type: field

A field with associated triggers.

NewValue

Data type: must be the same data type as Field, or a data type that is convertible.

The value to insert in Field.

Comments

VALIDATE first checks any TableRelation and then executes the OnValidate trigger of the field.

Example

The following C/AL code shows how to use the VALIDATE function.

When you enter an account number in a ledger, the system executes some table trigger code to transfer the name of the account from the chart of accounts.

If you enter an account number in a batch job, the system does not automatically execute the code which transfers the name of the account. The following code tells the system to execute the appropriate field-level trigger code:

Variable | Data Type | Subtype
GeneralLedgerEntry | Record | G/L Entry

GeneralLedgerEntry.VALIDATE("G/L AccountNo", '100');

This corresponds to:

GeneralLedgerEntry."G/L AccountNo" := '100';
GeneralLedgerEntry.VALIDATE("G/L AccountNo");

The VALIDATE function is useful for centralizing processing and thereby making your application easier to maintain.

For example, if that the OnValidate trigger of the Total Amount field performs a calculation that uses values from three other fields as operands, the calculation must be performed again if the contents of any of these fields changes.

You should avoid entering the calculation formula in the OnValidate triggers of each field because this can create all sorts of errors if the calculation formula has to be changed later and you have to update the code in all the triggers. Instead, you should enter the calculation formula in the OnValidate trigger of only one of the fields and call this trigger code from the OnValidate triggers of the other fields.


WRITEPERMISSION (Record)

Use this function to find out if you can write to a table. This function can test for both full write permission and a partial write permission that has been granted with a security filter. A write permission consists of Insert, Delete and Modify permissions.

This function uses the filter that is currently applied to the Record to determine whether or not you have write permission. If no filter is applied, the function tests for full write permission. If a filter has been set, the function only tests for write permission within the range of the filter.

To determine whether or not the user has a partial write permission, because a security filter has been applied, use the SETPERMISSIONFILTER (Record) function before testing the permission with WRITEPERMISSION (Record).

Ok := Record.WRITEPERMISSION

Ok

Data type: boolean

This return value tells you if you have permission to write to the table using any of the following Record functions: INSERT, DELETE, MODIFY, RENAME, DELETEALL, MODIFYALL.

If Ok is... | You can...
TRUE | Write to some or all of the table
FALSE | Not write to the table

Record

Data type: record

A record in the table for which you want to know if you have write permission.

Comments

If you do not have permission to write to a table and you attempt to write, the system generates a run-time error. This function lets you find out beforehand if you have write permission. When the permissions are checked, the combination of permissions in the license file and the user's permissions in the Permission table is considered.


RECORDID

This data type contains the table number and the primary key of a table. You can store a RecordID in the database but you cannot set filters on a RecordID.


GETRECORD (RecordID)

Use this function to return a recordref that refers to the record identified by recordID.

RecordRef := RecordID.GETRECORD

RecordRef

Data type: recordref

The recordref of the record.

RecordID

Data type: recordID

The recordID of the record for which you want the recordref.

Comments

No data is read from the database when you run this function and therefore no other fields in the record are set. Furthermore, no filters are set on the record.


TABLENO (RecordID)

Use this function to return the table number of the table identified by recordid. This function returns an error if the record is blank.

No := RecordID.TABLENO

No

Data type: integer

The number of the table.

RecordID

Data type: recordID

The recordID of the record whose number you want returned.


RECORDREF

This complex data type identifies a row in a table. Each record consists of fields (which form the columns of the table). A record is typically used to hold information about a fixed number of properties.

The RecordRef object can refer to any table in the database. Use the RecordRef.OPEN function to select the table you want to access. When you use the RecordRef.OPEN function a new object is created. This object contains references to the open table, filters and the record itself and all the fields it contains.

If one RecordRef variable is assigned to another RecordRef variable, they both refer to the same table instance.


ADDLINK (RecordRef)

Use this function to add a link to a record in a table.

[ID := ]ADDLINK(URL[, Description])

ID

Data Type: Integer

The ID of the URL that you want to add to the record. Every time you add a link to a form or a table an entry is created in the Record Link system table. Each entry is given an ID.

URL, Description

Data Type: String

The link that you want to add to the record and an optional description of it.

Comments

The URL can be a link to a Web site, a file stored on the local or on a remote computer, or a link to a Navision form.


ASCENDING (RecordRef)

Use this function to change or check the order in which the system will search through the table referred to by the recordref.

[IsAscending :=] RecordRef.ASCENDING([SetAscending])

IsAscending

Data Type: boolean

This return value tells you the order in which a search will be made.

If IsAscending is... | It means the system will search in...
TRUE | Ascending order
FALSE | Descending order

RecordRef:

Data Type: recordref

SetAscending

Data type: boolean

Determines the order of the search.

To... | Enter...
Search in ascending order | TRUE
Search in descending order | FALSE
Check the search order | leave blank

This function works exactly like the Record.ASCENDING function.


CAPTION (RecordRef)

Use this function to return the caption of the table that is currently selected. This function returns an error if no table is selected.

Caption := RecordRef.CAPTION

Caption

Data type: text

The caption of the table.

RecordRef

Data type: recordref

The recordref that identifies the table that you are interested in.

This function works exactly like the Record.TABLECAPTION function.


CLOSE (RecordRef)

Use this function to close the current form or table.

RecordRef.CLOSE

RecordRef

Data type: recordref

The recordref of a record in the table that you want to close.

Comments

You must use this function if you have a number of recordrefs defined as variables because these will be maintained until the variable gets out of scope.


COUNT (RecordRef)

Use this function to count the number of records that are within the filters that are currently applied to the table referred to by the recordref.

Number := RecordRef.COUNT

Number

Data type: integer

The number of records in the table.

RecordRef

Data type: recordref

The recordref that refers to the table.

Comments

This function returns the number of records that meet the conditions of any filters associated with the records. If no filters are set, the function tells you the total number of records in the table.

This function works exactly like the Record.COUNT function.


COPYLINKS (RecordRef)

Use this function to copy all the links from a particular record.

COPYLINKS(FromRecord)

Comments

You use this function to copy all the links from a specified record and paste the links to the current record.

The link can be a link to a Web site, a file stored on the local or on a remote computer, or a link to a Navision form.


COUNTAPPROX (RecordRef)

Use this function to obtain an approximate count of the number of records in the table, for example, for updating progress bars or displaying informational messages.

Number := RecordRef.COUNTAPPROX

Number

Data type: integer

The number of records in the table.

If a filter has been set on the record, this function will behave exactly as the Record.COUNT function.

RecordRef

Data type: recordref

The recordref of a record in the table to be counted.

Comments

The count is approximate because it uses statistical information maintained by SQL Server, which is not kept precisely in synchronization with modifications to the table and is not under transaction control. However, it is much faster to use this information than to perform an accurate record count under transaction control, especially when there is a large number of records in the table.

This function works exactly like the Record.COUNTAPPROX function.


CURRENTKEY (RecordRef)

Use this function to return the current key of the table referred to by the recordref. The current key is returned as a string.

CurrentKey := RecordRef.CURRENTKEY

CurrentKey

Data type: text

The name of the current key of Record.

RecordRef

Data Type: recordref

The recordref that refers to the table for which you want to identify the current key.

Example

Create the following text constants and variables in the C/AL Globals window:

Text Constant | ENU Value
Text000 | The current key in the "%1" table is "%2".
Variable | Data type
RecRef | RecordRef

The following C/AL code shows how to use the CurrentKey function:

RecRef.OPEN(18);

MESSAGE(Text000,RecRef.CAPTION,RecRef.CURRENTKEY)

RecRef.Open(18) opens table 18 and causes a run-time error if table 18 does not exist.

RecRef.Caption returns the caption of the table.

RecRef.CURRENTKEY returns the caption of the current key in the table.


CURRENTKEYINDEX (RecordRef)

Use this function to return or set the current key of the table referred to by the recordref. The current key is set or returned as a number.

[CurrKeyIndex :=] RecordRef.CURRENTKEYINDEX([NewKeyIndex])

CurrKeyIndex

Data Type:

The number of the current key

RecordRef

Data Type: recordref

NewKeyNo

Data Type: Integer

The number of the new key


DELETE (RecordRef)

Use this function to delete a record in a C/SIDE table. See also DELETEALL.

[Ok :=] RecordRef.DELETE([RunTrigger])

Ok

Data type: boolean

The return value. If the record does not exist and you do not include a return value, the function will terminate with a run-time error.

If Ok is... | It means that the system...
TRUE | Deleted the record
FALSE | Did not delete the record because either it could not find it in the table, or the user did not have the correct permissions, or the C/AL code terminated

RecordRef

Data type: recordref

The recordref that refers to the record that you want to delete.

RunTrigger

Data type: boolean

This optional parameter lets you run the C/AL code in the OnDelete trigger.

To have the system... | Enter...
Execute the code in the OnDelete trigger | TRUE
Not execute the code in the OnDelete trigger | FALSE (default)

Comments

The current key and any filters on the record have no effect on this operation. The system identifies the record to delete by the values in its primary key.

In a multiuser environment, another application can delete the record from the table after you read the record and before you try to delete it. The Database Management System automatically detects such a situation, which causes the RecordRef.DELETE function to fail with a run-time error.

To prevent this situation, you can lock the table while you are using it with the RecordRef.LOCKTABLE function.

This function works exactly like the Record.DELETE function.


DELETEALL (RecordRef)

Use this function to delete all records in a C/SIDE table that fall within a specified range. See also the RecordRef.DELETE function.

RecordRef.DELETEALL([RunTrigger])

RunTrigger

Data type: boolean

This parameter lets you run the C/AL code in the OnDelete trigger.

To have the system... | Enter...
Execute the code in the OnDelete trigger | TRUE
Not execute the code in the OnDelete trigger | FALSE (default)

RecordRef

Data type: recordref

Identifies the table in which the deletion will occur. The system only deletes those records selected by the filters set for recordref.

This function works exactly like the Record.DELETEALL function.


DELETELINK (RecordRef)

Use this function to delete a link that has been added to a record in a table.

DELETELINK(ID)

ID

Data Type:

The ID of the link you want to delete.

Comments

Every time you add a link to a form or a table an entry is created in the Record Link system table. Each entry is given an ID.


DELETELINKS (RecordRef)

Use this function to delete all of the links that have been added to a record.

DELETELINKS


DUPLICATE (RecordRef)

Use this function to duplicate the table that contains the recordref.

RecordRef := RecordRef.DUPLICATE

RecordRef

Data type: recordref

The recordref that identifies the record and the table that you want to duplicate.

Comments

The recordref that is returned refers to a table with the exact same values, filters, current keys and marks as the original table. However, any changes that you make to the duplicate will not be reflected in the original. (This is different than assigning one recordref to another recordref, where they continue to refer to the same table and where changes made to one are reflected in the other.)


FIELD (RecordRef)

Use this function to return the recordref of the field that has the number fieldno in the table that is currently selected. If no field has this number, the function returns an error.

Field := RecordRef.FIELD(FieldNo)

Field

Data type: fieldref

RecordRef

Data type: recordref

The recordref of the record for which you want the fieldref.

FieldNo

Data type: integer

The number that the field has in the table that is currently selected. This is the field for which you want the fieldref.


FIELDCOUNT (RecordRef)

Use this function to return the number of fields in the table that is currently selected or to return the number of fields that have been defined in a key. These functions returns an error if no table or no key is selected.

Count := RecordRef.FIELDCOUNT

Count

Data type: integer

The number of fields in the table.

RecordRef

Data type: recordref

The recordref of the record that you use to identify the table.


FIELDEXIST (RecordRef)

Use this function to find out if the field that has the number fieldno exists in the table that is referred to by the recordref. The function returns an error if no table is currently selected.

Exist := RecordRef.FIELDEXIST(FieldNo)

Exist

Data type: boolean

The return value. The possible values are:

TRUE | The field exists in the table
FALSE | The field does not exist in the table

RecordRef

Data type: recordref

The recordref that identifies the record and the table that you are interested in.

FieldNo

Data Type: integer

The fieldno that you want to know whether or not it exists in the table.


FIELDINDEX (RecordRef)

Use this function to return the fieldref of the field that has this index in the table referred to by the recordref.

Field := RecordRef.FIELDINDEX(Index)

Field

Data type: fieldref

The fieldref of the field that is in the index.

RecordRef

Data type: recordref

Index

Data type: integer

Comments

The first field in the index must have index 1, the second index 2 and so on. The last field must have index = FIELDCOUNT. If the index is out of the range supplied or if no table is selected, the function returns an error.


FILTERGROUP (RecordRef)

Use this function to change the filter group that is being applied to the table. You can also use this function to return the number of the current filtergroup. You cannot return the number of the filtergroup and set a new filtergroup at the same time.

A filtergroup can contain a filter for a RecordRef that has been set earlier with SETFILTER or SETRANGE. The total filter applied is the combination of all the filters set in all the filtergroups.

[CurrGroup :=] RecordRef.FILTERGROUP([NewGroup])

CurrGroup

Data Type: integer

RecordRef

Data Type: recordref

The recordref that is used to identify the table.

NewGroup

Data Type: integer

This function works exactly like the Record.FILTERGROUP function.


FIND (RecordRef)

Use this function to find a record in a table based on the values stored in the key fields.

[Ok :]= RecordRef.FIND([Which])

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find the record. If you include a return value, the system assumes you will handle any errors. Ok can have these values:

If Ok is... | It means the record was...
TRUE | Found
FALSE | Not found

RecordRef

Data type: recordref

The recordref that refers to the table in which you want to find a record.

Which

Data type: text or code

Tells the system how to perform the search. The system searches through the table until either it finds the record or there are no more records. Each character in this string can be present only once. You can combine the '=', '<' and '>' characters.

This... | Tells the system to search for...
'=' | A record that equals the key values (default)
'>' | A record that is larger than the key values
'<' | A record that is less the key values
'+' | The last record in the table ('+' can only be used alone)
'-' | The first record in the table ('-' can only be used alone)

If SearchStr contains '=', '>' or '<', you must assign values to all fields of the current and primary keys before you call FIND.

Comments

FIND retrieves the first record that meets the conditions set by SearchStr and the filters associated with Record. The search path reflects the sort order defined by the current key. If the current key is not the primary key, there is a chance that several records might have the same values in current key fields. If this happens, the system uses the sort order defined by the primary key as the search path.

This function works exactly like the Record.FIND function.


FINDFIRST (RecordRef)

Use this function to find the first record in a table based on the current key and filter.

[Ok :]= RecordRef.FINDFIRST

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find the record. If you include a return value, the system assumes you will handle any errors. Ok can have these values:

If Ok is... | It means the record was...
TRUE | Found
FALSE | Not found

RecordRef

Data type: recordref

The recordref that refers to the table in which you want to find a record.

If the record was... | Then...
Found | The system returns the record in Record and sets any FlowField in the record to zero. You must update them using CALCFIELDS.
Not found | A run-time error occurs, if you omitted the return value Ok.

This function works exactly like the Record.FINDFIRST function.

Comment

This function should be used instead of FIND('-') when you only need the first record.

You should only use this function when you explicitly want to find the first record in a table/set. Do not use this function in combination with REPEAT .. UNTIL.

Example

The following C/AL code shows how to use the FINDFIRST function:

// Read the first record only

IF SalesSetup.FINDFIRST THEN BEGIN

  ConfigurePost(SalesSetup);

END;

Related Topics

FIND (RecordRef)

FINDLAST (RecordRef)

FINDSET (RecordRef)


FINDLAST (RecordRef)

Use this function to find the last record in a table based on the current key and filter.

Ok := RecordRef.FINDLAST

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find the record. If you include a return value, the system assumes you will handle any errors. Ok can have these values:

If Ok is... | It means the record was...
TRUE | Found
FALSE | Not found

RecordRef

Data type: recordref

The recordref that refers to the table in which you want to find the last record.

If the record was... | Then...
Found | The system returns the record in Record and sets any FlowField in the record to zero. You must update them using CALCFIELDS.
Not found | A run-time error occurs, if you omitted the return value Ok.

This function works exactly like the Record.FINDLAST function.

Comment

This function should be used instead of FIND('+') when you only need the last record.

You should only use this function when you explicitly want to find the last record in a table/set. Do not use this function in combination with REPEAT .. UNTIL.

Example

The following C/AL code shows how to use the FINDLAST function:

// Read the last record only

IF GLEntry.FINDLAST THEN;

Related Topics

FIND (RecordRef)

FINDFIRST (RecordRef)

FINDSET (RecordRef)


FINDSET (RecordRef)

Use this function to find a set of records in a table based on the current key and filter. The records can only be retrieved in ascending order.

Ok := RecordRef.FINDSET([ForUpdate][, UpdateKey])

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find a record. If you include a return value, the system assumes you will handle any errors. Ok can have these values:

If Ok is... | It means the record set was...
TRUE | Found
FALSE | Not found

RecordRef

Data type: recordref

The recordref that refers to the table in which you want to find the set of records.

If the record was... | Then...
Found | The system returns the record in Record and sets any FlowField in the record to zero. You must update them using CALCFIELDS.
Not found | A run-time error occurs, if you omitted the return value Ok.

ForUpdate

Data type: boolean

Set this to FALSE if you don't intend to modify any records in the set.

Set this to TRUE if you want to modify some records in the set.

If you set this parameter to TRUE, a LOCKTABLE is immediately performed on the table before the records are read.

UpdateKey

Data type: boolean

This only applies if ForUpdate is set to TRUE.

If you are going to modify any field value within the current key, set this parameter to TRUE.

This function works exactly like the Record.FINDSET function.

Comments

You should only use this function when you explicitly want to loop through a recordset. You should ONLY use this function in combination with REPEAT .. UNTIL.

Furthermore, FINDSET only supports descending loops. If you want to loop from the bottom up, you should use FIND(‘+’).

The general rules for using FINDSET are:

• FINDSET(FALSE,FALSE)- read-only. This uses no server cursors and the record set is read with a single server call.

• FINDSET(TRUE,FALSE)- is used to update non-key fields. This uses a cursor with a fetch buffer similar to FIND(‘-’).

• FINDSET(TRUE,TRUE)- is used to update key fields.

Note

This function is designed to optimize finding and updating sets. If you set any or both of the parameters to FALSE, you can still modify the records in the set but these updates will not be performed optimally.

Related Topics

FIND (RecordRef)

FINDFIRST (RecordRef)

FINDLAST (RecordRef)


GET (RecordRef)

Use this function to find a record based on the ID of the record.

[Ok:=]RecordRef.GET(RecordID)

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find the record. When you include the return value, the system assumes you will handle any errors. The return value can have these values:

If Ok is... | It means that the record was...
TRUE | Found
FALSE | Not found

RecordRef

Data type: recordref

The recordref that refers to the table.

RecordID

Data type: recordID

This field object contains the table number and the primary key of the table and is used to identify the record that you want to find.

Comments

This function always uses the primary key for the table and ignores any filters. The system does not change the current key and filters after you call this function.


GETFILTERS (RecordRef)

Use this function to find out which filters have been applied to the table referred to by the recordref.

String := RecordRef.GETFILTERS

String

Data Type: text

RecordRef

Data Type: recordref

The recordref that is used to identify the record that you want find out which filters have been applied to.

This function works exactly like the Record.GETFILTERS function.


GETPOSITION (RecordRef)

Use this functions to return a string that contains the primary key of the current record.

String := RecordRef.GETPOSITION([UseNames])

String

Data type: text or code

The string has the same format as the SourceTableRecord property on a form.

RecordRef

Data type: recordref

The recordref that refers to the record for which you want to know the primary key.

UseNames

Data type: boolean

Comments

The UseNames parameter is optional. If it is set to TRUE (default value) or if it is empty, the returned string contains references to field names in the table that the record is associated with. If the parameter is set to FALSE, field numbers are used instead.

This function works exactly like the Record.GETPOSITION function.


GETTABLE (RecordRef)

Use this function to make a recordref variable use the same table instance as a record variable.

RecordRef.GETTABLE(rec)

RecordRef

Data type: recordref

The recordref that refers to the table that you are interested in.

rec

Data type: record

See also RecordRef.SETTABLE.


GETVIEW (RecordRef)

String := RecordRef.GETVIEW([UseNames])

Use this function to return a string that describes the current sort order, key and filters on a table.

String

Data type: text or code

The string format is the same as the SourceTableView property on forms.

RecordRef

Data type: recordref

The recordref that refers to the table. This function returns an empty string if no table is selected.

UseNames

Data type: boolean

Comments

The UseNames parameter is optional. If it is set to TRUE (default value) or if it is empty, the returned string contains references to field captions in the table that the record is associated with. If the parameter is set to FALSE, field numbers are used instead.

If the RecordRef.SETVIEW function has been executed, the String parameter will return the value set by SETVIEW.

This function works exactly like the Record.GETVIEW function.


HASFILTER (RecordRef)

Use this function to find out whether or not a filter has been applied to the table referred to by a recordref.

Ok := RecordRef.HASFILTER

Ok

Data type: boolean

If you omit this return value, a run-time error occurs if the system cannot find the record. When you include the return value, the system assumes you will handle any errors. The return value can have these values:

If Ok is... | It means that the table referred to by the recordref...
TRUE | has a filter
FALSE | has no filter

RecordRef

The recordref that is used to identify the table.

This function works exactly like the Record.HASFILTER function.


HASLINKS (RecordRef)

Use this function to find out whether or not a record contains any links.

OK := HASLINKS

OK

Data Type: Boolean

The possible return values are:

If Ok is... | It means that...
TRUE | The record contains at least one link.
FALSE | The record does not contain any links.

Comments

The link can be a link to a Web site, a file stored on the local or on a remote computer, or a link to a Navision form.


INIT (RecordRef)

Use this function to initialize a record in a table.

RecordRef.INIT

RecordRef

Data type: recordref

The recordref that is used to identify the record that you want to initialize.

This function assigns default values to each field in the record. The values the system assigns in the record correspond to those defined when the table was created. If no value was assigned when the table was created, the system assigns values based on the data type, as shown in this table:

If the data type is... | The default value is...
Boolean | No
Option | 0
Integer | 0
Decimal | 0.0
Date | 0D (Undefined date)
Time | 0T (Undefined time)
Code | '' (empty string)
Text | '' (empty string)
BigText | <Empty>
Binary | <Empty>
BLOB | <Empty>
DateFormula | '' (empty string)
TableFilter | <Empty>
BigInteger | 0
Duration | 0
DateTime | 0DT (Undefined datetime)
GUID | 00000000-0000-0000-0000-000000000000
RecordID | <Empty>

Comments

The system does not initialize primary key or timestamp fields.

After the system executes this function, you can change the values in any or all of the fields before you call the INSERT (RecordRef) function to enter the record in the table. Be sure that the fields that make up the primary key contain values that make the total primary key unique. If the primary key is not unique (record already exists), the system rejects the record.

This function works exactly like the Record.INIT function.


INSERT (RecordRef)

Use this function to insert a record into a table.

[Ok :=] RecordRef.INSERT([RunTrigger])

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot insert the record. If you include the return value, you must handle any errors. The return value can have the following values:

If Ok is... | It means that the record...
TRUE | Was inserted
FALSE | Was not inserted

RecordRef

Data type: recordref

The recordref that refers to the record that you want to insert.

RunTrigger

Data type: boolean

This parameter lets you run the C/AL code in the OnInsert trigger.

To have the system... | Enter...
Execute the code in the OnInsert trigger | TRUE
Not execute the code in the OnInsert trigger | FALSE (default)

Comments

The system uniquely identifies records using the values in primary key fields. The C/SIDE Database Management System (DBMS) checks the primary key for the table before it inserts a new record.

If the table contains an auto-increment field, the auto-increment feature is used if the record contains a zero value in that field. The auto-increment feature enters the new value into the field as part of the insert.

If the auto-increment field contains a non-zero value, that value is inserted into the table and the auto-increment feature is not used. If the value in the auto-increment field is greater that the last auto-increment value in the table, the next auto-increment value that is entered into the table will be greater than the value in the field that you just inserted. If the value in the auto-increment field already exists in the table, a runtime error occurs.

This function works exactly like the Record.INSERT function.


ISEMPTY (RecordRef)

Use this function to find out whether any records exist within a filtered set of records in a table.

Empty := RecordRef.ISEMPTY

Empty

Data type: boolean

RecordRef

Data type: recordref

The recordref of a record that refers to a table (possibly with filters).

Comments

This function tells you whether the table is empty or not if you have not applied filters to the record. If you have applied filters, the function determines whether the filtered set of records is empty.

The number of filters that you have applied to the records affects the speed of the ISEMPTY function. The fewer the number of filters, the faster the system performs the operation.

When you are using SQL Server, this function is faster than using the Record.COUNT function and then testing the result for zero.

This function works exactly like the Record.ISEMPTY function.


KEYCOUNT (RecordRef)

Use this function to return the number of keys that exist in the table that is referred to by the recordref. This function returns an error if no table is selected.

Count := RecordRef.KEYCOUNT

Count

Data type: integer

The amount of keys that have been defined in the table.

RecordRef

Data type: recordref

The recordref that identifies the record and the table that you are interested in.


KEYINDEX (RecordRef)

Use this function to return the keyref of the key that has this index in the table that is currently selected.

Key := RecordRef.KEYINDEX(Index)

Key

Data type: keyref

The keyref of the field that has the index.

RecordRef

Data type: recordref

The recordref that identifies the record and the table that you are interested in.

Index

Data type: integer

The number of the index that you are interested in.

Comments

The first key in the index must have index 1, the second index 2 and so on. The last key must have index = KEYCOUNT. If the index is out of the range supplied or if no table is selected, the function returns an error.


LOCKTABLE (RecordRef)

Use this function to lock a table to protect it from write transactions that conflict with each other.

RecordRef.LOCKTABLE([Wait] [, VersionCheck])

RecordRef

Data type: recordref

The recordref that refers to the table that you want to lock.

Wait

Data type: boolean

This parameter tells the system what to do if the table already is locked:

To make... | Enter...
The system wait until the table is unlocked, if another application already has locked the table | TRUE (or leave blank)
LOCKTABLE end with a run-time error, if another application already has locked the table | FALSE

VersionCheck

Data type: boolean

Use this optional parameter to do a version check.

To... | Enter...
Not check the version | FALSE (or leave blank)
Check the version | TRUE

The examples below show you how to use the VersionCheck parameter.

Comments

Because all write operations automatically lock the table in use, LOCKTABLE would appear unnecessary. Imagine, however, a transaction in which an application wants to inspect data and then only possibly change it, with a guarantee that the data being changed has not been modified by other applications since the read. The solution is to explicitly lock the table before the read operation. This makes sure no other application makes changes between the read and the possible write.

This function works exactly like the Record.LOCKTABLE function.


MODIFY (RecordRef)

Use this function to modify a record in a C/SIDE table. See also MODIFYALL.

[Ok :=] RecordRef.MODIFY([RunTrigger])

Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find the record. If you include the return value, you must handle any errors. The possible values are:

If Ok is... | It means that the system...
TRUE | Modified the record
FALSE | Could not find the record

RecordRef

Data type: recordref

The recordref that identifies the record that you want to change.

RunTrigger

Data type: boolean

This parameter lets you run the C/AL code in the OnModify trigger.

To have the system... | Enter...
Execute the code in the OnModify trigger | TRUE
Not execute the code in the OnModify trigger | FALSE (default)

Comments

Select the record you want to replace using the primary key fields. The record's current key and filters do not affect the operation.

In multiuser environments, another application could modify the record between the time you read the record and when you attempt to modify it. The DBMS automatically watches for this and, if a conflict occurs, cancels the MODIFY function and displays an error message.

This function works exactly like the Record.MODIFY function.


NAME (RecordRef)

Use this function to return the name of the table that is currently selected. This function returns an error if no table is selected.

Name := RecordRef.NAME

Name

Data type: text (30)

The name of the table.

RecordRef

Data type: recordref

The recordref that identifies the table that you are interested in.

This function works exactly like the Record.TABLENAME function


NEXT (RecordRef)

Use this function to step through a specified number of records and retrieve a record.

[Steps :=] RecordRef.NEXT([Steps])

Steps

Data type: integer

This function returns the number of records inspected which meet the criteria of any filters and the current key. This value can be less than Steps, depending on the number of records in the table. If the table is empty, the system returns zero and does not change Record.

RecordRef

Data type: recordref

The recordref that refers to the record that you want to use as the starting point for the steps. This function returns 0 if no table is selected.

Steps

Data type: integer

Used to define the direction of the search and how many records to step over.

This value... | Tells the system to...
> 0 | Search Steps records forwards in the table.
< 0 | Search Steps records backwards in the table.
= 0 | No effect

If you do not specify Steps, the system finds the next record.

Comments

This function locates a record positioned a given number of steps forward or backward from Record. Movement through the table is governed by the filters and the current key associated with the records. The fields in Record which will be compared with the current key fields must contain appropriate values before the function is called.

This function is similar to the Record.NEXT function.


NUMBER (RecordRef)

Use this function to return the table ID (number) of the table that contains the record referred to by the recordref.

No

Data type: Integer

The return value - the number of the table or of the field.

RecordRef

Data type: recordref

The recordref that refers to the table that you are interested in.


OPEN (RecordRef)

Use this function to make a RecordRef variable refer to a table which is identified by its number in a particular company.

RecordRef.OPEN(No[, Temp][, CompanyName])

RecordRef

Data type: recordref

No

Data type: integer

The number of the table.

Temp

Data type: boolean

CompanyName

Data type: text or code

The name of the company that you want to change to. If you omit this parameter, the system uses the current company. This works in the same way as Record.CHANGECOMPANY.

See also Record.GETTABLE

Examples

Example 1:

recordref.OPEN(DATABASE::Customer);
message('The %1 table contains %2 records;
recordref.CAPTION, recordref.COUNTAPPROX);

Example 2:

MyRecordRef.OPEN(27,FALSE);
TempMyRecordRef.OPEN(27,TRUE);

IF MyRecordRef.FIND('-') THEN // This is true and will find the first record in the table.
MESSAGE('MyRecordRef finds')
ELSE
MESSAGE('MyRecordRef does not find');

IF TempMyRecordRef.FIND('-') THEN // This is false because there are no records in a temporary table.
MESSAGE('TempMyRecordRef finds')
ELSE
MESSAGE('TempMyRecordRef does not find');

"MyRecordRef" opens table 27 and the "FIND('-')" finds the first record in the table.

"TempMyRecordRef" opens a temporary table which is empty and therefore the "FIND('-')" returns false.


READCONSISTENCY (RecordRef)

Ok := RecordRef.READCONSISTENCY

Ok

Data type: boolean

This return value tells you whether or not read consistency is supported.

If Ok is... | It means that...
TRUE | The table supports read consistency.
FALSE | The table does not support read consistency.

RecordRef

Data type: recordref

Refers to a record in the table to be checked for this feature.

Comments

The advantage of read consistency is that a snapshot of the data can be used in situations where you do not want the data to change during the transaction. For example, you can print a report and be sure that other users have not updated the report data. Further, this function does not negatively affect the concurrency of the system in a multiuser environment.

The Microsoft Dynamics NAV Database Server supports read consistency as an integral part of the database architecture. At present, SQL Server does not support this feature. It implements a consistent snapshot by locking data as it is read to prevent other users from changing it. This significantly reduces concurrency for tables that are frequently accessed by multiple users.

This function works exactly like the Record.READCONSISTENCY function.


READPERMISSION (RecordRef)

Use this function to find out if you can read from a table. This function can test for both full read permission and a partial read permission that has been granted with a security filter.

This function uses the filter that is currently applied to the RecordRef to determine whether or not you have read permission. If no filter is applied, the function tests for full read permission. If a filter has been set, the function only tests for read permission within the range of the filter.

To determine whether or not the user has a partial read permission, because a security filter has been applied, use the SETPERMISSIONFILTER (RecordRef) function before testing the permission with READPERMISSION (RecordRef).

Ok := RecordRef.READPERMISSION

Ok

Data type: boolean

This return value tells you whether you have permission to read from the table.

If Ok is... | You can...
TRUE | Read from some or all of the table
FALSE | Not read from the table

RecordRef

Data type: recordref

The recordref that refers to the record in the table for which you want to know if you have read permission.

Comments

If you do not have permission to read from a table and you attempt to read, the system generates a run-time error. This function lets you find out beforehand if you have read permission. When the permissions are checked, the combination of the permissions in the license file and the user's permissions in the Permission table is considered.

This function works exactly like the READPERMISSION (Record) function.


RECORDID (RecordRef)

Use this function to return the RecordID of the record that is currently selected in the table. If no table is selected, an error is generated.

RecordID := RecordRef.RECORDID

RecordID

Data type: recordID

RecordRef

Data type: recordref

The recordref of the record whose recordID you want to get.


RECORDLEVELLOCKING (RecordRef)

Ok := RecordRef.RECORDLEVELLOCKING

Use this function to find out whether the table supports record level locking.

Ok

Data type: boolean

The possible return values are:

If Ok is... | It means that...
TRUE | The table supports record level locking.
FALSE | The table does not support record level locking.

RecordRef

Data type: recordref

Refers to a record in the table to be checked for this feature.

Comments

When you are using SQL Server, you can use record level locking.

When you are running on the Microsoft Dynamics NAV Database Server, you cannot use record level locking.


RESET (RecordRef)

Use this function to remove all filters, including any special filters set by MARKEDONLY and change the current key to the primary key. The system also removes any marks on the record and clears any C/AL variables on the record.

RecordRef.RESET

RecordRef

Data type: recordref

The recordref that refers to the record that you want to reset. This function returns an error if no table is selected.

This function works exactly like the Record.RESET function.


SETPERMISSIONFILTER (RecordRef)

Use this function to apply the user's security filter to a RecordRef variable. The security filter is combined with any other filters that are placed on the RecordRef variable with SETFILTER (Record) or SETRANGE (Record).

The combined filter will not include any records outside the range of the security filter and this will prevent a run-time permission error from occurring when you read the records. If SETPERMISSIONFILTER is not set a permission error can occur if you attempt to read a record that is outside the range of the user's security filter.

This C/AL function only applies to the SQL Server Option for Microsoft Dynamics NAV.

RecordRef.SETPERMISSIONFILTER

Comments

Security filters are an essential part of record level security. Security filters limit the access that a user has so that they can only access the records, in the tables that they have permissions for, that match the criteria specified in the security filter.

For more information about record level security, see the manual Installation & System Management: Microsoft SQL Server Option and Application Designer's Guide.

This function works exactly like the SETPERMISSIONFILTER (Record) function.


SETPOSITION (RecordRef)

Use this function to set the fields in a primary key on a record to the values specified in the supplied string. The remaining fields are left untouched.

RecordRef.SETPOSITION(String)

String

Data types: text or code

RecordRef

Data type: recordref

The recordref that refers to the record.

This function works exactly like the Record.SETPOSITION function.


SETRECFILTER (RecordRef)

Use this function to set a filter on a record that is referred to by a recordref.

RecordRef.SETRECFILTER

RecordRef

Data Type: recordref

The recordref used to identify the record that you want to place a filter on.

This function works exactly like the Record.SETRECFILTER function.


SETTABLE (RecordRef)

Use this function to make a recordref variable use the same table instance as a record variable.

Any filters that are applied to the record are also applied to the recordref. If you change the filter that is applied to the record, you must call SETTABLE again to apply the new filter to the recordref.

RecordRef.SETTABLE(rec)

RecordRef

Data type: recordref

rec

Data type: record

See also RecordRef.GETTABLE.


SETVIEW (RecordRef)

Use this function to set the current sort order, key and filters on a table.

RecordRef.SETVIEW(String)

RecordRef

Data type: recordref

The recordref that refers to the table on which you want to set the current sort order, key and filters.

String

Data type: text or code

The string format is the same as the SourceTableView property on forms.

Comments

The value of the String parameter can be one returned by the RecordRef.GETVIEW function.

If the RecordRef.SETVIEW function is executed with an empty string, all the filters are removed and the primary key is used.

The RecordRef.SETVIEW function fails if no table is selected.

This function works exactly like the Record.SETVIEW function.


WRITEPERMISSION (RecordRef)

Use this function to find out if you can write to a table. This function can test for both full write permission and a partial write permission that has been granted with a security filter. A write permission consists of Insert, Delete and Modify permissions.

This function uses the filter that is currently applied to the RecordRef to determine whether or not you have write permission. If no filter is applied, the function tests for full write permission. If a filter has been set, the function only tests for write permission within the range of the filter.

To determine whether or not the user has a partial write permission, because a security filter has been applied, use the SETPERMISSIONFILTER (RecordRef) function before testing the permission with WRITEPERMISSION (RecordRef).

Ok := RecordRef.WRITEPERMISSION

Ok

Data type: boolean

This return value tells you if you have permission to write to the table using any of the following RecordRef functions: INSERT, DELETE, MODIFY, DELETEALL.

If Ok is... | You can...
TRUE | Write to some or all of the table
FALSE | Not write to the table

RecordRef

Data type: recordref

The recordref that refers to a record in the table for which you want to know if you have write permission.

Comments

If you do not have permission to write to a table and you attempt to write, the system generates a run-time error. This function lets you find out beforehand if you have write permission. When the permissions are checked, the combination of permissions in the license file and the user's permissions in the Permission table is considered.

This function works exactly like the WRITEPERMISSION (Record) function.


REPORT

Use this complex data type to store reports. Reports contain a number of simpler elements called controls. Controls are used to display information to the user or receive information from the user.


CREATETOTALS (Report)

Use this function to maintain totals for a variable in the same way as totals are maintained for fields by using the TotalFields property.

CREATETOTALS(Var1 [, Var2] ,...)

Var1, Var2, ...

Data type: decimal

Comments

Just like the TotalFields property, CREATETOTALS causes group and grand totals to be maintained. The totals can be printed by placing controls that have the variable or variables that are the arguments of CREATETOTALS as their source expressions in the appropriate sections: the group totals are printed in GroupFooter sections, and the grand totals are printed in Footer sections.

Example

To have the system maintain totals for the two variables Amount and Quantity, use CREATETOTALS like this:

CurrReport.CREATEOTALS(Amount, Quantity);


NEWPAGE (Report)

Use this function to force a page break when printing a report.

NEWPAGE

Comments

The page break generated by NEWPAGE is treated exactly like the page breaks that are generated automatically by the system with one exception: footers and headers will be printed in the same way as when an automatic page break occurs, but transport footers and headers are not generated and printed.

Example

If you have a certain table where you want to start a new page before certain records when printing a list of the table, you can use NEWPAGE like this in the OnPreSection trigger of the Body section of the relevant data item:

IF "Spare Parts".Pagebreak THEN
CurrReport.NEWPAGE;

The Pagebreak variable is supposed to be of type boolean, and when it is TRUE, a page break will be generated.


NEWPAGEPERRECORD (Report)

Use this function to return the current setting of the NewPagePerRecord property, and to set this property to a new value.

[IsNewPagePerRecord] := NEWPAGEPERRECORD([SetNewPagePerRecord])

IsNewPagePerRecord

Data type: boolean

The current setting of NewPagePerRecord.

SetNewPagePerRecord

Data type: boolean

The new setting of NewPagePerRecord.

Comments

See the description of the NewPagePerRecord property for details.


OBJECTID (Report)

Use this function to return the name of a report.

String:=Report.OBJECTID([UseNames])

String

Data type: text or code

Report

Data type: report

UseNames

Data type: boolean

The UseNames parameter is optional.

If the parameter is set to TRUE (default value) or if it is empty, the returned string contains the name of the report.

If the parameter is set to FALSE, the returned string (report xxx) contains the number of the report.


PAGENO (Report)

Use this function to return the current page number of a report, and to set a new page number.

[CurrPageNo] := PAGENO([NewPageNo])

Comments

This function should be used in the OnPostSection trigger of the section where you want to retrieve the current page number or set a new page number, as the system will have updated the page number at this point.


objecPAPERSOURCE (Report)

Use this function to return the paper source used for the current page or a specified page, and to set a new paper source.

CurrReport.PAPERSOURCE(PaperBinNo [, PhysicalPage])

PaperBinNo

The tray number

PhysicalPage

The page number

Comments

The PAPERSOURCE function has two parameters: the tray number, which is mandatory, and the page number, which is optional. If the printer does not support the tray number, the function call will be ignored, and the printer will continue using the previously selected tray.

The tray numbers that correspond to the options for the PaperSourceFirstPage and PaperSourceOtherPages properties are as follows:

1 | Upper or Only One Feed
2 | Lower Feed
3 | Middle Feed
4 | Manual Feed
5 | Envelope Feed
6 | Envelope Manual Feed
7 | Automatic Feed
8 | Tractor Feed
9 | Small-format Feed
10 | Large-format Feed
11 | Large-capacity Feed
14 | Cassette Feed
15 | Automatically Select
256 | Printer Specific Feed 1
257 | Printer Specific Feed 2
258 | Printer Specific Feed 3
259 | Printer Specific Feed 4
260 | Printer Specific Feed 5
261 | Printer Specific Feed 6
262 | Printer Specific Feed 7
263 | Printer Specific Feed 8

If the printer supports other tray numbers, you can enter these too.

If you do not specify a page number, the tray change will apply to the current page. The new tray will also apply to subsequent pages until the next tray change occurs.

When you do specify a page number, the tray change will take place when the specified page is printed. Subsequent pages will also use this tray until the next tray change. The tray change can be placed anywhere on a page and still apply to the whole page.

If you specify more than one paper tray selection for a page, the printer uses the last selection.


PREVIEW (Report)

Use this function to determine whether a report is being printed in preview mode or not.

IsPreview := PREVIEW

IsPreview

Date type: boolean

The return value. Possible values:

TRUE | Means that the report is run in preview mode
FALSE | Means that the report is not in preview mode

Comments

You must use the return value. A compile error is generated if this value is not used.

Example

Use the PREVIEW function like this:

IF CurrReport.PREVIEW THEN
... // preview specific processing
ELSE
... // processing that is not preview specific

A typical situation where you would not want to perform some processing in preview mode is this:

In an application, a count of how many times a document has been printed is stored in the database. This number has to be updated from inside the report that is used to print the document. To avoid updating the number when the report is run in preview mode, use a construct like the one above when adding the code that updates the count.


PRINTONLYIFDETAIL (Report)

Use this function to return the current setting of the PrintOnlyIfDetail property, and to set this property to a new value.

[IsPrintOnlyIfDetail] := PRINTONLYIFDETAIL([SetPrintOnlyIfDetail])

IsPrintOnlyIfDetail

Data type: boolean

The current setting of PrintOnlyIfDetail.

SetPrintOnlyIfDetail

Data type: boolean

The new setting of PrintOnlyIfDetail.

Comments

See the description of the PrintOnlyIfDetail property for details.


REPORT.RUN

Use this function to load and execute the report you specify. If, at design time, you do not know the specific report you want to run, use this function or the REPORT.RUNMODAL function. If you do know the specific report you want to run, you can use the r.RUN function or the r.RUNMODAL function.

REPORT.RUN(Number [, ReqWindow] [, SystemPrinter] [, Record])

Number

Data type: integer

The ID of the report you want to execute. You can use the Symbols option on the View menu to choose from a list.

If the report you specify does not exist, a run-time error occurs.

ReqWindow

Data type: boolean

Tells the system whether it should display the request window for the report. The request window is part of the report object.

To... | Enter...
Display the request window before running the report | TRUE (default)
Run the report without showing the request window | FALSE

SystemPrinter

Data type: boolean

Tells the system whether it should use the default Windows printer or use the Printer Selection table to find the right printer for this report. For example, if the report prints on continuous forms, you can set up an entry in the Printer Selection table to tell the system to always print this report on a specific printer.

To print on the printer defined... | Enter...
As the system printer | TRUE
Through the Printer Selection table | FALSE (default)

Record

Data type: record

Tells the system which record to use in the report. The system will use any filters attached to the record you specify.

Example

These examples show how to run a report.

With a Request Window

This example displays the request window and sends the report to the printer selected through the Printer Selection table.

REPORT.RUN(1001);

Without a Request Window

This example skips the request window and starts the report immediately and sends the report to the printer selected in the Printer Selection table. The third example does not display a request window and sends the report to the system printer.

REPORT.RUN(1001, FALSE);

Without a Request Window and to the System Printer

This example skips the request window and starts the report immediately. It also sends the report to the system printer instead of the printer selected through the Printer Selection table.

REPORT.RUN(1001, FALSE, TRUE);


REPORT.RUNMODAL

Use this function to load and execute the report you specify. The system runs the report modally. If, at design time, you do not know the specific report you want to run, use this function or the REPORT.RUN function. If you do know the specific report you want to run, you can use the r.RUN function or the r.RUNMODAL function.

REPORT.RUNMODAL(Number [, ReqWindow] [, SystemPrinter] [, Record])

Number

Data type: integer

The ID of the report you want to execute. You can use the Symbols option on the View menu to choose from a list.

If the report you specify does not exist, a run-time error occurs.

ReqWindow

Data type: boolean

Tells the system whether it should display the request window for the report. The request window is part of the report object.

To... | Enter...
Display the request window before running the report | TRUE (default)
Run the report without showing the request window | FALSE

SystemPrinter

Data type: boolean

Tells the system whether it should use the default Windows printer or use the Printer Selection table to find the right printer for this report. For example, if the report prints on continuous forms, you can set up an entry in the Printer Selection table to tell the system to always print this report on a specific printer.

To print on the printer defined... | Enter...
As the system printer | TRUE
Through the Printer Selection table | FALSE (default)

Record

Data type: record

Tells the system which record to use in the report. The system will use any filters attached to the record you specify.

Example

These examples show how to run a report.

With a request window

This example displays the request window and sends the report to the printer selected through the Printer Selection table.

REPORT.RUNMODAL(1001);

Without a request window

This example skips the request window and starts the report immediately and sends the report to the printer selected through the Printer Selection table. The third example does not display a request window and sends the report to the system printer.

REPORT.RUNMODAL(1001, FALSE);

Without a request window and to the system printer

This example skips the request window and starts the report immediately. It also sends the report to the system printer instead of the printer selected through the Printer Selection table.

REPORT.RUNMODAL(1001, FALSE, TRUE);


RUN (Report)

Use this function to load and execute the report you specify. Use this function or the r.RUNMODAL function if you know at design time the exact report you want to run. Otherwise, use the Report.RUNMODAL or Report.RUN function.

Report.RUN

Report

Data type: report

Once you define this variable, you can run this function or the Report.RUNMODAL function on the variable. The system automatically clears the variable after it executes this function.

Comments

If the report you specify does not exist, a compile error occurs.

Example

This example shows how to use this function. Assume that the variable r has been defined as Report 4711.

Record.SETCURRENTKEY(Key-field1, ...);
Record.SETFILTER(Field, Filter);
Report.XXX; // any user-defined function
Report.SETTABLEVIEW(Rec)
Report.RUN()


RUNMODAL (Report)

Use this function to load and execute the report you specify. Use this function or the Report.RUN function if you know at design time the exact report you want to run. Otherwise, use the Report.RUNMODAL or Report.RUN function.

Report.RUNMODAL

Report

Data type: report

Once you define this variable, you can run this function or the Report.RUN function on the variable. As opposed to the Report.RUN function, the system does not automatically clear the variable after it executes this function. You must handle clearing the variable.

Comments

If the report you specify does not exist, a compile error occurs.

The system runs the request form modally when you use this function.

Example

This example shows how to use this function. Assume that the variable Report has been defined as Report 1.

CLEAR(r)
Record.SETRECFILTER()
Report.XXX; // any user-defined function
Report.SETTABLEVIEW(Rec)
Report.RUNMODAL()

Note that the code above includes the CLEAR function to make sure the variable has been cleared.


SAVEASHTML (Report)

Use this function to save a report as an HTML file. A browser that supports HTML version 3.0 or later is recommended for viewing the file.

[Ok :=] Report.SAVEASHTML(Number, FileName [,SystemPrinter] [, Rec])

[Ok :=] Report.SAVEASHTML(FileName)

Report

Data type: report

Number

Data type: integer

FileName

Data type: text

SystemPrinter

Data type: boolean

Rec

Data type: record

Ok

Data type: boolean

Comments

The SaveAsHTML function can be used on the Report type and on Report variables.

FileName is the path and name of the file you want to print to.

The use of the parameters Number, SystemPrinter and Rec is similar to that of the report functions RUN and RUNMODAL.

When SaveAsHTML is called, the report is generated and saved to "FileName." The standard system status box "Saving to HTML" shows the status of the process. You can manually cancel the generation of the report and the saving of the report as an HTML file. Please note that the Request Form will not be shown.

The return value informs you whether or not the report has been saved successfully. If you use this value and an error occurs, the system simply returns FALSE. If you do not use the return value, the occurrence of an error results in an error message such as out of hard disk space, the file parameter is not open, the user cancelled from the Save As HTML box, and so on. Further, the object is closed.


SAVEASXML (Report)

Use this function to save a report as an XML file.

[Ok :=] Report.SAVEASXML(Number, FileName [,SystemPrinter] [, Rec])

[Ok :=] Report.SAVEASXML(FileName)

Report

Data type: report

Number

Data type: integer

FileName

Data type: text

SystemPrinter

Data type: boolean

Rec

Data type: record

Ok

Data type: boolean

Comments

The SaveAsXML function can be used on the Report type and on Report variables, just like the SAVEASHTML function.

FileName is the path and name of the file you want to print to.

The use of the parameters Number, SystemPrinter and Rec is similar to that of the report functions RUN and RUNMODAL.

When SaveAsXML is called, the report is generated and saved to "FileName." The Saving to XML status window shows the status of the process. If you click Cancel, the report will not be generated or saved as an XML file. Note that the Request Form will not be shown.

The return value informs you whether or not the report has been saved successfully. If you use this value and an error occurs, the system simply returns FALSE. If you do not use the return value, the occurrence of an error results in an error message such as "Out of hard disk space", "The file parameter is not open", "The user cancelled from the Save As XML box", and so on. The object is then closed.


SHOWOUTPUT (Report)

Use this function to return the current setting of whether a section should be outputted or not, and to change this setting.

[IsShow] := SHOWOUTPUT ([SetShow])

IsShow

Data type: boolean

The return value. Possible values:

TRUE | Means that the section will be outputted
FALSE | Means that the section will not be outputted

SetShow

Data type: boolean

The new setting. Possible values:

TRUE | Means that the section should be outputted
FALSE | Means that the section should not be outputted

Comments

This function is typically used when there are more than one section of the same type and it must decided from, for example, the value of a field whether the section should be outputted.

Example

In order to print a section only when the field called Amount if different from 0, use SHOWOUTPUT like this in the OnPreSection trigger of the section:

CurrReport.SHOWOUTPUT(Amount <> 0);


TOTALSCAUSEDBY (Report)

Use this function to determine which field caused a group total to be calculated - meaning determining which field changed contents and thereby concluded a group.

FieldNo := TOTALSCAUSEDBY

FieldNo

Data type: integer

The number of the field that caused the group to end and a group total to be calculated.

Comments

This function can only be used in group header and group footer sections. It is useful when you have defined several levels of grouping and need to know which of the groups that has changed and caused a group total to be calculated.

Example

If you are designing a report where you group records according to the contents of several fields, and you do not want to output the group header section when the Item field changes, use C/AL code like this in the OnPreSection trigger of the section:

IF CurrReport.TOTALSCAUSEDBY = FIELDNO(Item) THEN

CurrReport.SHOWOUTPUT(FALSE);


URL (Report)

This function returns a string with the full URL to a report.

String:=Report.URL([UseNames])

String

Data type: text or code

Object

A variable of the data type Form or Report and any subtype.

UseNames

Data type: boolean

The UseNames parameter is optional. If it is set to TRUE (default value) or if it is empty, the returned string contains references to field names in the table that the record is associated with. If the parameter is set to FALSE, field numbers are used instead.

Comments

This function is equivalent to the functionality in the menu item Copy Link.

Example

For examples of how to format URLs, see Composing URLs.

Note

If the URL links to a report with several tables and this function is executed, only one view in the request form is shown, namely the primary table (that is, the first table shown in the request form).


USEREQUESTFORM (Dataport & Report)

Use this function to return the current setting of the UseReqForm property, and to set this property to a new value.

[IsUseRequestForm] := USEREQUESTFORM([SetUseRequestForm])

IsUseRequestForm

Data type: boolean

The current setting of UseReqForm

SetUseRequestForm

Data type: boolean

The new setting of UseReqForm.

Comments

This function should be used before the request form is run - that is, in the OnInitReport trigger. Although it will not cause an error if it is used elsewhere, it will have no effect.

See the description of the UseReqForm property for details.


BIGTEXT

Use this complex C/AL data type to handle large text documents.

This data type cannot be shown in a message window or be seen in the debugger.

The maximum length of a BigText variable is 2,147,483,647 characters and this corresponds to 2 GB.

Comments

You can use the BigText functions to manipulate a BigText variable, for example to extract part of a BigText variable or to add a text string to a BigText variable.

The normal string functions cannot be used with a BigText variable.


CODE

Use this simple data type to denote a special type of string that the system converts to uppercase and removes any trailing or leading characters. A code variable can be from 1 to 250 characters in length. The length of a code variable equals the number of characters in the text, without leading or trailing spaces.

Comments

You can index any character position in a string, for example A[65]. The resulting value will be a char data type.

Example

This example shows some typical examples of code string assignments. In these examples, assume that the variable c is a code variable with a maximum length of 4.

This assignment... | Results in the variable c which contains...
c := 'ABC'; | 'ABC' and is 3 characters in length
c := '1'; | '1' and is 1 character in length
c := ''; | '' (empty string) and is zero (0) characters in length
c := ' 2 '; | '2' and is 1 character in length


TEXT

Use this simple data type to denote a text string. The string can be from 1 to 250 characters in length. The length of a text variable equals the number of characters in the string. An empty text string has a length of zero (0).

Comments

You can index any character position in a text string, for example A[65]. The resulting value will be a Char data type.

Example

This example shows some typical examples of text strings. In these examples, we assume that the text variable has a maximum length of 6.

This assignment... | Results in...
text := 'ABC'; | A text variable which contains 'ABC'
text := '123456abc'; | A run-time error because the length (9) exceeds the maximum length of 6.


LENGTH

Use this function to retrieve the length of a BigText variable.

Length := BigText.LENGTH

Length

Data type: integer

To delete the content in a BigText variable use the CLEAR function:

CLEAR(BigText)


ADDTEXT

Use this function to add a text string to a BigText variable. The string can be inserted anywhere in the Variable or added at the end of the variable.

BigText.ADDTEXT(Variable [,Position])

Variable

Data type: text or bigtext

The string that will be added to the BigText variable

Position

Data type: integer

This is an optional parameter that defines the position in the BigText variable where the string is inserted. If this parameter is omitted the string is added at the end of the BigText variable.

To delete the content in a BigText variable use the CLEAR function:

CLEAR(BigText)


GETSUBTEXT

Use this function to retrieve part of a BigText variable.

[RetLength] := BigText.GETSUBTEXT(Variable, Position [,Length])

RetLength

Data type: integer

The length of the string that is retrieved from the variable.

Variable

Data type: text or bigtext

The subtext of the BigText that is retrieved. This is the actual text that is returned

Position

Data type: integer

The position in the BigText variable that the subtext is to be retrieved from. Position indicates the start of the text string.

Length

Data type: integer

The length of the subtext that should be retrieved. This parameter is optional. If this parameter is omitted the function retrieves a subtext that starts at Position and runs to the end of the BigText variable.

To delete the content in a BigText variable use the CLEAR function:

CLEAR(BigText)


TEXTPOS

Use this function to retrieve the position at which a specific string first occurs in a BigText.

Position := BigText.TEXTPOS(String)

Position

Data type: integer

This return value indicates the position where the first occurrence of the string starts in the BigText variable

String

Data type: text

The text string to search for in the BigText variable.

To delete the content in a BigText variable use the CLEAR function:

CLEAR(BigText)


WRITE

Use this function to stream a BigText to a BLOB field in a table.

[Ok := ] BigText.WRITE(OutStream)

Ok

Data type: boolean

This optional return value tells you whether or not the write transaction was successful.

OutStream

Data type: outstream

The object to which you write a BigText.

Example:

How to stream a BigText to a BLOB field in a table.

Define the following variables:

Variable | Data type | Comment
bstr | BigText |
table | Record | a field of data type BLOB in the table
ostream | OutStream |

bstr.ADDTEXT('This is the text string that we want to store in a BLOB field.');

table.BlobField.CREATEOUTSTREAM(ostream);

bstr.WRITE(ostream);

table.INSERT();

To delete the content in a BigText variable use the CLEAR function:

CLEAR(BigText)


READ

Use this function to stream a BigText that is stored as a BLOB in a table to a BigText variable.

[Ok := ] BigText.READ(InStream)

Ok

Data type: boolean

This optional return value tells you whether or not the read transaction was successful.

InStream

Data type: instream

The InStream object type to which you read a BigText.

Example:

How to stream a BigText that is stored as a BLOB in a table to a BigText variable.

Define the following variables:

Variable | Data type | Comment
bstr | BigText |
table | Record | a field of data type BLOB in the table
istream | InStream |

table.FIND('-');

table.CALCFIELDS(BlobField);

table.BlobField.CREATEINSTREAM(istream);

bstr.READ(istream);

You use the CALCFIELDS function to calculate the BlobField. A BlobField is a binary large object (maximum size 2GB) and must be calculated if you want to use it in C/AL or display it in the application.

To delete the content in a BigText variable use the CLEAR function:

CLEAR(BigText)


CONVERTSTR (String)

Use this function to convert the characters in a string based on the characters in the strings FromCharacters and ToCharacters, which serve as conversion tables. For example, if FromCharacters[1] is found in String[x], then String[x] is set to ToCharacters[1]. If FromCharacters[2] is found in String[y], then String[y] is set to ToCharacters[2], and so on.

NewString := CONVERTSTR(String, FromCharacters, ToCharacters)

NewString

Data type: text constant or code

The converted string.

String

Data type: text constant or code

The string you want to convert.

FromCharacters

Data type: text constant or code

This string describes the characters to replace. Please note that the CONVERTSTR function is case sensitive.

ToCharacters

Data type: text constant or code

This string describes the new characters to insert. The CONVERTSTR function is case sensitive. The length of this string must correspond to the length of FromCharacters. If the length of the FromCharacters and ToCharacters strings both are zero (empty strings), the system makes no changes.

Comments

A run-time error occurs if the lengths of the FromCharacters and ToCharacters strings are not equal.

Example

This example shows how to use the CONVERTSTR function:

OriginalString
 := Text000;
FromChars := Text001;
ToChars := Text002;
NewString := CONVERTSTR(OriginalString,
 FromChars,
 ToChars);
MESSAGE(Text003, OriginalString);
MESSAGE(Text004, NewString);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Want to leave without saving?'
Text001 | 'lws'
Text002 | 'LWS'
Text003 | 'The original sentence is:\ %1'
Text004 | 'The sentence is converted to:\ %1'

The first message window shows:

The original sentence is:

Want to leave without saving?

The second message window shows:

The sentence is converted to:

Want to Leave Without Saving?


COPYSTR (String)

Use this function to copy a substring of any length from a specific position in a string (text or code) to a new string.

NewString := COPYSTR(String, Position [, Length])

NewString

Data type: text constant or code

The resulting string or substring.

String

Data type: text constant or code

The string you want the system to copy from.

Position

Data type: integer

The position of the first character to copy. The value of Position must be greater than zero (0). If Position is greater than the length of the string, the system returns an empty string.

Length

Data type: integer

The number of characters to copy. Length must be greater than zero (0). If the value of Length means that

Position + Length > (total length of the string)

the result includes all characters from Position to the end of the string.

Comments

If you omit Length, the resulting string includes all characters from Position to the end of the string.

Example

This example shows how to use the COPYSTR function.

Str
 := Text000;
Position := 7;
Length := 8;
MESSAGE(Text001, Str);
NewStr := COPYSTR(Str, Position, Length);
MESSAGE(Text002, NewStr);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Using the COPYSTR function'
Text001 | 'The original string is:\>%1<'
Text002 | 'The copied string is: \>%1<'

The first message window shows the original string:

The original string is:

>Using the COPYSTR function<

The second message window shows the copied string:

The copied string is:

>the COPY<


DELCHR (String)

Use this function to delete one or more characters in a string.

NewString := DELCHR(String [, Where] [, Which])

NewString

Data type: text constant or code

The resulting string.

String

Data type: text constant or code

The input string.

Where

Data type: text constant or code

This string tells the system where to make the deletion. You can include one or more of the following characters in the Where string.

Include... | To have the system delete any...
= | Character in String that matches a character in Which. (default)
< | Leading character in String that matches a character in Which.
> | Trailing character in String that matches a character in Which.

Which

Data type: text or code

This string defines the characters you want to delete. The DELCHR function is case-sensitive.

If you do not define any characters, the system uses the equals sign (=) as the default for Where and spaces as the default for Which. It then deletes all spaces.

Example

This example shows how to use the DELCHR function.

String
 := Text000;
Where := '<>';
Which := 'Ws';
NewString := DELCHR(String, Where, Which);
MESSAGE(Text001, String,NewString);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Windy Solutions'
Text001 | '>%1<, is transformed to: >%2<'

The two strings are shown in the message window as:

>Windy Solutions<, is transformed to: >indy Solution<


DELSTR (String)

Use this function to delete a substring inside a string (text or code).

NewString := DELSTR(String, Position [, Length])

NewString

Data type: text constant or code

The resulting string.

String

Data type: text constant or code

The input string.

Position

Data type: integer

The position of the first character you want to delete. Position must be greater than zero (0).

If Position exceeds the length of String, DELSTR returns the original string, without deleting anything.

Length

Data type: integer

This tells the system how many characters to delete. Length must be greater than zero (0). If you omit Length, the system deletes all characters starting with Position and continuing to the end of the string.

Example

This example shows how to use the DELSTR function.

Str
 := Text000;
Position := 11; // Remove the word 'prices' and a blank
Length := 7;
NewStr := DELSTR(Str, Position, Length);
MESSAGE(Text001, Str);
MESSAGE(Text002, NewStr);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Adjusting prices - Please wait'
Text001 | 'The original string:\ >%1<'
Text002 | 'The modified string:\ >%1<'

The first message window above will show the following:

The original string:
>Adjusting prices - Please wait<

while the second message window will show:

The modified string:
>Adjusting - Please wait<


FORMAT (String)

Use this function to format a value into a string.

String := FORMAT(Value [, Length] [, FormatStr/Number])

String

Data type: text or code

This string contains the formatted output.

Value

Data type: any

This is a C/AL variable (expression) of any simple data type, such as option, integer, biginteger, decimal, char, text, code, date, time, datetime, boolean, binary or GUID.

If, when the system formats Value, the result is a value larger than the maximum length MAXSTRLEN of String, a run-time error occurs.

Length

Data type: integer

Use this optional argument to determine the length of String. These rules apply:

If Length...

It means...

Equals zero (0)

The system will return the entire value (default)

Is greater than zero (0)

String will be exactly Length characters.

If Value is less than Length characters, the system inserts either leading or trailing spaces, depending on the format you select.

If Value is an integer which exceeds Length digits, the system places Length asterisks in String.

If Value is not an integer and it exceeds Length characters, the system truncates String accordingly.

Is less than zero (0)

String will have the maximum length of Length characters.

If Value is less than Length characters, the length of String will equal the length of Value.

If Value is an integer which exceeds Length digits, the system places Length asterisks in String.

If Value is not an integer and it exceeds Length characters, the system truncates String accordingly.

FormatStr

Date type: string

A literal string that defines a format as in the Format property.

Number

Data type: integer

Use this optional argument to determine the format you want the system to use. Here is a list of the basic options. The example below explains all available formats:

The following table shows the predefined formats for the decimal data type.

Decimal | Format
<Sign><Integer Thousand><Decimals> | 0
<Sign><Integer><Decimals> | 1
<Sign><Integer><Decimals><1000Character,.> | 2
<Integer Thousand><Decimals><Sign,1> | 3
<Integer><Decimals><Sign,1> | 4

Note:

You can only use one of FormatNumber and FormatStr at a time.

Comments

For more information about the formats used by the various data type, see the Format property. This describes the various predefined formats in detail, and how to create customized formats.

Format number 9 is designed to be used when importing data with an XMLport and has only one function to convert the data from XML format to the corresponding C/SIDE formats.

Example

This example shows how to use the FORMAT function.

MESSAGE(Text000, FORMAT(-123456.78, 15, 3));

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The formatted value: >%1<'

The message window shows:

The formatted value: > 123,456.78

To use a string to build a format, use the function like this:

MESSAGE(Text001, FORMAT(TODAY,0,'<Month Text> <Day>.');

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text001 | 'Today is %1'

which could give this message:

Today is April 15.


INCSTR (String)

Use this function to increase a positive number or decrease a negative number inside a string by one (1).

NewString := INCSTR(String)

NewString

Data type: text constant or code

The result, after the system has increased or decreased String.

String

Data type: text constant or code

The string you want to increase or decrease.

Comments

If String contains more than one number, only the number closest to the end of the string is changed. For example, the system changes 'A10B20' to 'A10B21'.

The system considers zero (0) a positive number, so it increases it by one. For example, the system changes 'A0' to 'A1'.

When String contains a number like 99, which is increased to 100, the length of the output string is: LEN(String) + 1.

If String does not contain any number at all, the output string will be the empty string.

Example

The following example shows how to use the INCSTR function:

Account
 := Text000;
NegAccount := Text001;
MyAccount := Text002;
MESSAGE(Text003, Account, NegAccount, MyAccount);
ResAccou := INCSTR(Account);
ResNegAc := INCSTR(NegAccount);
ResMyAcc := INCSTR(MyAccount);
MESSAGE(Text004, ResAccou, ResNegAc, ResMyAcc);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Account no. 99 does not balance'
Text001 | 'Account no. 2342 shows a total of $ -452'
Text002 | 'My bank account shows a total of $ 0'
Text003 | 'The test strings before INCSTR is called:\%1\%2\%3\'
Text004 | 'The text strings after INCSTR has been called:\%1\%2\%3'

These messages will be output:

The text strings before INCSTR is called:
Account no. 99 does not balance.
Account no. 2342 shows a total of $ -452
My bank account shows a total of $ 0

The text strings after INCSTR has been called:
Account no. 100 does not balance.
Account no. 2342 shows a total of $ -453
My bank account shows a total of $ 1

The example shows that if the string contains more than one number, the system changes only the last number. Furthermore, the system increases positive numbers and zero and decreases negative numbers.


INSSTR (String)

Use this function to insert a substring into a string.

NewString := INSSTR(String, SubString, Position)

NewString

Data type: text constant or code

The result of inserting SubString into String.

String

Data type: text constant or code

The string into which you want to insert a substring.

SubString

Data type: text constant or code

The substring you want to insert into String

Position

Data type: integer

Use this optional argument to tell the system where to insert SubString. Position must be greater than or equal to 1.

If Position is greater than the length of String, the system concatenates the result and places that into NewString.

Example

This example shows how to insert one string into another.

Str
 := Text000;
SubString := Text001;
MESSAGE(Text002 + '>%1<', Str);
NewStr := INSSTR(Str,
 SubString,
 12);
MESSAGE(Text003 + '>%1<', NewStr);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Press Enter to continue'
Text001 | 'or Esc '
Text002 | 'The test string before INSSTR is called:\'
Text003 | 'The resulting string after INSSTR is called:\'

The first message window shows:

The test string before INSSTR is called:
>Press Enter to continue<

The second message window shows:

The resulting string after INSSTR is called:
>Press Enter or Esc to continue<


LOWERCASE (String)

Use this function to convert all letters in a string to lowercase.

NewString := LOWERCASE(String)

NewString

Data type: text constant or code

The string, after it has been converted to lowercase.

String

Data type: text constant or code

The string you want to convert. The system only changes letters in the range A..Z and, if applicable, special national characters.

Example

This example shows how to use the LOWERCASE function.

Str
 := Text000;
MESSAGE(Text001, Str);
Lower := LOWERCASE(Str);
MESSAGE(Text002, Lower);

Create the following text constants in the /AL Globals window:

Text Constant | ENU Value
Text000 | 'The Entries are Sorted by Name'
Text001 | 'The string before LOWERCASE is:\>%1< '
Text002 | 'The string after LOWERCASE is:\>%1< '

The first message window shows:

The string before LOWERCASE is:
>The Entries are Sorted by Name<

The second message window shows:

The string after LOWERCASE is:
>the entries are sorted by name<


MAXSTRLEN (String)

Use this function to return the maximum defined length of a string variable.

MaxLength := MAXSTRLEN(String)

MaxLength

Data type: integer

The maximum length of the string variable.

String

Data type: text constant or code

The string variable for which you want to find the maximum length.

Example

In this example, assume that City has been defined as a text variable, with a maximum length of 30.

City
 := Text000;
MaxLength := MAXSTRLEN(City);
Length := STRLEN(City);
MESSAGE(Text001 + Text002, MaxLength, Length);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Vedbaek'
Text001 | 'The MAXSTRLEN function returns: %1,\'
Text002 | 'while the STRLEN function returns: %2'

The message window shows:

The MAXSTRLEN function returns: 30
while the STRLEN function returns: 7


PADSTR (String)

Use this function to change the length of a string to a length you define. The system does this by either truncating the string or adding filler characters at the end of the string.

NewString := PADSTR(String, Length [, FillCharacter])

NewString

Data type: text constant or code

The output string. The length of NewString as returned by the system is Length characters. If the maximum (defined) length of the NewString is less than Length, a run-time error occurs.

String

Data type: text constant or code

The string you want to increase or decrease.

Length

Data type: integer

The desired length of the output string. If Length is less than STRLEN (String) , the system truncates the string. Otherwise it is expanded with filler characters.

FillCharacter

Data type: text constant or code

This is a string of the length 1. The system uses the character you enter here to fill empty spaces at the end of the output string. If not specified, blanks are used as default.

Example

This example shows how to use the PADSTR function.

Str1
 := Text000;
Str2 := Text001;
Len1 := STRLEN(Str1);
Len2 := STRLEN(Str2);
MESSAGE(Text002 + Text003 + Text004, Str1, Len1, Str2 Len2);
Str1 := PADSTR(Str1, 5); // Truncate the length to 5
Str2 := PADSTR(Str2, 15, 'w'); // Concatenate w's until
// length = 15
Len1 := STRLEN(Str1);
Len2 := STRLEN(Str2)
MESSAGE(Text005 + Text003 + Text004, Str1, Len1, Str2, Len2);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | '13 characters'
Text001 | 'Four'
Text002 | 'Before PADSTR is called:\'
Text003 | ' >%1<, has the length %2\'
Text004 | ' >%3<, has the length %4\'
Text005 | 'After PADSTR is called:\'

The first message window shows:

Before PADSTR is called:
>13 characters< has the length 13
>Four< has the length 4

The second message window shows:

After PADSTR is called:
>13 ch< has the length 5
>Four< has the length 15


SELECTSTR (String)

Use this function to retrieve a substring from a comma-separated string.

NewString := SELECTSTR(Number, CommaString)

Number

Data type: integer

This number tells the system which substring to retrieve. The substrings in the comma-separated string are numbered 1, 2, 3, and so on.

If Number is greater than the actual number of substrings, a run-time error occurs.

CommaString

Data type: option

A string containing substrings separated by commas.

NewString

Data type: option

The substring that the system retrieves from CommaString.

Comments

SELECTSTR treats string values as OPTIONS. This means that identical values in different strings are not allowed.

Example

This example shows how to use the SELECTSTR function:

CommaStr
 := Text000;
SubStr1 := SELECTSTR(2, CommaStr); // Pick out the 2nd substring
SubStr2 := SELECTSTR(4, CommaStr); // Pick out the 4th substring
MESSAGE(Text001 + '>%1<\' + '>%2<', SubStr1, SubStr2);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'This,is a comma,separated,string'
Text001 | 'The two calls to SELECTSTR return:\'

The message window will show the following:

The two calls to SELECTSTR return:
>is a comma<
>string<


STRCHECKSUM (String)

Use this function to calculate a checksum for a string containing a number.

CheckNumber :=STRCHECKSUM(String [, WeightString] [, Modulus])

String

Data type: text constant or code

This string contains the number for which you want to calculate a checksum. You can only enter the numeric characters 0-9 in this string. Entering anything else will cause a run-time error.

WeightString

Data type: text constant or code

This string contains numbers you want the system to use as weights when calculating the checksum. The default value is a string containing STRLEN(String) '1'-characters.

You can only enter the numeric characters 0-9 in this string. Entering anything else will cause a run-time error.

If String is longer than WeightString, the system will concatenate a string containing STRLEN(String) - STRLEN(WeightString) '1'-characters to the end of WeightString. If WeightString is longer than String, a run-time error occurs.

Modulus

Data type: integer

The number you want to use in the checksum formula (see below). The default value is 10.

CheckNumber

Data type: integer

The checksum, which the system calculates using this formula:

where n = STRLEN(String).

Example

These examples show how to use the STRCHECKSUM function.

Calculating a checksum:

StrNumber
 := '4378';
Weight := '1234';
Modulus := 7;
CheckSum := STRCHECKSUM(StrNumber, Weight, Modulus);
MESSAGE(Text000 + Text001, StrNumber, CheckSum);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The number: %1\'
Text001 | 'has the checksum: %2'

STRCHECKSUM('4378','1234', 7) returns:

(7 - (4x1 + 3x2 + 7x3 + 8x4) MOD 7) MOD 7 = 0

The message window shows:

The number: 4378
has the checksum: 0

Calculating a modulus 10 checksum for a bar code:

The STRCHECKSUM function can be used to calculate checksums for 13- and 8-digit EAN (European Article Number) and EAN compatible bar codes such as UPC (Universal Product Code) or JAN (Japanese Article Number).

A 13-digit EAN code has this format:

  1. The system uses the 12 digits in positions 13 to 2 to calculate the checksum at position 1.

  2. Starting with position 2, the system totals all even values. It then multiplies the result by three. This value is called Even.

  3. Starting with position 3, the system totals all odd values. The result is called Odd.

  4. Total = Even + Odd.

  5. The modulus 10 checksum is then: (10 - Total MOD 10) MOD 10.

Here's how to use STRCHECKSUM to calculate this result:

StrNumber
 := '577622135746';
Weight := '131313131313';
CheckSum := STRCHECKSUM(StrNumber, Weight);
MESSAGE(Text000 + Text001, StrNumber, CheckSum);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The EAN code: %1\'
Text001 | 'has the checksum: %2'

The message window shows:

The EAN code: 577622135746
has the checksum: 3


STRLEN (String)

Use this function to return the length of a string you define.

Length := STRLEN(String)

Length

Data type: integer

The length of String.

String

Data type: text constant or code

The string for which you want to determine the length.

Comments

The difference between the STRLEN and MAXSTRLEN functions is that the first tells you the actual number of characters in the input string, while the second tells you the maximum defined length of the input string. See the following example for more information.

Example

This example shows the difference between the STRLEN and the MAXSTRLEN functions. Assume the variable City was defined with a maximum length of 30 characters.

City
 := Text000;
MaxLength := MAXSTRLEN(City)
Length := STRLEN(City);
MESSAGE(Text001 + Text002, MaxLength, Length);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Atlanta'
Text001 | 'The MAXSTRLEN function returns: %1,\'
Text002 | 'while the STRLEN function returns: %2'

The message window shows:

The MAXSTRLEN function returns: 30
while the STRLEN function returns: 7

This shows that the MAXLENGTH function returns the maximum possible length according to the definition of the string variable, while STRLEN returns the actual length of the text.


STRPOS (String)

Use this function to search for a substring inside a string.

Position := STRPOS(String, SubString)

Position

Data type: integer

The position of SubString in String. If the system cannot find SubString, it returns zero (0).

String

Data type: text constant or code

The string you want to search in.

SubString

Data type: text constant or code

The string you want to search for. The STRPOS function is case-sensitive.

Comments

The STRPOS function only returns the position of the first occurrence of the substring.

Example

This example shows how to use the STRPOS function.

String
 := Text000;
SubStr := Text001
Pos := STRPOS(String, SubStr);
MESSAGE(Text002 + Text003 + Text004, SubStr, String, Pos);
// The STRPOS function is case sensitive. Furthermore it only
// returns the position of the 1st occurrence of the substring.

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'ABC abc abc xy'
Text001 | 'abc'
Text002 | 'The search for the substring: >%1<\'
Text003 | 'in the string: >%2<,\'
Text004 | 'returns the position: %3'

The message window shows:

The search for the substring: >abc<
in the string: >ABC abc abc xy<
returns the position: 5


STRSUBSTNO (String)

Use this function to replace %1, %2, %3... and #1, #2, #3... fields in a string with the values you provide as optional parameters.

NewString := STRSUBSTNO(String [,Value1, ...])

NewString

Data type: text constant or code

The result after the system substitutes the corresponding values in the '#' and '%' fields.

String

Data type: text constant or code

A string containing '#' and/or '%' fields. The % fields are replaced by the values with their full lengths, while # fields are replaced by the values truncated to the length of the # field.

Value1,...

Data type: any

One or more values (expressions) you want to insert into String. You can specify up to 10 values.

Example

This example shows how to use the STRSUBSTNO function.

Str
 := Text000;
AccountNo := 3452;
MESSAGE(Text001, Str);
Str := STRSUBSTNO(Str, AccountNo, 2345 + 5462);
MESSAGE(Text002, Str);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The balance of account %1 is $ %2'
Text001 | 'The string before STRSUBSTNO has been called:\%1'
Text002 | 'The string after STRSUBSTNO has been called:\%1'

The first message window shows:

The string before STRSUBSTNO has been called:
The balance of account %1 is $ %2

The second message window shows:

The string after STRSUBSTNO has been called:
The balance of account 3452 is $ 7,807


UPPERCASE (String)

Use this function to convert the letters in a string to uppercase.

NewString := UPPERCASE(String)

NewString

Data type: text constant or code

The string, after the system has converted the letters to uppercase.

String

Data type: text constant or code

The string you want to convert.

Example

This example shows how to use the UPPERCASE function.

Lower
 := Text000;
MESSAGE(Text001, Lower);
Upper := UPPERCASE(Lower);
MESSAGE(Text002, Upper);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Outstanding Order Status'
Text001 | 'The test string before UPPERCASE is called:\%1 '
Text002 | 'The string after UPPERCASE is called:\%1 '

The first message window shows:

The test-string before UPPERCASE is called:
Outstanding Order Status

The second message window shows:

The string after UPPERCASE is called:
OUTSTANDING ORDER STATUS


ARRAYLEN (Array)

Use this function to return the total number of elements in an array or the number of elements in a specific dimension.

Length := ARRAYLEN(Array [, Dimension])

Length

Data type: integer

The number of elements in the array or the number of elements in a specific dimension.

Array

Data type: any data type

The array you want to investigate.

Dimension

Data type: integer

If you omit this optional argument, the function returns the total number of elements in the array. To get the number of elements in a specific dimension, use Dimension with a valid value. The valid values are determined by the number of dimensions of the input array. For example, the valid values for a three-dimensional array would be 1, 2, and 3.

Comments

If you use ARRAYLEN with an input parameter that is not an array, a run-time error occurs.

Example

The following C/AL code shows how to use the optional arguments:

//
 Array1 is a one-dimensional integer array with size 2
// Array2 is a two-dimensional integer array with size 2x2
MESSAGE(Text000, ARRAYLEN(Array1));
MESSAGE(Text001, ARRAYLEN(Array2,1));
MESSAGE(Text002, ARRAYLEN(Array2,2));
MESSAGE(Text003, ARRAYLEN(Array2));

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Array1, Total number of elements %1'
Text001 | 'Array2, Dimension no. 1: Size %1'
Text002 | 'Array2, Dimension no. 2: Size %1'
Text003 | 'Array2, Total number of elements: %1'

These messages appear:

Array1, Total number of elements: 2

Array2, Dimension no. 1: Size 2

Array2, Dimension no. 2: Size 2

Array2, Total number of elements: 4


COMPRESSARRAY (Array)

Use this function to move all non-empty strings (text) in an array to the beginning of the array. The resulting StringArray has the same number of elements as the input array, but empty entries and entries that contain only blanks appear at the end of the array.

[Count =:] COMPRESSARRAY(StringArray)

Count

Data type: integer

The number of non-empty strings that the system compressed.

StringArray

Data type: array of strings

The string array you want to compress.

Comments

When compressing an array of strings, the system sorts the non-empty strings in the resulting array in the same way as in the original array.

The COMPRESSARRAY function is especially useful for printing names and addresses. For instance, you can use this function to remove blank lines in account statements.

Example

The illustration shows how COMPRESSARRAY works. The figure shows a StringArray presented with the input to the left and the output to the right. All non-empty entries have been moved to the top of the array.

Input | Output
Joe Raybon | Joe Raybon
 | One Meca Way
 | Atlanta
One Meca Way |
Atlanta |

This C/AL code shows how to compress the arrays as shown in the illustration above.

Name[1]
 := ''; // Empty String
Name[2] := Text000;
Name[3] := Text001;
Name[4] := ' '; // A string containing blanks
Name[5] := Text002;
Name[6] := '';
MESSAGE(Text003, Name[1], Name[2], Name[3], Name[4], Name[5], Name[6]);
COMPRESSARRAY(Name); // The empty lines (strings) are removed
MESSAGE(Text004, Name[1], Name[2], Name[3],Name[4], Name[5], Name[6]);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Joe Raybon'
Text001 | 'One Meca Way'
Text002 | 'Atlanta'
Text003 | 'Before compression, the address is...\%1\%2\%3\%4\%5\%6'
Text004 | 'After compression, the address is...\%1\%2\%3\%4\%5\%6'

The first message window shows:

Before compression, the address is...

Joe Raybon

One Meca Way

Atlanta

The second message window shows:

After compression, the address is...

Joe Raybon

One Meca Way

Atlanta

The system moves all empty and blank strings, which cause blank lines, to the end of the array. It also moves the other elements to the beginning of the array.

Attention

Empty lines are not printed if they occur on the first or last line in a message window.


COPYARRAY (Array)

Use this function to copy one or more elements in an array to a new array.

COPYARRAY(NewArray, Array, Position [, Length])

NewArray

Data type: array

The array to copy to - the destination array.

Array

Data type: array

The array to copy from - the source array.

Position

Data type: integer

The position of the first array element to copy.

Length

Data type: integer

The number of array elements to copy. If you do not specify Length, the system copies all array elements from Position to the last element. Use this equation to determine valid values:

1 =< LENGTH =< MAXLEN(ARRAY) - POSITION + 1

Comments

You can only copy from one-dimensional arrays. Repeat the COPYARRAY function to copy two- and three-dimensional arrays.

Example

If array1 is an integer array with dimension 10, and it contains the numbers from 1 to 10, the following command copies the numbers 6,7,8,9,10 to array2, an integer array with dimension 5:

COPYARRAY (array2,array1,6,5);

If the Length had been omitted, like this:

COPYARRAY (array2,array1,6);

the effect would be exactly the same - because in this example, the default copying of everything from position 6 and forward from array1 just happens to fit in array2, which has a dimension of 5. On the other hand, this command would cause a runtime error:

COPYARRAY (array2,array1,3);

because there would now have to be copied seven elements from array1 to array2 - and array2 has only room for five.


CODECOVERAGELOG

Use this function to start and stop the logging of code. You can also use it to retrieve the current logging status.

[IsActive]:= CODECOVERAGELOG([NewIsActive])

IsActive

Data type: Boolean

NewIsActive

Data type: Boolean

Comments

You must only start the Code Coverage tool from the command prompt when you want to get a total overview of the code used when running Microsoft Dynamics NAV or when you are testing the application.

To start Microsoft Dynamics NAV with the Code Coverage tool on, enter the following command:

fin COVERAGELOG

To start Microsoft Dynamics NAV with the Code Coverage tool on and to log the results in file xx.xx, enter the following command:

fin COVERAGELOG, COVERAGEFILENAME=xx.xx

To start Microsoft Dynamics NAV with the Code Coverage tool set to off and to load an existing result from file xx.xx, enter the following command:

fin COVERAGEFILENAME=xx.xx.

Running the Code Coverage tool for this purpose will generate a very large log file.

More information:

Code Coverage Functionality


GLOBALLANGUAGE (Language)

Use this function to set and retrieve the current C/SIDE global language setting.

[LanguageID]:= GLOBALLANGUAGE([NewLanguageID])

LanguageID

Data type: Integer

NewLanguageID

Data type: Integer

Comments

This function sets or retrieves the current C/SIDE global language setting. The LanguageID is a standard Windows language ID. The Windows Language virtual table contains a list of these IDs and the corresponding names and short names.

See the description of the multilanguage features for more information.


LANGUAGE (Language)

Use this function to set and retrieve the current language setting for an object (form, report or dataport).

[CurrLanguage]:= LANGUAGE([NewLanguage])

CurrLanguage

Data type: Integer

NewLanguage

Data type: Integer

Comments

This function sets or retrieves the current language setting for an object. CurrLanguage and NewLanguage are standard Windows language IDs. The Windows Language virtual table contains a list of these IDs and the corresponding names and short names.

You cannot set or retrieve the language for objects other than forms, reports and dataports.

See the description of the multilanguage features for more information.


WINDOWSLANGUAGE (Language)

Use this function to retrieve the current Windows language setting.

LanguageID:= WINDOWSLANGUAGE

LanguageID

Data type: Integer

Comments

This function retrieves the current Windows language setting. The LanguageID is a standard Windows language ID. The Windows Language virtual table contains a list of these IDs and the corresponding names and short names. See the description of the multilanguage features for more information.


APPLICATIONPATH

Use this function to return the path to the directory where the executable file for Microsoft Dynamics NAV is installed.

APPLICATIONPATH

Comments

This function returns a string that contains the path to the directory where the executable file for Microsoft Dynamics NAV is installed. This string ends with a backslash ('\') and does not contains the name of the executable file.

The string cannot contain more than 255 characters.

If this function is called from an application that is running on a Microsoft Dynamics NAV Application Server, it returns the path to the directory where the Microsoft Dynamics NAV Application Server is installed.


COMMANDLINE

Use this function to return a list of the parameters used to start Microsoft Dynamics NAV .

String := COMMANDLINE

String

Data type: text or code

Contains a list of the parameters used to start the system.

Example

If you start the system with this command:

c:\Program Files\Microsoft Dynamics NAV\Fin database=xyzco

the system will return the string:

database=xyzco

when you use the COMMANDLINE function.


CONTEXTURL

Use this function to return a context string that defines the current position of the running objects.

String:=CONTEXTURL

String

Data type: text or code

Example

Here are two examples of a context string:

navision://client/run?database=filename&company=companyname

navision://client/run?server=servername&company=companyname&servertype=MSSQL


ENVIRON

Use this function to return a string associated with an environment variable.

String := ENVIRON(Name)

String

Data type: text constant or code

The string associated with the environment variable.

Name

Data type: text constant or code

The name of the environment variable.

Comments

If the environment variable does not exist, the string that is returned may contain garbage.


GUIALLOWED

Use this operating system function to check whether the C/AL code is allowed to show any information on the screen. When you run Microsoft Dynamics NAV Application Server, GUIALLOWED always returns FALSE and any call to CONFIRM or d.OPEN, or any attempt to use a form, report or dataport will generate an error.

[Ok:=] GUIALLOWED()

Ok

Data type: boolean

If Ok is... | It means that...
TRUE | the C/AL code is running on a C/SIDE client and the graphical user interface (GUI) is available.
FALSE | the C/AL code is running on Microsoft Dynamics NAV Application Server and that no user interface is available.

Example

This example shows how to use GUIALLOWED:

IF GUIALLOWED THEN
 MESSAGE(Text000);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | Code is running on a C/SIDE client

If the code runs on a C/SIDE client, which means that the user interface is available, a message box will appear with the message, 'Code is running on a C/SIDE client.' If the code runs on Microsoft Dynamics NAV Application Server, the message will not be displayed.

Note

If the MESSAGE function or the ERROR function is called when the code is running on Microsoft Dynamics NAV Application Server, the message is written to the event log of the operating system. For more information on message logging, see the manual Installation & System Management: Microsoft Dynamics NAV Application Server.

Note that User Portal Application Server accepts GUIALLOWED.


HYPERLINK

Use this function to, for example, start Microsoft Internet Explorer and pass a URL as an argument to that program.

HYPERLINK(URL)

URL

Data type: text

A URL (Uniform Resource Locator) that is passed to the default Internet browser as an argument.

Comments

C/SIDE does not check the syntax or validity of the URL that is passed on to the browser. You can even pass an empty string (this will usually start the browser and load the URL that the user has defined as the Start Page.)

C/SIDE determines the default Internet browser based on the setting in the system registry. If the browser is already running, this instance will be reused.

The HYPERLINK function works with a number of protocols and file types that are approved in the version of the program that you are using. This protocols and file types are listed in the .stx file. This means that different versions of Microsoft Dynamics NAV can approve different protocols and file types.

The standard W1 version contains the following list of approved protocols and file types:

Protocols – navision, http, https

File Types – bmp, doc, dot, htm, html, mhtml, mht, ig, gif, ini, jpg, mdb, mov, mpeg, mpg, pub, pdf, ppt, pps, rtf, sys, txt, url, wri, wpd, wps, xls, xsn, xml, zip, fdf, aspx, chm, vsd, mpp, wmv, wma, msg

The HYPERLINK function does not work on Microsoft Dynamics NAV Application Server.

Example 1

To create a command button that starts the default Internet browser and directs it to an interesting site on the World Wide Web, you could add this code to the OnPush trigger of the command button:

HYPERLINK('http://www.microsoft.com');


OSVERSION

Use this function to return a string which contains the name and version of the operating system or operating environment.

String := OSVERSION

String

Data type: text constant or code

This string tells you the type and version of the operating system or operating environment. Here are some typical examples of what the system returns:

If the operating system/environment is... | The system returns...
Windows 2000 | Windows_NT_5.0
Windows XP | Windows_NT_5.1
Windows 2003 | Windows_NT_5.2

Example

This example shows how to use the OSVERSION function.

Ver := OSVERSION;
MESSAGE(Text000, Ver);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'The operating system is: %1'

A typical result:

The operating system is: WIN_NT_5.0


SHELL

Use this function to execute external programs and operating system commands from C/AL programs. You can run this function modally or non-modally, depending on whether or not you include the return value from the external program in your code.

[ReturnCode]:= SHELL(Name [, Param, ...])

ReturnCode

Data type: integer

ReturnCode is used for two different purposes:

First, if ReturnCode is used, the external program will be run modally, while it will be run non-modally if ReturnCode is not used. For instance, if you want to go to the operating system and get a directory listing and then bring that information back into the system, include ReturnCode. Omit ReturnCode if you want to run the external program non-modally. For instance, if all you want to do is pass information (such as a name and address) to a standardized letter that is set up in a word processor, you would omit the ReturnCode.

Second, ReturnCode can contain the return value of the external program. Since external programs can return different codes to reflect whether errors occurred during the execution of the program, the values stored in ReturnCode depend on the external program.

Name

Data type: text or code

The path and name of the command. When you enter the path, keep in mind these shortcuts:

You can... | If the command is located...
Omit the drive designation | On the current drive
Omit the full path | In the current directory
Enter only the subdirectory name | In a subdirectory of the current directory

Param,...

Data type: text or code

One or more optional arguments sent with the external program or command.

The parameter(s) cannot be passed as part of the Name argument. The Name argument must be filled in and it must not contain any parameters except for the executable. The parameter information must be hard coded into the system as a text constant or as a variable.

The SHELL function has been designed so that each user can create a list of trusted executables. This list is maintained in the user’s zup file. The way this function works depends on whether the executable is given as a text constant or as a variable.

Text Constant

If the name of the executable is passed to the SHELL function as a text constant the executable is trusted and the user is not prompted to confirm that they trust the executable. This is also the case when the executable (text constant) is called with a number of other arguments that have been assigned manually.

Variable

If the name of the executable is passed to the SHELL function as a variable the executable is not trusted and the user is prompted to confirm whether or not they trust the executable the first time it is called. Once the user has confirmed that they trust the executable it can be called again at any time without their having to confirm that they trust it.

Microsoft Dynamics NAV Application Server

The SHELL function can only be used with a text constant on Microsoft Dynamics NAV Application Server.

Example

OBJECT Codeunit 98123 SHELL ex

{

  OBJECT-PROPERTIES

  {

    Date=30-08-04;

    Time=14:12:57;

    Modified=Yes;

    Version List=;

  }

  PROPERTIES

  {

    OnRun=BEGIN

            // The following is NOT trusted and will give a warning:

            ExecName := 'C:\windows\notepad.exe';

            param := 'C:\MyFile.txt';

            ret := SHELL(ExecName, param);

            // The following IS trusted and will not give a warning:

            param := 'C:\MyFile.txt';

            ret := SHELL(TEXT000, param);

            //The following is not possible - will only give an error

            //message during runtime. This is also if it's a TextConst:

            ExecName := 'C:\windows\notepad.exe C:\MyFile.txt';

            ret := SHELL(ExecName);

          END;

  }

  CODE

  {

    VAR

      ret@1000 : Integer;

      param@1001 : Text[30];

      TEXT000@1002 : TextConst 'ENU=C:\windows\notepad.exe';

      ExecName@1003 : Text[30];

    BEGIN

    END.

  }

}


SLEEP

Use this function to return control to the operating system for a specifiable amount of time.

SLEEP(Duration)

Duration

Data type: integer

The number of milliseconds to return control to the operating system for.

Comments

When using SLEEP, control is guaranteed to return to the operating system for at least Duration milliseconds (implying that the period may be longer, depending on what the operating system is doing at the time when control is to return to the caller.)


TEMPORARYPATH

Use this function to return the path to the directory where the temporary file for Microsoft Dynamics NAV is installed.

TEMPORARYPATH

Comments

This function returns a string that contains the path to the directory where the temporary file for Microsoft Dynamics NAV is installed. This string ends with a backslash ('\') and does not contains the name of the temp file.

The string cannot contain more than 255 characters.

If this function is called from an application that is running on a Microsoft Dynamics NAV Application Server, it returns the path to the directory where the Microsoft Dynamics NAV Application Server is installed.


CLEAR (Variable)

Use this function to clear the value of a single variable. CLEAR also clears all filters that were set if the variable is a record and resets the key to the primary key. Use the CLEARALL function to clear all internal variables, keys, and filters in the object and in any associated objects such as reports, forms, codeunits, and so on that contain C/AL code. Note, however, that CLEARALL does not affect or change values for variables in single instance codeunits.

CLEAR(Variable)

Variable

Data type: any

This parameter is an identifier (variable) of any C/AL data type, including simple and composite data types. The following rules apply:

The system sets a... | To...
Number variable | 0 (zero)
String variable | empty string
Date variable | 0D (undefined date)
Time variable | 0T (undefined time)
Boolean variable | FALSE

Comments

For a composite data type, such as a record or an array, the system clears all elements. Furthermore, all fields in a record will be initialized with the InitValue of the field.

CLEAR can also be used on the GUID data type. It converts the GUID to zeros. Use the CREATEGUID function to create a new unique GUID.

For an Automation object, CLEAR releases the Automation object and decreases the reference count. It is up to the Automation server to decide if this should cause a shutdown. After CLEAR, you can use CREATE on the Automation variable to create a new instance of the object.

If you use CLEAR on a codeunit, only the reference to the codeunit is deleted and not the codeunit itself, as with Automation objects. This means that the content of the codeunit stays intact.

If you have an array of controls, the whole array is destroyed when the array variable goes out of scope.

If you have an array of automation servers, you may CLEAR the whole array in one go, or CLEAR each element individually.

Example 1

The following example shows how to use CLEAR:

Name
 := Text000;
MESSAGE(Text001, Name);
CLEAR(Name);
MESSAGE(Text002, Name);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Joe Raybon'
Text001 | 'Initially the variable "Name" contains: >%1<'
Text002 | 'After using CLEAR the variable "Name" contains: >%1<'

The first message window will show:

Initially the variable "Name" contains: >Joe Raybon<

while the second message window will show:

After using CLEAR the variable "Name" contains: ><

Example 2

In the following example we will declare two variables:

MyTextVar, data type: "text".

GuidVar, data type: "GUID".

These variables will be declared and cleared. First by using CLEAR and then by using CLEARALL. To visualize this you need to create the following text constants in the C/AL Globals windows:

Name | ConstValue
Text000 | My Text
Text001 | Initally the variable "MyTextVar" contains >%1< and "GuidVar" is defined as >%2<
Text002 | After using CLEAR(MyTextVar) the variable "MyTextVar"contains >%1< and "GuidVar" is still defined as >%2<
Text003 | After using CLEAR(GuidVar) the variable "GuidVar" becomes undefined >%1<
Text004 | Giving the "MyTextVar" variable the initial value again and creating a new "GuidVar" results in >%1< and >%2<
Text005 | Using CLEARALL results in an empty "MyTextVar" >%1< and an undefined "GuidVar" <%2>

The following C/AL code declares the variables, then clears the variables one at a time by using CLEAR. and displays the values in massages.

MyTextVar := Text000;
GuidVar := CREATEGUID();
MESSAGE(Text001,MyTextVar,GuidVar);
CLEAR(MyTextVar);
MESSAGE(Text002,MyTextVar,GuidVar);
CLEAR(GuidVar);
MESSAGE(Text003,GuidVar);

The following C/AL code declares the variables again, and then clears all the variables by using CLEARALL. This example uses only one line of code instead of the two used earlier:

MyTextVar := Text000;
GuidVar := CREATEGUID();
MESSAGE(Text004,MyTextVar,GuidVar);
CLEARALL;
MESSAGE(Text005,MyTextVar,GuidVar);


CLEARALL (Variable)

Use this function to clear all internal variables (except REC variables), keys, and filters in the object and in any associated objects, such as reports, forms, codeunits, and so on that contain C/AL code. CLEARALL works by calling CLEAR repeatedly on each variable. However, this is not the case with codeunits, where the CLEARALL function works by calling CLEARALL inside the codeunit. It deletes the contents of the codeunit, whereas CLEAR only deletes the reference to the codeunit.

CLEARALL does not affect or change values for variables in single instance codeunits.

Comments

When a function is called repeatedly within the same transaction, the system retains all values for variables and filters in memory between calls. For example, this is used to assign numbers to entry numbers when posting. When you do not want to retain the values in memory, use the CLEARALL function to clear them.

Refer to the description of the CLEAR function for information about the initial values of cleared variables. Take into consideration that fields in a record will be initialized with the InitValue of the field.


COPYSTREAM (Variable)

Use this variable function to copy the information contained in an InStream to an OutStream.

[Ok :=] COPYSTREAM(OutStream, InStream)

Ok

Data type: boolean

Indicates whether or not the data could be copied.

OutStream

The OutStream object type to which you will copy the information (the destination Stream).

InStream

The InStream object type you want to copy from (the source Stream).

Example

This example shows how to use the COPYSTREAM function:

Variables:

F1:
 File;
F2: File;
InS: InStream;
OutS: OutStream;

Code:

F1.OPEN('c:\Test.txt');
F1.CREATEINSTREAM(InS);
F2.CREATE('c:\CopyTest.txt');
F2.CREATEOUTSTREAM(OutS);
COPYSTREAM(OutS,InS);
F1.CLOSE();
F2.CLOSE();


EVALUATE (Variable)

Use this function to evaluate a string representation of a value into its normal representation. The system assigns the result to a variable.

[Ok :=] EVALUATE(Variable, String[, Number])

Ok

Data type: boolean

A return code that tells you whether or not an error occurred during the evaluation of the string.

If Ok is... | It means...
TRUE | No errors occurred during the evaluation of the string. The system assigned the value to Variable.
FALSE | Errors occurred during the evaluation of the string. The system did not modify the original value of Variable.

If you omit this optional return value and an error occurs during the evaluation of the string, a run-time error occurs. If you include it, the system assumes you will handle any errors.

Variable

Data type: boolean, integer, option, date, time, text constant, code or GUID.

Any type of variable. The value of the string is assigned to the variable.

String

Data type: text constant or code

A string containing a value of any simple C/AL data type.

Number

Data type: integer

This optional value can be used when exporting data with an XMLport. The only valid value is 9 and this indicates that the data must be converted from XML format to C/SIDE format.

Example

This example shows how the EVALUATE function works when called with three different types of variables.

Value := '010196';
Ok1 := EVALUATE(VarInteger, Value);
Ok2 := EVALUATE(VarDate, Value);
Ok3 := EVALUATE(VarYesNo, Value);
MESSAGE(Text000 + Text001 + Text002,
VarInteger, Ok1, VarDate, Ok2, VarYesNo, Ok3)

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'VarInteger = #1######, and the return code is: %2\'
Text001 | 'VarDate = #3######, and the return code is: %4\'
Text002 | 'VarYesNo = #5######, and the return code is: %6'

The message window shows:

VarInteger = 10196 , and the return code is: Yes
VarDate = 01/01/96, and the return code is: Yes
VarYesNo = No , and the return code is: No

This example shows that while the system can interpret Value ('010196') as both an integer and a date expression, it cannot interpret it as a boolean expression. This causes an error, shown in the return code Ok3 (=FALSE).


TABLEFILTER

Use this data type to apply a filter to another table. At the moment, this data type can only be used when you are setting security filters from the Permission table.


VARIANT

The C/AL variant data type can contain any variants from OCX and Automation objects (VT_VARIANT). However, not all these values can be mapped to C/AL values. The description of COM data types and C/AL data types provides more information.

The variant data type can contain the following C/AL data types: record, file, action, codeunit, Automation, boolean, option, integer, decimal, char, text, code, date, time, binary, DateFormula, TransactionType, InStream and OutStream.

You can use the variant data type to pass Automation variants from one external component (Automation or OCX) to another. This requires that the recipient component can accept the original variant. You can also assign a C/AL variable to a variant and pass it to an external component. When you pass C/AL variants ByRef to an external COM component, small conversion differences may occur. Therefore, we recommend that you pass C/AL variants ByVal if you do not need to assign a new value to the C/AL variant in your external component.

Returning Variants in Internal Function Calls

The C/AL variant is a complex data type. To return C/AL variants in function calls, you must pass them in a parameter ByVar (called ByRef in COM).

Variants and Approximation

A C/AL variant contains two allocation areas. There is one for C/AL variables and one for Automation and OCX variants. This means that every time you assign a C/AL variable to a variant, the variant will contain the same data as the original variable. The conversion process does not change the data in any way. Note, however, that this is not the case with DATI2VARIANT because it is a VT_VARIANT. When you assign an external variable to a variant, the variant will also contain the same data as the original external variable.

More information:

DATI2VARIANT

VARIANT2DATE

VARIANT2TIME


ISACTION (Variant)

Use this function to find out whether a C/AL variant contains an action variable or not.

Ok := Variant.ISACTION

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains an action variable.
FALSE | The C/AL variant does not contain an action variable.

Variant

Data type: variant


ISAUTOMATION (Variant)

Use this function to find out whether a C/AL variant contains an automation variable or not.

Ok := Variant.ISAUTOMATION

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains an automation variable.
FALSE | The C/AL variant does not contain an automation variable.

Variant

Data type: variant


ISBINARY (Variant)

Use this function to find out whether a C/AL variant contains a binary variable or not.

Ok := Variant. ISBINARY

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains a binary variable.
FALSE | The C/AL variant does not contain a binary variable.

Variant

Data type: variant


ISBOOLEAN (Variant)

Use this function to find out whether a C/AL variant contains a boolean variable or not.

Ok := Variant. ISBOOLEAN

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains a boolean variable.
FALSE | The C/AL variant does not contain a boolean variable.

Variant

Data type: variant


ISCHAR (Variant)

Use this function to find out whether a C/AL variant contains a char variable or not.

Ok := Variant. ISCHAR

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains a char variable.
FALSE | The C/AL variant does not contain a char variable.

Variant

Data type: variant


ISCODE (Variant)

Use this function to find out whether a C/AL variant contains a code variable or not.

Ok := Variant. ISCODE

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains a code variable.
FALSE | The C/AL variant does not contain a code variable.

Variant

Data type: variant


ISCODEUNIT (Variant)

Use this function to find out whether a C/AL variant contains a codeunit variable or not.

Ok := Variant.ISCODEUNIT

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains a codeunit variable.
FALSE | The C/AL variant does not contain a codeunit variable.

Variant

Data type: variant


ISDATE (Variant)

Use this function to find out whether a C/AL variant contains a date variable or not.

Ok := Variant. ISDATE

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains a date variable.
FALSE | The C/AL variant does not contain a date variable.

Variant

Data type: variant


ISDATEFORMULA (Variant)

Use this function to find out whether a C/AL variant contains a dateformula variable or not.

Ok := Variant.ISDATEFORMULA

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains a dateformula variable.
FALSE | The C/AL variant does not contain a dateformula variable.

Variant

Data type: variant


ISDECIMAL (Variant)

Use this function to find out whether a C/AL variant contains a decimal variable or not.

Ok := Variant. ISDECIMAL

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains a decimal variable.
FALSE | The C/AL variant does not contain a decimal variable.

Variant

Data type: variant


ISFILE (Variant)

Use this function to find out whether a C/AL variant contains a file variable or not.

Ok := Variant.ISFILE

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains a file variable.
FALSE | The C/AL variant does not contain a file variable.

Variant

Data type: variant


ISINSTREAM (Variant)

Use this function to find out whether a C/AL variant contains an InStream variable or not.

Ok := Variant.ISINSTREAM

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains an InStream variable.
FALSE | The C/AL variant does not contain an InStream variable.

Variant

Data type: variant


ISINTEGER (Variant)

Use this function to find out whether a C/AL variant contains an integer or not.

Ok := Variant. ISINTEGER

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains an integer.
FALSE | The C/AL variant does not contain an integer.

Variant

Data type: variant


ISOPTION (Variant)

Use this function to find out whether a C/AL variant contains an option variable or not.

Ok := Variant. ISOPTION

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains an option variable.
FALSE | The C/AL variant does not contain an option variable.

Variant

Data type: variant


ISOUTSTREAM (Variant)

Use this function to find out whether a C/AL variant contains an OutStream variable or not.

Ok := Variant.ISOUTSTREAM

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains an OutStream variable.
FALSE | The C/AL variant does not contain an OutStream variable.

Variant

Data type: variant


ISRECORD (Variant)

Use this function to find out whether a C/AL variant contains a record variable or not.

Ok := Variant.ISRECORD

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains a record variable.
FALSE | The C/AL variant does not contain a record variable.

Variant

Data type: variant


ISTEXT (Variant)

Use this function to find out whether a C/AL variant contains a text variable or not.

Ok := Variant. ISTEXT

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains a text variable.
FALSE | The C/AL variant does not contain a text variable.

Variant

Data type: variant


ISTIME (Variant)

Use this function to find out whether a C/AL variant contains a time variable or not.

Ok := Variant. ISTIME

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains a time variable.
FALSE | The C/AL variant does not contain a time variable.

Variant

Data type: variant


ISTRANSACTIONTYPE (Variant)

Use this function to find out whether a C/AL variant contains a transactiontype variable or not.

Ok := Variant.ISTRANSACTIONTYPE

Ok

Data type: boolean

The return value.

TRUE | The C/AL variant contains a transactiontype variable.
FALSE | The C/AL variant does not contain a transactiontype variable.

Variant

Data type: variant


XMLport

The XMLport object is conceptually related to a dataport; you also use XMLports to import and export data, but in XML format. XMLports make the process of exchanging data in XML between systems more simple and streamlined. You only need a basic knowledge of XML and you do not have to create XML documents using external products.

For information about how to design XMLports, see the manual Application Designer's Guide.


EXPORT (XMLport)

Use this function to create an XML data stream (XML document) and send it to a chosen destination.

[{Ok} :=] EXPORT(Number, OutStream[, Record])

Number

Data type: Integer

The ID of the XMLport that you want to execute.

OutStream

Data type: ISequentialStream

This is where the XMLport object will write the XML data stream.

Record (optional)

Data type: Record

Tells the system which record to use in the XMLport. The system will use any filters attached to the record.


IMPORT (XMLport)

Use this function to read and parse an incoming XML data stream (XML document).

[{Ok} :=] IMPORT(Number, InStream [, ResponseOutStream])

Number

Data type: Integer

The ID of the XMLport that you want to execute.

InStream

Data type: ISequentialStream

The source from which the import XMLport object will read the XML data stream.

ResponseOutStream(optional)

Data type: ISequentialStream

You set this parameter if the XMLport import object needs to call an export XMLport object to make a reply document. Destination will be passed to the export object.


ActiveControlOnOpen

Use this property to tell the system which control should be activated when the form is opened.

Applies to

Forms

Settings

Set this property to the ID of the control that should be activated when the form is opened. If this property is not set, the system makes the control in the top left corner of the form the active control by default.

Comments

If this property is set to an ID that is not present on the form, the default will be used (no error will occur).


AltSearchField

Use this property to select an alternative field for doing lookups for this field.

Applies to

Fields

Settings

The Name of the field that should be used as an alternative search field.

Comments

This property is used to make it easier for users to search and lookup in a table. If, for example, the primary key of a table is a numeric identifier, and it is used as a foreign key in another table, users would normally have to memorize all or parts of these identifiers when they perform a lookup into this table. If, however, you set a field with more easily memorizable contents (for example, a field containing names or addresses) as an alternative search field for the primary key field, users could search for these names or addresses and still retrieve the correct numeric identifier.


AssistEdit

Use this property to provide assist-edit capabilities for a text box.

Applies to

Text boxes

Settings

The AssistEdit settings are:

To provide... | Choose...
Assist-edit capabilities and an AssistEdit button to the text box | Yes
No assist edits | No (default)

Comments

You can add C/AL code in the OnAssistEdit trigger to change the system's default assist-edit behavior.

See also Lookup, DrillDown, and DropDown.


AutoCalcField

Use this property to tell the system to automatically calculate this FlowField. The source expression to this control must be a FlowField in the source table.

Applies to

Check boxes, option boxes, text boxes, picture boxes, indicators

Settings

The AutoCalcField settings are:

To... | Choose...
Automatically calculate the FlowField | Yes (default)
Not automatically calculate the FlowField | No


AutoCalcField (XMLports)

Use this property to specify whether or not the value in this field (FlowField) should be recalculated before the field is exported.

Applies to

XMLports

Settings

To have the system... | Select
Automatically calculate the FlowField | Yes (default)
Not automatically calculate the FlowField | No


AutoEnter

Use this property to have the system automatically accept the user's entry and move the focus to the next field once the user fills the field. If you set this property to Yes, the user does not have to press Enter to move to the next field.

Applies to

Text boxes

Settings

The AutoEnter settings are:

To... | Choose...
Move the focus to the next field once the maximum number of characters has been entered | Yes
Leave the focus in the current field until the user presses Enter or Esc | No (default)

Comments

See also NextControl.


AutoFormatExpr

AutoFormatExpr is a C/AL expression that tells the system how to format the data. The system evaluates the expression when it performs updates. Together with the AutoFormatType property, this property determines how data is formatted. In the standard application, these two properties are only used to format amounts that can be stated in a foreign currency.

When you use the AutoFormatType and AutoFormatExpr properties to format a field, a trigger called AutoFormatTranslate in CodeUnit 1 is called. AutoFormatTranslate has ID 12 and takes two parameters; one from the AutoFormatType property and one from the AutoFormatExpr property. The AutoFormatType property contains an integer (0, 1 or 2) and the AutoFormatExpr property contains text (“ =LCY”).

These properties are used when you have an amount or a unit amount that you want to be able to display in another currency and these properties determine the number of decimals that will be displayed. For example, a sales order will use 2 decimals when the currency is defined as US dollar and 0 decimals when the currency is defined as IDR (Indonesian rupiah).

Applies to

Fields, text boxes

Settings

The settings for the AutoFormatType property and the AutoFormatExpr property depend on the type of data in the control or database field you need to format. There are three categories of data: amount, unit amount and other types of data.

Amounts

AutoFormatType must be 1 and AutoFormatExpr must return a currency code (the blank currency code denotes LCY) in order for the system to format data as amount data.

Unit Amounts

AutoFormatType must be 2 and AutoFormatExpr must return a currency code (the blank currency code denotes LCY) in order for the system to format data as unit amount data.

Other Types of Data

AutoFormatType must be 0 and AutoFormatExpr must be blank for the system to format data using the default C/SIDE settings (Standard Format 0).

Comments

If the AutoFormatType property does not contain a value, the format specified in the DecimalPlaces property will determine how the decimal is formatted in the table, report or form. On the other hand, if you enter a value in the AutoFormatType property, it will override the value specified in the DecimalPlaces property and the AutoFormatType property will determine how the decimal is formatted in the table, report or form. Furthermore, if you enter a value in the AutoFormatType property for a report or form, it will override the value entered in the DecimalPlaces property in the table and determine how the decimal is formatted in the report or form.


AutoFormatType

The system uses this property together with the AutoFormatExpr property to determine how data is formatted. In the standard application, these two properties are only used to format amounts that can be stated in a foreign currency.

When you use the AutoFormatType and AutoFormatExpr properties to format a field, a trigger called AutoFormatTranslate in CodeUnit 1 is called. AutoFormatTranslate has ID 12 and takes two parameters; one from the AutoFormatType property and one from the AutoFormatExpr property. The AutoFormatType property contains an integer (0, 1 or 2) and the AutoFormatExpr property contains text (“ =LCY”).

These properties are used when you have an amount or a unit amount that you want to be able to display in another currency and these properties determine the number of decimals that will be displayed. For example, a sales order will use 2 decimals when the currency is defined as US dollar and 0 decimals when the currency is defined as IDR (Indonesian rupiah).

Applies to

Fields, text boxes

Settings

The settings for the AutoFormatType property and the AutoFormatExpr property depend on the type of data in the control or database field you need to format. There are three categories of data: amount, unit amount and other types of data.

Amounts

AutoFormatType must be 1 and AutoFormatExpr must return a currency code (the blank currency code denotes LCY) in order for the system to format data as amount data.

Unit Amounts

AutoFormatType must be 2 and AutoFormatExpr must return a currency code (the blank currency code denotes LCY) in order for the system to format data as unit amount data.

Other Types of Data

AutoFormatType must be 0 and AutoFormatExpr must be blank for the system to format data using the default C/SIDE settings (Standard Format 0).

Comments

If the AutoFormatType property does not contain a value, the format specified in the DecimalPlaces property will determine how the decimal is formatted in the table, report or form. On the other hand, if you enter a value in the AutoFormatType property, it will override the value specified in the DecimalPlaces property and the AutoFormatType property will determine how the decimal is formatted in the table, report or form. Furthermore, if you enter a value in the AutoFormatType property for a report or form, it will override the value entered in the DecimalPlaces property in the table and determine how the decimal is formatted in the report or form.


AutoIncrement

Use this property to specify whether or not each field value should be automatically given a new number that is greater than the number given to the previous value.

Applies to

Fields of the Integer and BigInteger data type.

Comments

A table can only contain one field that has been defined as an auto-increment field.

The numbers that are assigned will not necessarily be consecutive because:

  • If you delete some records from a table, the numbers that are used in these records will not be reused.

  • If several transactions are being performed at the same time, they will each be assigned a different number. However, if one of these transactions is rolled back, the number that it was assigned cannot be reused.

If you add an auto-increment field to an existing table, it will automatically generate consecutive values and insert them into the table.

If you enable the auto-increment property for a field that already contains data, there must be no zero values in the field.

The AutoIncrement property is designed to always assign numbers automatically. If you want to insert a record, you must make sure that the value in the field is blank before you insert the record. This is even more critical when you are using the SQL Server Option. If you want to manually assign a value to a field that has the AutoIncrement property set to Yes, you must be member of the SQL Server db_owner database role for the database in question.

The AutoIncrement property does not work for C/SIDE temporary tables.


AutoPosition

Use this property to have the system automatically position the form in one of several places.

Applies to

Forms

Settings

The AutoPosition settings are:

To... | Choose...
Center this form on the screen | CenterScreen
Center this form with respect to the active form | CenterActiveForm
Place this form outside the active form | OutsideActiveForm
Place this form outside the active control | OutsideActiveControl
Not have the system automatically position the form | None (default)

Comments

If you choose None, the system relies on the XPos and YPos properties to determine where to place the form. If you choose another setting, the system ignores the XPos and YPos settings.

If the form is displayed as a lookup (in lookup mode), the system automatically places it outside the active control.

The system checks this property when it opens the form.

Your entry here has no effect on any related subforms.


AutoRepeat

Use this property to repeat the action when the user holds down the mouse button.

Applies to

Command buttons

Settings

The AutoRepeat settings are:

To have the system... | Choose...
Repeat the action when the user holds down the mouse | Yes
Perform the action one time for each time the user presses and releases the mouse button | No (default)

Comments

See also PushAction.


AutoReplace

Use this property to determine if records that are imported will automatically replace existing records with the same primary key.

Applies to

Data items (in dataports)

Settings

The AutoReplace settings are:

To... | Choose...
Replace records | Yes
Not replace records | No (default)


AutoSave

Use this property to determine if records that are imported will automatically be inserted in a C/SIDE table.

Applies to

Data items (in dataports)

Settings

The AutoSave settings are:

To... | Choose...
Insert records automatically | Yes (default)
Not insert records automatically | No

Comments

If AutoSave is No, you will have to insert records yourself, by using C/AL code in the OnAfterImportRecord trigger. This is, for example, necessary in situations where you have to perform some processing to decide if the record should be inserted, or to calculate or retrieve additional data before inserting the record.

In a situation where a record already exists and AutoSave is Yes, the setting of the AutoReplace property determines if the imported record will overwrite the existing record.


AutoSplitKey

Use this property to have the system automatically create a key for a new record placed between the current record and the previous record.

Applies to

Forms

Settings

The AutoSplitKey settings are:

To... | Choose...
Let the system create a key which will place a new record between the current record and the previous record | Yes
Prevent the system from creating a key which will place the new record between the current record and the previous record | No (default)

Comments

There are two prerequisites for turning this property on:

  • The current key must be the primary key.

  • The last field in the primary field must be an integer BigInteger, GUID or decimal field. If these conditions are met, you can set this property to Yes.


AutoUpdate

Use this property to determine if records that are imported will be initialized with values from an existing record with the same primary key.

Applies to

Data items (in dataports)

Settings

The AutoUpdate settings are:

To... | Choose...
Update records | Yes (default)
Not update records | No

Comments

When AutoUpdate is Yes, an imported record that has the same primary key as an existing record will be updated with values from the record already in the database for those fields that do not contain values.

The intended use is a situation where you are importing a file with partial information, for example, if you have created new prices for an item list in an external file, and this file only contains item numbers and prices. In this case, you would want to update the price field, and keep the information in the rest of the fields of the database table.


BackColor

Use this property to determine the background color of the control.

Applies to

Forms, labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes

Comments

Use the Color option on the View menu to pick a color or enter the RGB value of the color you want for the background.

The default is the system background color.

See also ForeColor and BackTransparent.


BackTransparent

Use this property to make the background transparent. If you set this property to Yes, the system ignores the BackColor setting.

Applies to

Labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, text boxes, picture boxes, indicators, frames, tab controls, table boxes

Settings

The BackTransparent settings are:

To... | Choose...
Ignore the BackColor setting and make the background transparent | Yes (default for labels, images, check boxes, option buttons, picture boxes, indicators, frames, tab controls)
Use the BackColor setting and make the background solid | No (default for command buttons, menu buttons, table boxes)

Comments

See also ForeColor.


BackupKey

This property is used by the backup/restore system. Under normal circumstances, you will not need to set it yourself.

Applies to

Keys

Settings

When BackupKey is... | The Enabled property of secondary keys will..
Yes | be restored during restore
No | not be restored during restore

Comments

During backup, secondary keys where the Enabled property is Yes are marked with BackupKey = Yes, and the secondary indexes are not stored in the backup. When the backup is restored, the system checks the setting of BackupKey, reenables secondary keys where BackupKey = Yes, and recreates the indexes.

Therefore, you will normally only see BackupKey as set to No (the default), as it is only set otherwise in the backup. If, however, a restore is suspended during key creation (to be resumed at a later time), you can see - and set - BackupKey.


Bitmap

Use this property to select a bitmap to use for a label, command button, menu button, check box, or option button

Applies to

Labels, command buttons, menu buttons, check boxes, option buttons.

Settings

Enter the filename of the bitmap you want to use, for example c:\pictures\thisone.bmp.

There are 44 predefined bitmaps in the system. They can be chosen by entering a number from 1 to 44. They are the bitmaps that are used at various places in the system.

Comments

The bitmap is actually imported into the system. This means that if you change the bitmap, you will have reimport it, in order to update the version that is used. You can do this by reentering the Value of this property.

The maximum size of a bitmap is 32 KB. To use larger bitmaps than this, you will have to use a BLOB field.

See also BitmapList and BitmapPos.


BitmapList

Use this property to specify a list of bitmaps from which the system will select the correct bitmap to display.

Applies to

Picture boxes

Settings

A comma-separated list of filenames, like c:\pictures\foo.bmp,c:\pictures\bar.bmp.

There are 44 predefined bitmaps in the system. They can be chosen by entering a number from 1 to 44. They are the bitmaps that are used at various places in the system. You can mix external bitmaps, stored in files, and these internal bitmaps in the list.

Comments

The SourceExpr of the control is used to choose which bitmap to display - the first in the list is number 1, the second is number 2, and so forth.

The bitmaps are actually imported into the system. This means that if you change one or more of the bitmaps, you will have to reimport them, in order to update the versions that are used. You can do this by reentering the Value of this property.

The size limit for all the user-defined bitmaps included in the list is 32 KB.

See also Bitmap and BitmapPos.


BitmapPos

Use this property to position a bitmap.

Applies to

Command buttons, menu buttons, check boxes, option buttons

Settings

The BitmapPos settings are:

To position the bitmap... | Select...
None (the system will not display the bitmap) | None
On the left | Left (default for command buttons, check boxes, option buttons)
On the right | Right (default for menu buttons)
At the top | Top
At the bottom | Bottom
In the center | Center

Comments

See also Bitmap and BitmapList.


BlankNumbers

Use this property to tell the system to blank a range of numbers as it formats them.

Applies to

Text boxes

Settings

The BlankNumber settings are:

If you want the system to... | Select...
Not blank any numbers | DontBlank (default)
Blank negative numbers | BlankNeg
Blank negative numbers and zero | BlankNegAndZero
Blank numbers equal to zero | BlankZero
Blank positive numbers and zero | BlankZeroAndPos
Blank positive numbers | BlankPos

Comments

See also BlankZero.


BlankZero

Use this property to tell the system whether to display zeros (0) and No.

Applies to

Fields, text boxes

Settings

The BlankZero settings are:

To... | Choose...
Blank zeros and No | Yes
Display zeros and No | No (default)

Comments

The setting for the text box overrides the setting for the field on the current form.

See also BlankNumbers.


Border

Use this property to tell the system whether to display a border around the control.

Applies to

Labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes

Settings

The Border settings are:

To... | Choose...
Display a border | Yes (default for command buttons, menu buttons, text boxes, picture boxes, indicators, frames, tab controls, table boxes)
Omit the border | No (default for labels, images, check boxes, option boxes, and text boxes in a report)

Comments

See also BorderColor, BorderStyle, and BorderWidth.


BorderColor

Use this property to tell the system what color to use for the border. This property only applies if Border is set to Yes.

Applies to

Labels, images, shapes, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes

Comments

Use the Color option on the View menu to pick a color or enter the RGB value of the color you want for the border. The default is the system border color.

See also BorderStyle, and BorderWidth.


BorderStyle

Use this property to determine the type of border to display around the form or control.

Applies to

Forms, labels, images, shapes, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms

Settings

For forms, the BorderStyle settings are:

To use a border that is... | Select...
A single line | Single (default)
A double line | Double
No border | None

For controls, the BorderStyle settings are:

To use a border that is... | Select...
A single line | Normal (default for labels, images, shapes, subforms)
Raised | Raised (default for frames, tab controls)
Semi-sunken | SemiSunken (default for picture boxes, indicators and non editable text boxes)
Sunken | Sunken (default for table boxes and editable text boxes)
Bumped up | BumpUp
Bumped down | BumpDown

Comments

For controls, you can only use this property if the Border property is set to Yes.

For controls, you can use the Color option on the View menu to pick a border style or select one of the values shown above.

See also BorderColor and BorderWidth.


BorderWidth

Use this property to set the width of the border around the frame.

Applies to

Labels, images, shapes, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes

Settings

The BorderWidth settings are:

To display a... | Select...
Hairline border | Hairline (default)
One point (1 pt.) border | 1pt
Two point (2 pt.) border | 2pt
Three point (3 pt.) border | 3pt
Four point (4 pt.) border | 4pt
...and so on. |

Comments

You can only use this property if the BorderStyle property is set to Normal.

Use the Color option on the View menu to pick a border width or select one of the values shown above.

See also BorderColor and Border.


BottomMargin

Use this property to set the bottom margin of a report. The unit of measure is 1/100 mm.

Applies to

Reports

Comments

A bottom margin specified in the page setup dialog will override BottomMargin.

Some printers require a minimum margin. If you specify a margin that is smaller than the minimum margin, the minimum margin will be used when printing.

The default is 20 mm.


CalcFields

Use this property to list the FlowFields from the source table that you want the system to automatically calculate.

Applies to

Forms, reports, dataports, XMLports

Comments

Use the AssistEdit button to select the FlowFields.


CalcFormula

Use this property to define the calculation for a FlowField. You can choose from several methods of calculations including sum (total), average, maximum value, minimum value, record count, lookup and whether or not a record exists.

Applies to

Fields

Settings

Use the AssistEdit button to set up the calculation formula. The AssistEdit window lets you reverse the sign, choose a table and fields, and create filters.

Comments

For example, the comment fields in the standard application, which indicate whether or not there is a comment attached to the record, include a calculation definition.


CallFieldValidate

Use this property to determine if the OnValidate trigger for the field will be executed when a field is imported.

Applies to

Dataports

Settings

The CallFieldValidate settings are:

To... | Choose...
Execute the trigger | Yes
Not execute the trigger | No (default)

There is one situation, however, when the default value of the CallFieldValidate property is Yes. If you set the FileFormat dataport property to UPXML (for User Portal dataports only), the default value of the CallFieldValidate property will be Yes.

When you use the default value of the FileFormat property, Variable, the default value of the CallFieldValidate property is No.

Comments

When fields are imported, they are validated in the same order as they appear in the Field Designer. Note that the code in the OnValidate trigger may or may not initialize other fields in the record, so you should investigate carefully if the order in which the fields are validated is important (by looking at the OnValidate triggers of the fields).


Cancel

Use this property to let the user push this command button by pressing Esc.

Applies to

Command buttons

Settings

The Cancel settings are:

If you want Esc to... | Choose...
Activate or push this command button | Yes
Deactivate or not push this command button | No (default)

Comments

This only applies to the first command the system receives after the user opens the form. When the user presses Enter or Esc, the system first checks to see if there is a specified response. It only executes the default and cancel properties if there is not.

See also Default.


Caption

This property shows the caption in the currently selected language. The value is taken from the CaptionML property if this property is set. A caption is the text the system uses to show the identity of a control (for example, in the caption bar of a form or as the basis for a label for another control).

Applies to

Table, codeunits, fields, forms, reports, dataports, XMLports, labels, command buttons, menu buttons, check boxes, option buttons, text boxes, picture boxes, indicators, frames, menu items

See Also

CaptionML describes the CaptionML property, while a general description of the multilanguage functionality can be found here.


CaptionBar

Use this property to specify the type of caption bar the system displays.

Applies to

Forms

Settings

The CaptionBar settings are:

To use this type of caption bar... | Choose...
Normal | Normal (default)
Narrow | Narrow
No caption bar | None

Comments

The system checks this setting when it opens the form.

Your selection here has no effect on subforms.


CaptionClass

Use this property to control the caption that is used in the label of a field in a database table or in the label of a control on a form.

Comments

The data type of the C/AL expression must be either Text (max length 80) or Code.

Because this property allows you to enter an expression, C/SIDE must be able to differentiate between a literal string like 'DIM1' and a variable or function called DIM1. Every text string that you enter must be enclosed in ' ' or it will be interpreted as a variable or function. Whatever you enter must result in a string. For example, if you want to enter 1 + 5, you must either enter '1+ 5' if that's what you want, or FORMAT(1 + 5) which results in '6'.

The expression is then interpreted by Trigger 15 in CodeUnit 1.

Examples:

C/AL Expression | Comments
DIM1 | This value produces an error unless a text variable exists with the name DIM1.
'DIM1' | OK. The caption class is 'DIM1.'
'DIM'+FORMAT(2) | OK. The caption class is 'DIM2.'
1+5 | Error. The data type is Integer.

More information:

Caption Classes


CaptionML

The CaptionML property is used to provide the text that will be used to identify a control or other object in the user interface. CaptionML is multilanguage enabled. This means that it can contain a list of texts in different languages. The text that is actually used will be selected according to the current language setting of the user. See the general description of the multilanguage features here for more information.

Applies to

Tables, codeunits, fields, forms, reports, dataports, XMLports, labels, command buttons, menu buttons, check boxes, option buttons, text boxes, picture boxes, indicators, frames, menu items

Format

The CaptionML property has this format:

<Language ID>=<caption>

where <Language ID> is a Windows standard three-letter language ID and <caption> is the caption text for this language. Semicolons separate entries.

An example of a CaptionML value:

DAN=Navn;DEU=Name;ESP=Nombre;FRA=Nom

Values are set up for Danish (DAN), German Standard (DEU), Spanish Traditional Sort (ESP) and French Standard (FRA).

How to Enter CaptionML Values

You can enter values for the CaptionML property in two ways:

  1. If you enter a Caption, this value will be inserted in CaptionML as the value for the language that is currently selected. That is, if the language is set to Danish when a value is entered in Caption, CaptionML will be updated with a DAN=<value> string.

  2. When the AssistButton in the CaptionML Value field is clicked, the Multilanguage Editor opens. This is a form with two columns: Language and Value. The Language column is populated with all languages defined by Windows. For your convenience, the names, not the abbreviated names, of the languages are displayed. The CaptionML value for a language is added by entering a value in the Value field for that language. You have to close this form by clicking OK. If it is closed by Esc, the CaptionML field is not updated.

Comments

The following explains how the default caption is determined for the various objects in C/SIDE:

For a ... | The default caption comes from ...
Table | Name property
Field | Name property
Code unit | Name property
Form | Name property
Report | Name property
Dataport | Name property
XMLport | Name property
Command button and menu item | PushAction or Name property
Menu button, indicator, text box, picture box and frame | Name property
Check box | OptionValue or Name property

The scenario for a Label control merits a little more explanation. The Caption property of a Label control is set to the Caption property of the parent control (as specified in the ParentControl property of the Label). When labels are added to a form by a Form Wizard (or by having the Add Label toggle on in the Toolbox when a control is inserted), the ParentControl is set by default. If a Label control does not have a ParentControl, the Name property of the Label control is used as a caption.

When a Label does have a parent control and this parent control is related to a table, C/SIDE will search for a Caption in this way:

  1. The CaptionML of the Label itself.

  2. The CaptionML of the parent control.

  3. The CaptionML of the table field that the parent control relates to.

  4. The Name property of the parent control.

  5. The Name property of the table field that the parent control relates to.

  6. The Name property of the Label itself.

For example, the CaptionML property for a database field with the name "Name" contains

DAN=Navn,DEU=Name,FRA=Nom

You create a text box with a label for this field where the label has the text box as its parent control. You do not set a value for Caption of CaptionML of the label. The label will get the caption "Navn" if the user selects Danish as the language, "Name" for German and "Nom" for French (rule number 3 from above). If you delete the CaptionML values for the database field, the user will see "Name" as the caption of the label no matter what language is selected (rule number 5 from above).

The upshot is that you should not worry about setting the Caption or CaptionML of a Label for a data-bound control. You should set the appropriate CaptionML for the database field, and the rest will be worked out by C/SIDE.

See the general description of the multilanguage features here for more information, including descriptions of what happens if there are no values for the language the user has selected.


CharAllowed

Use this property to set the range of characters you will allow the user to enter into this field or text box.

Applies to

Fields, text boxes

Comments

For example, if you want users to type only uppercase letters in this field, enter AZ. This tells the system to only accept uppercase characters between the range A-Z. If you want both upper- and lowercase characters, leave this field blank.

You can specify multiple ranges of characters by entering the parameters in pairs. For example, admpzz tells the system to accept the following characters: a, b, c, d, m, n, o, p and z.

If you only want to allow a single character, you must enter the parameter twice - a start and an end range.

For text boxes, you can use this property to further limit the characters allowed, based on the field's setting.

The system checks this setting for the text box and for the field during validation.


ClearOnLookup

Use this property to tell the system to delete the current contents of the field before it adds the value the user selects via the lookup.

Applies to

Fields, text boxes

Settings

The ClearOnLookup settings are:

To... | Choose...
Replace the current contents of the field | Yes (default for all fields except FlowFilter fields)
Paste into the current contents of the field | No (default if a FlowFilter field)


ClosingDates

Use this property to tell the system to let the user enter a closing date into this field. The default is No.

Applies to

Fields, text boxes

Comments

All dates have a corresponding closing date. To the system, a closing date is a period following the given date, but before the next normal date. Closing dates are sorted immediately after the corresponding normal date but before the next normal date.

For fields, this property only applies to date fields.

The system checks this setting for the text box and for the field during validation.


Clustered

Use this property to determine whether or not the index is clustered.

Applies to

Keys


Compression

Use this property to specify whether or not a BLOB is compressed.

Applies to

Fields of the BLOB data type.

Comments

Applies only to the Microsoft SQL Server Option for Microsoft Dynamics NAV.

If you want to access BLOB data with an external tool, for example to display a bitmap, you must set the compressed property of the BLOB to No.

The Microsoft Dynamics NAV client and C/Front can both access BLOBs correctly and do not need to use this property.


Data Type

Use this property to specify the data type of a table field.

Applies to

Fields

Comments

You can choose the data type from a drop-down list in the same way as you can choose it in the Table Designer.


DataCaptionExpr

Use this property to enter a C/AL expression that the system will evaluate and display to the left of the caption of the form.

Applies to

Forms

Comments

The system reevaluates the expression each time the user switches from one record to another or when one of the fields in the record changes.


DataCaptionFields

Use this property to select the fields that will appear to the left of the caption on forms that display the contents of this table. For example, in the standard application, the customer name and number appear to the left of the caption on the customer card. For the customer table, those two fields are selected in this property.

Applies to

Tables and forms

Comments

For card forms (forms that show one record at a time), the DataCaptionFields property from the table is used and any setting of the property on the form is ignored. If there is no DataCaptionFields property defined in the table, the primary key is used.

For tabular forms (forms that show a number of records at a time, as in a table box) the rules are these:

A data caption is only displayed when a filter that contains the field(s) that are defined as the value of the DataCaptionFields for the form evaluate to one value. If this is so, two situations are possible:

  1. There is a TableRelation on one or more of the fields. In this case, the DataCaptionFields from the table that is pointed to are used. If this table does not have a value for the DataCaptionFields property, the primary key for that table is used.

  2. There is no TableRelation. In this case, the (single) value that was the result of the evaluation of the filter is used directly.

(A form is considered a tabular form when the TableBoxID property of the form is not blank.)

Example

The easiest way to comprehend what is going on here is perhaps to look at an example. In the standard application, you can find this example:

The Customer Card form (form 21) is based on the Customer table (table 18). By using menu items from Customer menu, the user can open different forms. One is form 21, Cust. Ledger Entry, another is form 22, Customer List (this form is invoked indirectly, as the menu item action is Lookup Table and this form is the lookup table for the Customer table.)

In the Customer table, DataCaptionFields is set to No., Name. On the Cust. Ledger Entry form, DataCaptionFields is set to No.. When the Cust. Ledger Entry form is opened from the Customer Card form, a filter is set on Customer No. field of the Cust. Ledger Entries table, selecting only those entries that pertain to the customer that is currently displayed on the Customer Card (by setting the RunFormLink property of the menu item that invokes the Cust. Ledger Entry form to Customer No.=FIELD(No.).)

This is the situation outlined as situation 1 above, and the number and name of the customer are used as a caption on the (tabular) Cust. Ledger Entry form. To see what happens when no filter is set, try to click Show All. Now, there is no longer a filter on the ledger entries, and, correspondingly, the caption disappears.

Next, open the Customer List form from the Customer menu on the Customer Card. At first, there is no caption, which is to be expected since all customers are shown and no filter is set. Now, try to set a filter on the No. field to restrict the form the show only one customer. As you can see, no caption appears in this situation. This is because no DataCaptionFields are defined for the Customer List form.

The example here obviously does not cover all the possible combinations, but it should give you an idea about how this property is to be used. The important point is that the DataCaptionFields property on a form does not directly put any caption on the form, but only works when used with appropriate settings of DataCaptionFields at table level.


DataItemIndent

This property determines the indentation level of a data item.

Applies to

Data items and reports

Settings

Data indentation levels start from 0 (zero). Data items can be indented ten levels deep, meaning that the largest possible level is 10.

You can only indent a data item one level at a time. In other words, the indentation level of a data item can be no more than one greater than the level of the preceding data item.

Comments

Normally, you will set the indentation level property from the Report Designer, where data items can be indented by clicking a button.

When a report is run, the data items are processed in the following way. The first data item is processed. If there is an indented data item, it will be processed each time a record has been retrieved and processed in the first data item.

This process is recursive; if there is a data item with additional indentations after the second one, this third data item will be processed in the same way as the second one was with regard to the top-level data item, and so on.

You can also indent data items in dataports, but only dataports where the FileFormat property is set to UPXML can be compiled with indented data items.


DataItemLink

Use this property to specify the corresponding fields from two data items that are linked by the DataItemLinkReference property. The link is defined as a property of the indented data item.

Applies to

Data items and reports

Settings

The syntax of the DataItemLink property is:

<field>=FIELD(<reference field>)

<field> | a field from this (the indented) data item
<reference field> | a field from the less indented data item that is pointed to by the setting of the DataItemLinkReference property

Comments

The effect of the DataItemLink property is to set a filter on the indented data item, selecting only those records that contain the same value in the linked field as the corresponding field in the current record from the less indented data item contains.

Normally, you will not enter the value of this property directly. Instead you will use the AssistButton in the Value field to select both fields from lookups into lists of the field names from the two data items that are involved.

Example

Suppose that you have two data items. One (called Customer) is a list of customers, and the other, the indented data item, contains a record for each sales order that has been made. In the customer table, the primary key is the customer number, stored in the No. field. In the table that contains sales data, each record contains this customer number as a foreign key in a field called Sell-to Customer No.

Setting the DataItemLinkReference property of the indented data item to point to the data item that is based on the customer table and setting the value of the DataItemLink property of the indented data item to

Sell-to Customer No.=FIELD(No.)

will put a filter on the records in the indented data item, so that only records that pertain to the current customer record are selected. It corresponds to placing this C/AL statement in the OnPreDataItem trigger of the indented data item:

SETRANGE("Sell-to Customer No.",Customer."No.");


DataItemLinkReference

Use this property to specify the data item on a higher level to which an indented data item will be linked. When you have specified DataItemLinkReference, you must use the DataItemLink property to specify a field from each data item to base the link on.

Applies to

Data items and reports

Settings

The value of the DataItemLinkReference property must be specified as the DataItemVarName of the less indented data item.

The default is the name of the last preceding data item in the report with less indentation (meaning the first data item with less indentation that is met when stepping backwards through the data items of the report).

Comments

Even though you can set DataItemLinkReference and DataItemLink in a data item that is not indented under another data item, this will not have any effect.


DataItemSeparator

Use this property to define the string that is to be used to separate data items.

Applies to

Dataports

Settings

The DataItemSeparator settings are:

This string.. | Means...
<None> | that there will no be DataItemSeparator
<NewLine> | any combination of CR and LF characters
<CR/LF> | CR followed by LF
<CR> | CR alone
<LF> | LF alone
<TAB> | Tabulator alone
Other strings | the literal string entered

The strings in the table above must be entered literally, that is: the < and > characters must be entered. These special strings can be combined, and also be mixed with other characters.

The default is <NewLine><NewLine>.

CR refers to the character with ASCII value 13

LF refers to the character with ASCII value 10


DataItemTable

The value of this property is the name of the database table that a data item is based on.

Applies to

Data items

Comments

This property is set automatically when you use the Report Designer or Dataport Designer to create data items.

If you have two data items based on the same table, you must specify a different name for one of the data items in the DataItemVarName property.


DataItemTableView

Use this property to define the key, sort order and filter for this data item.

Applies to

Data items

Comments

Use the AssistButton to select the key, sorting order and filter you want.

If you select a key, the users of the report or dataport will not be able to select any key, sorting order or filters for that data item.

If you select a sorting order, this sorting order will be suggested as the default if the users of the report or dataport select a sorting order.

If you select a filter, this filter will be used together with the filters that the user specifies in the request form.

Selecting a sorting order or a filter, or both, does not inhibit the user from selecting a key.


DataItemVarName

Use this property to set a name for a data item. This name can be used to refer to a record from the data item (when writing C/AL code in a trigger) or to the data item itself in the DataItemLinkReference property.

Applies to

Data items

Comments

The default is the name of the DataItemTable. There cannot be two data items with the same name in a report or dataport (see also DataItemTable).


DataLength

Use this property to specify the maximum length of the data stored in this field.

Applies to

Fields

Comments

For text and code fields, enter the maximum length of the field. The database only stores the actual content of the field - not the maximum length you specify.

This field does not apply to the other data types since they have fixed lengths.


DataPerCompany

Use this property to tell the system whether or not the data in this table applies to all companies in the database or only to this company.

Applies to

Tables

Settings

The DataPerCompany settings are:

To make the data available... | Choose...
Only to this company | Yes (default)
To all companies in the database | No

Comments

Typically, you will choose the default, Yes. However, there are some cases where you may want to make the data in this table available to all companies in the database. For example, in the standard application, the report list table (which contains a list of all the reports in the application) is marked No.


DateFormula

The system uses this property to verify that the date the user enters is correct, based on the date formula you enter here.

Applies to

Fields, text boxes

Settings

Enter the date formula. Here is a summary of the syntax you must use:

This entry... | Means...
30D | 30 days
2W | 2 weeks
CM+10D | Current month plus 10 days
CM+1M | Current month plus one month
CQ+1M+20D | Current quarter plus one month plus 20 days
CW+1W | Current week plus one week
D15 | On the 15th of each month

The system considers a week to begin on Monday and end on Sunday.

Comments

For fields, this property only applies to text and code fields.

The system checks this setting for the text box and for the field during validation.

It is recommended that you no longer use this property. DATEFORMULA is now a data type.


DecimalPlaces

Use this attribute to tell the system how to display decimal numbers if you want a format other than the default, which is two decimal places (for amounts).

Applies to

Fields, text boxes

Settings

You can enter a minimum and maximum value for the number of decimal places. For example...

If you enter... | The system interprets this as ...
1 | A minimum of 1 and a maximum of 1 decimal place
1:4 | A minimum of 1 and a maximum of 4 decimal places
2: | At least 2 decimal places
:2 | No more than 2 decimal places

Comments

If the setting for the field is greater than the setting for the text box (it cannot be less), the system uses the setting for the text box to determine how to round the number.

For decimal fields, use this setting to specify the number of decimal places you want the system to store.

For text boxes, you can use this property to limit the number of decimal places that appear, based on the setting for the field. You cannot increase the number of decimal places beyond what is set up for the field.

For text boxes, you can change this property setting at runtime using C/AL code.

The system checks this setting for the text box and for the field during validation.


Default

Use this property to tell the system that this command button is the default command button. When a command button is chosen as the default, the system selects it when the user presses Enter or double clicks the mouse. Please note that focus need not be on the button.

Applies to

Command buttons

Settings

The Default settings are:

If you want this command button to... | Choose...
Be the default | Yes
Not be the default | No (default)

Comments

This only applies to the first command the system receives after the user opens the form. When the user presses Enter or Esc, the system first checks to see if there is a specified response. It only executes the default and cancel properties if there is not.

See also Cancel.


DefaultFieldsValidation

Use this property to tell the system whether to validate fields.

Applies to

XMLports

Settings

The DefaultFieldsValidation settings are:

To have the system... | Select...
Validate the fields | Yes (default)
Not validate the fields | No

Comments

This property sets the default value for the XMLport field property FieldValidate. Therefore, if you change the setting of the DefaultFieldsValidation property, the change is implemented for all fields. However, for fields for which the FieldValidate property has been set to Yes or No, no change will be made.

If you change the value of the FieldValidate property, the change does not affect the value of the DefaultFieldsValidation property. This means that FieldValidate can override DefaultFieldsValidation, but that it can also inherit the default value of DefaultFieldsValidation.


DelayedInsert

Use this property to have the system wait until the user leaves the record before it inserts the new record into the database. By default, the system inserts the new record when the user leaves the control that shows the primary key in the table.

Applies to

Forms

Settings

The DelayedInsert settings are:

To have the system insert the record when the user... | Choose...
Leaves the record | Yes
Leaves the control that shows the primary key | No (default)


DeleteAllowed

Use this property to tell the system whether to let users delete records while using this form.

Applies to

Forms

Settings

The DeleteAllowed settings are:

To... | Choose...
Let users delete records | Yes (default)
Prevent users from deleting records | No


Description

Use this property to include an optional description of the table, field, form, report or control. This description is for internal purposes only and does not appear to the end user.

Applies to

Tables, fields, forms, reports, labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms, menu items


DeviceFontName

Use this property for reports that are designed specifically for dot matrix printers to prevent the printer from switching into graphics mode when printing text. Specify the name of a device font (a font that is built into a printer).

Applies to

Reports

Comments

Use the AssistButton to select a device font from the list of device fonts supported by a particular printer.

If the printer that is used for this report does not support the specified DeviceFontName or if DeviceFontName is left as <Undefined>, Helvetica will be used.

A device font specified in the page setup dialog will override DeviceFontName.


Dimensions

Use this property to enter the dimensions of a variable, that is to create a multi-dimensional variable - an array.

Applies to

Variables

Settings

Enter the dimensions as a semicolon-separated list of integers, where each number defines the number of elements in that dimension. The maximum number of dimensions is 10 and the total number of elements in all dimensions is 1,000,000.

Example

To define an integer array with dimensions 3 x 3 x 4, start by creating an integer variable (for example called A.) Then, in the property sheet, set the Dimensions property to 3;3;4.

To access the elements in the array, use a syntax like this:

A[2][3][2]

Note that indexing starts from 1 (not 0 as in some programming languages).


Direction

Use this property to specify whether the XMLport can import, export or import and export data in XML format.

Applies to

XMLports

Settings

To... | Select...
Import | Import
Export | Export
Import and Export | Both (default)


Divisor

Sometimes it is useful to display a number as, for example, thousands. The value of this property is the figure by which to divide numbers for this purpose. If you enter 1000, 13,000 would be displayed as 13 (but only displayed: the data in the database would not be changed).

Applies to

Text boxes

Comments

The default is undefined, which means that numbers will be displayed as is.


DrillDown

Use this property to provide a drill-down for a text box.

Applies to

Text boxes

Settings

The DrillDown settings are:

To provide... | Choose...
A drill-down for the text box | Yes
No drill-down | No (default)

Comments

Drill-downs are a system-wide feature of FlowField which let you see the underlying transactions that make up the information shown in the FlowField. For instance, if the FlowField shows an account balance, providing a drill-down for this text box lets the user quickly see the various transactions that make up the balance shown in the field.

See also OnDrillDown.


DrillDownFormID

Use this property to enter the ID of the form you want to use as a drill-down.

Applies to

Tables, text boxes

Comments

Drill-downs are a system-wide feature of FlowField which let you see the underlying transactions that make up the information shown in the FlowField.

For text boxes, the default is the form defined in the DrillDownFormID property for the table.


DropDown

Use this property to provide a drop-down menu for a text box. The drop-down menu shows the user a list of the available options.

Applies to

Text boxes

Settings

The DropDown settings are:

To provide... | Choose...
A drop-down menu for the text box | Yes
No drop-down menu | No (default)

Comments

For option fields, you define the list of options using the OptionString property.


Editable

Use this property to determine whether a field, form or control can be edited.

Applies to

Fields, forms, check boxes, option buttons, text boxes, matrix boxes, frames, tab controls, table boxes, subforms, menu items.

Settings

The Editable settings are:

To... | Choose...
Allow the field, form or control to be edited | Yes (default)
Prevent the field, form or control from being edited | No

Comments

For fields, use this property to make a field for display only.

For controls, if the Editable setting for the container that contains this control is set to No, that setting overrides what you enter here.

If a form has Editable set to No, then the controls on the form will not be editable, even if their (individual) Editable properties are set to Yes.

This property can be set dynamically by using the UPDATEEDITABLE function in the OnBeforeInput trigger of the control.


Ellipsis

Use this property to append an ellipsis (...) to the caption on a command button or menu item. An ellipsis tells the user that other choices will appear if he or she selects the command button or menu item.

Applies to

Command buttons, menu items

Settings

The Ellipsis settings are:

To have the system... | Choose...
Append an ellipsis (...) | Yes
Omit the ellipsis | No (default)


Enabled

Use this property to activate or inactivate a field or key. For controls, use this property to determine whether a control can respond to user-generated events.

Applies to

Keys, fields, command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms, menu items

Settings

The Enabled settings are:

To... | Select...
Enable the field, key, or control | Yes (default)
Disable the field, key, or control | No

Comments

For keys, this property tells the system whether or not it should maintain the key in the database. If you are not using the key or if you seldom use the key, you may want to mark it as disabled for performance reasons. When you need to use the key you can always change the setting.

For fields, this property tells the system whether or not you will store data in the field. If the field is unused, you should disable it to conserve database space. In a dataport, a disabled field is read from the external file on import, but it is not inserted in the database.

For controls, keep in mind that the Enabled setting for the container that contains this control overrides what you enter here.

The system automatically grays menu items, buttons, and labels for text boxes when they are disabled.

For controls, this property can be set dynamically by using the EDITABLE function.


Encoding

Use this property to specify which system the XMLport should apply or support for character encoding.

Applies to

XMLports

Settings

The two options available for this property, UTF8 and UTF16, are the two most commonly used encoding systems. UTF8 is the default setting.

Comments

Information about the encoding system that is used is inserted into the header of the XML document. For example, <? XML version = 1.0 encoding=utf8 ?>.


Field No.

Use this property to assign a unique numeric ID to this field.

Applies to

Fields

Settings

No two fields can have the same Field No. within a table.

Comments

As opposed to other development tools, the system uses the Field No. for reference purposes. So you can use the Name in your code, the system automatically converts the Name to the Field No. when you compile your C/AL code.

Normally, Field No.'s are assigned automatically by the Table Designer when you add fields to a table during design.


FieldClass

Use this property to specify the class of the field. There are three classes of fields in Microsoft Dynamics NAV: Normal, FlowField and FlowFilter.

Applies to

Fields

Settings

The FieldClass settings are:

If you will use the field... | Choose...
As a normal data entry field | Normal
To compute the results of FlowFields | FlowFilter
As a calculated field | FlowField


FieldEndDelimiter

Use this property to define the string that is to be used to mark the end of a field.

Applies to

Dataports

Settings

The FieldEndDelimiter settings are:

This string.. | Means...
<None> | that there will no be FieldEndDelimiter
<NewLine> | any combination of CR and LF characters
<CR/LF> | CR followed by LF
<CR> | CR alone
<LF> | LF alone
<TAB> | Tabulator alone
Other strings | the literal string entered

The strings in the table above must be entered literally, that is: the < and > characters must be entered. These special strings can be combined, and also be mixed with other characters.

The default is " (a quote).

CR refers to the character with ASCII value 13

LF refers to the character with ASCII value 10

Comments

FieldEndDelimiter is only used if FileFormat is Variable. Otherwise, the setting is ignored.

The string defined as FieldEndDelimiter is used in addition to the string defined as FieldSeparator. The intended use is in situations where the fields include characters that themselves are delimiters. If it is not necessary to use FieldEndDelimiter for this purpose, set it to <None>.

When importing, the delimiters can be present in the file or not. A line like this

a,"b",c,"text with comma,",d

would (if FieldStartDelimiter and FieldEndDelimiter is " and FieldSeparator is ,) be broken into fields like this

a

b

c

text with comma,

d

See also FieldStartDelimiter.


FieldSeparator

Use this property to define the string that is to be used to separate fields.

Applies to

Dataports

Settings

The FieldSeparator settings are:

This string.. | Means...
<None> | that there will no be FieldSeparator
<NewLine> | any combination of CR and LF characters
<CR/LF> | CR followed by LF
<CR> | CR alone
<LF> | LF alone
<TAB> | Tabulator alone
Other strings | the literal string entered

The strings in the table above must be entered literally, that is: the < and > characters must be entered. These special strings can be combined and can also be mixed with other characters.

The default is , (a comma).

CR refers to the character with ASCII value 13

LF refers to the character with ASCII value 10

Comments

FieldSeparator is only used if FileFormat is Variable. Otherwise, the setting is ignored.

See also FieldEndDelimiter and FieldStartDelimiter.


FieldStartDelimiter

Use this property to define the string that is to be used to mark the start of a field.

Applies to

Dataports

Settings

The FieldStartDelimiter settings are:

This string.. | Means...
<None> | that there will no be FieldStartDelimiter
<NewLine> | any combination of CR and LF characters
<CR/LF> | CR followed by LF
<CR> | CR alone
<LF> | LF alone
<TAB> | Tabulator alone
Other strings | the literal string entered

The strings in the table above must be entered literally, that is: the < and > characters must be entered. These special strings can be combined, and also be mixed with other characters.

The default is " (a quote).

CR refers to the character with ASCII value 13

LF refers to the character with ASCII value 10

Comments

FieldStartDelimiter is only used if FileFormat is Variable. Otherwise, the setting is ignored.

The string defined as FieldStartDelimiter is used in addition to the string defined as FieldSeparator. The intended use is in situations where the fields include characters that themselves are delimiters. If it is not necessary to use FieldStartDelimiter for this purpose, set it to <None>.

When importing, the delimiters can be present in the file or not. A line like this

a,"b",c,"text with comma,",d

would (if FieldStartDelimiter and FieldEndDelimiter is " and FieldSeparator is ,) be broken into fields like this

a

b

c

text with comma,

d

See also FieldEndDelimiter.


FieldValidate

Use this property to specify whether or not the values in the source field should be validated by the OnValidate trigger for the field.

Applies to

XMLports

Settings

To have the system... | Select...
Validate the fields | Yes
Not validate the fields | No

Undefined is the default value.

Comments

This property only applies to fields and works in combination with the DefaultFieldsValidation XMLport property.

The DefaultFieldsValidation property sets the value for the XMLport field property FieldValidate. Therefore, if you change the setting of the DefaultFieldsValidation property, the change is implemented for all the fields. However, if the FieldValidate property of a field is set to Yes or No, no change will be made to this field.

If you change the value of the FieldValidate property, the change does not affect the value of the DefaultFieldsValidation property. This means that FieldValidate can override DefaultFieldsValidation, but that it can also inherit the default value of DefaultFieldsValidation.


FileFormat

Use this property to set the format of the file a dataport reads from or writes to.

Applies to

Dataports

Settings

When the FileFormat settings are intended:

To... | Choose...
Read/write in a variable length format | Variable (default)
Read/write in a fixed length format | Fixed

Comments

If FileFormat is set to variable, you must also set the FieldEndDelimiter, FieldStartDelimiter and FieldSeparator properties in order to define how fields should be separated.

If FileFormat is set to Fixed, these three properties are ignored, and the StartPos and Width properties must be set in order to define the placement of the fields in the imported line.


FileName

Use this property to set the name of the external file to read data from or write data to in a dataport.

Applies to

Dataports

Settings

FileName must be set to a filename that is valid in the operating system. If not, a run-time error will occur.

Comments

This property can be set dynamically by using the FILENAME function. In this way - and in combination with the Import property - you can create dataports that dynamic: it can be determined at run time whether data should be inputted or outputted, and the name of the external file to read from or write to can be set.

If FileName is left blank, a default request options form tab will be created, where this property can be set at run time. If no name is specified or the UseReqForm property is set to No, a run-time occur will occur.


Focusable

Use this property to determine whether a control can gain focus.

Applies to

Command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms, menu items

Settings

The Focusable settings are:

If the setting is... | It means the control can...
Yes (default) | Receive focus
No | Not receive focus

Comments

If the Focusable setting for the container that contains this control is set to No, that setting overrides what you enter here.

See also FocusOnClick and Cancel.


FocusOnClick

Use this control to allow the user to put focus on this control by clicking the mouse or by using the designated access key.

Applies to

Command buttons, menu buttons, check boxes, option buttons

Settings

The FocusOnClick settings are:

If you want to... | Choose...
Let the user place focus on this control by clicking or using the access key | Yes (default for check boxes and option buttons)
Prevent the user from placing focus on this control by clicking or using the access key | No (default for command buttons and menu buttons)

Comments

For example, if you were creating a form that lists sales orders and you added a command button to let the user post all selected orders, you would select No for the FocusOnClick property for the command button. Otherwise, when the user clicked the command button, the system would remove the focus from the selected orders, and there would be nothing to post.

With the exception of command buttons, menu buttons, check boxes and option buttons, focusable controls always receive focus when you click on them.

See also Focusable.


FontBold

Use this property to display text in bold.

Applies to

Labels, images, command buttons, menu buttons, check boxes, option buttons, frames, tab controls and text boxes.

Settings

The FontBold settings are:

To display the text in... | Choose...
Boldface | Yes
Normal or regular type | No (default)

Comments

For text boxes, the setting of this property can be changed dynamically by using the UPDATEFONTBOLD function in the OnFormat trigger.

See also FontSize, FontName, FontItalic, FontStrikethru, and FontUnderline.


FontItalic

Use this property to display text in italics.

Applies to

Labels, images, command buttons, menu buttons, check boxes, option buttons, frames, tab controls

Settings

The FontItalic settings are:

To display the text in... | Choose...
Italics | Yes
Normal or regular type | No (default)

Comments

See also FontSize, FontBold, FontName, FontStrikethru, FontUnderline.


FontName

Use this property to select the font the system displays.

Applies to

Labels, images, command buttons, menu buttons, check boxes, option buttons, frames, tab controls

Comments

FontName is a string that contains the name of the typeface you want to use. The default font used by the system is MS Sans Serif.

See also FontSize, FontBold, FontItalic, FontStrikethru, FontUnderline.


FontSize

Use this property to choose the point size of the font the system displays.

Applies to

Labels, images, command buttons, menu buttons, check boxes, option buttons, frames, tab controls

Comments

FontSize is an integer that specifies the font size in points. The default font size is 8pt.

See also FontName, FontBold, FontItalic, FontStrikethru, FontUnderline.


FontStrikethru

Use this property to cross out (strike through) the text, like this.

Applies to

Labels, images, command buttons, menu buttons, check boxes, option buttons, frames, tab controls

Settings

The FontStrikethru settings are:

To display the text... | Choose...
With strikethru | Yes
Without strikethru (as normal text) | No (default)

Comments

See also FontSize, FontBold, FontItalic, FontName, FontUnderline.


FontUnderline

Use this property to place a single underline beneath text.

Applies to

Labels, images, command buttons, menu buttons, check boxes, option buttons, frames, tab controls

Settings

The FontUnderline settings are:

To display the text... | Choose...
With underlines | Yes
Without underlines (as normal text) | No (default)

Comments

See also FontSize, FontBold, FontItalic, FontName, and FontStrikethru.


ForeColor

Use this property to determine the foreground color of the control.

Applies to

Labels, images, command buttons, menu buttons, check boxes option boxes, text boxes, indicators, frames, tab controls

Comments

Use the Color option on the View menu to pick a color or enter the RGB value of color you want for the foreground. The default is the system foreground color.

See also BackColor and BackTransparent.


Format

Use this property to define how the system formats the source expression for various data types.

Applies to

Text boxes, dataport fields

Comments

The Format property can be set to a predefined format, or you can build a format of your own. See also the FORMAT function.

Basic Settings

To choose a predefined format, use the syntax: <Standard Format,X>, where X is one of the entries in the Select... column of the following table:

To use this format... | Select...
Standard Display Format (the default for all data types) | 0
Standard Display Format 2 (edit) | 1
C/AL Code Constant Format | 2

Note you must enter the brackets < and >, as in <Standard Format,2>.

For a list of the predefined formats that are available, read the rest of this Help topic.

Building Formats

The Format property also lets you create your own formats. To create a format, use the syntax described below and keep the following rules in mind:

  • A format property consists of zero or more Chars, Fields or Attributes.

  • Fields and Attributes are expressed with an identifier inside brackets (<>).

  • Attributes must contain a comma (,) and a parameter after the identifier.

  • Fields can optionally take a comma (,) and a FieldLen.

The precise syntax is:

FormatProperty := | [<Char> | <Field> | <Attribute>]
<Char> := | character with ASCII value [32..255]
<Field> := | '<' <FieldName> [',' <FieldLen>] '>' [, <Attribute>]
<FieldName> := | literal name of field (format component)
<FieldLen> := | length of field (0 or no entry means that the length is dynamic)
<Attribute> := | ['<' <AttributeName> ',' <Char> '>']
<AttributeName> := | [Standard Format | Filler | 1000Character | Comma | Overflow | Filler Character | Precision]

Note

In the following table a full stop is used as the decimal symbol. Filler and Filler Character both mean the character that is used to fill empty spaces.

The FieldName is a "component" that you can use to build a format expression. Depending on the data type of the text box or dataport field, FieldName can be chosen from this list:

Data Type | FieldNames
Decimal | Sign, Integer, Decimals, Integer Thousand
Date | Day, Month, Month Text, Quarter, Year, Year4, Week, Week Year,Week Year4, Weekday, Weekday Text, Closing
Time | Hours24, Hours12, Minutes, Seconds, Thousands, AM/PM, Second dec
DateTime | Day, Month, Month Text, Quarter, Year, Year4, Week, Week Year, Week Year4, Weekday, Weekday Text, Hours24, Hours12, Minutes, Seconds, Thousands, AM/PM, Second dec
Integer & BigInteger | Sign, Integer, Integer Thousand
Boolean | Text, Number
Option | Text, Number
Code | Text
Char | Char/Number, Char, Number
Text | Text

Example

Here are some examples of how to use the Format property:

  1. Choosing a standard format:

Use the Standard Format attribute to select one of the standard formats (these are listed at the end of this Help topic).

For example, <Standard Format,5> will select Standard Format 5.

  2. Using a standard format with an attribute:

<Precision,2:3><Standard Format,0> will use Standard Format 0 and will format the data with a minimum of 2 and a maximum of 3 decimal places. See also the DecimalPlaces property. If you do not specify any precision the form will use the precision specified in the Decimal Places property of the corresponding field in the table.

  3. Building a Format

You can create your own formats by using Chars (which will be displayed literally), Fields (to choose specific components of a value, for example the year-part of a date) and Attributes (for example to select which character to use as a filler).

For example, a text box based on a source expression of the Date data type, that uses the following format string:

<Weekday Text>, <Month Text> <Day>

will display the date as: Monday, April 15

In the following list of predefined formats, you can see many examples of how to build formats.

You must remember that the settings that are specified under the Regional and Language Options in Windows determine how a number of the separators are displayed. This applies to the time and decimal separators among others.

The Standard Formats

The following tables list the predefined formats for each data type:

Decimal | Format | Example
<Sign><Integer Thousand><Decimals> | 0 | -76,543.21
<Sign><Integer><Decimals> | 1 | -76543.21
<Sign><Integer><Decimals> | 2 | -76543.21
<Integer Thousand><Decimals><Sign,1> | 3 | 76,543.21-
<Integer><Decimals><Sign,1> | 4 | 76543.21-
XML format | 9 | -76543.21
For Dates, the Regional and Language Options in Windows is used to select the actual format that is used. The table below shows the Fields that will be used to build the various formats. This table, incidentally, corresponds to the Regional setting for a European country/region.
Date | Format | Example
<Closing><Day,2>-<Month,2>-<Year> | 0 | 05-04-03
<Closing><Day,2>-<Month,2>-<Year> | 1 | 05-04-03
<Day,2><Month,2><Year><Closing>D | 2 | 050403D
<Closing><Year>-<Month,2>-<Day,2> | 3 | 03-04-05
<Closing><Day>. <Month Text> <Year4> | 4 | 5. April 2003
<Closing><Day,2><Month,2><Year> | 5 | 050403
<Closing><Year><Month,2><Day,2> | 6 | 030405
<Day,2><Filler Character, >. <Month Text,3> <Year4> | 7 | 5. Apr 2003
XML format | 9 | 2003-04-05
The following table shows how these formats will change if the Regional and Language Options is set to "United States."
US Date | Format | Example
<Closing><Month,2>/<Day,2>/<Year> | 0 | 04/05/03
<Closing><Month,2>/<Day,2>/<Year> | 1 | 04/05/03
<Month,2><Day,2><Year><Closing>D | 2 | 040503D
<Closing><Year>/<Month,2>/<Day,2> | 3 | 03/04/05
<Month Text> <Closing><Day>, <Year4> | 4 | April 5, 2003
<Closing><Month,2><Day,2><Year> | 5 | 040503
<Closing><Year><Month,2><Day,2> | 6 | 030405
<Day,2><Filler Character, >. <Month Text,3> <Year4> | 7 | 5. Apr 2003
XML format | 9 | 2003-04-05
For Times, the Regional and Language Options in Windows are used to select the actual format used. The table below shows the Fields that will be used to build the various formats. This table, incidentally, corresponds to the Regional setting for a European country/region.
Time | Format | Example
<Hours24>.<Minutes,2>.<Seconds,2> | 0 | 4.35.55
<Hours24>.<Minutes,2>.<Seconds,2><Second dec.> | 1 | 4.35.55.553
<Hours24,2><Filler Character,0><Minutes,2><Seconds,2> <Second dec.><Comma,.>T | 2 | 043555.553T
XML format | 9 | 04.35.55.553Z
The next table shows how these time formats will appear if the Regional setting is changed to "United States."
US Time | Format | Example
<Hours12>:<Minutes,2>:<Seconds,2><Second dec.> <AM/PM> | 0 | 4:35:55 AM
<Hours12>:<Minutes,2>:<Seconds,2><Second dec.> <AM/PM> | 1 | 4:35:55.553 AM
<Hours24,2><Filler Character,0><Minutes,2><Seconds,2> <Second dec.><Comma,.>T | 2 | 043555 .553T
XML format | 9 | 04:35:55.553Z
The following table shows the fields that have been used to define the standard formats for DateTime. Note that the date, time and decimal separators that are displayed are determined by the Regional and Language Options that have been selected on your computer.
DateTime | Format | Example
<Day,2>-<Month,2>-<Year> <Hours24>.<Minutes,2> | 0 | 05-04-03 4.35
<Day,2>-<Month,2>-<Year> <Hours24>.<Minutes,2>.<Seconds,2><Second dec> | 1 | 05-04-03 4.35.55.553
<Day,2>-<Month,2>-<Year> <Hours24>.<Minutes,2> | 2 | 05-04-03 4.35
<Day,2>-<Month,2>-<Year> <Hours24>.<Minutes,2>.<Seconds,2> | 3 | 05-04-03 4.35.55
XML format | 9 | 2003-04-05T03:35:55.553Z
US DateTime | Format | Example
<Month,2>/<Day,2>/<Year> <Hours24,2>:<Minutes,2> <AM/PM> | 0 | 04/05/03 04:35 AM
<Month,2>/<Day,2>/<Year> <Hours24,2>:<Minutes,2>:<Seconds,2><Second dec> <AM/PM> | 1 | 04/05/03 04:35:55.553 AM
<Month,2>/<Day,2>/<Year> <Hours24,2>:<Minutes,2> <AM/PM> | 2 | 04/05/03 04:35 AM
<Month,2>/<Day,2>/<Year> <Hours24,2>:<Minutes,2>:<Seconds,2> <AM/PM> | 3 | 04/05/03 04:35:55 AM
XML format | 9 | 2003-04-05T03:35:55.553Z
Integer & BigInteger | Format | Example
<Sign><Integer> | 0 | -567
<Sign><Integer> | 1 | -567
<Sign><Integer> | 2 | -567
XML format | 9 | -567
Boolean | Format | Example
<Text> | 0 | Yes/No
<Text> | 1 | Yes/No
<Number> | 2 | 1/0
XML format | 9 | true/false
Option | Format | Example
<Text> | 0 | Blue
<Text> | 1 | Blue
<Number> | 2 | 1
XML format | 9 | 1

Standard format 9 is used to display the data in the standard XML formats.

For Chars, all formats are: <Char/Number>.

For Text and Code, all formats are: <Text>.


Format/Evaluate

Use this property to specify whether the system should format and evaluate the data that is being imported or exported as XML data types or as the standard C/SIDE data types.

Applies to

XMLports

Settings

C/SIDE Format/Evaluate (default)

XML Format/Evaluate

Comments

Importing

If the XML document that you want to import contains data that corresponds to the standard C/SIDE data types, you should select C/SIDE Format/Evaluate (default value). The data will then be evaluated before being inserted into the database.

On the other hand, if the XML document that you want to import contains data that uses the standard XML data types, you must use the XML Format/Evaluate setting. This will ensure that the data is evaluated and converted to the C/SIDE data types before being inserted into the database.

However, if the data that you want to import does not follow either the Standard C/SIDE formats or the XML formats, you must import the data into a temporary table in text format. You can then use C/AL code to convert the data before inserting it into the database.

Exporting

If you want to export data which uses the standard C/SIDE data types to an XML document and use these data types in the XML document, you should select C/SIDE Format/Evaluate (default value). The data from the database will then be formatted according to the standard rules for C/SIDE data types.

If you want to export data in the standard XML formats to an XML document, you should use the XML Format/Evaluate setting. This will ensure that the data you are exporting from the database is formatted and exported in the standard XML formats.

The following XML Data types require evaluation:

XML Data Type | Microsoft Dynamics NAV Data Type
decimal float double | Decimal
boolean | Boolean
datetime | DateTime
time | Time
date | Date
integer | Integer
duration | Duration

This is an XMLport property and therefore applies to all the data that is being streamed. It cannot be applied to specific fields only.

For more information about formatting C/SIDE data types, see Format. For more information about evaluating variables, see EVALUATE (Variable). For more information about using temporary tables, see Temporary (XMLports).


GroupTotalFields

Use this property to specify those fields of a data item that should be used to group records. The GroupTotalFields and the TotalFields properties can be used in conjunction to maintain totals for one or more fields, and both the group totals and the grand totals can be output by using the appropriate sections.

Applies to

Data items

Settings

A comma-separated list of field names. The fields can be selected by using the assist-edit function in the Value field of this property.

Any field in the list must be a field in the active key of the underlying table. If it is not, the system will not run the report.

Comments

When records are retrieved, they will be grouped by the contents of the fields that are defined as the GroupTotalFields. If there is more than one field in the list, the groups will be nested. This means that there will be a group composed of records that have the same contents in the first field indicated. Inside of this group, records will be grouped according to the contents of the second field in the list, and so forth.

When using GroupTotalFields, you must be aware of the relationship to the currently active key of the underlying table. See the example below.

The GroupHeader section will be output before a new group is begun, and the GroupFooter section after all records in a group have been processed. At this time, the fields designated as TotalFields will contain group totals for the group that was last processed. The group totals are printed by placing controls that have these fields as their source expressions in the GroupFooter section.

The TOTALSCAUSEDBY C/AL function can be used to determine which field changed contents, and thus which group has been finished. Using this function can be necessary if you have defined more than one field in GroupTotalFields and it has to be decided whether to output a GroupHeader or GroupFooter section or not.

The fact that the functionality of GroupTotalFields is closely connected with the active key demands that some precautions be taken.

Example

Suppose that these two fields are listed as GroupTotalFields:

No.,City

while the active key consists of these three fields:

No.,Name,City

If the contents of the Name field change as the records are processed, the grouping that was supposed to take place, based on the City field, will fail.

Therefore, it may be necessary to deprive the user of the possibility of choosing a key from the request form of the report, as the grouping will only work with the one key that it was designed for. You can remove the request form altogether by using the UseReqForm, or, less drastically, remove the Sort... button by using the DataItemTableView property to set an explicit sorting order (key) for the data item.


HeadingHeight

Use this property to determine the height of the column headings in a table box.

Applies to

Table boxes, matrix boxes

Comments

Enter zero (0) if you do not want a heading.

Specify the height in increments of 1/100 millimeter.


Height

Use this property to define the height of the control. The system shows you the height in increments of 1/100 of a millimeter.

Applies to

Forms, labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms

Comments

Typically, you will click on the form or control to select it and then use the mouse to size it. You can also enter an exact measurement if you like.

If you use the wizard, the system sizes the form and controls for you. You can change the height as necessary.

For forms, changing the height of the form here has no effect on any subforms. You can change the setting of this property dynamically by using the HEIGHT function.

For controls, the system ignores this property setting for a control that is contained within a table box.

See also Width, HorzGrid and VertGrid.


HorzAlign

Use this property to determine how the system horizontally aligns the data or the caption of the control.

Applies to

Labels, command buttons, menu buttons, check boxes, option buttons, text boxes

Settings

The HorzAlign property settings are:

To align the data... | Select...
On the left | Left
On the right | Right
In the center | Center
To the right if numeric, otherwise to the left | General (default)

Comments

If you choose right or center, the system truncates the rightmost part of the text as necessary.

See also VertAlign.


HorzGlue

Use this property to tell the system how to anchor this control horizontally. You can anchor it to the left, right, or left and right of the form or subform.

Applies to

Labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, matrix boxes, text boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms

Settings

The HorzGlue settings are:

To anchor the control... | Select...
On the left | Left (default)
On the right | Right
On the left and right | Both

Comments

If you select Both, the system resizes the control when the user resizes the window.

If this control is contained in a table box, the system ignores the setting for this control.

If the control is used as a column of a table box and you set the HorzGlue property to Both, the system will resize the column accordingly when the user resizes the frame.

If you set this property to Both for several columns in a table box, the system applies the setting to the leftmost column.

The HorzGlue and VertGlue properties are not active during design, except for the HorzGlue on columns.

See also VertGlue.


HorzGrid

Use this property to set the distance between horizontal grid lines in the form and section designers. The grid is shown as one dot per five grid distances.

Applies to

Forms, reports (sections)

Settings

The HorzGrid settings are:

To have the system... | Enter...
Use the default setting | default (1.1 millimeter)
Display no horizontal grid | infinite
Display a custom grid you define | (the number; 0 means no grid)

The unit of measure is 1/100 mm.

Comments

Enter zero (0) or infinite if you do not want the system to display a horizontal grid.

See also VertGrid.


ID

Use this property to assign a unique numeric ID to this codeunit, table, form, report, dataport, XMLport or control.

Applies to

Codeunits, tables, forms, reports, dataports, XMLports, labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms and menu items.

Settings

The ID you assign must be unique within the scope of the object. For example, two codeunits, tables, or forms cannot have the same ID, and no control can have the same ID as another control on that form.

Comments

As opposed to other development tools, the system uses the ID for reference purposes. So that you can use the Name in your code, the system automatically converts the Name to the ID when you compile your C/AL code.

If you do not set the ID property, you will be prompted for one when you try to save the object.

For controls, the system assigns a numeric ID for you, based on the next available number for the form or the report. You can change this ID if you need to.


Import

Use this property to determine whether the dataport imports or exports data.

Applies to

Dataports

Settings

The Import settings are:

To... | Choose...
Import data to a C/SIDE table | Yes (default)
Export data to an external file | No

Comments

This property can be set dynamically by using the IMPORT function. In this way - and in combination with the FileName property - you can create dataports that are dynamic: it can be determined at runtime whether data should be inputted or outputted, and the name of the external file to read from or write to can be set.

Import can only be set dynamically in the OnPreDataPort trigger.

If Import is left blank, a default request options form tab will be created, where this property can be set at runtime.


InColumn

Use this property when the parent is a data container and control fills a column.

Applies to

Check boxes, option buttons, text boxes, picture boxes, indicators

Comments

There is no default setting for this property.

Normally the system will set this property for you when you create a data control inside a table box.

See also InColumnHeading.


InColumnHeading

Use this property when the parent is a data container, when InColumn is set to Yes, and when the control fills the heading of the column.

Applies to

Labels, images, shapes

Comments

There is no default setting.

Normally the system will set this property for you when you create a static control inside a table box.


Indent

Use this property to indent text from the left margin.

Applies to

Text boxes

Comments

You can only set indention from the OnFormat trigger by using the UPDATEINDENT function.

The unit of measure is 1/100 mm.


Indentation

Use this property to set the indentation level of an element or an attribute in the XMLport Designer.

Applies to

XMLports

Comments

In the XMLport Designer, you specify the names of elements and their attributes in the Tag Name field.

When you are determining the indentation level of an element or an attribute, remember that:

  • You must list the elements and their attributes in the order in which they appear in the XML document.

  • You must list child elements and attributes under the parent element that they define.

  • You can only indent each child one level more than its parent.

  • The first element is the only one that can have indentation 0.

  • The indentation level that you set in the Properties window corresponds directly to the indentation level you can set in the XMLport Designer. You can also use the buttons in the XMLport Designer to change the indentation level of an element or an attribute.


InFrame

Use this property when the parent is a frame and control is located inside the frame.

Applies to

Labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms, menu items

Comments

There is no default setting.

Normally the system will set this property for you when you create a control inside a frame.


InitValue

Use this property to specify the initial value the system should supply for this field each time the user creates a new record.

Applies to

Fields

Comments

This attribute is only important if you create the record in a window or using the C/AL functions INIT, CLEAR or CLEARALL. For example, this attribute is commonly used in boolean fields when you want either Yes or No to be the default.


InlineEditing

Use this property to require the user to click in the table box or press F2 to begin editing the text inside the table box.

Applies to

Table boxes, matrix boxes

Settings

The InlineEditing settings are:

If you want the user to... | Choose...
Click or press F2 to begin editing | Yes
Not have to click or press F2 to begin editing | No (default)

Comments

The effect of setting this property to Yes is that by default, no editing will be allowed when the form is opened. The user must click on an active editable control, press F2 when an editable control is in focus, or choose to insert a new record to begin editing.

The setting of this property can be changed dynamically by using the INLINEEDITING function.


InMatrix

Use this property when the parent is a matrix box and the control fills the matrix part of a matrix box.

Applies to

Check boxes, option buttons, text boxes, picture boxes, indicators

Settings

There is no default setting for this property.

Normally the system will set this property for you when you create a data control inside a matrix box.

Comments

See also InMatrixHeading.


InMatrixHeading

Use this property to place the control in the heading of the matrix when the parent is a matrix box and InMatrix is set to Yes.

Applies to

Labels, images, shapes

Settings

There is no default setting.

Normally the system will set this property for you when you create a static control inside a matrix box.


InPage

Use this property when the parent property is a tab control and you want to specify the page the control appears on.

Applies to

Labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms, menu items

Comments

There is no default setting.

Normally the system will set this property for you when you create a control inside a tab control.

See also PageNames.


InsertAllowed

Use this property to tell the system whether or not it should let users add records while using this form.

Applies to

Forms

Settings

The InsertAllowed settings are:

To... | Choose...
Let users add records | Yes (default)
Prevent users from adding records | No


InvalidActionAppearance

Use this option to tell the system how to display the caption and, if applicable, the bitmap, if it could not perform the action you specified with the PushAction property.

Applies to

Command buttons, menu items

Settings

The InvalidActionAppearance settings are:

To have the system... | Choose...
Keep the same appearance | Normal
Gray the caption and bitmap | Disable (default)
Hide the caption and bitmap | Hide

Comments

The system tests for this property when it opens a form or menu.


KeepWithNext

Use this property to avoid page breaks between a section and a following section of the same type.

Applies to

Sections

Settings

To... | Choose...
Avoid page breaks between the sections | Yes (the default)
Allow page breaks between the sections | No


Key

Use this property to identify the field or fields that make up this key. You can select up to 20 fields for each key and you can have up to 40 keys for each table. The combination of the data in the fields you select for the key must be unique. The first key you create will be the primary key for the table.

Applies to

Keys

Settings

If the key consists of more than one field, separate the fields with commas. For instance, you would enter:

field1,field,2,field3

Comments

For example, if the primary key includes four fields, the secondary keys can include these four fields and up to 16 additional fields from the table. Similarly, if the primary key consists of 20 fields, the secondary keys can only consist of different combinations of these 20 fields.

Searching for specific data is normally easier if several keys have been defined and maintained for the table. The indexes for each of the keys provide specific views that let the system quickly perform flexible searches. There are advantages and disadvantages to creating a large number of keys. For example:

If you... | Performance increases... | Performance slows...
Increase the number of secondary keys marked as active | When you retrieve data in several different sorting sequences, since the system has already sorted the data. | When you enter data since the system has to maintain the indexes for each secondary key.
Decrease the number of secondary keys marked as active | When you enter data since the system has a minimal number of indexes to maintain. | When you retrieve data. You may have to define or reactivate the secondary keys to get the appropriate sortings. Depending on the size of the database, this can take some time, because the system has to rebuild the index.


KeyGroups

Use this property to specify the predefined key groups that a key belongs to. After you have assigned a key to one or more key groups, you can selectively activate or deactivate the key by enabling and disabling the key groups.

Applies to

Keys

Comments

To change the status of keys in Microsoft Dynamics NAV, you must have access to the C/SIDE development environment.

If you do not have access to C/SIDE, you can have your Microsoft Certified Business Solutions Partner create a set of keys that makes a particular type of task easier, for example, running a lengthy report.

These keys can be set up as a key group, which you can enable and disable without risk. The program will perform better when you have disabled the key group because the system does not have to maintain the keys included in the key group.

Adding a large number of keys to database tables decreases performance. However, by making the keys members of predefined key groups you can have the necessary keys defined and only activate them when they are going to be used.

To enable or disable a key group for sorting, click File, Database, Information and the Database Information window appears. Then click Tables, Key Groups and the Database Key Groups window appears. You can then enable or disable a key group by clicking the appropriate button.

Unfortunately, it is very difficult to get an overview of the keys and tables that are affected when you enable or disable a key group. However, you can look at the design of any table and see the keys that have been defined for that table and whether or not the keys belong to a key group.

To see which keys in a table belong to a key group:

  1. Open a table in the Table Designer and click View, Keys to open the Keys window., You can now see the keys that have been defined for that table.

  2. With the focus on the Keys window, click View, Show Column to open the Show Column window.

  3. In the Show Column window, enter a check mark beside KeyGroups and click OK.

  4. The Keys window now displays a KeyGroups column that lists the key groups that any of the keys in this table belong to.

Furthermore, even though you have enabled or disabled a specific key group you can still disable or re-enable any of the individual keys that belong to that key group. To enable or disable a key, open the Keys window for the table in question and enter or remove a check mark in the Enabled field beside the key.

Related Topics

KEYGROUPENABLE

KEYGROUPDISABLE

KEYGROUPENABLED


LeaderDots

Use this property to include leading dots before the data.

Applies to

Labels, text boxes

Settings

The setting for the LeaderDots property are:

To display... | Choose...
Leading dots | Yes (default for labels unless in a column heading)
Normal text (without dots) | No (default for text boxes)

Comments

If you enter Yes, the system ignores the setting for PadChar.

The system places the leading dots before, after, or both before and after the caption when the HorzAlign property is set to Right, Left, or Center, respectively


LeftMargin

Use this property to set the left margin of a report. The unit of measure is 1/100 mm.

Applies to

Reports

Comments

A left margin specified in the page setup dialog will override LeftMargin.

Some printers require a minimum margin. If you specify a margin that is smaller than the minimum margin, the minimum margin will be used when printing.

The default is 21 mm.


LinkedInTransaction

Use this property to read and modify data from linked server data sources, such as Excel, Access or another SQL Server.

Applies to

The Microsoft SQL Server Option for Microsoft Dynamics NAV.

Comments

This property is available when you have set the LinkedObject property to Yes.

You must set the LinkedInTransaction property to No when the Microsoft Dynamics NAV table description refers to an object outside the current database or on a linked server.

The access to linked server data sources is not under Microsoft Dynamics NAV transaction control. This means that if a Microsoft Dynamics NAV transaction is aborted, any changes that were made during this transaction to a linked object that is outside the current database or on a linked server will remain in effect.

For more information, see the manual Application Designer's Guide.


LinkedObject

Use this property to link to SQL Server objects.

Applies to

Tables in the Microsoft SQL Server Option for Microsoft Dynamics NAV.

Comments

When you set the LinkedObject property to Yes, the LinkedInTransaction property becomes available.


LinkFields

Use this property to specify the fields from two tables that are linked by the LinkTable property. This property is only available for XML items that have a table as their data source.

Applies to

XMLports

Settings

The syntax of the LinkFields property is:

<field>=FIELD(<reference field>)

<field> | a field from the table that is specified as the data source of this XML item
<reference field> | a field from the table that is specified in the LinkTable property.

Comments

This property works in combination with the LinkTable property and the LinkTableForceInsert property.

The property sets a filter on the table that is the data source of this XML item and selects only those records that contain the same value in the linked field as the corresponding field in the current record from the table specified in the LinkTable property.

Normally, you will not enter the value of this property directly. Instead you will use the AssistButton in the Value field to select both fields from lookups into lists of the field names from the two tables.

Example

You have defined two XML items; one based on the Customer table that contains a list of customers and one based on the Sales Header table that contains a record of each sales order that has been made.

In the Customer table, the primary key is the customer number and is stored in the No. field. In the Sales Header table that contains the sales data, each record contains this customer number as a foreign key in the field called Sell-to Customer No.

Setting the LinkTable property of the second XML item to point to the Customer table and setting the Linkfields property of the first XML item to point to the Sell-to Customer No. field places a filter on the records in the Customer table. This means that only those records in the Sales Header table that refer to the current customer are selected.

It corresponds to placing this C/AL statement in the OnPreXMLItem trigger of the indented data item:

SETRANGE("Sell-to Customer No.",Customer."No.");


LinkTable

Use this property to specify the table that this XML item should be linked to. This property is only available for XML items that have a table as their data source.

Applies to

XMLports

Comments

This property works in combination with the LinkFields and the LinkTableForceInsert properties.

Example

Exporting

You are exporting data about specific customers and the orders that they placed. To do this you create an XMLport based on two database tables:

  • The Customer table that contains general information about the customer – address, telephone and so on.

  • The Sales Header table that contains information about the orders placed by these customers.

In the Customer table, the primary key is the customer number and is stored in the No. field. In the Sales Header table, each record contains this customer number as a foreign key in the field called Sell-to Customer No.

Set the LinkTable property of the Sales Header XML item to point to the Customer table and set the LinkFields property of the Sales Header XML item so that the Sell-to Customer No. field is equal to the No. field in the Customer table. This places a filter on the records in the Customer table and ensures that only those records in the Sales Header table that refer to the customers you specified are selected and exported by the XMLport.

This corresponds to placing the following C/AL code in the OnPreXMLItem trigger of the

indented data item:

SETRANGE("Sell-to Customer No.",Customer."No.");

Importing

You are importing some XML data that contains information about some new customers as well as details of their first orders. To do this you create an XMLport based on two database tables:

  • The Customer table that contains general information about the customer – address, telephone and so on.

  • The Sales Header table that contains information about the orders placed by these customers.

In the Customer table, the primary key is the customer number and is stored in the No. field. In the Sales Header table, each record contains this customer number as a foreign key in the field called Sell-to Customer No.

You must set the LinkTable property of the Sales Header XML item to point to the Customer table and set the LinkFields property of the Sales Header XML item so that the Sell-to Customer No. field points to the No. field in the Customer table. This ensures that the customer numbers in the incoming data stream are inserted into both the Customer table and the Sales Header table.

Needless to say, the incoming data stream must conform to the XML schema that you have defined for your XMLport.

In this example, the information you are importing has a header/line relationship – each customer can place many orders. In other words, the customer information is the parent of the of the sales header information. In this kind of relationship the parent information generally functions as a kind of wrapper that encapsulates the information about the children.

The schema typically starts by supplying some of the parent information. Then comes the information about the children and it finishes off by supplying the last of the parent information.

When the XML stream is processed, it therefore begins with the parent information, for example, the customer number is inserted into the No. field in the Customer table. Next comes the sales header information and the customer number is inserted into the Sell-to Customer No. field in the Sales Header table. The rest of the sales header information is then inserted into that table.

In this case you must use the LinkTableForceInsert property to ensure that the parent information is inserted before the child information. In other words, the customer information is inserted into the Customer table before you start processing the sales header information. This makes it possible to validate the sales header information against the customer information as it is inserted.

After the sales header information has been processed, the last of the customer information is inserted into the Customer table.

Needless to say, if the customer number already exists, you receive an error. This means that you will probably have to insert the data into a temporary table, modify it and then insert it into the correct tables.


LinkTableForceInsert

Use this property to specify whether or not data from the linked table should be forcibly inserted into a table in order to prevent the system generating an error.

Applies to

XMLports

Settings

To have the system... | Select...
Forcibly insert data | Yes (default)
Not forcibly insert data | No

Comments

This property works in combination with the LinkFields and the LinkTable properties.

Setting this property to Yes will forcibly insert data from the linked table and run the OnAfterInitRecord trigger on the main table.

This feature is useful if you have a header – line relation in your XML document. The table and the header information must be inserted before you can insert the line information. You can therefore use this property to ensure that the header information is inserted before the XMLport starts reading the line information.


LogHeight

Use this property to define the logical height of the form. The logical size of a form can be larger than its physical size, which is what the system actually displays when the form is opened.

Applies to

Forms

Comments

The unit of measure is 1/100 mm.

If the logical size of the form is set to be larger than the physical size, the system will automatically add scroll bars as necessary.

All controls are placed according to the logical size of the form. This means that controls can be scrolled out of view.

If you set this property to infinite, the system will not include scroll bars. You can change this property at runtime by using the LOGHEIGHT function..

See also LogWidth.


LogWidth

Use this property to define the logical width of the form. The logical size of the form can be larger than the physical size of the form, which is what the system actually displays when the form is opened.

Applies to

Forms

Comments

The unit of measure is 1/100 mm.

If the logical size of the form is set to be larger than the physical size, the system will automatically add scroll bars as necessary.

All controls are placed according to the logical size of the form. This means that controls can be scrolled out of view.

If you set this property to infinite, the system will not include scroll bars. You can change this property at runtime by using the LOGWIDTH function.

See also LogHeight.


Lookup

Use this property to provide a lookup window for a text box.

Applies to

Text boxes

Settings

The Lookup settings are:

To provide... | Choose...
A lookup for the text box | Yes
No lookup | No (default)

Comments

By default, the system's lookup provides a list of records in the table. Using this list, the user can select a record and retrieve information from it into this control. If you want the lookup to provide other functionality, use the OnLookUp trigger to add C/AL code that provides that functionality.

See also LookupFormID and PermanentAssist.


LookupFormID

Use this property to define the ID of the form you want to use as a lookup.

Applies to

Tables, text boxes

Comments

For text boxes, the default is the lookup form defined for the table. You define this form through the LookupFormID property on the Table Properties list.

See also Lookup.


LookupMode

Use this property to tell the system whether this form is in lookup mode.

Applies to

Forms

Settings

The LookupMode settings are:

If you want this form to... | Choose...
Be in lookup mode | Yes
Not be in lookup mode | No (default)

Comments

If you choose No, the system automatically disables the LookupOK and LookupCancel actions.

The system checks this property when it opens the form.

The setting of this property can be changed dynamically by using the LOOKUPMODE function.


MaintainSIFTIndex

Applies to

Keys

This property determines whether SIFT structures should be created (when set to Yes) or dropped (when set to No) in SQL Server to support the corresponding SumIndexFields for the Microsoft Dynamics NAV key.

SumIndexFields are created in Microsoft Dynamics NAV to support, for example, FlowField calculations and other fast summing operations. SQL Server can sum numeric data by scanning the table. If the SIFT structures exist for the SumIndexFields, summing the fields will be faster, especially for large sets of records, but modifications to the table will be slower since the SIFT structures must also be maintained.

In situations where SumIndexFields must be created on a key to allow FlowField calculations, but the calculations are performed infrequently or on small sets of data, you can disable this property to prevent slow modifications to the table.


MaintainSQLIndex

Applies to

Keys

This property determines whether a SQL Server index corresponding to the Microsoft Dynamics NAV key should be created (when set to Yes) or dropped (when set to No). A Microsoft Dynamics NAV key is created in order to sort data in a table by the required key fields. However, SQL Server can sort data without an index on the fields to be sorted. If an index exists, sorting by the fields matching the index will be faster, but modifications to the table will be slower. The more indexes there are on a table, the slower the modifications become.

In situations where a key must be created to allow only occasional sorting (for example, when running infrequent reports), you can disable this property to prevent slow modifications to the table.

Note

You cannot disable this property for the primary key of a table. This key is always created in SQL Server.


MatrixColumnWidth

Use this property to define the width of the columns in a matrix box. The system shows you the width in increments of 1/100 of a millimeter.

Applies to

Matrix boxes

Settings

This property is updated by the system when you use the mouse to resize columns. You can also enter an exact position manually in the Property Sheet.


MatrixSourceTable

Use this property to select the ID of the table that should be used as the matrix (horizontal) table of a matrix box.

Applies to

Matrix boxes

Settings

Use the Lookup button to select the table you want.


Maximizable

Use this property to tell the system whether or not the form should have a standard maximize button in the top right corner.

Applies to

Forms

Settings

The Maximizable settings are:

To... | Choose...
Include a maximize button | Yes (default)
Omit a maximize button | No

Comments

The system checks this setting when it opens the form.

Your entry here has no effect on any associated subforms.

See also Minimizable.


MaximizedOnOpen

Use this property to tell the system whether or not it should maximize the form immediately after it opens the form.

Applies to

Forms

Settings

The MaximizedOnOpen settings are:

To... | Choose...
Maximize the form when opened | Yes
Display the form normally | No (default)

Comments

The system checks this setting when it opens the form.

Your entry here has no effect on any associated subforms.

You can change this property at runtime using C/AL code.

You can only enter Yes here if the MinimizedOnOpen property is set to No.


MaxIteration

Use this property to set a limit on the number of times that a data item will be iterated when the report is run.

Applies to

Data items

Settings

Valid settings of this property are integers between 0 and the maximum value of an integer (2,147,483,647).


MaxLength

Use this property to set the maximum number of characters a user can enter into a text box.

Applies to

Text boxes

Comments

See also AutoEnter.


MaxOccurs

Use this property to specify the maximum number of times that an element can occur.

Applies to

XMLports

Settings

The possible values are Unbounded and Once.

The default value of the MaxOccurs property varies depending on what you have selected as the SourceType of this element.

Element SourceType | Default Value
Table | Unbounded
Text | Unbounded
Field | Once

Comments

The minimum number of times an element can appear is determined by the value of the MinOccurs property.

The MinOccurs and MaxOccurs properties conform to the standard occurrence constraints that are used when defining XML schemas.

The minimum number can be either 1 or 0.

The maximum number can be either 1 or infinite.


MaxValue

Use this property to set the maximum numeric value for a field or control. For example, a field that contains a sales profit percentage might have a maximum value of 99.99.

Applies to

Fields, check boxes, option boxes, text boxes, indicators

Comments

For check boxes, option boxes, and text boxes, the default comes from the field's MaxValue setting (if there is no field MaxValue setting, the default comes from the data type). Here you can narrow that setting, but not expand it.

For indicators, this table shows the defaults:

If you want to show... | The default is...
Integers | 9999
Decimals | 9999.0
Dates | December 31, 9999
Time | 23:59:59

The system checks both the control and field setting during validation.

See also MinValue, NotBlank, and Numeric.


MenuItemType

Use this property to define the type of menu item.

Applies to

Menu items

Settings

The MenuItemType settings are:

If the menu item... | Choose...
Is a standard menu item | MenuItem (default)
Separates other items | Separator

Comments

Normally you specify the menu item properties using the menu item editor which you can display by selecting the Menu Items option on the View menu.


MenuLevel

Use this property to set the menu level for a control. Levels are indicated by indentation.

Applies to

Menu items

Comments

Normally you specify the menu item properties using the menu item editor, which you can display by selecting the Menu Items option on the View menu.

The number you enter indicates the relative level of the option. The default is zero (0).


MinOccurs

Use this property to specify the minimum number of times that an element can occur.

Applies to

XMLports

Settings

The possible values are Once and Zero (0). The default value is Once.

Comments

The maximum number of times an element can appear is determined by the value of the MaxOccurs property.

The MinOccurs and MaxOccurs properties conform to the standard occurrence constraints that are used when defining XML schemas.

The minimum number can be either 1 or 0.

The maximum number can be either 1 or infinite.


Minimizable

Use this property to tell the system whether or not the form should have a standard minimize button in the top right corner.

Applies to

Forms

Settings

The Minimizable settings are:

To... | Choose...
Include a minimize button | Yes (default)
Omit a minimize button | No

Comments

The system checks this setting when it opens the form. Your entry here has no effect on any associated subforms.

See also Maximizable.


MinimizedOnOpen

Use this property to tell the system whether to minimize the form immediately after it is opened.

Applies to

Forms

Settings

The MinimizedOnOpen settings are:

To... | Choose...
Minimize the form when opened | Yes
Display the form normally | No (default)

Comments

The system checks this setting when it opens the form.

Your entry here has no effect on any associated subforms.

You can only enter Yes here if the MaximizedOnOpen property is set to No.

This property can be set dynamically by using the MINIMIZEDONOPEN function.


MinValue

Use this property to set the minimum value for a field or a control.

Applies to

Fields, check boxes, option boxes, text boxes, indicators

Comments

For check boxes, option boxes, and text boxes, the default comes from the field's MinValue setting (if there is no field MinValue setting, the default comes from the data type). Here you can narrow that setting, but not expand it.

For indicators, this table shows the defaults:

If you want to show... | The default is...
Integers | 0
Decimals | 0.0
Dates | January 1, 0
Time | 00:00:00

The system checks both the control and field setting during validation.

See also MaxValue, NotBlank, and Numeric.


ModifyAllowed

Use this property to tell the system whether to let users modify records while using this form.

Applies to

Forms

Settings

The ModifyAllowed settings are:

To... | Choose...
Let users modify records | Yes (default)
Prevent users from modifying records | No


MultiLine

Use this property to tell the system if a label or text box can display multiple lines of text inside a single text box or label.

Applies to

Labels, text boxes

Settings

The MultiLine settings are:

To display... | Choose...
Multiple lines | Yes (default if the control is a label used as a column heading)
Only one line | No (default in all other cases)


MultipleNewLines

Use this property to tell the system whether to let users add multiple new lines between records.

Applies to

Forms

Settings

The MultipleNewLines settings are:

To... | Choose...
Let users add multiple new lines between records | Yes
Prevent users from adding new lines between records | No (default)

Comments

See also AutoSplitKey.


Name

Use this property to assign a name to this table, field, form, report, dataport, XMLport or control. The name is used for internal purposes. You use the name you enter here to identify the codeunit, table, form, report, dataport, XMLport or control in C/AL code.

Applies to

Codeunits, tables, fields, forms, reports, dataports, XMLports, labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms, menu items

Settings

Unlike the ID, the Name does not have to be unique, although it is a good idea to assign unique names. You can enter up to 30 characters.

Comments

As opposed to other development tools, the system uses the ID for reference purposes. So you can use the Name in your code, the system automatically converts the Name to the ID when you compile your C/AL code.

For forms, reports, dataports and XMLports, the system uses the Name as the default for the Caption property.

For controls, the system assigns a default name for you, based on the ID for all controls except check boxes, option boxes, picture boxes, and indicators.

For option boxes, the default comes from the option value, the variable or field name, or the ID.

For check boxes, picture boxes, and indicators the default comes from the variable or field name, or the ID.


NewPagePerGroup

Use this property to determine whether there should be generated a page break before each new group, as defined by the GroupTotalFields property.

Applies to

Data items

Settings

To... | Choose...
Generate a page break | Yes
Not generate a page break | No (the default)

Comments

If you have indicated more than one group in the GroupTotalFields property, you may not want a page break generated for every group. In that case, you can use the TOTALSCAUSEDBY C/AL function to find out which group is changing and the NEWPAGE C/AL function to generate page breaks as needed.


NewPagePerRecord

Use this property to determine whether a page break will be generated after each record is outputted.

Applies to

Data items

Settings

To... | Choose...
Generate a page break | Yes
Not generate a page break | No (the default)


NextControl

Use this property to tell the system on which control it should place focus when the user leaves this control. The user leaves this control by pressing Tab or Enter.

Applies to

Command buttons, menu buttons, check boxes, option boxes, text boxes, picture boxes, indicators, subforms

Comments

On a card form, the system moves from top to bottom, left to right by default. On a tabular form, the system moves from left to right, top to bottom by default. If you press Shift+Tab you reverse the order.

In a tab control, after it reaches the end of the page, it moves to the next page of tab control.

See also AutoEnter.


NotBlank

Use this property to force the user to make an entry into this field, if the user has selected this field.

Applies to

Fields, text boxes

Comments

If you want to force the user to make an entry into this field before saving the record to the database, use the OnBeforePutRecord trigger for that purpose.

You can use this property together with the InitValue property to make sure an entry is made into this field. The system checks this setting for both the control and field during validation.

See also MinValue, MaxValue, and Numeric.


Numeric

Use this property to force the user to enter only numbers in this field or text box.

Applies to

Fields, text boxes

Comments

The system checks this setting for both the control and field during validation.

See also MinValue, MaxValue, and NotBlank.


Occurrence

Use this property to specify whether or not an attribute must occur in the data that is being imported or exported.

Applies to

XMLports

Settings

If the attribute | Select
Must be part of the data | Required (default)
Does not have to be part of the data | Optional

Comments

This property is mainly used to ensure that the XML data that you are importing conforms with the data structure in Microsoft Dynamics NAV.


OptionCaption

Use this property to define the text string options that will be displayed to the user. An OptionCaption is the text that the system uses to show the option values available for a field, text box or variable. The OptionString property contains the set of values that are acceptable choices. If you have set the OptionCaptionML property, this overrides the OptionCaption setting.


OptionCaptionML

Use this property to set the strings that will be displayed to the user for selecting an option. OptionCaptionML is only used if the field, variable or text box has an OptionString property. The OptionString property contains the set of values that are acceptable choices, and it is one of these values that will be saved in the database or used in C/AL code.

OptionCaptionML is multilanguage enabled. This means that it can contain a list of texts in different languages. The text that is actually used will be selected according to the current language setting of the user. See the general description of the multilanguage features here for more information.

Applies to

Fields, text boxes, variables

Format

The OptionCaptionML property has this format:

<Language ID>=<optioncaption [,optioncaption]*>

where <Language ID> is a Windows standard three-letter language ID and <optioncaption [,optioncaption]*> is the OptionCaption text(s) for this language. Semicolons separate entries.

Although you can use OptionCaptionML to limit the number of options displayed to the user, it is recommended that you use OptionString to do this. You cannot expand the set of options. If you do, a runtime error will occur when the user selects an option that is outside the option set defined for the field or variable.

An example of an OptionCaptionML value:

DAN=Resultatopgørelse,Balance;DEU=GuV,Bilanz;ESP=Comercial,Balance

Values are set up for Danish (DAN), German Standard (DEU) and Spanish Traditional Sort (ESP).

How to Enter OptionCaptionML Values

When the AssistButton in the OptionCaptionML Value field is clicked, the Multilanguage Editor opens. This is a form with two columns: Language and Value. The Language column is populated with all languages defined by Windows. For your convenience, the names, not the abbreviated names, of the languages are displayed. The OptionCaptionML value for a language is added by entering a value in the Value field for that language. You have to close this form by clicking OK. If it is closed by Esc, the OptionCaptionML field is not updated.

Comments

The easiest way to understand the relationships between OptionString and OptionCaptionML properties on fields (or variables) and controls is to go through some scenarios:

  1. An Option field in a table has this OptionString: opt1,opt2,op3. OptionCaptionML is not set. A form is designed based on this table with a text box that is based on the Option field. OptionString and OptionCaptionML are not set for the text box.

    Result: The user will see opt1, opt2 and opt3 as the available choices.

  2. An OptionCaptionML property is added to the database field, containing

    DAN=valg1,valg2,valg3;ENG=choice1,choice2,choice3

    Result: if the user selects DAN as their language, they will see valg1, valg2, valg3 as the available choices on the form. If she chooses ENG, she will see choice1,choice2,choice3. See the general description of the multilanguage features for a description of the situation where the selected language is not available.

  3. An OptionCaptionML property is added to the text box, containing:

    DAN=valg nummer 1,valg nummer 2,valg nummer 3

    Result: If the user sets DAN as the language, the choices are valg nummer 1, valg nummer 2, valg nummer 3. If the user sets the language to ENG, the same set of choices is available!

  4. The OptionCaptionML is removed from the field. The situation now is that the field has an OptionString and the text box has an OptionCaptionML set for DAN. The text strings in the OptionCaptionML will be used in all languages.

Please note that the results for scenarios 3 and 4 are the same. As long as any OptionCaptionML property is set, either on the text box or on the field, the OptionString will never be used to display choices to the user.


OptionString

Use this property to set the option values for a field, text box or variable. OptionString is multilanguage enabled. If the OptionCaptionML property is set, the user will see the OptionCaptionML values as the option values, but the value that is used in C/AL or stored in the database will always be the corresponding value from OptionString.

This means that the strings presented to the user can be in different languages. The strings that are actually used will be selected according to the current language setting of the user. See the general description of the multilanguage features here for more information. If OptionCaptionML is not set, the user will see the values from OptionString.

For other multilanguage enabled properties (Caption, ToolTip, PageNames and ReqFilterHeading), there is a relationship between the property itself and the multilanguage counterpart. There is not a similar relationship between OptionString and OptionCaptionML. The only connection is that in the absence of the OptionCaptionML property, the strings displayed are taken from the OptionString property.

Applies to

Fields, text boxes, variables

Comments

For Option fields and variables, use this property to list the options you want the system to accept (and display, if OptionCaptionML is not set). You can enter a maximum of 250 characters. Separate the options with a comma. For example: option1,option2,option3.

For controls, you can use this property to limit the number of options that the user can select. You cannot add options (if you do, a runtime error will occur when the user selects an option outside the set of options defined for the field or variable).

The system recursively checks this property setting during validation.


OptionValue

Use this property to set the value of this option button. When the SourceExpr of this option button matches the option value you enter here, the system highlights this option button.

Applies to

Option buttons

Comments

Enter the value you want the current option to have.


Orientation (Indicator)

Use this function to determine how the system fills a percentage indicator. For example, you can use a percentage indicator to tell the user the processing status of a task that may take several minutes, such as the printing of a long report.

Applies to

Indicators

Settings

The Orientation property settings are:

If you want the indicator to fill from the... | Choose...
Left | Left (default)
Right | Right
Top | Top
Bottom | Bottom

Comments

See also Percentage.


Orientation (Report)

Use this property to set the page orientation for this report.

Applies to

Reports

Settings

The Orientation settings are as follows:

To print and preview this report in... | Choose...
Portrait | Portrait
Landscape | Landscape

Comments

Leave Orientation as <Undefined> to have the default document settings of the printer that is used for this report determine the page orientation.

A page orientation specified in the page setup dialog will override Orientation.


PadChar

Use this property to tell the system which character to use to pad a string. The system uses the value in the HorzAlign property to determine whether the characters should be added to the left, right, or both left and right (centered).

Applies to

Labels, text boxes

Settings

Enter the character you want the system to use to pad the string. For example, if you want the system to pad the string with periods, enter a period (.).

Comments

See also LeaderDots.


PageNames

Use this property to create a list of page names, separated by commas, which correspond to the pages of the tab control. The value is taken from the PageNamesML property if this property is set.

Applies to

Tab controls

Comments

Use this property to specify the pages of a tab control.

See also

PageNamesML describes the ToolTipML property, while a general description of the multilanguage functionality can be found here.

The InPage property is automatically set for a control that is added to a page within a tab control.


PageNamesML

The PageNamesML property is used to provide the text that will be used as a caption for a page in a tab control. PageNamesML is multilanguage enabled. This means that it can contain a list of texts in different languages. The text that is actually used will be selected according to the current language setting of the user. See the general description of the multilanguage features here for more information.

Applies to

Tab controls

Format

The PageNamesML property has this format:

<Language ID>=<pagenames>

where <Language ID> is a Windows standard three-letter language ID and <pagenames> is a list of page names as in the PageNames property.

An example of a PageNamesML value:

DAN=Generelt,Kommunikation,Fakturering;ENG=General,Communication,Invoicing

Values are set up for Danish (DAN) and UK English (ENG).

How to Enter PageNamesML Values

You can enter values for the PageNamesML property in two ways:

  1. If you enter a PageNames value, this value will be inserted in PageNamesML as the value for the language that is currently selected. That is, if the language is set to Danish when a value is entered in PageNames, PageNamesML will be updated with a DAN=<value> string. You have to use the abbreviated name (DAN for Danish, for example) of the languages.

  2. When you click the AssistButton in the PageNamesML Value field, the Multilanguage Editor opens. This is a form with two columns: Language and Value. The Language column is populated with all languages defined by Windows. For your convenience, the names, not the abbreviated names, of the languages are displayed. The PageNamesML value for a language is added by entering a value in the Value field for that language. You have to close this form by clicking OK. If it is closed by Esc, the PageNamesML field is not updated.

Comments

See the general description of the multilanguage features here for more information, including descriptions of what happens if there are no values for the language the user has selected.


PaperSize

Use this property to set the paper size for this report.

Applies to

Reports

Comments

Use the AssistButton to select a paper size from the list of paper sizes that are supported by a particular printer. The list of paper size names is taken from the fin.stx file.

If the printer that is used for this report does not support the specified PaperSize, the default document settings of the printer will determine the page size. You may also experience that the displayed name of a paper size is different in the page setup dialog. This is because the paper sizes that are displayed here are taken from the actual printer. The printer manufacturer may have given a paper size a different name than the one in the fin.stx file. The physical paper size, however, will be the same (if the actual printer supports this size).

Leave PaperSize as <Undefined> to have the default document settings of the printer that is used for this report determine the page size.

A paper size specified in the page setup dialog will override PaperSize.

If you want to use the custom page size associated with your printer driver, set the PaperSize property to <Undefined>. Specify the custom page size in your printer driver properties and use that as the default.


PaperSourceFirstPage

Use this property to specify which paper source to use when printing page one of the report.

Applies to

Reports

Comments

Use the AssistButton to select a paper source from the list of paper sources supported by a particular printer. The list contains 13 standard trays and 8 printer specific trays. It is based on information in the fin.stx file.

If the printer that is used for this report does not support the specified PaperSourceFirstPage, it will use the default tray specified by the printer driver.

If you leave the PaperSourceFirstPage property as <Undefined>, the printer will use the default tray.

If you do not specify a value for the PaperSourceOtherPages property, a value specified for PaperSourceFirstPage will apply.

The printer specific trays contained in the list are intended for use with printers that have other paper sources than the ones listed. To find out how a Printer Specific Feed is mapped to the actual feed on an actual printer, you will have to experiment with choosing a Printer Specific Feed. Then, when you select a printer in the Page Setup dialog, you can see how the Printer Specific Feed is mapped for that particular printer.

Attention

A different setting in the Print dialog or Page Setup dialog overrides the value specified for the PaperSourceFirstPage property.

See also PAPERSOURCE.


PaperSourceOtherPages

Use this property to specify which paper source to use when printing pages other than page one.

Applies to

Reports

Comments

Use the AssistButton to select a paper source from the list of paper sources supported by a particular printer. The list contains 13 standard trays and 8 printer specific trays. It is based on information in the fin.stx file.

If the printer that is used for this report does not support the specified PaperSourceOtherPages, it will use the default tray specified by the printer driver.

If you leave the PaperSourceOtherPages property as <Undefined>, the printer will use the tray specified for the PaperSourceFirstPage property. If you have not specified a value for this property, the printer will use the default tray.

The printer specific trays contained in the list are intended for use with printers that have other paper sources than the ones listed. To find out how a Printer Specific Feed is mapped to the actual feed on an actual printer, you will have to experiment with choosing a Printer Specific Feed. Then, when you select a printer in the Page Setup dialog, you can see how the Printer Specific Feed is mapped for that particular printer.

Attention

A different setting in the Print dialog or Page Setup dialog overrides the value specified for the PaperSourceOtherPages property.

See also PAPERSOURCE.


ParentControl

Use this property to specify the parent control from which this control should inherit default attributes.

Applies to

Labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms, menu items

Comments

You enter the ID of the control you want as the parent. There is no default setting.

Normally the system sets this property for you when you create a control inside a container control, when you create a label using the add label button of the ToolBox, or when you create controls from fields using the Field menu.


PasswordText

Use this property to display the text the user enters in this text box as a string of asterisks (********).

Applies to

Text boxes

Settings

The PasswordText settings are:

To display... | Choose...
Asterisks | Yes
The actual text the user types | No (default)


PasteIsValid

Use this property to tell the system whether it should be allowed to insert records in this table by pasting.

Applies to

Tables

Settings

The PasteIsValid settings are:

To... | Choose...
Allow insert by pasting | Yes (default)
Not allow insert by pasting | No

Comments

You should consider carefully whether it should be allowed to insert records by pasting. If records are normally inserted in the table by an external function (in a code unit) that performs consistency checks and other processing, you should set PasteIsValid to No - otherwise the consistency of your data might be compromised.

The OnInsert trigger of the table is executed when a record is inserted by pasting.


Percentage

Use this property to create an indicator that shows the user the completion percentage of the current task.

Applies to

Indicators

Settings

The Percentage settings are:

To have the system... | Choose...
Display a percentage indicator | Yes (default)
Omit the percentage indicator | No

Comments

You can use a percentage indicator to tell the user the processing status of the lengthy tasks, such as the printing of a long report.

See also Orientation.


PermanentAssist

Use this property to always display the lookup, drill-down, AssistEdit and drop-down buttons.

Applies to

Text boxes

Settings

The PermanentAssist settings are:

To... | Choose...
Always display lookup, drill-down, AssistEdit, and drop-down buttons | Yes (default)
Only display these buttons when the control is in focus. | No

Comments

The system ignores this property when the control is in a column in a table box.

See also Lookup, DrillDown, and DropDown.


Permissions

Use this property to give a database object extra permission to perform some operations on one or more tables. The operations can be to read, insert, modify and delete data.

Applies to

Tables, forms, reports, dataports, XMLports and codeunits

Comments

The license file determines the permissions that users have within Microsoft Dynamics NAV. These permissions are further refined by the security permissions that you grant the different users within Microsoft Dynamics NAV.

Sometimes the license file only gives you indirect permission to perform operations on some tables. Security permissions can also be used to give users only indirect permission to some tables. If you only have indirect permission to, for example, insert data into a particular table, you cannot insert data into this table from the standard user interface. You must use a database object that has been given extra permission to insert data into the table in question.

Important

Once you set the Permissions property of an object only users that have direct permission, to perform all the extra operations that the object has been given, can modify this object.

Do not use the Permissions property to give extra permissions to an object that you would like your ordinary users to be able to modify. These users might not have direct permission to perform these operations. This is why you should be careful when you use the Permissions property for tables and forms.


PlaceInBottom

Use this property to indicate whether a footer section should always be printed at the bottom of the (physical) page.

Applies to

Footer sections

Settings

To... | Choose...
Always print the section at the bottom of the page | Yes
Print the footer section right after the last section printed | No (the default)

Comments

Obviously, this property has the greatest impact on the last page of a report, but there might also be white space at the bottom of other pages. This is the case if the next section to print does not fit in what remains of the physical page.


PopulateAllFields

Use this property to have fields filled out automatically with a single filter value when a new record is inserted in a table.

Applies to

Forms

Settings

To... | Choose...
Not have fields filled out automatically | No (the default)
Have fields filled out automatically | Yes

Comments

Values will be inserted in those fields where a filter expression that is currently active evaluates into exactly one value.

Key fields are always populated.


PrintOnEveryPage

Use this property to indicate whether a header or footer section should be printed on every page, or only on the first (headers) or the last (footers).

Applies to

Header and footer sections

Settings

To... | Choose...
Print on every page | Yes
Print on first or last page only, respectively | No (the default)


PrintOnlyIfDetail

Use this property to determine whether the decision to output the sections of a data item will be based on whether an indented data item - or several nested data items - generate any output.

Applies to

Data items

Settings

To... | Choose...
Print output only if indented data items produce output | Yes
Always print | No (the default)


ProcessingOnly

This property is used to set whether a report will produce printed output, or will only be able to process data.

Applies to

Reports

Settings

The ProcessingOnly settings are:

For a report that... | Choose...
Will not produce output | Yes
Will produce output | No (the default)

Comments

It is not allowed to insert controls in any section when ProcessingOnly is Yes.

If ProcessingOnly is Yes, the Print and Preview in the request form are replaced by an OK button.


PushAction

Use this property to make the system immediately perform the action you specify.

Applies to

Command buttons, check boxes, option buttons

Settings

The PushAction settings are:

To have the system perform this action... | Choose...
Close form and return OK | OK
Close form, do not return OK | Cancel
Close lookup form and return OK | LookupOK
Close lookup form, do not return OK | LookupCancel
Close form and return Yes | Yes
Close form and return No | No
Close the form | Close
Stop processing | Stop
Show help for this form | FormHelp
Run an application object | RunObject
Run a system command (external program) | RunSystem
Perform a lookup into the current table | LookupTable

Comments

In the list of actions above, the first group could be said to return an action to the caller. For example, OK is used to close a form and return OK to the caller. The second group (the last four actions) are different: these actions call upon the system to perform an action (for example, show the context-sensitive help for a form).

RunObject and RunSystem require that you specify the action further by setting one or more of the properties named Run....

If you choose RunObject, you will have to specify the application object to run by using the RunObject property. If the object you choose is a form, you can specify how to run this form further by using the RunFormView, RunFormLink, RunFormLinkType and RunFormOnRec properties.

If you choose RunSystem, use the RunCommand property to specify the external program to run (including command-line parameters).

See also InvalidActionAppearance.


RecordSeparator

Use this property to define the string that is to be used to separate records.

Applies to

Dataports

Settings

The RecordSeparator settings are:

This string.. | Means...
<None> | that there will no be RecordSeparator
<NewLine> | any combination of CR and LF characters
<CR/LF> | CR followed by LF
<CR> | CR alone
<LF> | LF alone
<TAB> | Tabulator alone
Other strings | the literal string entered

The strings in the table above must be entered literally, that is: the < and > characters must be entered. These special strings can be combined, and also be mixed with other characters.

The default is <NewLine>.

CR refers to the character with ASCII value 13

LF refers to the character with ASCII value 10


ReqFilterFields

Use this property to indicate those fields that will automatically be included on the tab of the request form that pertains to this data item. The user can set filters on these fields.

Applies to

Data items

Settings

A comma-separated list of field names. The fields can be selected by using the assist-edit function in the Value field of this property.

Comments

When the request form is in use, the user will be able to add other fields and set filters on these fields.

Even so, it may still be a good idea to use this property: if the underlying table has many fields, the occasional user of the report or dataport may not easily find the relevant fields to filter.

If you do not want the user to be able to put filters on other fields, you must remove the request form altogether by using the UseReqForm property of the report or dataport, or remove the tab for this data item, by setting a specific key.


ReqFilterHeading

Use this property to create a caption for the request form tab that pertains to this data item. The value is taken from the ReqFilterHeadingML property if this property is set.

Applies to

Data items

Settings

Any valid string. If ReqFilterHeadingML is set, the value for the selected language is used. If ReqFilterHeadingML is not set, the default is the name of the table that is the DataItemTable of the data item.


ReqFilterHeadingML

The ReqFilterHeadingML property is used to provide the text that will be used as a ReqFilterHeading for a request form tab. ReqFilterHeadingML is multilanguage enabled. This means that it can contain a list of texts in different languages. The text that is actually used will be selected according to the current language setting of the user. See the general description of the multilanguage features here for more information.

Applies to

Data items

Format

The ReqFilterHeadingML property has this format:

<Language ID>=< reqfilterheading >

where <Language ID> is a Windows standard three-letter language ID and <reqfilterheading> is the caption text for this language. Semicolons separate entries.

How to Enter ReqFilterHeadingML Values

You can enter values for the ReqFilterHeadingML property in two ways:

  1. If you enter a ReqFilterHeading, this value will be inserted in ReqFilterHeadingML as the value for the language that is currently selected. That is, if the language is set to Danish when a value is entered in ReqFilterHeading, ReqFilterHeadingML will be updated with a DAN=<value> string. You have to use the abbreviated name (DAN for Danish, for example) of the languages.

  2. When the AssistButton in the ReqFilterHeadingML Value field is clicked, the Multilanguage Editor opens. This is a form with two columns: Language and Value. The Language column is populated with all languages defined by Windows. For your convenience, the names, not the abbreviated names, of the languages are displayed. The ReqFilterHeadingML value for a language is added by entering a value in the Value field for that language. You have to close this form by clicking OK. If it is closed by ESC, the ReqFilterHeadingML field is not updated.

Comments

See the general description of the multilanguage features here for more information, including descriptions of what happens if there are no values for the language the user has selected.


RightMargin

Use this property to set the right margin of a report. The unit of measure is 1/100 mm.

Applies to

Reports

Comments

A right margin specified in the page setup dialog will override RightMargin.

Some printers require a minimum margin. If you specify a margin that is smaller than the minimum margin, the minimum margin will be used when printing.

The default is 0 mm.


RowHeight

Use this property to specify the height of the rows in a table box.

Applies to

Table boxes, matrix boxes

Comments

Enter the row height in increments of 1/100 of a millimeter.


RunCommand

Use this property as a parameter to the PushAction property to execute an operating system command.

Applies to

Command buttons, check boxes, option buttons, menu items

Comments

To use this property, first select RunSystem in the PushAction property. Then you can enter any operating system command in this property. Separate any parameters with spaces.

See also InvalidActionAppearance, RunObject RunFormView, RunFormLink and RunFormLinkType.


RunFormLink

Use this property as a parameter to the PushAction property to set up a link to the form you are launching.

Applies to

Command buttons, check boxes, option buttons, menu items

Comments

For example, suppose the current form is the customer card and you are providing a way to see the outstanding sales orders for the current customer. To do so you would select RunObject in the PushAction property and use the RunObject property to tell the system to run the customer sales orders form. In this property you would select the Customer No. field as the link between the two forms.

See also RunFormView and RunFormLinkType.


RunFormLinkType

Use this property as a parameter to the PushAction property to define the type of link to the form you are launching.

Applies to

Command buttons, check boxes, option buttons, menu items

Settings

The RunFormLinkType settings are:

To execute the form link when the... | Select...
Form is opened | OnOpen (default)
Form is updated or the user changes records | OnUpdate

Comments

For example, suppose the current form is the customer card and you are providing a way to see the outstanding sales orders for the current customer. To do so you would select RunObject in the PushAction property and use the RunObject property to tell the system to run the customer sales orders form. Then you would select the Customer No. field as the RunFormLink between the two forms. In this property you would tell the system when to execute the link between the two forms.

See also RunFormView.


RunFormOnRec

Use this property as a parameter to the PushAction property to display the same record on the form you will launch from this control as is already displayed on the current form.

Applies to

Command buttons, check boxes, option buttons, menu items

Settings

The RunFormOnRec settings are:

To... | Select...
Display the current record on the form you will launch from this control | Yes
Not display the current record on the form you will launch from this control | No (default)

Comments

For example, suppose the current form is the sales order and you are providing a way to see the sales statistics for the current customer. To do so you would select RunObject in the PushAction property and use the RunObject property to tell the system to run the sales statistics form. In this property you could select Yes to tell the system to display the same record on both forms.

See also RunFormView and RunFormLink.


RunFormView

Use this property as a parameter to the PushAction property to set a specific Table View for the form you will launch from this control. For example, you can use this property to tell the system how to sort the information.

Applies to

Command buttons, check boxes, option buttons, menu items

Comments

See also RunObject, RunFormLinkType, and RunFormLink.


RunObject

Use this property as a parameter to the PushAction property to identify the object you want to run immediately.

Applies to

Command buttons, check boxes, option buttons, menu items

Comments

To use this property, first select RunObject in the PushAction property. Then use this property to select the object you want to run.

Use the following properties to set parameters for the object you want to run: RunFormView, RunFormLinkType and RunFormLink.


SaveColumnWidths

Use this property to tell the system whether to save the widths of the columns in the table boxes of this form. If you choose to save this information, the system will restore those column width settings the next time the user opens this form.

Applies to

Forms

Settings

The SaveColumnWidths settings are:

To... | Choose...
Save the column width settings | Yes (default)
Ignore the column width settings | No

Comments

The system records this information and saves it in the .zup file, a user-specific file that contains user settings.


SaveControlInfo

Use this property to tell the system whether to save user-specific control information for this form. The control information includes which control was active when the user last closed the form as well as the row and column which were active at that time. If you choose to save this information, the system will use it to place focus.

Applies to

Forms

Settings

The SaveControlInfo settings are:

To... | Choose...
Save any user-defined filters | Yes (default)
Ignore any user-defined filters | No

Comments

The system records the control information and saves it in the .zup file, a user-specific file that contains user settings.


SavePosAndSize

Use this property to tell the system whether to save user-specific information about the size and placement of this form. If you choose to save this information, the system will display this form in the same size and place as it appeared the last time that the user opened the form.

Applies to

Forms

Settings

The SavePosAndSize settings are:

To... | Choose...
Save any user-defined position and size information | Yes (default)
Ignore any user-defined position and size information | No

Comments

The system records this information and saves it in the .zup file, a user-specific file that contains user settings.


SaveTableView

Use this property to tell the system whether to save the Table View the user has defined for this form and reapply it the next time the user opens the form.

Applies to

Forms

Settings

The SaveTableView settings are:

To... | Choose...
Save any user-defined table view | Yes (default)
Ignore any user-defined table view | No

Comments

The system records the last record a user was viewing and saves this information in the .zup file, a user-specific file that contains user settings.

See also SourceTableView.


SaveValues

Use this property to tell the system whether or not it should save user-specific control values for this form.

Applies to

Forms

Settings

The SaveValues settings are:

To... | Choose...
Save any user-defined control values | Yes
Ignore any user-defined control values | No (default)

Comments

The system records this information and saves it in the .zup file, a user-specific file that contains user settings.


SectionHeight

Use this property to set the height of a section. The unit of measure is 1/100 mm.

Applies to

Sections

Settings

You can set this property manually for exact measurement, but usually the height of a section is set automatically by the Section Designer as sections are resized with the mouse or as fields are added to the sections.

Comments

The system will always make the height of a section large enough when a control is added; that is, a little larger than the bounding box around the control.


SectionWidth

Use this property to set the width of a section. The unit of measure is 1/100 mm.

Applies to

Sections

Settings

You can set this property manually for exact measurement, but usually the width of a section is set automatically by the Section Designer as sections are resized with the mouse or as fields are added to the sections.

Comments

All sections in one report must have the same width. Therefore, if one section is resized horizontally, all other sections in that report will have their SectionWidth properties adjusted accordingly.


ShapeStyle

Use this property to determine what a shape control displays.

Applies to

Shapes

Settings

The ShapeStyle property settings are:

To display... | Select...
A rectangle with square corners | Rectangle (default)
A rectangle with rounded corners | Rounded rectangle
An oval | Oval
A triangle | Triangle
A diagonal line (\) | NWLine
A diagonal line(/) | NELine
A horizontal line | HorzLine
A vertical line | VertLine


ShortCutKey

Use this property to assign a shortcut key for selecting a menu item. Pressing the key you designate with this property provides the same result as clicking the item.

Applies to

Menu items

Comments

For example, to make Ctrl+X the shortcut key, you would enter Ctrl+X.

Please note that some keys already have system assignments, such as Shift+F12 for the Object Designer. You should not reuse any of the shortcut keys already assigned.


ShowCaption

Use this property to tell the system whether or not it should display the caption.

Applies to

Command buttons, menu buttons, check boxes, option buttons, frames

Settings

The ShowCaption settings are:

If you want to... | Choose...
Display the caption | Yes (default)
Not display the caption | No


ShowPrintStatus

Use this property to determine whether the system will display a window that shows the printing status of a report when it is run.

Applies to

Reports

Settings

To... | Choose...
Not show a status window | No
Show a status window | Yes (the default)

Comments

Apart from showing the progress of the report, the window also contains a Cancel button that will cause the processing and printing of the report to terminate, when clicked. If you set ShowPrintStatus to No, the user will not have the opportunity to stop the report prematurely.

If the ProcessingOnly property is Yes, there will be no status dialog, even if ShowPrintStatus is Yes. If you need a status dialog, you must create one yourself.


ShowStatus (Dataports)

Use this property to determine whether the system will display a window that shows the status of a dataport when it is run.

Applies to

Dataports

Settings

To... | Choose...
Not show a status window | No
Show a status window | Yes (the default)

Comments

Apart from showing the progress of the dataport, the window also contains a Cancel button that, when clicked, will cause the processing of the dataport to terminate. If you set ShowStatus to No, the user will not have the opportunity to stop the dataport prematurely.


SIFTLevelsToMaintain

Use this property to specify which SIFT levels are maintained for a key.

Applies to

Keys

Comments

Applies only to the Microsoft SQL Server Option for Microsoft Dynamics NAV.

For more information about SIFT in the SQL Server Option for Microsoft Dynamics NAV , see the Application Designer's Guide.


SignDisplacement

Use this property to shift negative values to the right for display purposes only. You can shift negative values in increments of 1/100 of a millimeter.

Applies to

Text boxes

Example

If you enter 600 (6 millimeters) here you would see a result similar to:

(+)999888777

(+)123456789

(-) 123456789

(-) 999888777

(+)987654321


SingleInstance

When you set this property to Yes on codeunit X, all codeunit variables that use codeunit X will use the same instance. That is, all codeunit variables of codeunit X will use the same set of internal variables when the code is running on the same client. Codeunit X remains instantiated until you close the company.

Applies to

Codeunits

Settings

To... | Choose...
have only one instance of a codeunit, that makes the codeunit a single instance codeunit | Yes
not set a codeunit as a single instance codeunit | No (the default value)

Example

Here is an example of how you can use the SingleInstance property:

Two forms can connect to the same codeunit.

On Form1:

Codeunit1.SetNumber(100);

On Form2:

Number := Codeunit1.GetNumber();
 MESSAGE(Format(Number));

The SingleInstance property in Codeunit1 is set to Yes. Form1 calls a function on Codeunit1 and sets the parameter to 100. Codeunit1 saves this parameter in a local variable. Form2 is now able to get the parameter value (=100) from Codeunit1. A message is displayed.


Sizeable

Use this property to tell the system whether or not the form should have a border the user can resize and a Size option on its Control menu.

Applies to

Forms

Settings

The Sizeable settings are:

To... | Choose...
Let the user resize the form | Yes (default)
Prevent the user from resizing the form | No

Comments

The Control menu appears when you press Alt+- (hyphen) for forms, Alt+Spacebar for some tools and for the application window, or if you click on the horizontal bar in the top left corner of the frame.

The system checks this setting when it opens the form.

Your entry here has no effect on any associated subforms.


SourceExpr

Use this property to specify the source expression for this control. A source expression is a C/AL expression that tells the system where to find the value of a control. The system evaluates the source expression when it performs updates.

Applies to

Command buttons, menu buttons, check boxes, option boxes, text boxes, picture boxes, indicators, dataport fields

Comments

A source expression can be as simple as the name of a table field; it can also be a complex C/AL expression.

For some controls, the source expression has a special meaning:

For a menu item, the setting of SourceExpr must evaluate to boolean. TRUE means that the menu item will appear checked, FALSE that it will appear unchecked (normal).

For a control that has a BitmapList property, the (integer) source expression is used to select a bitmap from the list.


SourceField

Use this property to select the field that you want to map XML data to.

Applies to

XMLports

Comments

This property is only available if you have selected Field in the SourceType property.

You must have selected Table as the SourceType of the parent tag and specified the table in the SourceTable property.

The SourceField property is related to the DataSource field in the XMLport Designer.

When you click the AssistButton in the Value field for the SourceField property, the window that opens lists all the tables that have been defined as part of this XMLport and you can select a field from one of these tables.

If you have given a table a variable name in the properties window for that element, this name is displayed in the Field Lookup window.

When you select the variable name that you have given the current table, the selection is displayed in the DataSource field of the XMLport Designer and in the Value field of the SourceField property in the following format: tablevariablename::fieldname.


SourceTable

Use this property to select the ID of the table from which this form will display records.

Applies to

Forms

Comments

Use the Lookup button to select the table you want.


SourceTable

Use this property to specify the table to which you want to map XML data or the table that you want to export data from.

Applies to

XMLports

Comments

This property is available if you selected Table in the SourceType property.

The values of the VariableName and the SourceTable properties correspond to the contents of the DataSource field in the XMLport Designer. The values that you enter in these properties in the Properties window are shown in the DataSource field in the XMLport Designer.

If you have defined a text variable, you can only see the name of the text variable in the DataSource field in the XMLport Designer.

Example:

If you have defined a table as an XML item, the DataSource field can display the following information:

Properties window |  | XMLport Designer
SourceTable | VariableName | DataSource field
Customer | <Customer> default | <Customer>(Customer)
Customer | Cust. | Cust.<Customer>


SourceTablePlacement

Use this property to tell the system what record to display when the user opens this form.

Applies to

Forms

Settings

The SourceTablePlacement settings are:

To display... | Choose...
A specific record | Record
The first record in the table | First
The last record in the table | Last
The record being shown the last time the user displayed the form | Saved (default)

Comments

If you choose Record, you must use the SourceTableRecord property to define the record you want the system to display. The system checks this property setting when it opens the form. The system records the last record a user was viewing and saves this information in the .zup file, a user-specific file that contains user settings.


SourceTableRecord

Use this property in combination with the SourceTablePlacement property to define a specific record you want the system to display when the user opens this form.

Applies to

Forms

Comments

To use this property, you must also select Record in the SourceTablePlacement property. Use the AssistEdit button to select the record you want. The system checks this property setting when it opens the form.


SourceTableView

Use this property to define the key, sort order and filter you want the system to use to determine the view of the source table presented to the user.

Applies to

Forms

Comments

Use the AssistEdit button to help you select the key, sort order and filter. The system checks this property setting when it opens the form.


SourceTableView

Use this property to filter the data in the table that you have set as the source for this XML item.

Applies to

XMLports

Comments

The AssistButton in the Value field for this property opens the Table View window that allows you to specify which key is used for sorting the data in the table, whether the data should be sorted in ascending or descending order as well as place a filter on the table.


SourceType

Use this property to specify what a particular tag in the XMLport Designer corresponds to in the Microsoft Dynamics NAV database.

Applies to

XMLports

Settings

Select... | When...
Text | the XML data in the object denoted by the TagName property cannot be mapped directly to the Microsoft Dynamics NAV database or when the database does not need the information. The name of the Text field in the XMLport Designer is put into a global text variable. This variable functions just like a normal C/AL Global variable. However, it is not visible in C/AL Globals window but it is visible in the C/AL Symbol Menu.
Table | the object denoted by the TagName property corresponds to a Microsoft Dynamics NAV table. You should also select this value when a Microsoft Dynamics NAV table record needs to be initialized.
Field | access is required to a field in the database. For this selection to be valid, you must first have declared a table as the parent of this object or attribute. Failure to do so will cause an error to occur when you try to compile the XMLport object.

Comments

This property is directly related to the SourceType field in the XMLport Designer.


SQL Data Type

Use this property to specify the data type you want to allow in a code field.

Applies to

Code fields in the Microsoft SQL Server Option for Microsoft Dynamics NAV.

Comments

The values available are Varchar, Integer and Variant. Leaving the value set at <Undefined>means that you accept the default setting, which is Varchar.

Important

The Variant option is represented by the SQL_VARIANT SQL data type that has been introduced in SQL Server 2000 and is not supported by SQL Server 7.0. This means that selecting Variant as the SQL Data Type property when creating or modifying a table on SQL Server 7.0 results in an error.

When you set the value of the SQL Data Type property of a code field to Varchar, all the values in the field are compared and sorted as character data, including numeric values.

When you set the value of the SQL Data Type property of a code field to Integer:

  • All the values in the field are compared and sorted as integers. No alphanumeric values can be stored in the field.

  • If you enter negative values in the column outside Microsoft Dynamics NAV using external tools, they cannot be read into Microsoft Dynamics NAV.

  • The value "0"(zero) is used to represent an empty string in Microsoft Dynamics NAV.

  • Non-numeric code values or any numeric values beginning with "0"(zero) cannot be entered in the code field.

When you set the value of the SQL Data Type property of a code field to Variant:

  • The values in the field are compared and sorted according to their base data type. Numeric values are sorted after alphanumeric values.

  • Data that is entered into the code field in Microsoft Dynamics NAV is stored as either the VARCHAR or INTEGER base data type, depending on the value that has been entered.

  • Any value beginning with "0" (zero) can be entered in the code field and is stored as an INTEGER base data type.

Important

You can change the SQL Data Type of a code field from Varchar or Integer to Variant and the data in the column is changed accordingly. You cannot change the SQL Data Type of a code field from Variant to Varchar or Integer, unless there are no rows in the table or unless the field contains only an empty string in every row.


SQLIndex

Use this property to define the actual fields that are used in the corresponding index on SQL Server.

Applies to

Keys

Comments

This property allows you to define the fields that are used in the SQL index.

The fields in the SQL index can:

  • be different than the fields defined in the key in Microsoft Dynamics NAV - there can be fewer fields or more fields.

  • be arranged in a different order.

If the key in question is not the primary key and you use the SQLIndex property to define the index on SQL Server, the index that is created contains exactly the fields that you specify and will not necessarily be a unique index. It will only be a unique index if it contains all of the primary key fields.

Primary Key

When you define the SQL index for the primary key, it must include all the fields defined in the Microsoft Dynamics NAV key. You can add extra fields and you can still rearrange the fields to suit your needs.


Standard day/time unit

Use this property to denote the unit of measure that is used when you enter data into duration fields.

Applies to

Fields of the Duration data type.

Comments

The units of measure that you can enter are: day, hour, minute, second and millisecond.

The default value is hour.

Duration is always stored as milliseconds.


StartPos

Use this property to determine the starting position of a field in a data item of a dataport.

Applies to

Fields (in dataports)

Settings

Set the integer value of StartPos to the first character in this field. The first position is 1.

Comments

The setting of this property is only used if FileFormat is Fixed. If it is, StartPos and Width are used to define fields when records are imported or exported.


SubFormID

Use this property to identify a subform that will be opened in a subform control.

Applies to

Subforms

Comments

Enter the ID, either the number or the name, of the subform.


SubFormLink

Use this property to provide a link to a subform from the main form.

Applies to

Subforms

Comments

The system updates the link when the current record changes.


SubFormView

Use this property to set the Table View for a subform. For example, you can use this property to tell the system how to sort the information in the table for display in this subform.

Applies to

Subforms

Settings

Use the AssistEdit button to help you set the table view for the subform.


SubType

Use this property to provide additional information about what will be contained in this field. This property only applies to BLOB fields.

Applies to

Fields

Settings

The SubType settings are:

If you will store... | Choose...
Bitmaps | Bitmap
Memos | Memo
User defined information | User-Defined (default)

Comments

When you use C/AL functions IMPORT and EXPORT, the system will provide a dialog window from which the user can pick the BLOB to import or export.

Based on your selection here, the system will show only the appropriate file types. For instance, if you select Bitmap, the system shows only files with the extension .bmp. If you select Memo, the system shows only files with the extension .txt. If you select User-Defined, the system shows all files.


SumIndexFields

Use this property to specify the SumIndexFields for the key, if applicable.

Applies to

Keys

Comments

You can select up to 20 SumIndexFields for each key.

Changing existing keys may affect the behavior of the system since other parts of your application may depend on the existence of certain keys.


TableBoxID

Use this property to specify the ID of the table box that displays the source table associated with this form.

Applies to

Forms

Comments

If there is more than one table box on the form, use this property to specify the table box ID of the main or primary table box.

The system checks this property when it opens the form.


TableIDExpr

Use this property to specify the ID of the table to which you want to apply a table filter.

Applies to

Fields

Comments

The field must be of the TableFilter data type and the Table ID Expression must be of the Integer data type and is typically the "Object ID" of the table.

To understand how this property is applied, see the Permission table.


TableNo

Use this property to specify the number of the source table, if any, for this unit of code.

Applies to

Code units

Settings

Use the lookup to select the table you want. If this code unit can apply to any table, choose undefined.

Comments

If you do select a table here you can use the global variable CurrRec in this code unit and you can use the Codeunit.Run function to execute this code unit.


TableRelation

Use this property to define relationships (links) to other tables. For instance, if you want to provide a lookup into another table, enter the name of that table here.

Applies to

Fields, text boxes

Comments

The TableRelation property lets you establish lookups into other tables. For instance, on the Item card you can select a vendor from which you normally purchase the item. This is done through a table relationship.

This property is also used to tell the system where to look to validate entries.

See ValidateTableRelation for more information.

In addition, when you choose the option to test the relationships between primary and secondary indexes, this property tells the system what to test. This option is one of the Database options on the File menu.

See TestTableRelation for more information.


TagName

Use this property to specify the name of a tag in an XML document.

Applies to

XMLports

Comments

The name that you specify is inserted in the TagName field of the XMLport Designer of the element or attribute in question.

You must enter tag names in the order in which they appear in the XML document. Parent elements must precede their child elements. You indent the tag names of child elements under their parent elements using one indentation per level. You list attributes under the elements that they define and you indent them to the child level.


TagType

Use this property to specify whether an XML object is an element or an attribute.

Applies to

XMLports

Settings

The possible values are: Element and Attribute. The default value is Undefined.

Comments

This property is directly related to the TagType field in the XMLport Designer.


Temporary

Use this property to create a temporary table.

Applies to

Record variables

Settings

To... | Choose...
Create a temporary table | Yes
Not create a temporary table | No (the default)

Comments

Obviously, changes made to a temporary table will not be stored to the database.

Using a temporary table can be useful in some situations. If you need to perform a lot of calculations on data in a table, for example, in a report, but it is not of the utmost necessity that the data used are the newest version, you can reduce load on the server by copying the table in question to a temporary table and working with this copy.


Temporary (XMLports)

Use this property to create a temporary table.

Applies to

XMLports

Settings

To... | Select...
Create a temporary table | Yes
Not create a temporary table | No (default)

Comments

Here a couple of examples of how you can use temporary tables:

  • If the data that you are importing has a different structure than the table in Microsoft Dynamics NAV that you want to insert it into, you could import the data into a temporary table. The temporary table holds the data in cache without writing it to the database. You can then modify the data before inserting it into the database.

  • If the data that you are importing contains a record that already exists in the database, you cannot import it because C/SIDE only allows you to insert new records into the database. To get around this problem you can import the data into a temporary table, locate the record and use C/AL code to modify it and then insert it into the database.


TestTableRelation

Use this property to tell the system whether to include this field when it tests the field relations between primary and secondary indexes.

Applies to

Fields

Settings

The TestTableRelation settings are:

To have the system... | Choose...
Test the table relationship for this field | Yes (default)
Not test the table relationship for this field | No

Comments

You may want to use this property to exclude certain fields from the table relation test. If, for example, a table in your application has a field that is a foreign key, but records from this other table may have been deleted, you would not want to test the relationship with this table. Of course, you should only set this property to No if you are certain that testing this relationship would only cause insignificant errors - errors that do not compromise the consistency of your application tables.

This test is available from the Database option on the File menu. You can use this property to limit the number of relationships the system has to test.

See also TableRelation and ValidateTableRelation.


TextType

Use this property to specify which type of text this element or attribute contains.

Applies to

XMLports

Settings

The possible values are: Text and BigText. The default value is Text.


TimerInterval

Use this property to tell the system when to execute code contained in the active form's OnTimer trigger.

Applies to

Forms

Settings

The default value of this property is zero (0). This means that the system will not execute code in the OnTimer trigger.

You can specify a TimerInterval value in milliseconds ranging from zero to the highest defined integer (corresponding to approx. 25 days).

Comments

When you open a form for which you have specified a TimerInterval value, the system executes the OnOpenForm trigger. A timer then starts to count the TimerInterval in milliseconds. Once the specified interval has elapsed, the system will execute the OnTimer trigger. The timer then resets to zero and the system repeats the process until you close the form.

In some cases, the TimerInterval value specified may be too short to allow the system to complete execution of the OnTimer trigger before starting the next instance of the trigger. In this case, the system notes the number of overlapping instances and executes the trigger continuously as long as necessary.

Problems with your computer's operating system can affect the absolute performance of the timer.


Title

Use this property to have the system capitalize the first letter in each word the user types.

Applies to

Fields, text boxes

Settings

The Title settings are:

If you want the system to... | Choose...
Capitalize the first letter in each word | Yes
Show the entries exactly as entered | No (default)

Comments

The system checks both the control and the field settings during validation.


ToolTip

Use this property to create short help messages that appear when the user points the cursor at an object such as a command button or menu item. The value is taken from the ToolTipML property if this property is set.

Applies to

Labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms, menu items

Comments

The default is an empty string, which means there will be no tool tip.

See Also

ToolTipML describes the ToolTipML property, while a general description of the multilanguage functionality can be found here.


ToolTipML

The ToolTipML property is used to provide the text that will be used as a ToolTip for a control. ToolTipML is multilanguage enabled. This means that it can contain a list of texts in different languages. The text that is actually used will be selected according to the current language setting of the user. See the general description of the multilanguage features here for more information.

Applies to

Labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms, menu items

Format

The ToolTipML property has this format:

<Language ID>=<tooltip>

where <Language ID> is a Windows standard three-letter language ID and <caption> is the caption text for this language. Semicolons separate entries.

An example of a ToolTipML value:

DAN=Dette felt indeholder kundens navn;ENG=This field contains the name of the customer

Values are set up for Danish (DAN) and UK English (ENG).

How to Enter ToolTipML Values

You can enter values for the ToolTipML property in two ways:

  1. If you enter a ToolTip, this value will be inserted in ToolTipML as the value for the language that is currently selected. That is, if the language is set to Danish when a value is entered in ToolTip, ToolTipML will be updated with a DAN=<value> string. You have to use the abbreviated name (DAN for Danish, for example) of the languages.

  2. When the AssistButton in the ToolTipML Value field is clicked, the Multilanguage Editor opens. This is a form with two columns: Language and Value. The Language column is populated with all languages defined by Windows. For your convenience, the names, not the abbreviated names, of the languages are displayed. The ToolTipML value for a language is added by entering a value in the Value field for that language. You have to close this form by clicking OK. If it is closed by Esc, the ToolTipML field is NOT updated.

Comments

See the general description of the multilanguage features here for more information, including descriptions of what happens if there are no values for the language the user has selected.


TopLineOnly

Use this property to have the system display only the top line of the frame, with the caption left-justified.

Applies to

Frames

Settings

The TopLineOnly settings are:

To have the system display... | Choose...
Only the top line of the frame | Yes
The entire frame | No (default)


TopMargin

Use this property to set the top margin of a report. The unit of measure is 1/100 mm.

Applies to

Reports

Comments

A top margin specified in the page setup dialog will override TopMargin.

Some printers require a minimum margin. If you specify a margin that is smaller than the minimum margin, the minimum margin will be used when printing.

The default is 20 mm.


TotalFields

Use this property to indicate the fields of a data item for which the system should maintain totals. If this property is used in conjunction with the GroupTotalFields, totals can be maintained for both the groups that are defined and all records that are output; if used by itself, TotalFields will maintain totals for all records.

Applies to

Data items

Settings

A comma-separated list of field names. The fields can be selected by using the assist-edit function in the Value field of this property.

Comments

The totals are printed by placing controls that have the fields that are indicated in TotalFields as their source expressions in a Footer, GroupFooter or TransFooter section of the data item.


TransactionType

There are four basic transaction type options: Browse, Snapshot, UpdateNoLocks and Update. Each transaction type defines the behavior of a transaction in Microsoft Dynamics NAV and takes effect from the beginning of a transaction.

Additionally, there is a Report option that maps to one of the basic options. This enables a report to use the most concurrent read-only form of data access for the connected server. When you use Microsoft Dynamics NAV Database Server, it maps to Snapshot and when you use SQL Server, it maps to Browse.

The transaction behavior when using SQL Server is as follows:

Browse

This is a read-only transaction. Modifications cannot occur within the transaction. All read operations are performed with READ UNCOMMITTED locking. Therefore, no locks are placed and locks placed by other sessions are not honored. This means that it is possible to read uncommitted data.

Snapshot

This is a read-only transaction. Modifications cannot occur within the transaction. All read operations are performed with SERIALIZABLE locking. Therefore, share-locks are placed and are maintained until the end of the transaction. This guarantees a consistent snapshot of the data read within the transaction.

Microsoft's definition of "SERIALIZABLE" is as follows:

"A transaction isolation level that ensures that a database changes from one predictable state to another. If multiple concurrent transactions can be executed serially, and the results are the same, the transactions are considered serializable."

For further information about SERIALIZABLE locking, consult Microsoft's SQL Server documentation.

UpdateNoLocks

This is an update transaction. Modifications can occur within the transaction. The locking behavior for read operations on each table is the same as for the Browse transaction type until the table is either modified by a write operation or locked with the Record.LOCKTABLE function. From this point until the end of the transaction, all read operations are performed with both SERIALIZABLE and UPDLOCK locking.

This transaction type improves concurrency for all tables that users access within the transaction by delaying locking as much as possible. However, the disadvantage is that you must know when to lock the tables for the required transaction behavior.

This is the default transaction type if you have not specified a type with the CURRENTTRANSACTIONTYPE function.

Update

This is an update transaction. Modifications can occur within the transaction. The locking behavior for read operations on each table is the same as for the Snapshot transaction type until the table is either modified by any write operation or locked with the Record.LOCKTABLE function. From this point onwards, all read operations are performed with both SERIALIZABLE and UPDLOCK locking.

This transaction type provides full transaction isolation from the beginning of the transaction, regardless of the lock status of tables that users access within the transaction.


UpdateOnAction

Use this property to tell the system to save the current record before it executes the action associated with this control and then update the form after it completes the action.

Applies to

Command buttons, check boxes, option buttons, menu items

Settings

The UpdateOnAction settings are:

If you want the system to... | Choose...
Update this form before and after it executes the action | Yes (default)
Not update this form before and after it executes the action | No


UpdateOnActivate

Use this property to tell the system to update this form when it is activated.

Applies to

Forms

Settings

The UpdateOnActivate settings are:

If you want the system to... | Choose...
Update this form when activated | Yes
Not update this form when activated | No (default)


UseReqForm

Use this property to decide whether the user of the report or dataport will be presented with a request form or not.

Applies to

Reports, dataports

Settings

To... | Choose...
Not show a request form | No
Show a request form | Yes (the default)

Comments

If UseReqForm is No, no request form will be shown. This implies that the user will not be able to choose a sorting order or to set filters, and that the print dialog will not be shown (that is, a report will be printed and a dataport will be run immediately.)


UseSystemPrinter

Use this property to decide which printer will be suggested when the report is run.

Applies to

Reports

Settings

To suggest... | Choose...
The system default printer | Yes
The printer that is set for this User/Report combination in the system setup | No (the default)

Comments

The user will be able to select another printer at runtime (if UseReqForm is Yes.)

If the UseSystemPrinter is set to No, but there is no specific printer defined for the User/Report combination, the system default printer will be suggested.


ValidateTableRelation

Use this property to tell the system whether to validate a table relationship.

Applies to

Fields, text boxes

Settings

The ValidateTableRelation settings are:

To have the system... | Choose...
Validate the table relationship | Yes (default)
Not validate the table relationship | No

Comments

For fields, use this property to tell the system whether or not it should validate the user's entry based on the information already in the table set up through the TableRelation property.

If you want to let users enter any value without having the system validate the entry, choose No. For example, on the item card you can specify the vendor you normally purchase the item from. In the standard application, this property is set to No for this field, to let users select a vendor that may not already be in the Vendor table.

For text boxes, use this property to tell the system whether or not it should validate a table relationship.

See also TestTableRelations.


ValuesAllowed

Use this property to specify the values you want to allow in the field or text box.

Applies to

Fields, Text boxes

Comments

For example, if you only want the user to enter 1, 3, or 5 in this field, enter 1;3;5 here. Separate the values with a semicolon. The system recursively checks this property setting during validation.


VariableName

Use this property to specify a variable name for the table that you have specified in the SourceTable property. It is also used to specify a variable name for a text that you have specified in the SourceType property.

Applies to

XMLports

Comments

The text or table variables that you define here act the same way as variables that has been defined in the C/AL Globals window but they are not be visible in the C/AL Globals window but it is visible in the C/AL Symbol Menu.

The values of the VariableName and SourceTable properties correspond to the contents of the DataSource field in the XMLport Designer. The values that you enter in these properties in the Properties window are shown in the DataSource field in the XMLport Designer.

If you have defined a text variable, you can only see the name of the text variable in the DataSource field in the XMLport Designer.

Example:

If you have defined a table as an XML item, the DataSource field can display the following information:

Properties window |  | XMLport Designer
SourceTable | VariableName | DataSource field
Customer | <Customer> default | <Customer>(Customer)
Customer | Cust. | Cust.<Customer>


VertAlign

Use this property to determine how the system vertically aligns the data or the caption of the control.

Applies to

Labels, command buttons, menu buttons, check boxes, option buttons, text boxes

Settings

The VertAlign property settings are:

To align the data... | Select...
At the top | Top
At the bottom | Bottom (default for labels in column headings)
In the center | Center (default for labels, command buttons, menu buttons, check boxes, option buttons, text boxes)

Comments

If you choose bottom or center, the system truncates lines of the text as necessary.

See also HorzAlign.


VertGlue

Use this property to tell the system how to anchor this control vertically. You can anchor it to the top, bottom, or top and bottom of the form or subform.

Applies to

Labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms

Settings

The VertGlue settings are:

To anchor the control... | Select...
At the top | Top (default)
At the bottom | Bottom
To both the top and bottom | Both

Comments

If this control is contained in a table box, the system ignores the setting for this control.

If you select Both, the system resizes the control when the user resizes the window.

The HorzGlue and VertGlue properties are not active during design, except for HorzGlue on columns.

See also HorzGlue.


VertGrid

Use this property to set the distance between vertical grid lines in the form and sections designers. The grid is shown as one dot per five grid distances.

Applies to

Forms, reports (sections)

Settings

The VertGrid settings are:

To have the system... | Enter...
Use the default setting | default (1.1 millimeter)
Display no vertical grid | infinite
Display a custom grid you define | (the number; 0 means no grid)

The unit of measure is 1/100 mm.

Comments

Enter zero (0) or infinite if you do not want the system to display a vertical grid.

See also HorzGrid.


Visible

Use this property to tell the system whether to display the form or control.

Applies to

Forms, labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms, menu items

Settings

The Visible settings are:

To make the form or control... | Choose...
Visible | Yes (default)
Invisible | No

Comments

Since this property also applies to containers, such as forms and subforms, keep in mind that if the Visible property for the container is marked No, the system will not display the control, even if it is marked Yes here.

When this property is used to hide FlowFields on tabular forms, the FlowField is no longer calculated and this can improve performance slightly. However you might have some code on the form that uses the information in this FlowField and this will not work properly if the FlowField in question is invisible and therefore not calculated.

The setting of this property can be changed dynamically by using the VISIBLE function.


Width

Use this property to define the width of the form or control. The system shows you the width in increments of 1/100 of a millimeter.

Applies to

Forms, labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms

Comments

Typically, you will click on the form or control to select it and then use the mouse to size it. You can also enter an exact measurement.

If you use the wizard, the system sizes the form and controls for you. You can change the width as necessary.

For forms, changing the width here has no effect on any subforms. You can change the setting of this property dynamically by using the WIDTH function.

For controls, the width specifies the width of the column. Static controls in the heading inherit the width from the column control.

See also Height.


Width (Dataport field)

Use this property to determine the width of a field in a data item of a dataport.

Applies to

Fields (in dataports)

Settings

Set the integer value of Width to the number of characters in the field.

Comments

The setting of this property is only used if FileFormat is Fixed. If it is, StartPos and Width are used to define fields when records are imported or exported.


WithEvents

Use this property to specify whether you want C/SIDE to receive events from a component that it controls. A component can be an automation server or a custom control (OCX).

Applies to

Global variables of the type Automation.

Comments

When you declare a global variable of the type Automation, you can specify whether you want to receive events. When you set the WithEvents property for the variable to Yes, this automatically generates AL triggers for the events that the component provides. An AL trigger name consists of the name of the automation variable followed by "::<Event name>."


XMLVersionNo

Use this property to specify which version of XML the XML document conforms to. Two options are available: 1.0 (the default) and 1.1.

Applies to

XMLports

Comments

The XML version number is inserted into the XML document as the XML declaration, for example, <?xml version="1.0"?>.


XPos

Use this property to define the horizontal position of the form or control. The system shows you the position, in increments of 1/100 of a millimeter.

Applies to

Forms, labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms

Comments

This property is updated by the system when you insert a new object or drag a selected object to a new position. You can also enter an exact position manually in the Property Sheet.

If you use the wizard, the system positions the form and controls for you. You can change the position as necessary.

You can change the setting of this property dynamically by using the XPOS function.

For forms, the default position is centered.

For controls, you can also use the Align options on the Format menu to quickly align several controls.

If this control is contained inside a table box, the system ignores the setting for this control.

See also YPos and AutoPosition.


YPos

Use this property to define the vertical position of the form or control. The system shows you the position, in increments of 1/100 of a millimeter.

Applies to

Forms, labels, images, shapes, command buttons, menu buttons, check boxes, option buttons, text boxes, matrix boxes, picture boxes, indicators, frames, tab controls, table boxes, subforms

Comments

This property is updated by the system when you insert a new object or drag a selected object to a new position. You can also enter an exact position manually in the Property Sheet.

If you use the wizard, the system positions the form and controls for you. You can change the position as necessary.

You can change the setting of this property dynamically by using the YPOS function.

For forms, the default position is centered.

You can also use the Align options on the Format menu to quickly align several controls.

If this control is contained in a table box, the system ignores the setting for this control.

See also XPos and AutoPosition.

Normal

This class of field is used for ordinary fields that contain data stored in the database. The majority of the fields in the Microsoft Dynamics NAV Financial tables are ordinary fields.

FlowFilter

FlowFilter fields let you set ranges on the calculations shown in FlowFields. For instance, if a FlowField contains the total of customer entries, you can use a FlowFilter to see the total for a single month or range of months.

In the example described, the FlowFilter field is a date field. You can also set up FlowFilter fields to see information based on business units, departments, projects, and so forth.

The system does not save FlowFilter fields in the database. Instead, it stores them for each window on the individual workstation to let each user have his or her own filters.

FlowField

Flowfields display the result of the calculation described in the CalcFormula property. For instance, the Account Balance field in the General Ledger Account table shows the balance of the account and is calculated as the sum of the Net Amount field for all General Journal entries in the account.

You can use FlowFields to:

  • Calculate the total of a field over a set of records and display the results

  • Calculate averages

  • Determine the existence of records in a table

  • Determine the number of values in a table

  • Detemine the minimum value

  • Determine the maximum value

  • Look up a value in another column in another table

FlowFields are not physical fields stored in the database. Instead, they are a description of a calculation and a place for the system to display the result. To update a FlowField, you must use the CALCFIELDS function.

Table View

The term "table view" describes the view of the table you present to the user. You determine what records the user can see by setting filters, determining the sort order and selecting the keys.

RGB

The system uses the RGB color model for specifying colors. This model specifies the intensity of red, green, and blue on a scale of 0 to 255, with 0 (zero) indicating the minimum intensity. The settings of the three colors are converted to a single integer value by using this formula:

RGB value := Red + (Green * 256) + (Blue * 256 * 256)

Some examples:

Red | Green | Blue | RGB value | Color
255 | 0 | 0 | 255 | Red
0 | 255 | 0 | 65280 | Green
0 | 0 | 255 | 16711680 | Blue
0 | 255 | 255 | 16776960 | Cyan
255 | 0 | 255 | 16711935 | Magenta
255 | 255 | 0 | 65535 | Yellow
255 | 255 | 255 | 16777215 | White
128 | 128 | 128 | 8421504 | Gray
0 | 0 | 0 | 0 | Black

In order to extract the settings of the red, green and blue elements from an RGB value, you can use this method:

Convert the RGB value to a hexadecimal value. This will give you a hexadecimal number with up to six digits. From right to left each pair of hexadecimal digits is the setting of red, green and blue, respectively, and can be converted back to decimal. (If the hexadecimal number contains less than six digits, fill out the number with zeroes on the left.)

Examples:

RGB | Hex | Red | Blue | Green
6579300 | 646464 | 100 | 100 | 100
16422450 | FA9632 | 50 | 150 | 250

SumIndexFields

SumIndexFields(tm) let you quickly calculate the sums of numeric columns in tables, even in tables with thousands of records. SumIndexFields form the basis on which FlowFields are built.

A SumIndexField is associated with a key in the table. Each key can have up to 20 associated SumIndexFields. When you design your database, you can associate a decimal field with a key as a SumIndexField. This tells the DBMS to create and maintain a structure that contains the accumulated sum of the values in a column. When a user selects a new key, any SumIndexFields associated with that key become accessible.


OnActivate

The C/AL code in this trigger is executed when the control is activated.

Applies to

Command buttons, menu buttons, check boxes, option buttons, text boxes, picture boxes, indicators, subforms

Comments

When you call the ACTIVATE function, the system executes the OnDeactivate trigger for the previous control and then activates the new control. After the system activates the new control, it executes the code in the OnActivate trigger.

If there is an error in the C/AL code you enter into this trigger, the system closes the form.

You cannot use this trigger to write to the database.


OnActivateForm

The C/AL code in this trigger is executed after the user activates the form.

Applies to

Forms

Comments

For example, assume the user has two forms displayed, Form A and Form B, and the user is entering data on Form A. When the user activates Form B, typically by clicking on the form, the system executes the code in the OnDeactivateForm trigger for Form A and then executes the code in this trigger for Form B.

If there is an error in the code in this trigger, the system closes the form.


OnAfterAssignField

The C/AL code in this trigger is executed after a field has been assigned a value and before it is validated and imported.

Applies to

XMLports

Comments

This trigger is only used to import data. It gives you access to the values in the imported record and is typically used to manipulate the data that is being imported.


OnAfterAssignVariable

The C/AL code in this trigger is executed after the value defined in the XML document has been assigned to the text variable.

Applies to

XMLports

Comments

This trigger is only used to import data and gives you access to the imported value in text format.


OnAfterExportRecord

The C/AL code in this trigger is executed after a record has been exported.

Applies to

Dataports

Comments

This trigger will only be executed when Import is No.

You can use this trigger to perform operations on the external (export) file before the next record is exported - for example, moving the file pointer with f.SEEK in order to insert the next record in a specific place in the file.


OnAfterFormatField

The C/AL code in this trigger is executed after the value of a field has been formatted.

Applies to

Dataports

Comments

This trigger will only be executed when Import is No.

The trigger is executed after the field has been formatted, but before it is written to the file. The Text parameter contains the formatted value of the field, and you can do any processing that is necessary before actually writing the field to the file.


OnAfterGetCurrRecord

The C/AL code in this trigger is executed after the current record is retrieved from the table.

Applies to

Forms

Comments

In a form with a table box, the system only calls this trigger when it updates the current record in the table box.

If there is an error in the code in this trigger, the system closes the form.


OnBeforePassField

The C/AL code in this trigger is executed before a field is passed to the XML document.

Applies to

XMLports

Comments

This trigger is only used to export data. This trigger gives you access to the field value in the record just before it is exported and is typically used to manipulate the field.


OnAfterGetRecord (Data items)

The C/AL code in this trigger is executed each time a record has been retrieved from the data item.

Applies to

Data items

Comments

Use this trigger to perform any processing that is needed, based on the values in the fields of the individual records of a data item.

Example

If the record contains FlowFields, you can put CALCFIELDS statements in this trigger to have them calculated. While it is normally easier to use the CalcFields property to have it done automatically, there are situations where you have to use this trigger to perform the calculation explicitly. This is the case if, for example, you apply FlowFilters based on the context of the report or the dataport to the FlowFields inside this trigger. Then, you have to recalculate the FlowFields after you have applied the FlowFilters.

Another example is when you need to retrieve information from a table that is external to the report or dataport. This is the situation when the records of a data item contain fields that are foreign keys (that is, fields that are primary keys in other tables), and you want to extract further information from the related tables. For example, in a report, the records in a data item might contain a field with a Vendor code, while you want to print the full name and address of the vendor. You use this trigger to retrieve the information in order to print it in your report.


OnAfterGetRecord (Forms)

The C/AL code in this trigger is executed after a record is retrieved from a table but before it is displayed to the user. Typically, you will use this trigger to calculate variables that depend on the current record.

Applies to

Forms

Comments

In a form with a table box, the system calls this trigger for each record in the table box, as the records are updated.

If there is an error in the code in this trigger, the system closes the form.


OnAfterGetRecord (XMLports)

The C/AL code in this trigger is executed after a record is retrieved from a table and before it is exported to the XML document.

Applies to

XMLports

Comments

This trigger is only used to export data. It is typically used to manipulate the fields that are being exported from the table and to calculate the variables that depend on the record.


OnAfterImportRecord

The C/AL code in this trigger is executed after a record has been read from the external (import) file.

Applies to

Dataports

Comments

This trigger will only be executed when Import is Yes.

The trigger is executed after the record has been read from the table, but before it is inserted in the table. You can use this trigger to perform any postprocessing that is necessary before the record is inserted, SKIP inserting this record or stop the processing of the data item altogether by using BREAK.


OnAfterInitRecord

The C/AL code in this trigger is executed after a record has been loaded.

Applies to

XMLports

Comments

This trigger is only used to import data and is typically used to set up the preconditions for the record before it is inserted into the table in the database.


OnPreXMLItem

The C/AL code in this trigger is executed after the table has been initialized and before you start exporting data to an XML object. This trigger only applies to tables.

Applies to

XMLports

Comments

This trigger is only used to export data and is typically used to set filters on the data and to initialize variables before finding the first record.


OnAfterInput

The C/AL code in this trigger is executed when the user switches focus from one control to another.

OnAfterInput(TextString)

Applies to

Text boxes

Comments

The system executes this trigger after the user switches focus from one control to another. This means after it executes the OnInputChange trigger for the last time and before it executes OnValidate.

The TextString parameter contains the user's entry exactly as it was entered.

If there is an error in the C/AL code you enter into this trigger, the system closes the form.

You cannot use this trigger to write to the database.


OnAfterInsertRecord

The C/AL code in this trigger is executed after a record has been inserted into a table in the database.

Applies to

XMLports

Comments

This trigger is only used to import data and can be used to move data from temporary tables to real tables.


OnAfterValidate

The C/AL code in this trigger is executed after the user's input is validated.

Applies to

Check boxes, option buttons, text boxes, picture boxes, indicators

Comments

Use this trigger if you want to update the form after the system validates the user's input.

If there is an error in the C/AL code you enter into this trigger, the system closes the form.

You can use this trigger to write to the database.


OnAssistEdit

The C/AL code in this trigger is executed in place of the normal AssistEdit features the system provides.

Applies to

Text boxes

Comments

If there is an error in the C/AL code you enter into this trigger, the system closes the form.

You can use this trigger to write to the database.


OnBeforeEvaluateField

The C/AL code in this trigger is executed after the field has been imported from the external (import) file.

Applies to

Dataports

Comments

This trigger will only be executed when Import is Yes.

The trigger is executed after the field has been imported from the file, but before the value has been evaluated and validated. The Text parameter contains the imported field in text format, and you can perform any processing that is necessary before actually evaluating the field.


OnBeforeExportRecord

The C/AL code in this trigger is executed before a record is exported.

Applies to

Dataports

Comments

This trigger will only be executed when Import is No.

When it is executed, the next record of the data item will have been retrieved and any FlowFields have been calculated. You can use this trigger to perform any postprocessing that is necessary before the record is exported, SKIP exporting this record or stop the processing of the data item altogether by using BREAK.


OnBeforeImportRecord

The C/AL code in this trigger is executed before the next record is read from the external (import) file.

Applies to

Dataports

Comments

This trigger will only be executed when Import is Yes.

You can use this trigger to perform operations on the external (import) file before the next record is imported - for example, moving the file pointer with f.SEEK in order to read a specific record next.


OnBeforeInput

Use this trigger to specify whether the user can edit the control.

Applies to

Text boxes

Comments

This trigger only determines whether the control is editable.

The system executes this trigger after it executes OnFormat and before it executes OnInputChange.

If there is an error in the C/AL code you enter into this trigger, the system closes the form.

You cannot use this trigger to write to the database.


OnBeforeInsertRecord

The C/AL code in this trigger is executed after a record has been loaded and before it is inserted into a table in the database.

Applies to

XMLports

Comments

This trigger is only used to import data and is typically used for some last minute manipulation of the record before it is inserted into the table in the database.


OnBeforePassVariable

The C/AL code in this trigger is executed after the source expression has been formatted into a text variable and before the text variable is passed to the XML document.

Applies to

XMLports

Comments

This trigger is only used to export data and is typically used to manipulate the text variable.


OnBeforePutRecord

The C/AL code in this trigger is executed before a record is saved.

Applies to

Forms

Comments

If there is an error in the code in this trigger, the system closes the form.


OnCloseForm

The C/AL code in this trigger is executed immediately after a form is removed from the screen but before it has been closed.

Applies to

Forms

Comments

This trigger is called by a user action, such as when the user clicks on a Close button or takes an equivalent action, or when the CurrRec.Close function is called. Before the system executes this trigger, it executes the OnQueryCloseForm trigger.

If there is an error in the code in this trigger, the system closes the form.

You can write to the database from within this trigger.


OnCreateHyperlink

The C/AL code in this trigger is executed after the user creates a URL to a form or a report.

Object.OnCreateHyperlink(URL)

Object

A variable of the data type Form or Report and any subtype.

URL

Data type: text or code

Applies to

Forms and reports

Comments

A user can create a URL for the active form or report by clicking for example:

  • File, Send, Link by E-Mail

  • File, Send, Copy Link

  • File, Send, Shortcut to Desktop

C/SIDE fills in the URL parameter with the default URL string to the form. You can change the default value by changing the contents of the string.

Example

The following is an example of what a URL string can look like:

navision://client/run?database=c:\database.fdb&company=dot.com&target=form991&forcenewinstance=yes


OnDeactivate

The C/AL code in this trigger is executed when the control is deactivated.

Applies to

Command buttons, menu buttons, check boxes, option buttons, text boxes, picture boxes, indicators, subforms

Comments

When you call the ACTIVATE function, the system executes the code in the OnDeactivate trigger before it executes the OnActivate trigger for the new control. In other words, the system executes this trigger before it deactivates the control.

If there is an error in the C/AL code you enter into this trigger, the system closes the form.

You cannot use this trigger to write to the database.


OnDeactivateForm

The C/AL code in this trigger is executed after the user places focus on another form but before it deactivates this form.

Applies to

Forms

Comments

For example, assume the user has two forms displayed, Form A and Form B, and the user is entering data on Form A. When the user activates Form B, typically by clicking on the form, the system executes the code in this trigger for Form A and then executes the code in the OnActivateForm trigger for Form B.

If there is an error in the code in this trigger, the system closes the form.


OnDelete

The C/AL code in this trigger is executed when a user tries to delete a record.

Applies to

Tables

Comments

The system executes this trigger before it executes its default delete behavior.

If there is an error in the C/AL code you enter into this trigger, the system does not delete the record.


OnDeleteRecord

The C/AL code in this trigger is executed before the system deletes a record from the table.

[Ok]:= OnDeleteRecord

Ok

Data type: boolean

This return value tells the system whether to delete the record. The system checks the return value after each function call.

If Ok is... | The system will...
TRUE | Delete the record (default)
FALSE | Not delete the record

Applies to

Forms

Comments

If there is an error in the code in this trigger, the system cancels the action but does not close the form.

You can write to the database from within this trigger.


OnDrillDown

The C/AL code in this trigger will override the default drill-down behavior defined in the table definition for the FlowField.

Applies to

Text boxes

Comments

If there is an error in the C/AL code you enter into this trigger, the system cancels the drill-down. You can use this trigger to write to the database.


OnFindRecord

By default, when the system opens a form it displays the record that was shown when the user last exited the form. Insert C/AL code into this trigger to override this default behaviour and have the system display the first, last, or a specific record as defined in the C/AL variable, Rec.

[Ok]:= OnFindRecord(Which)

Which

Data type: text or code

Here are the options:

When the system returns the... | The parameter is...
First record | - (a dash)
Last record | + (a plus sign)
Record defined in Rec or the nearest match | =><

Ok

Data type: boolean

This return value tells the system whether or not the C/AL code in this trigger found the record.

If Ok is... | The record was...
TRUE | Found
FALSE | Not found (default)

Applies to

Forms

Comments

If there is an error in the code in this trigger, the system closes the form.

The system also calls this trigger when the user goes to the first or last record, for example, by pressing Ctrl+Home or Ctrl+End.


OnFormat

Use this trigger to determine how the entries the user makes appear on the screen, including the horizontal and vertical alignment of the entry.

OnFormat(TextString)

Applies to

Text boxes

Comments

The formatting instructions you enter in this trigger, via C/AL code, affect only what the user sees on screen. The code you place in this trigger does not affect how the system stores the data.

This is the first trigger the system executes when a user highlights the control to enter data. The system then executes the OnBeforeInput trigger.

The system calls this trigger after it performs the default formatting of the control. The TextString parameter contains the default formatting.

If there is an error in the C/AL code you enter into this trigger, the system closes the form.

You cannot use this trigger to write to the database.


OnHyperlink

The C/AL code in this trigger is executed after the OnInit trigger is executed for a form and after the OnInitReport trigger is executed for a report.

Object.OnHyperlink(URL)

Object

A variable of the data type Form or Report and any subtype.

URL

Data type: text or code

The trigger executes a URL string.

Applies to

Forms and reports

Comments

A URL can be created with a call to the trigger f.OnCreateHyperlink.


OnInit

Use this trigger to initialize the user-defined variables on the form. The system executes the C/AL code you enter into this trigger immediately after it clears the variables when it loads the form.

Applies to

Forms

Comments

This trigger cannot be used to access the controls on the form. You can change the properties that are dynamic, including those properties which can only be changed when the form is opened.

After the system executes this trigger, it calls the OnOpenForm trigger.

If there is an error in the code in this trigger, the system closes the form.


OnInitDataPort

The C/AL code in this trigger is executed when the dataport is loaded, for example code that initializes global variables.

Applies to

Dataports

Comments

The system executes this trigger before the request form is run and before any table views or filters are set.


OnInitReport

The C/AL code in this trigger is executed when the report is loaded. This could be, for example, code that initializes global variables.

Applies to

Reports

Comments

The system executes this trigger before the request form is run and before any table views or filters are set.


OnInitXMLport

The C/AL code in this trigger is executed when the XMLport is loaded and before any table views and filters are set.

Applies to

XMLports


OnInputChange

The C/AL code in this trigger is executed while the user makes entries into a text box. You can use this trigger to check the entries the user is making as he or she enters information.

Applies to

Text boxes

Comments

The system executes this trigger after it executes OnBeforeInput. It will continue to execute this trigger, after each keystroke, until the user finishes input. The system then executes the OnAfterInput trigger.

If there is an error in the C/AL code you enter into this trigger, the system closes the form.

You cannot use this trigger to write to the database.


OnInsert

The C/AL code in this trigger is executed when a user inserts a new record into this table.

Applies to

Tables

Comments

The system executes this trigger before it executes its default insert behavior.

If there is an error in the C/AL code you enter into this trigger, the system does not insert the new record.


OnInsertRecord

The C/AL code in this trigger is executed before the system inserts a new record into the table.

[Ok]:= OnInsertRecord

Ok

Data type: boolean

This return value tells the system whether it should insert the record. The system checks the return value after each function call.

If Ok is... | The system will...
TRUE | Insert the record (default)
FALSE | Not insert the record

BelowxRec

Data type: boolean

Upon return, this parameter shows whether the new record was inserted below xRec or not. When FALSE, it was not, that is: the record was inserted between xRec and another already existing record; when TRUE, the new record was inserted below xRec (as the last record in the table, so to speak.)

Applies to

Forms

Comments

If there is an error in the code in this trigger, the system cancels the action but does not close the form.

You can write to the database from within this trigger.


OnLookup (Controls)

The C/AL code in this trigger is executed in place of the normal lookup features the for this form only.

There are three layers of lookups in the system. The first layer is the system's default lookup behavior, which provides a lookup into the table with no filters applied or any other special parameters. You can define a lookup trigger for a field that the system will use in place of its standard behavior. Finally, you can use this trigger to define a lookup for a text box that the system will use in place its default standard lookup behavior or the lookup defined in the OnLookup trigger for the field.

OnLookup(TextString)

Applies to

Text boxes

Comments

For example, for the Customer Code field, the system automatically provides a lookup into the Customer table. If, for any reason, you want the system to look elsewhere or if you want to place a filter on the table before displaying the lookup, you would enter the C/AL code to do that here.

Insert C/AL code into this trigger that tells the system to place the entry the user highlights on the lookup into the field. Place the result of the lookup in the TextString parameter.

If there is an error in the C/AL code you enter into this trigger, the system cancels the lookup.

You can use this trigger to write to the database.


OnLookup (Fields)

The C/AL code in this trigger causes the system to display a lookup window you design.

There are three layers of lookups in the system. The first layer is the system's default lookup behavior, which provides a lookup into the table with no filters applied or any other special parameters. You can use this trigger to define a lookup for the field, which the system will use in place of its standard behavior. Finally, for the text box, you can define a lookup the system will use in place of the system's standard behavior or the lookup defined in this trigger - see OnLookup for a description of that trigger.

Applies to

Fields

Comments

The system executes this trigger instead of its default lookup behavior.

When using this trigger you typically first take a value from the field to determine what filters to apply or any other special parameters. Then you run the lookup form in modal mode. Next you transfer the value the user selects back to the field when the user chooses OK.

If there is an error in the C/AL code you enter into this trigger, the system closes the lookup form.


OnModify

The C/AL code in this trigger is executed when a user modifies an existing record.

Applies to

Tables

Comments

The system executes this trigger before it executes its default modify behavior.

If there is an error in the C/AL code you enter into this trigger, the system ignores the changes to the record.


OnModifyRecord

The C/AL code in this trigger is executed before the system modifies a record in the table.

[Ok]:= OnModifyRecord

Ok

Data type: boolean

This return value tells the system whether to modify the record. The system checks the return value after each function call.

If Ok is... | The system will...
TRUE | Modify the record (default)
FALSE | Not modify the record

Applies to

Forms

Comments

If there is an error in the code in this trigger, the system cancels the action but does not close the form.

You can write to the database from within this trigger.


OnNewRecord

The C/AL code in this trigger is executed after a new record is initialized but before the user can actually make any entries.

OnNewRecord(BelowxRec)

BelowxRec

Data type: boolean

Upon return, this parameter shows whether the new record was inserted below xRec or not. When FALSE, it was not, that is: the record was inserted between xRec and another already existing record; when TRUE, the new record was inserted below xRec (as the last record in the table, so to speak.)

Applies to

Forms

Comments

Typically, you use this trigger to initialize a new record and other variables on the form.

If there is an error in the code in this trigger, the system closes the form.


OnNextRecord

The C/AL code in this trigger determines how the system steps through the records in the table to determine the next record to display.

[ActualSteps]:= OnNextRecord(Steps)

Steps

Data type: integer

The number of records the system steps through before displaying another record. A negative value indicates steps backwards.

ActualSteps

Data type: integer

This return value tells the system the actual number of steps or records cycled through. The default is zero (0).

Applies to

Forms

Comments

The system executes this trigger in place of its default next record behavior.

If there is an error in the code in this trigger, the system closes the form.


OnOpenForm

The C/AL code in this trigger is executed after the form has been initialized and run.

Applies to

Forms

Comments

In this trigger you can change the properties that are dynamic, including those properties which can only be changed when the form is opened, such as the MaximizedOnOpen property.

The system executes this trigger after it executes the OnInit trigger.

If there is an error in the code in this trigger, the system closes the form.

You can write to the database from within this trigger.

If you use the LOCKTABLE function in this trigger, the lock on the table in question will be released as soon as the system has executed the trigger and not when you close the form.


OnPostDataItem

The C/AL code in this trigger is executed after a data item has been processed.

Applies to

Data items

Comments

The system executes this trigger after the last record in the data item has been processed (but before the OnPostReport or OnPostDataPort trigger is executed, if it is the last data item of the report or dataport).

Example

This trigger can be used to perform any cleaning-up or post-processing that is necessary after a data item has been processed. If, for example, you are creating a non-printing report where records have been updated, you can update all the records with the modification date like this:

MODIFYALL("Modification Date",TODAY);


OnPostDataPort

The C/AL code in this trigger is executed after a dataport has been run.

Applies to

Dataports

Comments

The system executes this trigger after all data items have been processed.


OnPostReport

The C/AL code in this trigger is executed after a report has been run.

Applies to

Reports

Comments

The system executes this trigger after all data items have been processed. The trigger is not run, however, if the report was stopped manually or by the QUIT function before processing had concluded.

Example

As this trigger is executed after the report has been processed, you can use it to inform the user about the result of the report run. If, for example, certain records could not be processed, but this is not considered a fatal error that should stop processing altogether, you could inform the user of the condition from this trigger:

IF ProblemsInReport THEN
MESSAGE(Text000, NumberOfErrors);

Create the following text constant in the C/AL Globals window:

Text Constant | ENU Value
Text000 | '%1 records were not processed'

As this trigger is executed before the End Write Transaction, you can also give the user the opportunity to rollback back the changes to the database (by leaving the report with the QUIT function.)


OnPostSection

The C/AL code in this trigger is executed after a section has been processed.

Applies to

Sections

Comments

The system executes this trigger after the section has been processed, but before it is actually printed.

This trigger should only be used to perform processing that has to do with the visual output of the report - not processing of data.

In this trigger the actual page number is valid, because if the section could not be printed on the current page, the necessary page break will already have been inserted by the time this trigger is executed.


OnPostXMLport

The C/AL code in this trigger is executed after the XMLport has been run.

Applies to

XMLports

Comments

This trigger is executed after all the data items have been processed.


OnPreDataItem

The C/AL code in this trigger is executed before a data item is processed.

Applies to

Data items

Comments

The system executes this trigger before the data item is processed, but after the associated variable has been initialized and table views and filters have been set.

Example

You can use this trigger to add further filtering than what is established by the DataItemLink or DataItemTableView properties, if, for example, you need to put a filter on an indented data item, based on more complex relations, perhaps some that require calculations. You can use the SETRANGE or SETFILTER function to add the extra delimitations.

If you need to create totals for a variable (as opposed to a field), you can add a statement like:

CurrReport.CREATETOTALS(SomeVariable);

to this trigger to have the totals maintained in the same way as totals for fields are maintained by using the TotalFields property.


OnPreDataPort

The C/AL code in this trigger is executed before the dataport is run.

Applies to

Dataports

Comments

The system executes this trigger after the request form has been run. The table views and filters for the data items in the dataport are set while this trigger is executed.


OnPreReport

The C/AL code in this trigger is executed before the report is run.

Applies to

Reports

Comments

The system executes this trigger after the request form has been run. The table views and filters for the data items in the report are set while this trigger is executed.

Example

As this trigger is executed after the request form has been processed, you have access to the filters that the user may have set. If you want to print the settings of these filters in the report, you can retrieve them as text strings like this:

ReportFilter := SomeRecord.GETFILTERS;

and then use the ReportFilter text string as the source expression of a control in a section of the report. See also GETFILTERS.


OnPreSection

The C/AL code in this trigger is executed before a section is processed.

Applies to

Sections

Comments

The system executes this trigger before calculating the space that is required for the section when it is outputted.

This trigger should only be used to perform processing that has to do with the visual output of the report - not processing of data.

A significant use of this trigger is to decide whether a section should be outputted, based on the value in one or more fields, or the setting of a variable.

Example

If, in a report, you do not want to print records where a field contains a certain value, you can put code in this trigger to test the field, and, when necessary, suppress printing it, like this:

CurrReport.SHOWOUTPUT(Amount <> 0);


OnPreXMLport

The C/AL code in this trigger is executed after the table views and filters are set and before the XMLport is run.

Applies to

XMLports


OnPush

The C/AL code in this trigger is executed when the user clicks the control with the left mouse button.

Applies to

Command buttons, check boxes, option buttons, menu items, labels, images, picture boxes, indicators, shapes

Comments

Typically, you will use attributes to tell the system to run a report or open a form when a button is pushed or a box is checked. You can, however, use this trigger to apply a filter before the report is printed or the form is displayed.

The system calls this trigger after it executes the default push action, such as RunObject.

If there is an error in the C/AL code you enter into this trigger, the system cancels the PushAction.

You can use this trigger to write to the database.


OnQueryCloseForm

The C/AL code in this trigger is executed immediately before the system closes the form.

[Ok]:= OnQueryCloseForm

Ok

Data type: boolean

This return value tells the system whether or not to close the form. The system checks the return value after each function call.

If Ok is... | The system...
TRUE | Closes the form (default)
FALSE | Does not close the form

Applies to

Forms

Comments

If neither the form nor any child form returns FALSE in this trigger, the system calls the OnCloseForm trigger, first for all child forms and then for the form itself (the parent form).

If there is an error in the code in this trigger, the system cancels the close action but does not close the form.

You can write to the database from within this trigger.


OnRename

The C/AL code in this trigger is executed when a user tries to rename a record.

Applies to

Tables

Comments

When you choose the option to rename a record, the system renames the record throughout the database. This process can take some time to complete, depending on the size of the database.

The system executes this trigger before it executes its default rename behavior.

If there is an error in the C/AL code you enter into this trigger, the system does not rename the record.


OnTimer

The system executes the C/AL code in this trigger once it has executed the OnOpenForm trigger and after the time specified in the TimerInterval property has elapsed. The frequency with which the system executes the OnTimer trigger is determined by the value you have specified for the TimerInterval property.

Applies to

Forms

Comments

If the C/AL code you enter into the OnTimer trigger makes large demands on system resources, this will have an adverse effect on the performance of the system.


OnValidate (Controls)

The C/AL code in this trigger is executed when the user leaves the control. Typically this trigger is used to make sure the entry is acceptable.

Applies to

Check boxes, option buttons, text boxes, picture boxes, indicators.

Comments

For example, you could use OnAfterInput to change the entry "P" into the first day of the current period and then use this trigger to make sure that day is valid.

The system executes this trigger after it executes the OnAfterInput trigger and after it executes the default validation for the control.

If there is an error in the C/AL code you enter into this trigger, the system does not close the form. The system does, however, invalidate the user's input.

You can use this trigger to write to the database.

You cannot call the UPDATE function in this trigger.


OnValidate (Fields)

The C/AL code in this trigger is executed when the system validates user input.

Applies to

Fields

Comments

The system executes this trigger after it executes its default validation behavior.

If there is an error in the C/AL code you enter into this trigger, the system displays an error message, leaves the user's entry in the field, but does not write the record to the database.


Caption Classes

When you have set the CaptionClass property on a field or control, users can configure the caption of the field or control without having to modify code.

C/SIDE passes the value of the CaptionClass property to the trigger with ID 15 on Codeunit 1, which translates the caption class to a caption that users can see. The following diagram illustrates this sequence:

Codeunit 1, trigger ID 15

C/SIDE calls this trigger with a language and a caption class. The trigger must convert the caption class into the specific caption for that language and return it as a string. Language is specified as an integer. Caption class is a text.

Example

TranslateCaptionClass(Language : Integer; CaptionClass : Text[80]) : Text[80]

case Language of

  1036 :

  case CaptionClass of

  'DIM1' : EXIT('Projet');

  'DIM2' : EXIT('Département');

  end;

 1033 :

  case CaptionClass of

  'DIM1' : EXIT('Project');

  'DIM2' : EXIT('Department');

  end;

end;

EXIT('');


Code Coverage Functionality

When you add the function (trigger) with ID 6 to Codeunit 1, the Code Coverage menu item appears on the Debugger submenu of the Tools menu. When users select the menu item, the trigger code must open a form. From here, they must be able to start and stop the logging of code. They must also be able to view the code that was logged.

You can use the CODECOVERAGELOG function to start and stop the logging of code.


Code Example for Streams

This code example demonstrates how you can read from and write to streams. We have defined the following variables:

Variable Name | Data Type | Subtype
recEmployee | Record | Employee
XMLDom | Automation | XMLDomDoc
StreamOutObj | OutStream |
StreamInObj | InStream |
Txt | Text |
Buffer | Text |
CreationDate | Date |

Writing Data to an OutStream

Here we want to create an OutStream to stream data out of a BLOB field for storage in an external object.

// Firstly, we define the record number we want to use.

recEmployee."No." := '5555';

// We now load the XML DOM, which will pass the OutStream to the external object.

XMLDom.load('SomeData.xml');
recEmployee.Picture.CREATEOUTSTREAM(StreamOutObj);
StreamOutObj.WRITE('Ver. 1.00');

// Write version.

StreamOutObj.WRITE('Company Ltd.');

// Write (c).

StreamOutObj.WRITE(TODAY);

// Write a DATE (today).

// The following information will be written as plain text.

StreamOutObj.WRITETEXT('Dear Customer,');
StreamOutObj.WRITETEXT();

// This inserts a carriage return and a new line.

StreamOutObj.WRITETEXT('We
 would like to thank you for your help.');
StreamOutObj.WRITETEXT();
StreamOutObj.WRITETEXT('We hope to see you soon!');
StreamOutObj.WRITETEXT();
XMLDom.save(StreamOutObj);
recEmployee.MODIFY();

Reading Data from an InStream

// Here we want to stream data into a BLOB field. To do so, we must create an InStream.

recEmployee.Picture.CREATEINSTREAM(StreamInObj);

// Read version.

StreamInObj.READ(Txt);
MESSAGE(Text000, Txt);

// Read (c).

StreamInObj.READ(Txt);
MESSAGE(Text001, Txt);

// Read date.

StreamInObj.READ(CreationDate);
MESSAGE(Text002, CreationDate);
StreamInObj.READTEXT(Buffer);
Message(Buffer);
StreamInObj.READTEXT(Buffer);
Message(Buffer);
StreamInObj.READTEXT(Buffer);
Message(Buffer);
XMLDom.load(StreamInObj);

Create the following text constants in the C/AL Globals window:

Text Constant | ENU Value
Text000 | 'Version is: %1'
Text001 | 'Copyright %1'
Text002 | 'Creation Date: %1'

More information:

InStreams and OutStreams


COM Data Types and C/AL Data Types

The following table shows how you map C/AL data types to COM data types:

C/AL Data Type | COM Data Type | Comment
Boolean | VARIANT_BOOL (VT_BOOL) |
Option | long (VT_I4) |
Integer | long (VT_I4) |
BigInteger | long (VT_I4) |
Decimal | CURRENCY (VT_CY) | The CURRENCY type in COM is a special data type with a fixed point, which has 15 digits to the left of the point and 4 to the right. You should note that the Decimal type in C/AL does not have a fixed point and can have a total of 18 digits. This could possibly lead to some rounding being performed when a Decimal number is passed to a method that expects a CURRENCY, the server manipulates that number and returns it as a CURRENCY. No matter how many digits the original Decimal had to the right of the decimal point, the returned CURRENCY will have no more than 4 digits.
Char | BSTR (VT_BSTR) |
Text | BSTR (VT_BSTR) |
Code | BSTR (VT_BSTR) |
Date | DATE (VT_DATE) |
Time | void (VT_VOID) |
DateTime | DATE (VT_DATE) |
Automation | TypedObject, UntypedObject (VT_DISPATCH) |
InStream | VT_STREAM |
OutStream | VT_STREAM |
Variant | VARIANT (VT_VARIANT) |

The following table shows how you map COM data types to C/AL data types:

COM Data Type | C/AL Data Type | Comments
VT_UNKNOWN | InStream or OutStream | Only the IID_IStream and IID_SequentialStream interfaces are supported. If you pass any other IUnknown interface, an error will occur at runtime.
short (VT_I2) | Integer |
long (VT_I4) | Integer BigInteger |
float (VT_R4) | Decimal |
double (VT_R8) | Decimal | The format of double and the C/AL Decimal are not completely compatible. From COM to C/AL, 14 significant digits are supported. If a server returns a number with more digits, an overflow error will occur at runtime.
CURRENCY (VT_CY) | Decimal | The CURRENCY type in COM is a special data type with a fixed point, which has 15 digits to the left of the point and 4 to the right. You must note that the Decimal type does not have a fixed point and can have a total of 18 digits.
DATE (VT_DATE) | Date DateTime | The COM DATE type contains both a date and a time value. C/AL has Date and Time as separate data types. Therefore, the time part of a COM DATE type will be lost when the COM DATE type is mapped to the C/AL Date type. To keep the date and the time, map the COM Date type to the C/AL DateTime data type. For more information, see VARIANT2DATE, VARIANT2TIME and DATI2VARIANT.
BSTR (VT_BSTR) | Text |
VARIANT_BOOL (VT_BOOL) | Boolean |
TypedObject/UntypedObject (VT_DISPATCH) | Automation/OCX |
VT_EMPTY | Text |
VARIANT (VT_VARIANT) | Variant |

Unsigned char (VT_UI1), SCODE (VT_ERROR) and SAFEARRAY (VT_ARRAY)

You can use the C/AL variant data type to pass unsigned char, SCODE or SAFEARRAY to another variant that supports these types. You cannot assign them to C/AL data types.

Comments

When you call a method with a ByRef parameter, the normal C/AL type conversions do not take place. This means that, for example, if the parameter is of type float, you have to use a C/AL variable of type Decimal. You cannot use Integer and have C/AL convert it for you. (Hint: if the value you want to pass has a "wrong" type - when, for example, it is a value from a database record field - you can assign it to a C/AL variable of the correct type before calling the COM object method.)

You will sometimes see a COM object method or a property in the C/AL Symbol Menu that has the type IDispatch. This means that the method or property returns or expects a COM object. In this case, you must use a C/AL Automation variable that has been declared (through the Subtype ) to be the correct COM object. You will have to study the documentation for the automation server to gain the necessary information.

You will also see properties and methods that do not have one of the "normal" types. For example, a method in Microsoft Excel can have a return value of type WORKBOOK. This means that the automation server has implemented a USERDEF type. C/SIDE supports USERDEF types in two contexts: IDispatch and Enumeration.

If the USERDEF type is an IDispatch, it means that is an interface (class, "object") with a specific GUID. You will have to use the same object for a return value or parameter. You do this by creating an Automation variable with the correct Subtype.

For example, Microsoft Excel has a number of methods that return a WORKBOOK variable. This means that you must declare a variable of type Automation, and with this Subtype: 'Microsoft Excel 8.0 Object Library'.Workbook.

If the USERDEF type is an Enumeration, you should know that you cannot use the symbolic name (for example, xl3DPie), but you must use the enumerator (for example, -4102). For Microsoft Office products, you can find this value by using the VBA Object Browser.


Composing URLs

URL format

The general format of the URL (Uniform Resource Locator) is:

navision://client/run?name1=value1&name2=value2&name3=value3

The syntax of each argument is name=value, and arguments are separated by "&"; name is case insensitive and may contain any alphanumeric character; value is a string that can contain any character. You can provide any number of arguments. The program ignores unknown arguments.

Valid name characters: [A..z] and [0..9].

Valid value characters: all

Note

The character "&" (=and) must be escaped as follows: "&&." This means that when there is only one "&" in a URL a separation of two arguments is indicated. Two "&&" indicate that "&" is part of value.

The following arguments have been defined:

Argument Name | Argument Value | Applies to | Description
servername | Server name | forms and reports | Indicates which database server C/SIDE should connect to. Note: use either "server" or "database" as argument - don't use both.
database | File name | forms and reports | Indicates which database file to access. Note: Use either "server" or "database" as argument - don't use both.
company | Company name | forms and reports | Indicates which company to open.
target | Object ID | forms and reports | Indicates which object to run. Valid object IDs are: form xxx report xxx where xxx is either the object number or object name.
view | View description | forms and reports | Indicates which filter to set. The format is the same as for the SourceTableView property on a form.
position | Record description | forms | Indicates which record to select. The format is the same as for the SourceTablePlacement property on a form.
servertype | MSSQL / NAVISION | forms and reports | Indicates which server to connect to.
requestform | yes / no | reports | Indicates whether a report should display its request form. Default value is no.
forcenewinstance | yes / no | forms and reports | Indicates whether a new instance of the Microsoft Dynamics NAV WIN32 client should be started regardless of whether a suitable instance is running or not. Default value is no.

If you choose a running client as target for the URL, the program ignores the values for the server, the database and the company because they have been used to select the particular running client.

If you choose a new client as target for the URL, the program stores the default values for the server, the database and the company in the zup file.

You must only use URLs without a specified server, database or company when you link to program functionality, such as the customer card and not when you link to data in the program, such as a view of a customer on a customer card.

Example

The following strings are examples of internal URLs. C/AL code cannot handle external URLs because of undefined escape characters. A defined escape character is described above, namely the "&&" character.

navision://client/run?servertype=NAVISION&database=c:\database.fdb&company=dot.com&target=Form991&forcenewinstance=yes

This example contains a URL with field names:

navision://client/run?servername=navi_srv1&company=CRONUS International Ltd.&target=Form Account Schedule&view=SORTING(Schedule Name,Line No.)&position=Schedule Name=CONST(),Line No.=CONST(0)&servertype=MSSQL

This example contains a URL with field numbers:

navision://client/run?servername=navi_srv1&company=CRONUS International Ltd.&target=Form 104&view=SORTING(Field1,Field2)&position=Field1=0(),Field2=0(0)&servertype=MSSQL


Event Triggers

The following information is useful when you have enabled C/SIDE to receive events from a component that it controls, for example, an automation server.

There are certain limitations on the triggers that are automatically generated for the events, which the component provides. Furthermore, incoming data is subject to certain restrictions.

Limitations

  • C/SIDE only supports the default outgoing, that is, source interfaces, which are defined by the automation variable. If more than one outgoing interface is defined by the automation server for a coclass, only event triggers for the default outgoing interface are generated in the C/AL code.

  • There can be a maximum of 39 parameters in function calls.

  • There can be a maximum of 1024 characters in prototype text strings for functions.

  • The connectable object strategy in COM is used to connect Microsoft Dynamics NAV and the automation server. The Sink object defined in this strategy and implemented in Microsoft Dynamics NAV only supports the IDispatch interface (and IUnknown). It is therefore expected that the automation server calls on IDispatch when executing events.

  • Parameter names will be truncated to a maximum of 30 characters.

  • There are no return values on event triggers.

  • The variable name along with "::" and the event trigger name will be truncated to a maximum of 30 characters.

Restrictions on Incoming Data

All received data are copied to an internal data type, which can handle any data type that COM allows. No data is lost in this conversion and there is no check for valid AL data types.

The data will remain in this internal data type until it is used inside the trigger. When data is used, it is converted to the appropriate C/AL data type. Note, however, that if the data type is Variant, no conversion occurs. No data is lost in the conversion and all the required checks are made. If the conversion is not possible because there is an invalid data type, or because data is outside the range, the event trigger causes an error message to pop up and terminates execution. Note that if data is never used in the event trigger, no checks for valid data, data type and data range are performed.

If parameter is a VAR parameter (that is, called ByRef) and data is used inside the event trigger, there will be an implicit conversion just before the event trigger returns. A check is made of whether conversion is possible. If this is not the case, an error message is shown and the event trigger terminates.


FlowFields

FlowFields display the result of the calculation described in the CalcFormula property. For instance, the Account Balance field in the General Ledger Account table shows the balance of the account and is calculated as the sum of the NetAmount filed for all General Journal entries in the account.

You can use FlowFields to:

  • calculate the total of a field over a set of records and display the results.

  • calculate averages.

  • determine the existence of records in a table.

  • determine the number of values in a table.

  • determine the minimum value.

  • determine the maximum value.

  • look up a value in another column in another table.

FlowFields are not physical fields stored in the database. Instead, they are a description of a calculation and a place for the system to display the result. To update a FlowField, you must use the CALCFIELDS function.


FlowFilters

FlowFilter fields let you set ranges on the calculations shown in FlowFields. For instance, if a FlowField contains the total of customer entries, you can use a FlowFilter to see the total for a single month or range of months.

In the example described, the FlowFilter field is a date field. You can also set up FlowFilter fields to see information based on the business units, departments, projects, and so forth.

The system does not save FlowFilter fields in the database. Instead, it stores them for each window on the individual workstation to let each user have his or her own filters.


Import Worksheet

This form is used during binary import of objects. If the import file contains only objects that either are entirely new or have been updated, they will normally be imported without further ado. If, however, one or more objects with the same ID already exist, a decision must be made about what to do. The Import Worksheet displays information about the existing and the new objects, and lets you decide how to handle conflicts.

The functions of the Import Worksheet (version check and so on) are only relevant for binary objects (files with a fob extension). Objects in text format are always imported, whether they overwrite existing objects or not.

How to Import Objects

Follow these steps to import objects:

  1. Click Tools, Object Designer.

  2. Click File, Import...

  3. Select the file that contains the binary objects from the dialog. (These files have an .fob extension.)

  4. When you have chosen a file, it will be examined. Depending upon the contents of the file, one of these things will happen:

  • If the file contains new or updated objects only, you will be asked if you want to import it now. If you click Yes, the objects will be imported. If you click Cancel, the import will be aborted. If, however, you click 1No, the Import Worksheet (described below) will appear.

  • If there are conflicts, you will be informed of this, and you can choose either to cancel the import, or to go to the Import Worksheet (by choosing OK from the dialog).

  • There are two kinds of conflicts: The first may occur if the version list numbers of the new and the existing objects are not the same. Another type of conflict arises if the default actions that were created by storing the Import Worksheet settings in the file with the objects (see below) are not valid (because the versions of the objects in the database are different from what was the case when the file was created).

Default Actions in the Import File

The setting of Action (see below) for each individual object in the Import Worksheet can be saved in the file with the objects. This means that it can be decided, when the file with the objects is created, how conflicts should be resolved. When importing, you can choose to revise these settings (by choosing No from the dialog that appears after the file has been examined), or you can choose to go ahead and import the objects.

If the assumptions that were made when the settings were saved are no longer valid, you will have to revise the settings. This will be the case if the objects in your database are not the same as the objects that were used to create the file.

The Import Worksheet

Each line in the Import Worksheet displays information about one object and lets you decide how to handle the object (by setting the Action option). The information below is displayed about each object, and, in addition, the Name, Modified, Version List, Size, Date and Time fields are displayed on the form for the object that has the focus.

Type

The type (Form, Report,...) of this object.

No.

The ID of the object.

Name

The Name of the (new) object.

New Object

This option is checked if this is an entirely new object (one that was not in the database before.)

New Object Changed

Checked if the new object has been marked as changed.

Existing Object Changed

Checked if the existing object has been changed in any way (Modified flag set, or version list changed).

Warning

If a warning icon (an exclamation mark) is displayed in this column, it means there is a conflict that must be resolved before this object can be imported.

Action

This option is the only field whose contents can be changed. The setting here determines how a conflict (flagged in the Warning field) will be resolved. These are the options:

Option | Meaning
Create | The new object will be added to the database. This option is only valid if no such object already exists.
Replace | The existing object will be replaced by the new object.
Delete | The existing object will be deleted and no new object created. This option is only valid if the new object has size 0. The intended use is to remove obsolete objects from the database. A new object that has this function is sometimes called a 'killer object'.
Skip | This object will not be imported.
Merge: Existing<-New | Only valid for tables. All fields in the existing table will remain, and any additional fields from the new object will be added.
Merge: New<-Existing | Only valid for tables. All fields in the new table will be imported, and any additional fields in the existing table will be added to the new table.
 | See What happens when objects are merged for more information about merging objects.

Existing Object Modified

Checked if the existing object has the Modified field set to Yes.

Existing Object Version List

The version list of the existing object.

New Object Modified

Checked if the new object has the Modified field set to Yes.

New Object Version List

The version list of the new object.

Using the Import Worksheet

For each individual object, you can choose an Action, given the constraints outlined in the table above.

Further, you can apply these actions by clicking the appropriate buttons:

Action | Meaning
OK | Perform the import according to the current settings in the worksheet.
Cancel | Cancel the import.
Replace All | Set Action for all objects to Replace.
Save As | Save the current settings in the worksheet in the import file, together with the objects.
Help | Display this Help topic.


MenuSuite Object

The MenuSuite object contains the menus that are displayed in the Navigation Pane and in the Navigation Pane Designer. Each menu contains content for a specific departmental area, for example, Finance or Manufacturing.

A menu suite has the following characteristics:

  • It consists of a set of menus.

  • A menu contains a collection of menu nodes, which are displayed in a tree structure.

  • A menu node can be either a menu group or a menu item.

  • Each menu node has a globally unique identifier (GUID).

  • A menu group contains a collection of menu nodes.

  • A menu item is the lowest level in the tree. When you click a menu item, its associated form, report, batch job, dataport or codeunit is run.

Creating and Designing MenuSuite Objects

You access a MenuSuite object from the Object Designer by clicking the MenuSuite button. You then have the following options:

  • Clicking New opens a dialog asking you to specify which design level you want to create an object for. If you have already created MenuSuite objects for all the levels you have permission to, a message will appear to inform you of this. Once you have made a selection, the Navigation Pane Designer opens, and you have the design permissions associated with that level.

  • Selecting a MenuSuite object and then clicking Design opens the Navigation Pane Designer with the chosen menu suite content displayed.

  • You can select the File, Import/Export, and Tools, Translate, Import/Export options.

  • You can compile MenuSuite objects (F11 or Tools, Compile). It is the object references that are compiled. If the MenuSuite object contains a reference to a non-existing form, report, batch job, dataport or codeunit, a compilation error occurs.

The Run button in the Object Designer is disabled when you click the MenuSuite button.

Design Permissions

You can create new forms or reports and insert these into menus as menu items. You can also make modifications to existing application objects. Otherwise you have exactly the same design permissions as an administrator. As a developer working at a Microsoft Business Solutions partner, you have permission to create a MenuSuite object at the Partner level. You also have permission to create a MenuSuite object at the Company level, which can be useful for testing purposes before you supply a company with a MenuSuite object.

Related Topics

  • Customizing a Menu Suite

  • Exporting a MenuSuite Object

  • The Navigation Pane Designer topic in the Microsoft Dynamics NAV online Help provides information about how an administrator can configure a menu suite to meet the needs of his company and its employees. This information is also relevant for developers.

  • The "MenuSuite Objects" chapter of the manual Application Designer's Guide.


Customizing a Menu Suite

You customize a menu suite in the Navigation Pane Designer. To access the various design options, you right-click on menu buttons, menu groups, menu items or anywhere in the content pane area. In addition to having access to the same design options as an administrator, you can:

  • create new menu items by specifying object type, object ID, caption and multilanguage caption.

  • set Object Type, Object ID, Caption and CaptionML properties for a menu item.

MenuSuite Object Levels

Microsoft Business Solutions provides a generic MenuSuite object, which we call the MBS level. This object is changed in various ways before end-users see its content. These changes are applied at different levels, which we have categorized as Country/Region, Add-on, Partner and Company. For example, the MenuSuite object is changed when the application undergoes localization changes. This takes place at the Country/Region level. As a developer working at a Microsoft Business Solutions partner, you customize a MenuSuite object at the Partner level. You can also configure a MenuSuite object at the Company level, which is the level that administrators work on. When designing a MenuSuite object, the header area of the Navigation Pane Designer displays a text to indicate the level you are working on.

Changes that are made to a MenuSuite object are stored as the differences between the previous MenuSuite object level and the current one. For example, when a company administrator configures a MenuSuite object at the Company level, the modifications are stored as the differences between the Company level and the Partner level, which was the previous level. If you export a MenuSuite object in text format and then open the text file, you will see information about the changes that you have made in comparison with the previous level. Click here to see an example.

There can only be one MenuSuite object for each level, with the exception of the Add-on MenuSuite object, for which there can be a maximum of 10 instances.

Related Topics

The Navigation Pane Designer topic in the Microsoft Dynamics NAV online Help provides information about how an administrator can configure a menu suite to meet the needs of his company and its employees. This information is also relevant for developers.


Create Item

Here you specify the Object Type, Object ID, Caption and CaptionML (multilanguage caption) of the menu item that you want to add to a menu. For example, if you have created a new report and want to add it as a menu item to a particular menu, then you select Report in the dropdown box in the Object Type field, and use the lookup in the Object ID field to select the report from the Report List. When you then click the Caption field, the name of the report is automatically filled in. You can rename it here if necessary.

The CaptionML field will by default show the code for the language that you use on your computer and the name of the menu item. If you have designed a menu item that will be used in different languages by different users, you must give the menu item a name in each language. When you click the AssistButton in the field, a window opens where you can enter a menu item name for each language code.


Design Level

Here you select the MenuSuite object level that you want to design. The form displays the levels that you have permission to use.

Microsoft Business Solutions provides a generic MenuSuite object, which we call the MBS level. This object is changed in various ways before end users see its content. These changes are applied at different levels, which we have categorized as Country/Region, Add-on, Partner and Company. For example, the MenuSuite object is changed when the application undergoes localization changes. This takes place at the Country/Region level. If you are a developer working at a Microsoft Business Solutions partner, you customize a MenuSuite object at the Partner level. You can also configure a MenuSuite object at the Company level, which is the level that administrators work on. When you are designing a MenuSuite object, the header area of the Navigation Pane Designer displays a text to indicate the level you are working on.

There can only be one MenuSuite object for each level, with the exception of the Add-on MenuSuite object, for which there can be a maximum of 10 instances.

Related Topics

  • MenuSuite Object

  • Customizing a Menu Suite


Item Properties

Here you can set up properties for the menu item that you have selected. For example, you may want the menu item to point to a different application object. The following properties are available:

Property | Description
Object Type | In the Object Type field, you can make a selection in the dropdown box. The following object types are available: Table, Form, Report, Batch Job, Codeunit, Dataport.
Object ID | You use the lookup in the Object ID field to select a specific object from a list. For example, if you had selected Report as the Object Type, clicking the lookup will display the Report List.
Caption | By default, the Caption field contains the name that has been assigned to the menu item. You can rename it here if you want.
CaptionML | The CaptionML field contains the code for the language that you use on your computer and the name of the menu item, for example, ENU=General Journals. If the menu item will be used in different languages by different users, you must give the menu item a name in each language. When you click the AssistButton in the CaptionML field, a window opens where you can enter a menu item name for each language code.


Exporting a MenuSuite Object

You can export a MenuSuite object in Microsoft Dynamics NAV object format (*.fob) or in text format. When you export a MenuSuite object in text format, the text file contains information about the changes that have been made to the object since the previous level. In the following you can see an example of a text file that contains the changes that have been made to a MenuSuite object at the Company level. To read about MenuSuite object levels, click here.

Example

When an administrator makes configuration changes to a menu suite, these changes are saved at the Company level. When this Company-level MenuSuite object is exported in text format, the text file contains information about the changes that have been made to the object since the previous level, which in this case would be the Partner level. In the following example, an administrator has made the following changes to his company's menu suite:

  • In the Finance menu, he has deleted a menu group called Setup, which contained one menu item called Accounting Periods.

  • He has added a new menu item, G/L Account Card, to the General Ledger menu group in the Finance menu.

  • He has moved the G/L Account Card menu item so that it is placed between the Chart of Accounts and Bank Accounts menu items in the General Ledger menu group.

The text file contains the following information:

OBJECT MenuSuite 70 Company

{

  OBJECT-PROPERTIES

  {

    Date=19-04-04;

    Time=16:04:10;

    Modified=Yes;

    Version List=;

  }

  PROPERTIES

  {

  }

  MENUNODES

  {

    { MenuItem       ;[{FA8395A4-7A0B-4524-B0FD-20436D9711A4}] ;Name=G/L Account Card;

                                                                CaptionML=ENU=G/L Account Card;

                                                                MemberOfMenu=[{F8D2429D-034B-4C58-9B5E-81BE962DB1BC}];

                                                                RunObjectType=Form;

                                                                RunObjectID=17;

                                                                ParentNodeID=[{B12180CF-0EFB-43AD-9118-7765E953AAFD}];

                                                                Visible=Yes;

                                                                NextNodeID=[{7A5B6DDE-B44B-41A0-95DA-69B7109F0E32}] }

    {                ;[{1BB06483-AFFD-4750-BF62-3ABA035E11B7}] ;Deleted=Yes }

    {                ;[{DF601C8A-07F7-4841-8929-9F2065BCB302}] ;Deleted=Yes }

    {                ;[{8AC7917D-2C91-457D-80D6-A24B42F71AE7}] ;NextNodeID=[{FA8395A4-7A0B-4524-B0FD-20436D9711A4}] }

  }

}

As you can see above, each menu node has a globally unique identifier (GUID) and various properties.


Upgrading Menu Suite Content

Menus in a menu suite that are inherited from the previous MenuSuite object level have the symbol >> on the menu button to the left of the menu name. These menus will be upgraded when you upgrade the corresponding MenuSuite object. Any changes that you have made to these menus will be merged into the new menu suite when you upgrade. For example, a menu item that you have added to a menu group – but where the menu group’s contents now have changed after an upgrade – will be placed as the last menu item in the menu group.

However, there will be cases where a straightforward merge cannot be carried out. For example, if you have added a menu item to a menu group that is no longer a part of the menu after an upgrade, then no merge can be made. Instead, the menu item will be placed in a Lost Items group at the bottom of the menu tree. Another example would be if you had added one or more menu items to a menu that is no longer present in the menu suite after an upgrade. In such a situation, the menu items will be placed in a Lost Items menu.

After an upgrade, you can take action on the menu items in a Lost Items group or menu - either by inserting them somewhere in the current menu (in the case of the Lost Items group), in another menu or by deleting them. A Lost Items group or menu is not visible in the Navigation Pane at runtime.

New menus that you have created are not affected by an upgrade. If there are new menu items available after the upgrade that you would like to insert in these menus, you will have to add them manually.


Multilanguage Functionality

Microsoft Dynamics NAV is multilanguage enabled. This means that a localized version of Microsoft Dynamics NAV can present itself in different languages. It is possible for the user to change the language that is used to display texts, and the change is immediate. There is no need to stop and restart Microsoft Dynamics NAV.

You should not confuse the multilanguage capability with localized versions. A localized version of Microsoft Dynamics NAV is a version of Microsoft Dynamics NAV that has been adapted to a local market. This means that all texts that are presented to the user have been translated into the local language, but it also means that functional areas have been adapted to the requirements of the local market.

A multilanguage version of Microsoft Dynamics NAV is a localized version of Microsoft Dynamics NAV that you can run in different languages while all other local adaptations remain the same. For example, you can run the Swiss version of Microsoft Dynamics NAV in German, French and Italian, but it is still a Swiss version of Microsoft Dynamics NAV in all other aspects. It is not the same as, say, a French version of Microsoft Dynamics NAV.

You should also be aware of the distinction between changing the language of Microsoft Dynamics NAV and changing the language of the data stored in Microsoft Dynamics NAV. You can address the first issue by enabling the multilanguage features. These features make it possible for the user to change the language of all the texts displayed by the application in captions for text boxes, on command buttons, in menus, and so on.

Changing the texts that are stored as application data is not part of the multilanguage capability. This is an application design issue. Examples of such texts are the names of items in the inventory or the comments for a customer.

Defining the Current Application Language

C/SIDE executes the function (trigger) with ID 4 on Codeunit 1 to determine the current language of the application. This trigger must return an integer (language ID). The trigger is not allowed to access the database. If you do not write code in this trigger, C/SIDE reads the value from the fin.stx file, which contains general texts used by C/SIDE.

Selecting a Language from the User Interface

When you add the function (trigger) with ID 5 to Codeunit 1, a new menu item appears on the Tools menu: Set Language. When users select the menu item, the trigger code must open a form. From here they must be able to select the language in which texts on command buttons, in menus, and so on are displayed.

Setting a Language from C/AL

Selecting a language from the user interface changes the global language. This will affect all application objects for which you have not set a language. The language of an application object can be set from C/AL. This also means that an object can change its language when it is executed, or it can allow the user to set the language at this point. The language of an object is changed by the LANGUAGE function. It is also possible to change the global language from C/AL. This is the same as changing the language from the user interface (meaning that individual objects can overrule this setting). Use the GLOBALLANGUAGE function to change the global language.

Selecting a Nonexistent Language

Situations may occur where the language the user selects is unavailable. This happens if the selected language is not installed. It can also happen if the language has been installed, but the language version contains only a part of the texts.

C/SIDE uses the following rules to find a text to display:

  1. The application object language selected by the user.

  2. The primary language of the application object selected by the user.

  3. The global language selected by the user.

  4. The application language.

  5. The primary language of the application language.

This means that the user will always see some text, but it is possible to have situations where different forms (or even different controls on a form) are run in different languages.

Some languages in Windows are tagged with a primary language ID. For example, the language with ID 1033 English (United States) is the primary language for a group of languages. One of these languages is the language with ID 2057 English (United Kingdom). Another example is 3081 English (Australian). Similar relationships exist for languages like French, Spanish and German. You can see all the Language IDs and the associated information (Primary ID, Name and Abbreviated Name) by designing a form based on the Windows Language virtual table.

Using Text Constants

The Text Constants tab has been added to the C/AL Globals and C/AL Locals forms. Here you can create a text constant that you can use in functions that can take text constants as parameters. The primary targets are the following dialog functions: ERROR, MESSAGE, CONFIRM and STRMENU.

The benefit of this is that a text constant is multilanguage enabled. You define a text constant by entering the identifier you will use in your code in the Name field. You enter the string itself in the ConstValue field. This value is automatically entered as the ConstValueML value for the currently selected language. You can enter a string for other languages by clicking the AssistButton in the ConstValueML field. This opens a form similar to the form used for entering multilanguage values for the multilanguage family of properties. See the Application Designer's Guide for more information on text constants.


Microsoft Dynamics NAV Application Server

No Graphical User Interface

As there is no graphical user interface (GUI) on Microsoft Dynamics NAV Application Server, there are some limitations on the C/AL code that can run on the application server. For more information on this, see the GUIALLOWED function.

The following functions are available when running Microsoft Dynamics NAV Application Server:

  • All system functions except for the GUI related functions, such as DIALOG and CONFIRM.

  • OCX and AUTOMATION functions.

  • CODEUNIT functions.

  • FILE functions.

The following functions are not available in Microsoft Dynamics NAV Application Server:

  • FORM functions.

  • REPORT functions.

  • Dataport functions.

Error Logging

When you run C/AL code with triggers containing functionality that invokes GUI, an error occurs. A corresponding error message is posted in the NT event log. For more information on message logging, see the manual Installation & System Management: Microsoft Dynamics NAV Application Server.

Calls to the following functions will create errors:

  • FORM, DIALOG and CONFIRM: an error is shown on screen when the application server runs from the Microsoft DOS command line. When Microsoft Dynamics NAV Application Server runs as a service, an error message is logged.

  • MESSAGE and ERROR: an error message is logged.

ATTENTION

REPORT and DATAPORT functions are not available. OCX and AUTOMATION functions are available. However, if they invoke GUI functions, they may cause Microsoft Dynamics NAV Application Server to stop running. The only way to restart the application server, is to reboot.

Starting Up Microsoft Dynamics NAV Application Server

Before you can successfully start a Microsoft Dynamics NAV Application Server, you must create a startup trigger on codeunit 1 with ID number 99. The trigger must have a parameter of type Text with a maximum length of 1024 characters. This parameter is passed to the codeunit trigger, which is always executed when Microsoft Dynamics NAV Application Server starts up. This trigger is not defined in the standard application. The interpretation of the text string is the responsibility of the C/AL programmer. If you do not supply the parameter, the Microsoft Dynamics NAV Application Server startup procedure fails.

Communication between Microsoft Dynamics NAV Client and Microsoft Dynamics NAV Application Server

To establish communication between a Microsoft Dynamics NAV client and Microsoft Dynamics NAV Application Server, you need to start a timer. You can make the application server start a timer that triggers an event at a certain interval. When Microsoft Dynamics NAV Application Server receives the event, it can check the database for unprocessed tasks, such as an order.

A user that runs a Microsoft Dynamics NAV client can put, for example, a 'send order' task in the task table in the database. Microsoft Dynamics NAV Application Server can then check the database for this task.

Example

This is an example of what the startup trigger can look like. First, the trigger instantiates a communication component. Then, if the parameter passed equals 'Test,' the application server is instructed to also look in the task table. The 'Test' parameter starts a timer.

InitComCom.RUN;
CASE StartupParm OF
 'Test': InitializeTaskTable.RUN;
END;


Normal Field Class

This class of field is used for ordinary fields that contain data stored in the database. The majority of the fields in the Microsoft Dynamics NAV tables are ordinary fields.


Options for Merging Objects

The sequence of events when objects are merged is this:

  1. The old object is decompiled.

  2. The new object is decompiled.

  3. The objects are merged.

  4. The resulting object is compiled.

If any of these steps fail, the merge will be discontinued.

The two options for merging work like this:

Existing <- New

These items from the existing object are always used:

  • Table properties

  • Local C/AL functions on the table, including local variables

  • Global variables

These items are merged into the existing object from the new object:

  • New fields

  • Field properties that are different in the objects

  • Trigger code on field level, including local variables

Fields are merged in based on the field number. The three possible scenarios are:

  1. The field exists in the old object, but not in the new. The field will be left as it was.

  2. The field exists in the new object, but not in the old. The field will be added.

  3. The field exists in both objects. If the properties are different in the new object, these new properties will be used.

Note that this can lead to problems that have to be resolved manually. Consider, for example, a new object that differs from an old object by introducing code in a field trigger and this code uses a global variable that is not in the old object. The merge will fail because (1) the global variables are taken from the old object, and (2) the merged object needs the global variable in order to compile.

A workaround would be to declare the global variable in the old object before merging the objects.

New <- Existing

Using this option reverses the scenario. This means that:

These items from the new object are always used:

  • Table properties

  • Local C/AL functions on the table, including local variables

  • Global variables

These items are merged into the new object from the existing object:

  • New fields

  • Field properties that are different in the objects

  • Trigger code on field level, including local variables


RGB Color Model

The system uses the RGB color model for specifying colors. This model specifies the intensity of red, green, and blue on a scale of 0 to 255, with 0 (zero) indicating the minimum intensity. The settings of the three colors are converted to a single integer value by using this formula:

RGB value:= Red + (Green*256) + (Blue*256*256)

Examples:

Red | Green | Blue | RGB value | Color
255 | 0 | 0 | 255 | Red
0 | 255 | 0 | 65280 | Green
0 | 0 | 255 | 16711680 | Blue
0 | 255 | 255 | 16776960 | Cyan
255 | 0 | 255 | 16711935 | Magenta
255 | 255 | 0 | 65535 | Yellow
255 | 255 | 255 | 16777215 | White
128 | 128 | 128 | 8421504 | Gray
0 | 0 | 0 | 0 | Black

To extract the settings of the red, green and blue elements from an RGB value, you can use this method:

Convert the RGB value to a hexadecimal value. This will give you a hexadecimal number with up to six digits. From right to left, each pair of hexadecimal digits is the setting of red, green and blue, respectively, and can be converted back to decimal. (If the hexadecimal number contains less than six digits, fill out the number with zeroes on the left.)

Examples:

RGB | Hex | Red | Blue | Green
6579300 | 646464 | 100 | 100 | 100
16422450 | FA9632 | 50 | 150 | 250


Sorting of Numerical Values in Code Fields

The following information is helpful if you use or are planning to use the SQL Server Option for Microsoft Dynamics NAV. We also recommend that you read this information if you use Microsoft Dynamics NAV Database Server and want Microsoft Dynamics NAV to sort numbers correctly when you view data with external programs.

How Number Sorting Works

Code fields in Microsoft Dynamics NAV can contain both numerical values and text strings. Microsoft Dynamics NAV ensures that numbers kept in code fields on Microsoft Dynamics NAV Database Server are sorted in the correct numerical order. However, this does not necessarily happen when you use external programs to access the same data. External programs may view and sort these numbers as text. This means that when Microsoft Dynamics NAV sorts the data, comparisons are made character by character and not by comparing the numerical content of the strings.

Numbers that you keep in code fields on SQL Server using the Varchar SQL data type are not sorted in the correct numerical order. The SQL Server Option for Microsoft Dynamics NAV sorts the numbers as if they were text strings. The following table illustrates the differences that occur:

Numerical Sorting | Text Sorting
1 | 1
2 | 10
3 | 100
4 | 2
10 | 3
100 | 4

To avoid this problem, we recommend that you use a numerical series that has a fixed length. You can do this in three ways:

  • Define a numerical series as consisting of a predefined number of digits that start with a digit other than zero, for example, 100-399 (300 numbers). If this numerical series is too short for your requirements, you can start a new numerical series, for example, 40,000-69,999 (30,000 numbers). If this numerical series is too short, you can start a new one, such as 7,000,000-9,999,999 (3,000,000 numbers). Users will quickly get used to entering numbers that have a fixed length, and the numbers will be sorted correctly.

1001

1002

1003

9999

This is the solution that we recommend because you can now define the SQL data type as being either Varchar or Integer and the sorting will still be correct.

  • Define a numerical series that consists of a predefined number of digits and that starts with a letter, such as A001-A999. This series will be sorted correctly. When the series is complete, you can define a new series by starting with a different letter. Users will quickly get used to entering numbers that have a fixed length, and the numbers will be sorted correctly.

A001

A002

A003

A999

You cannot apply this solution if you are using the numerical series feature in Microsoft Dynamics NAV. Further, even if you are not using the numerical series feature, this solution makes it very difficult to convert your data to the Integer SQL data type.

  • Define a numerical series as consisting of a definite number of digits that start with zeros, for example, 001-999.

We do not recommend this solution because there are several inherent drawbacks. Firstly, the user tends to ignore the zeros and to refer to the first number as 1. Users may, therefore, omit the zeros when entering numbers. Secondly, the numerical series feature in Microsoft Dynamics NAV does not permit numbers that start with zero. Furthermore, the SQL Server Option for Microsoft Dynamics NAV will not allow you to save numbers that are defined according to this system as the Integer SQL data type.

Important

As a general rule, data types used in fields that are related to each other must be compatible. Therefore, when you use a SQL data type in a field, you will normally have to change the SQL data type settings of related fields in other tables. For example, in the General Ledger application area, if you change the SQL data type of the No. field in the G/L Account table from Varchar to Integer (or if you change the data type from Code to Text), you must change the data type of the G/L Account No. fields in the G/L Entry and G/L Budget Entry tables to the corresponding data type. Failure to do so results in the display of incorrect totals, based on these tables, in the chart of accounts and elsewhere.

Numbering Principles

To ensure that numbers kept in code or text fields are sorted correctly, irrespective of which database server you are using, you must follow the principles described below:

  • Always use a numerical series that has a fixed length, for example, 100-399.

  • Never use a numerical series such as 1-999 in code or text fields.

  • Never use a numerical series such as 001-999 in code or text fields.

Filters

If you do not follow the numbering principles, problems will arise when you apply filters that involve numbers in Microsoft Dynamics NAV. Here is an example:

  • If you have not used a numerical series that has a fixed length, when you apply a filter, for example, 10..20, the result will be 10,100......20.

When you follow the numbering principles, you must remember to use these for filters that you apply. Here are two examples:

  • If you do not follow the numbering principles when you apply a filter, for example, 2..10, the result will contain no records. This is because 2 comes after 10.

  • You have followed the numbering principles and are using three-digit numbers. If you forget to follow the same principles when you apply a filter, for example, 10..20, the result will be 100,101,102......199.


SQL Server Data Types

Every available Microsoft Dynamics NAV data type is mapped to an appropriate SQL Server data type in the tables of the SQL Server Option for Microsoft Dynamics NAV. The following table shows which SQL Server data type is used for the corresponding Microsoft Dynamics NAV data type:

Microsoft Dynamics NAV Data Type | SQL Server Data Type
Integer | INTEGER
Option | INTEGER
Code(n) | VARCHAR(n), INTEGER, SQL_VARIANT
Text(n) | VARCHAR(n)
Decimal | DECIMAL(38,20)
Date | DATETIME
Time | DATETIME
Boolean | TINYINT
Binary(n) | VARBINARY(n)
BLOB | IMAGE
DateFormula | VARCHAR(32)
TableFilter | VARBINARY(252)
BigInteger | BIGINT
Duration | BIGINT
DateTime | DATETIME
GUID | UNIQUEIDENTIFIER
RecordID | VARBINARY(n)

Each of the SQL Server data types is created as NOT NULL except the IMAGE type, which allows NULL.

There are other SQL Server data types than those listed in the previous table. You can use and modify these from within Microsoft Dynamics NAV when you have created or altered SQL Server tables or views outside Microsoft Dynamics NAV.

Some of the SQL Server data types listed previously are compatible with other Microsoft Dynamics NAV data types. The following table shows the extended compatibility of SQL Server data types with Microsoft Dynamics NAV data types:

SQL Server Data Type | Microsoft Dynamics NAV Data Type
CHAR(n) | Code(n), Text(n), DateFormula
NCHAR(n) | Text(n)
NVARCHAR(n) | Text(n)
INTEGER | Code
TINYINT | Integer, Option, Boolean
SMALLINT | Integer, Option
NUMERIC(p,s), MONEY, SMALLMONEY, REAL, FLOAT(n), DECIMAL | Decimal, Integer, Option, Boolean
SMALLDATETIME | Date
BIT | Integer, Option
BINARY(n) | Binary(n)
TEXT | BLOB
NTEXT | BLOB
UNIQUEIDENTIFIER | Binary(16), Text(36)


SumIndexFields

SumIndexFields let you quickly calculate the sums of numeric columns in tables, even in tables with thousands of records. SumIndexFields form the basis on which FlowFields are built.

A SumIndexField is associated with a key in the table. Each key can have up to 20 associated SumIndexFields. When you design your database, you can associate a decimal field with a key as a SumIndexField. This tells the DBMS to create and maintain a structure that contains the accumulated sum of the values in a column. When a user selects a new key, any SumIndexFields associated with that key become accessible.


Table View

The term "table view" describes the view of the table you present to the user. You determine what records the user can see by setting filters, determining the sorting order and selecting the keys.


xRec and FIELDNO

When a user-defined function or a trigger is executed on a table object xRec and FIELDNO are set differently, depending on exactly how the function or trigger is executed. The tables below explain what happens in the different scenarios.

User-Defined Function

The table below explains what happens to xRec and FIELDNO when a user-defined function on a table object is called from either external or internal C/AL code. External C/AL code means that the calling code is in a different object, internal C/AL code means that the calling code is in the same object (another function in the same object).

Execution initiated by: | xRec value | FIELDNO value
external C/AL code | empty | 0
internal C/AL code | unchanged | unchanged

Triggers

The table below explains what happens to xRec and FIELDNO when a trigger is called from either external or internal C/AL code. External C/AL code means that the calling code is in a different object, internal C/AL code means that the calling code is in the same object (another function in the same object).

Scenario | xRec value | FIELDNO value
VALIDATE trigger called by external C/AL code that calls the VALIDATE function | Copy of Rec before assignment in VALIDATE trigger | Field number of field being validated
VALIDATE trigger called by internal C/AL code that calls the VALIDATE function | unchanged | unchanged
Any table.function called by C/AL that initiates a call to a trigger other than VALIDATE | Copy of Rec before trigger is executed | 0


ISSERVICETIER

Use this function to find out whether the code you are executing is running on the new Dynamic NAV three-tier architecture or on the old two-tier architecture.

[Ok :=] ISSERVICETIER

Ok

Data type: boolean

This optional return value tells you whether or not you are connected to a Dynamics NAV service tier.

Ok returns... | If
TRUE | The code you are executing is running on a Dynamics NAV service tier.
FALSE | The code you are executing is not running on a Dynamics NAV service tier.


CurrFieldNo

Use this function to return the number of the current field.

CurrFieldNo

CurrFieldNo is a built-in function that is used to identify which field has been altered. It can also be used to identify whether the field is being called by a user from a form or by the system via C/AL code. It is generally used with the OnValidate trigger.

Form

If the OnValidate trigger is called as a result of a change that has been implemented from a Form, CurrFieldNo is assigned the field number of the active field.

C/AL Code

If the field is called from C/AL code then there is no active field and CurrFieldNo is 0.

Example 1

To check whether the OnValidate trigger has been called from a form or from C/AL code, you can construct your code as follows:

FieldTrigger OnValidate

IF CurrFieldNo <> 0 THEN BEGIN
 Some code that should only be run if the trigger is called from C/AL code

ELSE

   Some code that should only be run if the trigger is called from a form.

Example 2

FieldTrigger 32 Currency Code [Code10]
OnValidate()
IF NOT (CurrFieldNo IN [0,FIELDNO("Posting Date")]) THEN
TESTFIELD(Status,Status::Open);

IF CurrFieldNo <> FIELDNO("Currency Code") THEN
UpdateCurrencyFactor

ELSE BEGIN

  IF "Currency Code" <> xRec."Currency Code" THEN BEGIN
 UpdateCurrencyFactor;
 RecreatePurchLines(FIELDCAPTION("Currency Code"));

  END ELSE

    IF "Currency Code" <> '' THEN BEGIN
   UpdateCurrencyFactor;
   IF "Currency Factor" <> xRec."Currency Factor" THEN
     ConfirmUpdateCurrencyFactor;

    END;

END;