CitectSCADA Cicode Reference
CitectSCADA Cicode Reference
10
November 2008
Legal Notice
DISCLAIMER
Citect Pty Ltd makes no representations or warranties with respect to this manual and, to the maximum extent
permitted by law, expressly limits its liability for breach of any warranty that may be implied to the replace-
ment of this manual with another. Further, Citect Pty Ltd reserves the right to revise this publication at any
time without incurring an obligation to notify any person of the revision.
COPYRIGHT
© Copyright 2008 Citect Pty Ltd All rights reserved.
TRADEMARKS
Citect Pty Ltd has made every effort to supply trademark information about company names, products and
services mentioned in this manual.
Citect, CitectHMI, and CitectSCADA are registered trademarks of Citect Pty. Ltd.
IBM, IBM PC and IBM PC AT are registered trademarks of International Business Machines Corporation.
MS-DOS, Windows, Windows NT, Microsoft, and Excel are either registered trademarks or trademarks of Mi-
crosoft Corporation in the United States and/or other countries.
DigiBoard, PC/Xi and Com/Xi are trademarks of Digi International Inc.
Novell, Netware and Netware Lite are are either registered trademarks or trademarks of Novell, Inc. in the
United States and other countries..
dBASE is a trademark of dataBased Intelligence, Inc.
All other brands and products referenced in this document are acknowledged to be the trademarks or regis-
tered trademarks of their respective holders.
GENERAL NOTICE
Some product names used in this manual are used for identification purposes only and may be trademarks of
their respective companies.
Introduction .................................................................................11
3
Contents
4
Contents
5
Contents
Functions Reference.................................................................117
6
Contents
7
Contents
8
Contents
Index.............................................................................................897
9
Contents
10
Part: 1
Introduction
This section provides some introductory material for CitectSCADA:
Introducing Cicode
12
Chapter: 1 Introducing Cicode
Cicode is a programming language designed for use in CitectSCADA to monitor and con-
trol plant equipment. It is a structured language similar to Visual Basic or ’C’. You need no
previous programming experience to use it.
Using Cicode, you can access all real-time data (variables) in the CitectSCADA project, and
all CitectSCADA facilities: variable tags, alarms, trends, reports, and so on. You can use
Cicode to interface to various facilities on the computer, such as the operating system and
communication ports. Cicode supports advanced features including pre-empted multi-
tasking, multi threads, and remote procedure calls.
Getting Started
Use the following sections as a quick start to using Cicode in your CitectSCADA projects:
Cicode can be stored in procedures called functions for multiple reuse and centralized
maintenance. For details, see Using Cicode Files.
Cicode can be typed directly into command fields in online CitectSCADA forms. For de-
tails, see Using Cicode Commands.
Cicode expressions are used to display and log data for monitoring and analysis, and to
trigger various elements in your system, such as alarms, events, reports, and data log-
ging. For information on using expressions, see Using Cicode Expressions.
A Cicode function is a small program, a collection of statements, variables, operators,
conditional executors, and other functions. A Cicode function can perform complex
tasks and give you access to CitectSCADA graphics pages, alarms, trend data, and so
on. For information on using functions, see the section titled Using Cicode Functions.
Cicode has many pre-defined functions that perform a variety of tasks. For details on
commonly used functions, see the section titled Working with Commonly Used Func-
tions. Where system functionality cannot be achieved with built-in functions, you can
write your own functions. See Writing Functions.
The Cicode Editor is the code editing tool provided with CitectSCADA for the writing,
editing and debugging of your Cicode code. For details, see The Cicode Editor.
See Also
Performing Advanced Tasks
Using Cicode Programming Standards
13
Chapter: 1 Introducing Cicode
When you compile your CitectSCADA project, the compiler reads all the functions in your
Cicode source files. Your system can then use these functions in the same way as it uses
built-in functions. You can use as many Cicode files as required. Cicode files reside in the
same directory as your CitectSCADA project. When you back up your project, all Cicode
source files in the project directory are also backed up.
See Also
The Cicode Editor
Creating Cicode files
Opening Cicode files
14
Part: 2
Using Cicode
This section contains information for Users and describes the following:
Using Cicode Commands Using Cicode Macros
Using Cicode Expressions Converting and Formatting Cicode Variables
Using Cicode Functions Working with Operators
Working with Commonly Used Functions Working with Conditional Executors
Writing Functions Performing Advanced Tasks
Using Variables Editing and Debugging Code
Using Arrays Using Cicode Programming Standards
16
Chapter: 2 Using Cicode Commands
Cicode commands extend the control element of a CitectSCADA control and monitoring
system. You use commands to control your CitectSCADA system and therefore the pro-
cesses in your plant.
Each command has a mechanism to activate it. Commands can be issued manually,
through an operator typing a key sequence, or by clicking on a button (or object) on a
graphics page. You can also configure commands to execute automatically:
When an operator logs into or out of the runtime system
When a graphics page is displayed or closed
When an alarm is triggered
In a report
When an event is triggered
To define a Cicode command, you enter a statement (or group of statements) in the com-
mand field (Input category) for an object.
Each statement in a command usually performs a single task, such as setting a variable to
a value, calculating a value, displaying a message on the screen, or running a report. For
information on using variables, see the section titled Using Variables.
If you want to evaluate a condition, like checking the state of your plant rather than per-
form an action or command upon your plant, use an expression instead. See the section ti-
tled Using Cicode Expressions.
See Also
Using Cicode Programming Standards
Setting Variables
You can set a Variable in CitectSCADA within a Command field, an Expression field, or in
a Cicode Function, by using the mathematical ’equals’ sign ( = ) assignment operator. The
value on the right is assigned (set) to the variable on the left, as shown in the following
Cicode example :
<VAR_TAG> = Val;
where:
<VAR_TAG> is the name of the variable, and Val is the value being assigned to the variable.
Examples
To set a digital variable (named BIT_1) to ON (1), use the command:
BIT_1 = 1;
To set a digital variable (named BIT_1) to OFF (0), use the command:
17
Chapter: 2 Using Cicode Commands
BIT_1 = 0;
To set a digital variable (named B1_PUMP_101_M) to OFF (0), use the command:
B1_PUMP_101_M = 0;
To set an analog variable (named B1_TIC_101_SP) to a value of ten (10), use the command:
B1_TIC_101_SP = 10;
You can copy a variable to another by assigning (setting) the value of a variable to the value
of another variable, for example:
B1_PUMP_101_COUNT = B1_PUMP_101_CLIMIT;
Performing Calculations
Mathematical calculations can be performed between variables in a Cicode statement. For
example:
B1_TIC_101_SP = B1_TIC_101_PV + B1_TIC_102_PV - 100;
When this command is executed, the variable B1_TIC_101_SP is set to a value that is the
sum of variables B1_TIC_101_PV and B1_TIC_102_PV minus 100.
18
Chapter: 2 Using Cicode Commands
B1_TIC_101_SP = 10;
The example above uses three statements, separated by semi-colons ( ; ). The first statement
sets the variable B1_PUMP_101_COUNT to the value of the variable
B1_PUMP_101_CLIMIT; the second statement sets the variable BATCH_NAME to the
string "Bread"; and the third statement sets the variable B1_TIC_101_SP to 10. Each state-
ment is executed in order.
Note: Separate each statement in a command with a semicolon (;). If you don’t, CitectSCA-
DA will not recognize the end of a statement, and errors will result when the project is com-
piled.
The number of statements you can enter in a command property is limited only by the size
of the field. However, for clarity, don’t use too many statements; enter the statements into
an Include File or write a Cicode Function. You then refer to the include file or call the func-
tion in the command property field.
where <filename> is any valid DOS file name. Be aware that the bracket characters (< >) are
part of the syntax.
You can use include files with most properties (except record names), but they are most
commonly used for commands and expressions, for example:
Key sequence: F5 ENTER
Command: @<setvars.cii>
19
Chapter: 2 Using Cicode Commands
In the above example, the setvars.cii include file would contain commands to be substi-
tuted for the Command property when you compile your project, for example:
PV12 = 10;
PV22 = 20;
PV13 = 15;
PV23 = 59;
PageDisplay("Mimic");
Notes
The include file name can contain a maximum of 64 characters, or 253 characters includ-
ing a path, and can consist of any characters other than the semi-colon (;) or the single
quote(’). You do not need to include the .cii extension, but if the file is not in the project
directory, you must enter the full path to the file. If the file is not in the project directory,
it will not be backed up with the Backup facility.
If modifying an Include file with the Cicode Editor, when you save your changes a .ci
file extension will be appended to the file name. Change this to a .cii file extension in
Windows Explorer.
The operator issues the command by pressing the F2 key, up to three characters, and the
Enter key. The three character sequence (identified by the three hash (#) characters) is called
an argument. The argument is passed into the command (as Arg1) when the command is
completed (when the operator presses the Enter key).
The operator might type:
The value 123 is passed to the command, and B1_TIC_101_SP is set to 123.
Always use a specific key (for example, Enter) to signal the end of a key sequence. If, for
example, you use the key sequence F2 ####, the operator must enter 4 characters for the
command to be executed - CitectSCADA waits for the fourth character. But if you use F2
#### Enter, the operator can enter between one and four characters as necessary. The com-
mand executes as soon as the Enter key is pressed.
20
Chapter: 2 Using Cicode Commands
To use more than one argument in a command, separate the arguments with commas ( , ):
Key sequence: F2 ###,## Enter
Command: B1_TIC_101_SP = Arg1; B1_TIC_101_PV = Arg2;
To set both variables, the operator can type:
The values 123 and 18 are passed to the command. B1_TIC_101_SP is set to 123 and
B1_TIC_101_PV is set to 18.
21
Chapter: 2 Using Cicode Commands
22
Chapter: 3 Using Cicode Expressions
Cicode expressions are the basic elements of the Cicode language. An expression can be a
constant, the value of a variable tag, or the result of a complex equation. You can use ex-
pressions to display and log data for monitoring and analysis, and to trigger various ele-
ments in your system, such as alarms, events, reports, and data logging.
You can enter a Cicode expression in any CitectSCADA editor form or graphic object that
contains an expression property. Unlike a command, an expression does not execute a spe-
cific task - it is evaluated. The evaluation process returns a value that you can use to display
information on the screen (for example, as a bar graph) or to make decisions. The following
expression returns a result of 12:
Numeric expression: 8 + 4
In the above example, the value of the expression is a constant (12) because the elements of
the expression are constants (8 and 4).
See Also
Displaying Data Using Expressions
Logging Expression Data
Triggering Events Using Expressions
Using Cicode Programming Standards
Using Cicode Files
Decision-Making
Some expressions return only one of two logical values, either TRUE(1) or FALSE(0). You
can use these expressions to make decisions, and to perform one of two actions, depending
on whether the return value is TRUE or FALSE. For example, you can configure a text ob-
ject with appearance as follows:
23
Chapter: 3 Using Cicode Expressions
When the system is running, the value of the expression B1_TIC_101_PV + B1_TIC_102_PV
is logged to the file [log]:B1_TIC.
See Also
Using Cicode Expressions
Trigger B1_PUMP_101_CMD
In this example, the trigger is the expression B1_PUMP_101_CMD (a digital variable tag).
If the pump is ON, the result of the trigger is TRUE, and the value of the expression
(B1_TIC_101_PV + B1_TIC_102_PV) is logged. If the pump is OFF, the result is FALSE, and
logging ceases.
See Also
Using Cicode Expressions
24
Chapter: 4 Using Cicode Functions
A Cicode function can perform more complex tasks than a simple command or expression
allows. Functions give you access to CitectSCADA graphics pages, alarms, trend data, and
so on.
CitectSCADA has several hundred built-in functions that display pages, acknowledge
alarms, make calculations, and so on. You can also write your own functions to meet your
specific needs.
See Also
Working with Commonly Used Functions
Writing Functions
where:
FunctionName is the name of the function
Arg1, Arg2, ... are the arguments you pass to the function
Evaluating Functions
You can use a function in any expression. For example, the AlarmActive() function returns
TRUE (1) if any alarms are active, and FALSE (0) if no alarms are active. In the following
text object, either "Alarms Active" or "No Alarms Active" is displayed, depending on the
return value of the expression.
ON text when AlarmActive(0)
ON Text "Alarms Active"
OFF Text "No Alarms Active"
Note: All functions return a value. This value either indicates the success of the function,
or provides information on an error that has occurred. In many cases (for example, when
used in a command) the return value can be ignored. You must use the parentheses () in
the function name, even if the function uses no arguments. Function names are not case-
sensitive: PageNext(), pagenext() and PAGENEXT() call the same function.
25
Chapter: 4 Using Cicode Functions
Each statement is executed in order. The "Shift" report is started first, the variable
B1_TIC_101_PV is set to 10 next, and finally, the "Boiler 1" page is displayed.
Functions combine with operators and conditional executors to give you specific control
over your processes, for example, you can test for abnormal operating conditions and act
on them.
This function displays the graphics page called "Boiler 1". Be aware that when you pass a
string to a function, you must always enclose the string in double quotes.
You can use the PageDisplay() function to display any graphics page in your system - in
each case, only the argument changes. For example, the following command displays the
graphics page "Boiler 2":
Command PageDisplay("Boiler 2");
You can use the Report() function to run a report (for example, the "Shift" report) when the
command executes:
Command Report("Shift");
The following example uses the Prompt() function to display the message "Press F1 for
Help" on the screen when the command executes:
Command Prompt("Press F1 for Help");
String assignment
You can also assign string variables in commands. For example, if BATCH_NAME is a vari-
able tag defined as a string data type, you can use the following command to set the tag to
the value "Bread":
26
Chapter: 4 Using Cicode Functions
BATCH_NAME = "Bread";
The order of the arguments is important to the operation of any function. The Login() func-
tion logs a user into your runtime system. The first argument ( "Manager" ) indicates the
name of the user, and the second argument ( "ABC" ) is the user’s password. If you reverse
the order of the arguments, the function would attempt to login a user called "ABC" - if a
user by this name does not exist, an error message displays.
27
Chapter: 4 Using Cicode Functions
In this instance, the value of B1_TIC_101_PV displays. If it is a real-time variable, the num-
ber that displays depends on its value at the time.
Note: Do not use double quotes around variables, for example, "B1_TIC_101_PV", other-
wise the text string B1_TIC_101_PV displays, not the value of the variable.
When the command executes, the page name is passed to the function as Arg1. The opera-
tor can then display any page, for example:
The following example shows an entry command event for a graphics page, using a com-
bination of two functions. The FullName() function returns the name of the user who is cur-
rently logged in to the run-time system, passing this name to the calling function, Prompt().
When the page is opened, a welcome message displays in the prompt line.
On page entry Prompt("Hello, " + FullName())
28
Chapter: 4 Using Cicode Functions
For example, if the current user is John Citizen, the message "Hello, John Citizen" displays.
29
Chapter: 4 Using Cicode Functions
30
Chapter: 5 Working with Commonly Used Functions
Cicode has many functions that perform a variety of tasks. Many of these are used for
building complex CitectSCADA systems. The functions you will most often use are divided
into six categories:
Alarm Functions
Page Functions
Keyboard Functions
Report Functions
Time/date Functions
Miscellaneous Functions
See Also
Functions Reference
Alarm Functions
You can use alarm functions to display alarms and their related alarm help pages, and to
acknowledge, disable, and enable alarms. You can assign a privilege to each command that
uses an alarm function, so that only an operator with the appropriate privilege can perform
these commands. However, you should assign privileges to commands only if you have
not assigned privileges to individual alarms.
AlarmAck: Acknowledges an alarm. The alarm where the cursor is positioned (when
the command is executed) is acknowledged. You can also use this function to acknowl-
edge multiple alarms.
AlarmComment: Adds a comment to the alarm summary entry at run time. The com-
ment is added to the alarm where the cursor is positioned when the command is execut-
ed. A keyboard argument passes the comment into the function. Verify that the length
of the comment does not exceed the length of the argument, or an error results.
AlarmDisable: Disables an alarm. The alarm where the cursor is positioned (when the
command is executed) is disabled. You can also use this function to disable multiple
alarms.
AlarmEnable: Enables an alarm. The alarm where the cursor is positioned (when the
command is executed) is enabled. You can also use this function to enable multiple
alarms.
AlarmHelp: Displays an alarm help page for the alarm. Each alarm in your system can
have an associated help page. The help page for the alarm at the position of the cursor
(when the command is executed) is displayed.
AlarmSplit: Duplicates an entry in the alarm summary display. You can use this func-
tion to add additional comments to the alarm entry.
Page Functions
With the page functions, you can display your graphics pages and the standard alarm pag-
es.
Note: The following page functions are not supported in the server process in a multipro-
cessor environment. Calling page functions from the server process results in a hardware
alarm being raised.
31
Chapter: 5 Working with Commonly Used Functions
PageAlarm: Displays current alarms on the alarm page configured in the project.
PageDisabled: Displays disabled alarms on the alarm page configured in the project.
PageDisplay: Displays a new page on the screen. The Page name or number is required
as an argument. (Use the PageLast() function to go back to the last page - the page that
this new page replaced).
PageFile: Displays a file on the file page configured in the project.
PageGoto: Displays a new page on the screen. This function is similar to the PageDis-
play() function, except that if PageLast() is called, it does not return to the last page.
PageHardware: Displays hardware alarms on the alarm page configured in the project.
PageLast: Displays the graphics page that was displayed before the current one. You
can use this function to ’step back’ through the last ten pages.
PageNext: Displays the next graphics page (defined in the Next Page property of the
Pages form).
PagePrev: Displays the previous graphics page (defined in the Prev Page property of the
Pages form).
PageSummary: Displays summary alarm information on the alarm page configured in
the project.
PageTrend: Displays a standard trend page.
Keyboard Functions
Keyboard functions control the processing of keyboard entries and the movement of the
keyboard cursor on the graphics page.
KeyBs: Backspaces (removes) the last key from the key command line. Use this function
with a ’Hotkey’ command. It is normally used to erase keyboard characters during runt-
ime command input.
KeyDown: Moves the cursor down the page to the closest animation point number
(AN).
KeyLeft: Moves the cursor left (across the page) to the closest animation point number
(AN).
KeyRight: Moves the cursor right (across the page) to the closest animation point num-
ber (AN).
KeyUp: Moves the cursor up the page to the closest animation point number (AN).
Report Functions
To run a report by operator action, use the following function:
Report: Runs the report on the report server.
Time/date Functions
The following functions return the current date and time:
Date: Returns the current date as a string.
Time: Returns the current time as a string.
Miscellaneous Functions
Beep: Beeps the speaker on the CitectSCADA computer.
FullName: Returns the full name of the user who is currently logged in to the system.
InfoForm: Displays the animation information form. This form displays the real-time
data that is controlling the current animation.
32
Chapter: 5 Working with Commonly Used Functions
33
Chapter: 5 Working with Commonly Used Functions
34
Chapter: 6 Writing Functions
CitectSCADA is supplied with over 600 built-in functions. One of these functions (or sev-
eral functions in combination) can usually perform most tasks in your system. However,
where system functionality cannot be achieved with built-in functions, you can write your
own functions.
A Cicode function is a small program: a collection of statements, variables, operators, con-
ditional executors, and other functions.
While you do not have to be an experienced programmer to write simple Cicode functions,
do not attempt to write large, complex functions unless you are familiar with computer
programming, and have experience with Cicode. Functions are equivalent to the subrou-
tines of BASIC and assembly language, and the subroutines and functions used in Pascal
and C.
Note: The Cicode Editor is designed specifically for editing and debugging Cicode func-
tions.
See Also
The Cicode Editor
Using Cicode Files
The line immediately following the FUNCTION statement, contains the name of the func-
tion, which is used to identify the function to CitectSCADA. This name is referred to when
the function is called upon (called) to be executed (perform the statements it contains) by
some other event, action, or function in CitectSCADA.
Note: Functions can contain statements that call other functions. These functions are then
executed before returning to the rest of the statements within the calling function.
The function name always ends with parentheses ( ), which may or may not contain one or
more arguments required by the function. Arguments are explained in the section titled
Function Argument Structure.
35
Chapter: 6 Writing Functions
All the lines between the function name line and the END statement line contain the state-
ments that will be executed when the function is called in CitectSCADA. These statements
are executed one at a time in logical order from top to bottom within the function. For de-
tails about function structure, see Formatting Functions. For details about Cicode function
syntax, see Following Cicode Syntax.
For details about using comments in Cicode and in Cicode functions, see Using Comments
in Cicode.
Function Uses
Cicode functions can have many purposes. Most often, functions are used to store a com-
mon set of commands or statements that would otherwise require repetitious typing and
messy command or expression fields.
Some functions are simple, created to avoid a long command or expression. For example,
the following command increments the variable tag COUNTER:
Command IF COUNTER < 100 THEN COUNTER = COUNTER + 1; ELSE COUNTER
= 0; END;
This command would be easier to use (and re-use) if it was written as a function that can
be called in the command:
Command IncCounter ( );
To be able to use the function like this, you must write it in a Cicode file, and declare it with
the FUNCTION keyword:
FUNCTION
IncCounter ( )
IF COUNTER < 100 THEN
COUNTER = COUNTER + 1;
ELSE
COUNTER = 0;
END
END
Be aware that the indented code is identical in functionality to the long command above.
By placing the command code inside a function, and using the function name in the com-
mand field as in the previous example, this function need only to be typed once. It can then
be called any number of times, from anywhere in CitectSCADA that requires this function-
ality. Because the code exists in the one location, rather than repeated wherever needed (in
potentially many places), it can be easily maintained (altered if necessary).
36
Chapter: 6 Writing Functions
by other functions, or called directly in commands and expressions. In fact, any function
can call - and be called by - any other function.
For example, you might need to write a set of functions for handling alarms. To perform
any action on an alarm, you first need to know which alarm. You would identify the alarm
in a separate function, and call this function from the other functions.
Pseudocode
The pseudocode above is a Cicode comment, enclosed between the comment markers /*
and */, and is ignored by the compiler. With pseudocode, you can get the logic of the func-
tion correct in a more readable structure, before you write it in Cicode syntax, leaving the
pseudocode within the finished code as comments.
It is good practice to use comments as file headers at the start of each Cicode file, to describe
the functions in the file - their common purpose, a broad description of how they achieve
that purpose, special conditions for using them, and so on. You can also use the header to
37
Chapter: 6 Writing Functions
record maintenance details on the file, such as its version number and date of revision. For
example:
/*
** FILE: Recipe Download.Ci
**
** AUTHOR: AJ Smith
**
** DATE: March 2008
**
** REVISION: 1.0 for CitectSCADA v7.1
**
** This file contains functions to allow the operator to load the
** recipe data from the SQL server to the PLC.
*/
38
Chapter: 6 Writing Functions
Single line ( ! ) and C++ style ( // ) comments can have a line of their own, where they refer
to the block of statements either before or after it. It is good practice to set a convention for
these comments. These comments can also be on the same line as a statement, to explain
that statement only. All characters after the ! or // (until the end of the line) are ignored by
the compiler.
Block (C style) comments begin with /* and end with */. These C style comments need no
punctuation between the delimiters.
The complete ELSE condition of the IF conditional executor will be ignored (and not exe-
cute) so long as the block comment markers are used in this example.
Note: The inline ( // ) comments have no effect within the block ( /* and */ ) comments (as
the whole section is now one big comment), and should remain unchanged, so that when
you do remove the block comments, the inline comments will become effective again.
39
Chapter: 6 Writing Functions
/*
This function is called from a keyboard command. The operator
presses the key and enters the name of the page to be displayed. If
the page cannot be displayed, an error message is displayed at the
prompt AN.
*/
INT
FUNCTION
MyPageDisplay ( STRING sPage ) ! pass in the name of the page to be displayed
! declare a local integer to hold the results of the pagedisplay function
INT Status;
! call the page Cicode pagedisplay function and store the result
Status = PageDisplay ( sPage ) ;
! determine if the page display was successful
IF Status < > 0 THEN ! error was detected
! display an error message at the prompt AN
DspError ( "Cannot Display " + sPage ) ;
END
! return the status to the caller
RETURN Status;
END
The rules for formatting statements in Cicode functions are simple, and help the compiler
in interpreting your code.
It is good practice to use white space to make your code more readable. In the example
above, all code between the FUNCTION and END statements is indented, and the state-
ment within the IF THEN conditional executor is further indented to make the conditions
and actions clear. Develop a pattern of indentation - and stick to it. Extra blank lines in the
code make it easier to read (and understand).
where:
40
Chapter: 6 Writing Functions
Function Scope
The optional Scope Statement of a function (if used), precedes all other statements of a func-
tion declaration in Cicode, including the FUNCTION Statement.
The scope of a function can be either PRIVATE or PUBLIC, and is declared public by de-
fault. That is, if no Scope Statement is declared, the function will have public scope.
Both PRIVATE and PUBLIC are Cicode keywords and as such, are reserved.
A private scope function is only accessible (can be called) within the file in which it is de-
clared.
Public scope functions can be shared across Cicode files, and can be called from pages and
CitectSCADA databases (for example, Alarm.dbf).
41
Chapter: 6 Writing Functions
Because functions are public by default, to make a function public requires no specific dec-
laration. To make a function private however, you must prefix the FUNCTION Statement
with the word PRIVATE.
PRIVATE
FUNCTION
FunctionName ( <Arguments> )
<Statement> ;
<Statement> ;
<Statement> ;
END
42
Chapter: 6 Writing Functions
If the RETURN Statement within the function encounters a different data type to that de-
clared in the return data type statement, the value is converted to the declared return data
type.
In the example below, the variable Status is declared as a real number within the function.
However, Status is converted to an integer when it is returned to the caller, because the
data type of the return was declared as an integer type in the return data type statement:
INT ! declare return value as integer
FUNCTION
FunctionName ( <Arguments> )
<Statement> ;
REAL Status = 5; ! declare variable as a REAL number
<Statement> ;
RETURN Status; ! returned as an integer number
END
If you do not specify a return data type, the function does not return a value.
Declaring Functions
The required FUNCTION Statement follows the optional Scope Statement (if used) and the
optional Return Data Type Statement (if used), and precedes all other statements of a func-
tion declaration in Cicode. Everything between it and the END Statement, contains the
function.
Both FUNCTION and END are Cicode keywords and, as such, are reserved.
You declare the start of a function with the FUNCTION Statement, and declare the end of
a function with the END Statement:
FUNCTION
<FunctionName> ( <Arguments> )
<Statement> ;
<Statement> ;
<Statement> ;
END
The FUNCTION Statement must be followed by the Name Statement, then the Argument
Statement, before any code statements that will be processed by the function.
For information on the Name and Argument Statements, see the sections titled Naming Ar-
guments and Function Argument Structure.
All code (as represented by the <Statement> placeholders) located between the FUNCTION
and END Statements, will be executed (processed by the function) when called to do so.
Functions can execute a large variety of statements, and are commonly used to process and
manipulate data, including the arguments passed when the function was called, plant-floor
and other CitectSCADA data, Windows data, and so on. CitectSCADA provides many
built-in functions. For more information, see the section titled Working with Commonly
Used Functions.
43
Chapter: 6 Writing Functions
Naming Functions
The required name statement follows the FUNCTION Statement and precedes the argu-
ments statement in a CitectSCADA function. The function name is used elsewhere in Cit-
ectSCADA to activate (call) the function to have it perform the statements it contains.
Replace the <FunctionName> placeholder in the following function example with an ap-
propriate name for your function. See the section Function Naming Standards for details.
FUNCTION
<FunctionName> ( <Arguments> )
<Statement> ;
<Statement> ;
<Statement> ;
END
You can use up to 32 ASCII text characters to name your functions. You can use any valid
name except for a reserved word. The case is not important to the CitectSCADA compiler,
so you can use upper and lower case to make your names clear. For example, Mixer-
RoomPageDisplay is easier to read than mixerroompagedisplay or MIXERROOMPAGE-
DISPLAY.
FUNCTION
MixerRoomPageDisplay ( <Arguments> )
<Statement> ;
<Statement> ;
<Statement> ;
END
Your functions take precedence over any other entity in CitectSCADA with the same name:
Variable tags. When you call a function by the same name as a variable tag, the function
has precedence. The variable tag can not be referred to because the function executes
each time the name is used.
Built-in functions. You can give your function the same name as any built-in Cicode
function. Your function takes precedence over the built-in function - the built-in func-
tion cannot be called. Because built-in Cicode functions cannot be changed, this pro-
vides a method of ’modifying’ any built-in function to suit an application. For example,
you might want to display the message "Press F1 for Help" whenever you display a
page. You could simply write a new function called PageDisplay ( ). The body of the
function would be the statements that display the page and prompt message:
Prompt ( "Press F1 for Help" ) ;PageDisplay ( <Arguments> ) ;
Your function is invoked whenever you use the function name in CitectSCADA.
44
Chapter: 6 Writing Functions
When you call a function, you can pass one or more arguments to the function, enclosed
within the parentheses ( ) located after the function name statement. Replace the <Argu-
ments> placeholder in the following function example with your Argument Statement.
FUNCTION
FunctionName ( <Arguments> )
<Statement> ;
<Statement> ;
<Statement> ;
END
For your function to perform tasks with data, it requires accessibility to the data. One way
to achieve this, is to pass the data directly to the function when the function is being called.
To enable this facility, Cicode utilizes arguments in its function structure. An argument in
Cicode is simply a variable that exists in memory only as long as its function is processing
data, so the scope of an argument is limited to be local only to the function. Arguments can-
not be arrays.
Arguments are variables that are processed within the body of the function only. You can-
not use an argument outside of the function that declares it.
As arguments are variables used solely within functions, they must be declared just as you
would otherwise declare a variable in Cicode. See the section titled Declaring Variable
Properties. An argument declaration requires a data type, a unique name, and may contain
an initial value which also behaves as the default value for the argument.
Notes: In the following function syntax example:
Every placeholder shown inside arrow brackets ( <placeholder> ) should be replaced in
any actual code with the value of the item that it describes. The arrow brackets and the
word they contain should not be included in the statement, and are shown here only for
your information.
Statements shown between square brackets ( [ ] ) are optional. The square brackets
should not be included in the statement, and are shown here only for your information.
Cicode function argument statements have the following syntax:
<ArgumentDataType>
<ArgumentName>
[ = <InitialDefaultValue> ]
where:
<ArgumentDataType> = Argument Data Type Statement: required, INT or REAL or
STRING. See the section titledDeclaring Argument Data Type.
<ArgumentName> = Argument Name Statement: required, up to 32 ASCII text charac-
ters, case insensitive, no spaces, no reserved words. See the section titled Naming Argu-
ments.
<InitialDefaultValue> = Argument Initialization Statement: optional, preceded by
equals ( = ) assignment operator, a value to assign to the argument variable when first
initialized, must be the same data type as that declared in the argument <Argument-
DataType> parameter, defaults to this value if no value passed in for this argument
when the function was called.
See the section titled Setting Default Values for Arguments.
45
Chapter: 6 Writing Functions
The Argument Statement in a Cicode function can have only one set of surrounding paren-
theses ( ), even if no arguments are declared in the function.
If more than one argument is used in the function, each must also be separated by a comma.
Argument Statements can be separated over several lines to aid in their readability.
When you call a function, the arguments you pass to it are used within the function to pro-
duce a resultant action or return a value. For information on passing data to functions, see
the section titled Passing Data to Functions (Arguments). For information on returning re-
sults from functions, see the section titled Returning Data from Functions.
Arguments are used in the function and referred to by their names. For instance, if we name
a function AddTwoIntegers, and declare two integers as arguments naming them FirstInt-
eger and SecondInteger respectively, we would end up with a sample function that looks
like the following:
INT
FUNCTION
AddTwoIntegers ( INT FirstInteger, INT SecondInteger )
INT Solution ;
Solution = FirstInteger + SecondInteger ;
RETURN Solution ;
END
In this example, the function would accept any two integer values as its arguments, add
them together, and return them to the caller as one integer value equal to the summed total
of the arguments values passed into the function.
This functionality of passing values into a function as arguments, manipulating the values
in some way, then being able to return the resultant value, is what makes functions poten-
tially very powerful and time saving. The code only needs to written once in the function,
and can be utilized any number of times from any number of locations in CitectSCADA.
Write once, use many.
46
Chapter: 6 Writing Functions
To declare the argument data type that will be used in the function, you must prefix the
Argument Name Statement with one of the Cicode data type keywords, in the <Argument-
DataType> placeholder in the following example.
FUNCTION
FunctionName ( <ArgumentDataType> <ArgumentName> [ =
<InitialDefaultValue> ] )
<Statement> ;
<Statement> ;
<Statement> ;
END
The Argument Statement in a Cicode function must have only one set of surrounding pa-
rentheses ( ) brackets, even if no arguments are declared in the function.
If more than one argument is used in the function, each must also be separated by a comma.
Argument Statements can be separated over several lines to aid in their readability.
Naming Arguments
If an argument is listed in a Cicode function declaration, the Argument Name Statement is
required, and is listed second, after the required Argument Data Type Statement, and be-
fore the optional Argument Initialization Statement.
The argument name is used only within the function to refer to the argument value that
was passed into the function when the function was called. The name of the argument vari-
able should be used in the executable statements of the function in every place where you
want the argument variable to be used by the statement.
Note: In the following function syntax example:
Every placeholder shown inside arrow brackets ( <placeholder> ) should be replaced
in any actual code with the value of the item that it describes. The arrow brackets and
the word they contain should not be included in the statement, and are shown here only
for your information.
Statements shown between square brackets ( [ ] ) are optional. The square brackets
should not be included in the statement, and are shown here only for your information.
Replace the <ArgumentName> placeholder in the following function example with an ap-
propriate name for your Argument variable. See the section titled Function Argument
Structure for details.
FUNCTION
FunctionName ( <ArgumentDataType> <ArgumentName> [ = <InitialDefaultValue> ] )
<Statement> ;
<Statement> ;
<Statement> ;
END
You can use up to 32 ASCII text characters to name your arguments. You can use any valid
name except for a reserved word. The case is not important to the CitectSCADA compiler,
so you can use upper and lower case to make your names clear. For example, iPacketQnty
is easier to read than ipacketqnty or IPACKETQNTY .
47
Chapter: 6 Writing Functions
FUNCTION
FunctionName ( INT iPacketQnty )
<Statement> ;
<Statement> ;
<Statement> ;
END
To refer to the argument (in the body of your function) you use the name of the argument
in an executable statement:
INT
FUNCTION
AddTwoIntegers ( INT FirstInteger, INT SecondInteger )
INT Solution ;
Solution = FirstInteger + SecondInteger ;
RETURN Solution ;
END
The default value for an argument must be of the same data type as declared for the argu-
ment in the Argument Data Type Statement.
You assign a default argument variable value in the same manner that you assign a Cicode
variable value, by using the equals ( = ) assignment operator. For example:
FUNCTION
PlotProduct ( INT iPackets = 200 , STRING sName = "Packets" )
48
Chapter: 6 Writing Functions
<Statement> ;
<Statement> ;
<Statement> ;
END
If you assign a default value for an argument, you do not have to pass a value for that ar-
gument when you call the function, (because the function will use the default value from
the declaration.) To pass an empty argument to a function, omit any value for the argument
in the call. For example, to call the PlotProduct function declared in the previous example,
and accept the default string value of "Packets", a Cicode function call would look like:
PlotProduct ( 500 , )
Notice that the second argument for the function was omitted from the calling code. In this
instance, the default value for the second argument ( "Packets" ) would remain unchanged,
and so would be used as the second argument value in this particular function call.
If you do call that function and pass in a value for that argument in the call, the default val-
ue is replaced by the argument value being passed in. However, the arguments are reini-
tialized every time the function is called, so each subsequent call to the function will restore
the default values originally declared in the function.
If more than one argument is used in a function, each must also be separated by a comma.
Equally, if a function containing more than one argument is called, each argument must be
accounted for by the caller. In this case, if an argument value is to be omitted from the call,
(to utilise the default value), comma placeholders must be used appropriately in the call to
represent the proper order of the arguments.
For more information on function calls, callers, and calling, see the section titled Calling
Functions from Commands and Expressions.
Argument Statements can be separated over several lines to aid in their readability.
49
Chapter: 6 Writing Functions
<Statement> ;
RETURN <ReturnValue> ;
END
The RETURN Statement consists of the RETURN keyword followed by a value to be re-
turned and finished with the semicolon (;) end-of-line marker.
The RETURN value must be of the same data type as was declared in the Return Data Type
Statement at the start of the function declaration. The return data type of a function can be
only one of four possible data types: INT (32 bits), REAL (32 bits), STRING (255 bytes), or
OBJECT (32 bits). If no Return Data Type Statement is declared, the function will not be able
to return any type of data.
If the RETURN Statement within the function encounters a different data type to that de-
clared in the Return Data Type Statement, the value is converted to the declared return data
type. For information about the Return Data Type Statement, see the section titled Declar-
ing the Return Data Type.
FUNCTION, INT, REAL, STRING, and OBJECT are Cicode keywords and as such, are re-
served.
Note: In the following function syntax example every placeholder shown inside arrow
brackets ( <placeholder> ) should be replaced in any actual code with the value of the item
that it describes. The arrow brackets and the word they contain should not be included in
the statement, and are shown here only for your information.
To declare the value that will be returned to the calling code, you must replace the <Return-
Value> placeholder in the following example with an appropriate data value to match the
Return Data Type as declared in the function.
<ReturnDataType>
FUNCTION
FunctionName ( <Arguments> )
<Statement> ;
<Statement> ;
RETURN <ReturnValue> ;
END
The RETURN statement passes a value back to the calling procedure (either another func-
tion, command or expression). Outside of the function, the return value can be read by the
calling statement. For example, it can be used by the caller as a variable (in a command), or
animated (in an expression).
50
Chapter: 7 Using Variables
A variable is a named location in the computer’s memory where data can be stored. Cicode
variables can store the basic data types (such as strings, integers, and real numbers) and
each variable is specific for its particular data type. For example, if you set up a Cicode vari-
able to store an integer value, you cannot use it for real numbers or strings.
Note: Each data type uses a fixed amount of memory: integers use 4 bytes of memory, real
numbers use 4 bytes, and strings use 1 byte per character. PLC INT types use only 2 bytes.
The computer allocates memory to variables according to the data type and the length of
time you need the variable to be stored.
Real-time variables (such as PLC variables) are already permanently stored in database
files on your hard disk. Any variable you use in a database field command or expression
must be defined as a variable tag, or the compiler will report an error when the system is
compiled.
Note: Cicode variables can handle a wide range of CitectSCADA variable tag data types.
For example, a Cicode variable of INT data type can be used to store I/O device data types:
BCD, BYTE, DIGITAL, INT, LONG, LONGBCD, and UINT.
See Also
Using Arrays
Variable Declaration Standards
Variable Naming Standards
Variable Scope Standards
Using Cicode Files
If you want to specify a digital data type, use the integer type. Digital types can either be
TRUE(1) or FALSE(0), as can integer types.
51
Chapter: 7 Using Variables
Note: Cicode may internally store floating point values as 64 bit to minimize the loss of data
during floating point calculations.
Naming Variables
Throughout the body of the function, the variable is referred to by its name. You can name
a variable any valid name except for a reserved word, for example:
STRING sStr;
REAL Result;
INT x, y;
OBJECT hObject;
Global variables
A global Cicode variable can be shared across all Cicode files in the system (as well as
across include projects). They cannot be accessed on pages or databases (for example,
Alarm.dbf).
Global Cicode variables are prefixed with the keyword GLOBAL, and must be declared at
the start of the Cicode file. For example:
GLOBAL STRING sDefaultPage = "Mimic";
INT
FUNCTION
MyPageDisplay(STRING sPage)
INT iStatus;
iStatus = PageDisplay(sPage);
IF iStatus <> 0 THEN
52
Chapter: 7 Using Variables
PageDisplay(sDefaultPage);
END
RETURN iStatus;
END
The variable sDefaultPage could then be used in any function of any Cicode file in the sys-
tem.
Note: Use global variables sparingly if at all. If you have many such variables being used
by many functions, finding bugs in your program can become time consuming. Use local
variables wherever possible. Global Cicode STRING types are only 128 bytes, instead of 256
bytes.
Module variables
A module Cicode variable is specific to the file in which it is declared. This means that it
can be used by any function in that file, but not by functions in other files.
By default, Cicode variables are defined as module, therefore prefixing is not required
(though a prefix of MODULE could be added if desired). Module variables should be de-
clared at the start of the file. For example:
STRING sDefaultPage = "Mimic";
INT
FUNCTION
MyPageDisplay(STRING sPage)
INT Status;
Status = PageDisplay(sPage);
IF Status <> 0 THEN
PageDisplay(sDefaultPage);
END
RETURN Status;
END
INT
FUNCTION
DefaultPageDisplay()
PageDisplay(sDefaultPage);
END
Note: Use module variables sparingly if at all. If you have many such variables being used
by many functions, finding bugs in your program can become time-consuming. Use local
variables wherever possible.
Local variables
A local Cicode variable is only recognized by the function within which it is declared, and
can only be used by that function. You must declare local variables before you can use
them.
Any variable defined within a function (that is, after the function name) is a local variable,
therefore no prefix is needed. Local variables are destroyed when the function exits.
Local variables always take precedence over global and module variables. If you define a
local variable in a function with the same name as a global or module variable, the local
variable is used; the global/module variable is unaffected by the function. This situation
should be avoided, however, as it is likely to cause confusion.
53
Chapter: 7 Using Variables
See Also
Variable Scope Standards
where Tag is the name of the database variable. For example, to change the value of the da-
tabase variable "LT131" at run time, you would use the following statement in your func-
tion:
LT131=1200; !Changes the value of LT131 to 1200
54
Chapter: 8 Using Arrays
A Cicode variable array is a collection of Cicode variables of the same data type, in the form
of a list or table. You name and declare an array of variables in the same way as any other
Cicode variable. You can then refer to each element in the array by the same variable name,
with a number (index) to indicate its position in the array.
See Also
Variable Declaration Standards
Declaring Array Properties
Declaring the Array Data Type
Naming Arrays
Declaring the Variable Array Size
Setting Default (Initial) Array Values
Passing Array Elements as Function Arguments
Using One-dimensional Arrays
Using Two-dimensional Arrays
Using Three-dimensional Arrays
Using Array Elements in Loops
Using the Table (Array) Functions
Using Cicode Files
See Also
Using Arrays
Using Cicode Files
55
Chapter: 8 Using Arrays
See Also
Using Arrays
Using Cicode Files
Naming Arrays
Throughout the body of a Cicode function, a Cicode variable array is referred to by its
name, and individual elements of an array are referred to by their index. The index of the
first element of an array is 0 (that is a four element array has the indices 0,1,2, and 3). You
can name a variable any valid name except for a reserved word; for example:
STRING StrArray[5]; ! list
REAL Result[5][2]; ! 2-D table
INT IntArray[4][3][2]; ! 3-D table
See Also
Using Arrays
Using Cicode Files
This single dimension array contains 5 elements. The compiler multiplies the number of el-
ements in the array by the size of each element (dependent upon the Data Type), and allo-
cates storage for the array in consecutive memory locations.
You cannot declare arrays local to a function. However, they can be declared as Module
(that is at the beginning of the Cicode file), or Global. When referring to the array within
your function, you must not exceed the size you set when you declared the array. The ex-
ample below would cause an error:
STRINGStrArray[5];
...
StrArray[10] = 100;
...
The compiler allows storage for 5 strings. By assigning a value to a 10th element, you cause
a value to be stored outside the limits of the array, and you could overwrite another value
stored in memory.
See Also
Using Arrays
Using Cicode Files
56
Chapter: 8 Using Arrays
See Also
Using Arrays
Using Cicode Files
See Also
Using Arrays
Using Cicode Files
57
Chapter: 8 Using Arrays
See Also
Using Arrays
Using Cicode Files
See Also
Using Arrays
Using Cicode Files
You use arrays in your functions in the same way as other variables, but arrays have special
properties that, in many situations, reduce the amount of code you must write.
See Also
Using Arrays
Using Cicode Files
58
Chapter: 8 Using Arrays
See Also
Working with Conditional Executors
Using Arrays
Using Cicode Files
59
Chapter: 8 Using Arrays
60
Chapter: 9 Using Cicode Macros
Cicode has the following macros:
IFDEF: Determines one of two possible outcomes based on the existence of a specified
non-alarm tag at compile time. Use one of the macros below for alarm tags.
IFDEFAdvAlm: Determines one of two possible outcomes based on the existence of a
specified advanced alarm tag at compile time.
IFDEFAnaAlm: Determines one of two possible outcomes based on the existence of a
specified analog alarm tag at compile time.
IFDEFDigAlm: Determines one of two possible outcomes based on the existence of a
specified digital alarm tag at compile time.
IFDEF
The IFDEF macro allows you to define two possible outcomes based on whether or not a
specified tag exists within a project at the time of compiling. The macro can be implement-
ed anywhere a simple expression is used, including fields within relevant CitectSCADA di-
alogs.
The macro was primarily created to avoid the "Tag not found" compile error being gener-
ated whenever a genie was missing an associated tag. By allowing a "0" or "1" to be gener-
ated within the Hidden When field of a Genie’s properties, elements could simply be
hidden if a required tag was missing, allowing the genie to still be pasted onto a graphics
page.
The macro accepts three arguments: the first specifies the tag that requires confirmation,
the second defines the outcome if the tag exists, the third defines the outcome if it does not
exist. In the case of a genie being pasted on a graphics page, the IFDEF function would be
configured as follows in the Hidden When field of the object properties dialog:
IFDEF("Bit_1",0,1)
If the tag "Bit_1" is defined in the tag database, the value in the Hidden When field will be
0. If Bit_1 is undefined, the value will be 1. Since the object is hidden when the value is
TRUE (1), the object will be hidden when Bit_1 is undefined. See Hiding Graphics Objects
for details.
Beyond this purpose, the IFDEF macro can be broadly used as a conditional variable. The
[<value if defined>] and <value if not defined> arguments can support any variable, expres-
sion, or constant. The [<value if defined>] argument is optional; if you leave it blank it will
generate the current variable. You can also use nested IFDEF macros.
Note: As different types of alarms can share the same name, you have to use a variation of
IFDEF to check for the existence of alarm tags. See IFDEFAnaAlm for analog alarms, IF-
DEFDigAlm for digital alarms, or IFDEFAdvAlm for advanced alarms.
Syntax
IFDEF(TagName, [<value if defined>], <value if not defined>)
61
Chapter: 9 Using Cicode Macros
Return Value
If the tag specified in the first argument exists, the value defined by the second argument
is returned. This could be a variable, expression, or constant, or the current tag value if the
argument has been left blank. If the specified tag does not exist, the variable, expression, or
constant defined by the third argument is returned.
Example
! Generate the tag value if tag "Bit_1" is defined
! Generate an empty string if "Bit_1" is not defined
IFDEF("Bit_1",," ")
! Generate a zero value (0) if tag "Bit_1" is defined
! Generate a true value (1) if "Bit_1" is not defined
IFDEF("Bit_1",0,1)
For more examples of how to implement the IFDEF macro, see the CitectSCADA Knowl-
edge Base article Q3461.
See Also
IFDEFAnaAlm, IFDEFDigAlm, IFDEFAdvAlm, Hiding Graphics Objects, IFDEF macro
IFDEFAdvAlm
Based on the IFDEF macro, IFDEFAdvAlm allows you to define two possible outcomes
based on whether or not a specified advanced alarm tag exists within a project at the time
of compiling. The macro can be implemented anywhere a simple expression is used, in-
cluding fields within relevant CitectSCADA dialogs.
The macro accepts three arguments: the first specifies the advanced alarm tag that requires
confirmation, the second defines the outcome if the alarm exists, the third defines the out-
come if it does not exist.
Note: As different types of alarms can share the same name, you have to use a variation of
IFDEF to check for the existence of alarm tags. See IFDEFAnaAlm for analog alarms, or IF-
DEFDigAlm for digital alarms.
Syntax
IFDEFAdvAlm(TagName, [<value if defined>], <value if not defined>)
Return Value
If the advanced alarm tag specified in the first argument exists, the value defined by the
second argument is returned. This could be a variable, expression, or constant, or the cur-
rent tag value if the argument has been left blank. If the specified alarm does not exist, the
variable, expression, or constant defined by the third argument is returned.
Example
! Generate tag value if advanced alarm "AdvAlarm_1" is defined
! Generate an empty string if "AdvAlarm_1" is not defined
IFDEFAdvAlm("AdvAlarm_1",,"")
! Generate a zero value (0) in Hidden When field if advanced alarm
"AdvAlarm_1" is defined
! Generate a true value (1) in Hidden When field if "AdvAlarm_1"
is not defined
IFDEFAdvAlm("AdvAlarm_1",0,1)
62
Chapter: 9 Using Cicode Macros
For more examples of how to implement the IFDEF macro, see the CitectSCADA Knowl-
edge Base article Q3461.
See Also
IFDEFAnaAlm, IFDEFDigAlm, IFDEF
IFDEFAnaAlm
Based on the IFDEF macro, IFDEFAnaAlm allows you to define two possible outcomes
based on whether or not a specified analog alarm tag exists within a project at the time of
compiling. The macro can be implemented anywhere a simple expression is used, includ-
ing fields within relevant CitectSCADA dialogs.
The macro accepts three arguments: the first specifies the analog alarm tag that requires
confirmation, the second defines the outcome if the alarm exists, the third defines the out-
come if it does not exist.
Note: As different types of alarms can share the same name, you have to use a variation of
IFDEF to check for the existence of alarm tags. See IFDEFDigAlm for digital alarms, or IF-
DEFAdvAlm for advanced alarms.
Syntax
IFDEFAnaAlm(TagName, [<value if defined>], <value if not defined>)
Return Value
If the analog alarm tag specified in the first argument exists, the value defined by the sec-
ond argument is returned. This could be a variable, expression, or constant, or the current
tag value if the argument has been left blank. If the specified alarm does not exist, the vari-
able, expression, or constant defined by the third argument is returned.
See Also
IFDEF, IFDEFDigAlm, IFDEFAdvAlm
Example
! Generate tag value if analog alarm "AnaAlarm_1" is defined
! Generate an empty string if "AnaAlarm_1" is not defined
IFDEFAnaAlm("AnaAlarm_1",,"")
! Generate a zero value (0) in Hidden When field if analog alarm
"AnaAlarm_1" is defined
! Generate a true value (1) in Hidden When field if "AnaAlarm_1"
is not defined
IFDEFAnaAlm("AnaAlarm_1",0,1)
For further examples of how to implement the IFDEF macro, see the CitectSCADA Knowl-
edge Base article Q3461.
See Also
IFDEF, IFDEFDigAlm, IFDEFAdvAlm
IFDEFDigAlm
Based on the IFDEF macro, IFDEFDigAlm allows you to define two possible outcomes
based on whether or not a specified digital alarm tag exists within a project at the time of
63
Chapter: 9 Using Cicode Macros
compiling. The macro can be implemented anywhere a simple expression is used, includ-
ing fields within relevant CitectSCADA dialogs.
The macro accepts three arguments: the first specifies the digital alarm tag that requires
confirmation, the second defines the outcome if the alarm exists, the third defines the out-
come if it does not exist.
Note: As different types of alarms can share the same name, you have to use a variation of
IFDEF to check for the existence of alarm tags. See IFDEFAnaAlm for analog alarms or IF-
DEFAdvAlm for advanced alarms.
Syntax
IFDEFDigAlm(TagName, [<value if defined>], <value if not defined>)
Return Value
If the digital alarm tag specified in the first argument exists, the value defined by the second
argument is returned. This could be a variable, expression, or constant, or the current tag
value if the argument has been left blank. If the specified alarm does not exist, the variable,
expression, or constant defined by the third argument is returned.
Example
! Generate tag value if digital alarm "DigAlarm_1" is defined
! Generate an empty string if "DigAlarm_1" is not defined
IFDEFDigAlm("DigAlarm_1",,"")
! Generate a zero value (0) in Hidden When field if digital alarm
"DigAlarm_1" is defined
! Generate a true value (1) in Hidden When field if "DigAlarm_1"
is not defined
IFDEFDigAlm("DigAlarm_1",0,1)
For more examples of how to implement the IFDEF macro, see the CitectSCADA Knowl-
edge Base article Q3461.
Related macros
IFDEFAnaAlm, IFDEFAdvAlm, IFDEF
Macro Arguments
The Cicode macros use the following arguments.
TagName
[<value if defined>]
<value if not defined>
TagName
The name of the tag you would like the IFDEF macro to confirm the existence of. The Cit-
ectSCADA compiler will check the current project database for a tag matching this name.
[<value if defined>]
Defines the outcome of the macro if the specified tag exists in the current project. This ar-
gument is optional, which means you can:
Generate any variable, constant, or expression.
Generate the current value for the specified tag by leaving the argument blank.
64
Chapter: 9 Using Cicode Macros
65
Chapter: 9 Using Cicode Macros
66
Chapter: 10 Converting and Formatting Cicode Vari-
ables
CitectSCADA provides four functions for converting integers and real numbers into
strings, and vice versa.
IntToStr: converts an integer variable into a string
RealToStr: converts a floating-point variable into a string
StrToInt: converts a string into an integer variable
StrToReal: converts a string into a floating-point variable
You can convert data types without using these Cicode functions, but the result of the for-
mat conversion might not be what you expect. If you want more control over the conver-
sion process, use the appropriate Cicode functions.
Note: Variables of type object cannot be converted to any other type.
When variables are automatically converted, or when the return value from a function call
is converted, specific rules apply.
See Also
Converting Variable Integers to Strings
Converting Real Numbers to Strings
Converting Strings to Integers
Converting Strings to Real Numbers
Formatting Text Strings
Escape Sequences (String Formatting Commands)
Using Cicode Files
The value of StringVar = " 5". (The ’#’ formatting characters determine the size and number
of decimal places contained in the string, that is a length of 4 with no decimal places.)
67
Chapter: 10 Converting and Formatting Cicode Variables
See Also
Converting and Formatting Cicode Variables
Using Cicode Files
The value of StringVar = " 5.200". (The ’#’ formatting characters determine the size and
number of decimal places contained in the string, that is a length of 10 including a decimal
point and three decimal places.)
See Also
Converting and Formatting Cicode Variables
Using Cicode Files
The value of IntVar is set to 50. If StringVar contains any characters other than numeric
characters, IntVar is set to 0.
See Also
Converting and Formatting Cicode Variables
Using Cicode Files
68
Chapter: 10 Converting and Formatting Cicode Variables
StringVar="50.25";
RealVar=StringVar;
The value of RealVar is set to 50.25. If StringVar contains any characters other than numeric
characters, RealVar is set to 0.
See Also
Converting and Formatting Cicode Variables
Using Cicode Files
More than one string can be joined together (concatenated) using the Cicode ’plus’ mathe-
matical operator ( + ). For example:
STRING sMyStringVariable;
sMyStringVariable = "This is my text string." + "This is my second
text string.";
The two strings would be joined together and assigned to the string variable sMyString-
Variable. However, if subsequently displayed somehow, like in the following MESSAGE
example, the concatenated string would look wrong because there is no space character po-
sitioned between the string sentences.
STRING sMyStringVariable;
sMyStringVariable = "This is my text string." + "This is my second
text string.";
MESSAGE("String Concatenation Example",sMyStringVariable,32);
69
Chapter: 10 Converting and Formatting Cicode Variables
To overcome this potential formatting problem, you could include an extra space as the last
character in the strings, or include the space as a third string in the concatenation. For ex-
ample:
sMyStringVariable = "This is my text string. " + "This is my
second text string. ";
or
sMyStringVariable = "This is my text string." + " " + "This is my
second text string. ";
However, these are considered poor programming practices and not recommended. In-
stead, you can use special string formatting commands known as escape sequences.
If the two strings (as used in the previous example), were formatted using appropriate es-
cape sequences positioned within the strings, and subsequently displayed somehow, like
in the following MESSAGE example, the concatenated string would look different, For ex-
ample:
STRING sMyStringVariable;
STRING sNewLine = "^n";
sMyStringVariable = "This is my text string." + sNewLine + "This
is my second text string.";
MESSAGE("String Concatenation Example",sMyStringVariable,32);
Strings and string variables can also be concatenated as in the previous example. Notice
how the newline escape sequence ( ^n ) was assigned to the string variable sNewLine, and
how this value was concatenated between the other strings and assigned to the string vari-
able sMyStringVariable for display in the MESSAGE function.
See Also
Converting and Formatting Cicode Variables
Using Cicode Files
70
Chapter: 10 Converting and Formatting Cicode Variables
can format the string display to do such things as break into separate lines at specific posi-
tions, insert tab spaces, insert quotes, or to display Hexadecimal numbers.
All Cicode escape sequences are preceded by a caret ( ^ ) character. The caret character is
interpreted as a special instruction, and together with the characters immediately following
it, are treated as an Cicode escape sequence formatting command. The escape sequences
used in Cicode are:
^b backspace
^f form feed
^n new line
^t horizontal tab
^v vertical tab
^’ single quote
^" double quote
^^ caret
^r carriage return
^0xhh where hh is a hexadecimal number (for example, ^0x1A)
See Also
Converting and Formatting Cicode Variables
Using Cicode Files
71
Chapter: 10 Converting and Formatting Cicode Variables
72
Chapter: 11 Working with Operators
With Cicode, you can use the data operators that are standard in most programming lan-
guages: mathematical, bit, relational, and logical operators.
See Also
Using Mathematical Operators
Using Bit Operators
Using Relational Operators
Using Logical Operators
Order of Precedence of Operators
Example
The following are examples of mathematical operators
Command PV12 = PV10 + PV11;
Comment PV12 is the sum of PV10 and PV11
Command Counter = Counter - 1;
Comment The value of Counter is decreased by 1
Command PV12 = Speed * Counter;
Comment PV12 is the product of Speed and Counter
Command Average = Total / ShiftHrs;
Comment Average is Total divided by ShiftHrs
Command Hold = PV12 MOD PV13;
Comment If PV12 = 10 and PV13 = 8, Hold equals 2 (the remainder when PV12 is
divided by PV13)
Command Hold = PV12 MOD PV13;
Comment If PV12 = 10 and PV13 = 8, Hold equals 2 (the remainder when PV12 is
divided by PV13)
Note: Cicode uses the standard order of precedence, that is multiplication and division are
calculated before addition and subtraction. In the statement A=1+4/2, 4 is divided by 2 be-
73
Chapter: 11 Working with Operators
fore it is added to 1, and the result is 3. In the statement A=(1+4)/2 , 1 is first added to 4 be-
fore the division, and the result is 2.5.
You can also use the addition operator (+) to concatenate (join) two strings.
Operator Description
+ Concatenate
For example:
See Also
Working with Operators
Using Cicode Files
For example
Command Tag3 = Tag1 BITAND Tag2;
Command Tag3 = Tag1 BITAND 0xFF;
Command Tag3 = Tag1 BITOR Tag2;
Command Tag3 = Tag1 BITXOR Tag2;
See Also
Working with Operators
Using Cicode Files
74
Chapter: 11 Working with Operators
For example:
Command IF Message = "Alarm Active" THEN ...
Expression PV12 <> PV10;
Command IF (Total + Count) / Avg < 10 THEN ...
Expression Counter > 1;
Command IF PV12 <= PV10 THEN ...
Expression Total >= Shift * Hours;
See Also
Working with Operators
Using Cicode Files
Examples:
Command Result = (PV12 = 10 AND PV13 = 2);
Comment If PV12 equals 10 and PV13 equals 2 then Result is TRUE(1)
Expression Motor_1 AND Motor_2;
Comment If both Motor_1 and Motor_2 are TRUE, that is Digital bits are 1 or ON,
then the expression is TRUE
Expression PV12 = 1 OR PV13 > 2 OR Counter <> 0;
Comment If either PV12 equals 1 or PV13 is greater than 2 or Counter is not equal
to 0, then the expression is TRUE
Command Result = (Motor1_Ol OR Motor2_Ol);
Comment If either Motor1_Ol or Motor2_Ol is TRUE, that is Digital bit is 1 or ON,
then Result is TRUE (1)
Command IF NOT PV12 = 10 THEN ...
Comment If PV12 does not equal 10 then the result is TRUE. This is functionally
identical to IF PV12 <> 10 THEN . . .
Expression NOT Tag_1;
Comment This expression is TRUE if Tag_1 = 0. This is most commonly used for
testing digital variables
See Also
Working with Operators
Using Cicode Files
75
Chapter: 11 Working with Operators
See Also
Working with Operators
Using Cicode Files
76
Chapter: 12 Working with Conditional Executors
The statements that control decisions and loops in your functions are called conditional ex-
ecutors. Cicode uses four conditional executors: If, For, While, and select case.
See Also
Formatting Executable Statements
Setting IF ... THEN Conditions
Using FOR ... DO Loops
Using WHILE ... DO Conditional Loops
Using the SELECT CASE statement
Using Cicode Files
When you use the If Then format, the statement(s) following are executed only if the ex-
pression is TRUE, for example:
INT Counter;
IF PV12 = 10 THEN
Counter = Counter + 1;
END
In this example, the Counter increments only if the tag PV12 is equal to 10, otherwise the
value of Counter remains unchanged. You can include several statements (including other
IF statements), within an IF statement, for example:
INT Counter;
IF PV12 = 10 THEN
Counter = Counter + 1;
IF Counter > 100 THEN
Report("Shift");
END
END
77
Chapter: 12 Working with Conditional Executors
In this example, the report runs when the Counter increments, that is when PV12 = 10, and
the value of the counter exceeds 100.
You can use the If Then Else format for branching. Depending on the outcome of the ex-
pression, one of two actions are performed, for example:
INT Counter;
IF PV12 = 10 THEN
Report("Shift");
ELSE
Counter = Counter + 1;
END
In this example, the report runs if PV12 is equal to 10 (TRUE), or the counter increments if
PV12 is anything but 10 (FALSE).
See Also
Working with Conditional Executors
This function displays the single message "This is a String Array" on the screen one word
at a time pausing for 15 seconds between each word.
See Also
Working with Conditional Executors
78
Chapter: 12 Working with Conditional Executors
WHILE Expression DO
Statement(s);
END
Be careful when using WHILE loops in your Cicode functions: WHILE loops can cause ex-
cessive loading of the CPU and therefore reduce system performance. If you use a WHILE
loop to loop forever, you should call the Cicode function Sleep() so that CitectSCADA can
schedule other tasks. The Sleep() function increases the performance of your CitectSCADA
system if you use many WHILE loops.
See Also
Working with Conditional Executors
Nested Loops
You can "nest" one loop inside the other. That is, a conditional statement can be placed com-
pletely within (nested inside) a condition of another statement.
See Also
Working with Conditional Executors
79
Chapter: 12 Working with Conditional Executors
Where the TO keyword specifies an inclusive range of values. The smaller value must be
placed before TO.
- IS <relop> expression.
Use the IS keyword with relational operators (<relop>). Relational operators that may be
used are <, <=, =, <>, >, >= .
If the Expression matches any CaseExpression, the statements following that CASE clause
are executed up to the next CASE clause, or (for the last clause) up to the END SELECT. If
the Expression matches a CaseExpression in more than one CASE clause, only the state-
ments following the first match are executed.
The CASE ELSE clause is used to indicate the statements to be executed if no match is found
between the Expression and any of the CaseExpressions. When there is no CASE ELSE
statement and no CaseExpressions match the Expression, execution continues at the next
Cicode statement following END SELECT.
You can use multiple expressions or ranges in each CASE clause. For example, the follow-
ing line is valid:
CASE 1 To 4, 7 To 9, 11, 13, Is > MaxNumber
You can also specify ranges and multiple expressions. In the following example, CASE
matches strings that are exactly equal to "everything", strings that fall between "nuts" and
"soup" in alphabetical order, and the current value of "TestItem":
CASE "everything","nuts" To "soup",TestItem
SELECT CASE statements can be nested. Each SELECT CASE statement must have a
matching END SELECT statement.
For example, if the four possible states of a ship are Waiting, Berthed, Loading, and Load-
ed, the Select Case statement could be run from a button to display a prompt detailing the
ship’s current state.
select case iStatus
CASE 1
Prompt("Waiting");
CASE 2
Prompt("Berthed");
CASE 3
Prompt("Loading");
CASE 4
Prompt("Loaded");
CASE Else
Prompt("No Status");
END SELECT
See Also
Working with Conditional Executors
80
Chapter: 13 Performing Advanced Tasks
This section introduces and explains event handling, CitectSCADA tasks, CitectSCADA
threads, how CitectSCADA executes, and multitasking - including foreground and back-
ground tasks, controlling tasks, and pre-emptive multitasking.
See Also
Handling Events
How CitectSCADA Executes
Multitasking
Foreground and background tasks
Controlling tasks
Pre-emptive multitasking
Handling Events
Cicode supports event handling. You can define a function that is called only when a par-
ticular event occurs. Event handling reduces the overhead that is required when event trap-
ping is executed by using a loop. The following example illustrates the use of the OnEvent()
function:
INT
FUNCTION MouseCallback()
INT x, y;
DspGetMouse(x,y);
Prompt("Mouse at "+x:####+","+y:####);
RETURN 0;
END
OnEvent(0,MouseCallback);
The function MouseCallBack is called when the mouse is moved - you do not need to poll
the mouse to check if it has moved. CitectSCADA watches for an event with the OnEvent()
function.
Because these functions are called each time the event occurs, you should avoid complex
or time consuming statements within the function. If the function is executing when anoth-
er call is made, the function can be blocked, and some valuable information may be lost. If
you do wish to write complex event handling functions, you should use the queue han-
dling functions provided with Cicode.
See Also
Performing Advanced Tasks
81
Chapter: 13 Performing Advanced Tasks
Multitasking
Multitasking is when you can run more than one task at the same time. Windows supports
this feature at the application level. For example you can run MS-Word and MS-Excel at the
same time.
CitectSCADA also supports multitasking internally; that is you can tell CitectSCADA to do
something, and before CitectSCADA has completed that task you can tell CitectSCADA to
start some other task. CitectSCADA will perform both tasks at the same time. CitectSCADA
automatically creates the tasks, all you have to do is call the functions.
Multitasking is a feature of CitectSCADA not the operating system. Most applications can-
not do this, for example if you start a macro in Excel, while that macro is running you can-
not do any other operation in Excel until that macro completes.
A multitasking environment is useful when designing your Cicode. It allows you to be flex-
ible, allowing the operator to perform one action, while another is already taking place. For
example, you can use Cicode to display two different input forms at the same time, while
allowing the operator to continue using the screen in the background.
82
Chapter: 13 Performing Advanced Tasks
See Also
Performing Advanced Tasks
Controlling tasks
You can use the Task functions to control the execution of Cicode tasks, and use the Cit-
ectSCADA Kernel at runtime to monitor the tasks that are executing. Since CitectSCADA
automatically creates new tasks (whenever you call a keyboard command, etc.), schedules
them, and destroys them when they are finished, most users will not need to consider these
activities in detail.
Sometimes it is desirable to manually ’spawn’ a new task. For example, suppose your
Cicode is polling an I/O Device (an operation which must be continuous), but a situation
arises that requires operator input. To display a form would temporarily halt the polling.
Instead you can spawn a new task to get the operator input, while the original task contin-
ues polling the device.
Note: The TaskNew Cicode function is used to spawn new tasks.
See Also
"Using the CitectSCADA Kernel" in the CitectSCADA User Guide
Performing Advanced Tasks
Task Functions
Pre-emptive multitasking
Cicode supports pre-empted multitasking. If a Cicode task is running, and a more impor-
tant task is scheduled, CitectSCADA will suspend the original task, complete the more im-
portant task and return to the original task.
Preemption is supported between Cicode threads and other internal processes performed
by CitectSCADA. You can, therefore, write Cicode that runs forever (for example, a contin-
uous while loop) without halting other Cicode threads or CitectSCADA itself. For example:
83
Chapter: 13 Performing Advanced Tasks
In the above example, the function Sleep() is used to force preemption. The Sleep() function
is optional, however it will reduce the load on the CPU, because the loop is suspended each
second (it will not repeat at a high rate).
See Also
Performing Advanced Tasks
84
Chapter: 14 Editing and Debugging Code
This section describes how to edit and debug your Cicode using the Cicode Editor.
85
Chapter: 14 Editing and Debugging Code
86
Chapter: 14 Editing and Debugging Code
Creating functions
To create a new Cicode function:
Start the Cicode Editor.
Choose File | New, or click New.
Type in your new Cicode function in the blank space, or at the end of the file. Format
the Cicode function correctly, following the documented syntax.
Save the Cicode file.
Saving files
To save a Cicode file:
Choose File | Save, or click Save.
If the file is new, you will be prompted by the Save as dialog. CitectSCADA automati-
cally suggests a name.
Type in a new name in the File name field.
Click Save to save the file, or Cancel to abort the save.
To save your Cicode file under a new name, choose Save as instead of Save. The original
file will remain in your project under the original filename, until you delete it. All source
files in your project directory will be included when you compile your project.
87
Chapter: 14 Editing and Debugging Code
88
Chapter: 14 Editing and Debugging Code
89
Chapter: 14 Editing and Debugging Code
90
Chapter: 14 Editing and Debugging Code
The Windows and Bars tab displays the current display state of the listed Toolbars and De-
bug Windows within the Cicode Editor. A check mark in the checkbox next to the Window
or Toolbar name enables the display of that Window or Toolbar in the Cicode Editor. A
grayed-out checkbox indicates that the window is disabled (presently unable to be dis-
played). For example: Many of the debug windows which display the active state of project
Cicode variables are disabled when a Cicode project is not running, and therefore the
Cicode Editor cannot be in debug mode).
Note: Right-click in the toolbar area to view a menu of available toolbars and debug win-
dows. For a description the buttons, see The Cicode Editor.
Toolbar options
Click the button on the toolbar to display the tool bar you want; for example, click Edit to
display the Edit tool bar.
Window options
The Cicode Editor has several editing and debug windows that you can use to display in-
formation about running Cicode and CitectVBA.
The Cicode Editor windows available are:
Breakpoint window
Output window
Global Variable window
Stack window
Thread window
Compile Errors window
CitectVBA Watch window
Files window
91
Chapter: 14 Editing and Debugging Code
Breakpoint window
Displays the Breakpoint Window, which is used to list all breakpoints that are currently set
within the project. Double clicking an item in the list loads the file into the editor and jumps
to the breakpoint position. Right-clicking an item allows the enable/disable/removal of the
list item.
Output window
Displays the Output Window, which lists the output messages sent by CitectSCADA dur-
ing debugging. It states when threads start and terminate, and if a break occurs. This win-
dow will show messages sent by the TraceMsg() function.
The Output window shows entries in the order that they occur:
92
Chapter: 14 Editing and Debugging Code
to the list when it is first assigned a value. Each time the Global variable is processed, its
value will be updated in the Global Variable Window.
Note: You must be in debug mode to view global variable values in this window.
Stack window
Displays the Call Stack window, which lists the stack values of the current thread. The stack
consists of the functions called (including the arguments), any variables used in the func-
tions, and return values. This is especially useful during debugging to trace the origin of
the calling procedures.
A stack is a section of memory that is used to store temporary information. For example,
when you call a Cicode function, the variables used inside the function exist only as long
as the function runs.
To view the values of arguments and variables in a procedure, place a breakpoint within
the procedure under watch. When that breakpoint is reached, the Stack Window will dis-
play the current call stack of the procedure containing the breakpoint. The values of the
stack are updated as the values change.
Thread window
Displays the Threads History window.
93
Chapter: 14 Editing and Debugging Code
94
Chapter: 14 Editing and Debugging Code
Files window
Displays the Files window containing three tabs.
The ’All Projects’ tab displays a tree hierarchy view of all projects and their Cicode and
CitectVBA files available within Citect Explorer.
The ’Open Project’ tab displays a tree hierarchy view of the currently selected project,
and all included projects. The currently selected project will be the top entry.
The ’Open Files’ tab lists the names of all files currently open for editing in the Cicode
Editor.
Note: Clicking any of the file names displayed in the tree will open that file in the editor
and give it the focus.
95
Chapter: 14 Editing and Debugging Code
96
Chapter: 14 Editing and Debugging Code
This option is overridden by the CitectSCADA will start debugger on hardware errors op-
tion. That is, if the above option is disabled, then this option is disabled also.
Note: Foreground Cicode cannot be suspended. The break point will be marked, but you
will not be able to step through the function.
[CitectSCADA startup options] Allow remote debugging
Allows debugging of Cicode on this computer from a remote CitectSCADA computer.
[CitectSCADA startup options] Remote IP Address
The Windows Computer Name or TCP/IP address of the remote CitectSCADA computer.
The Windows Computer Name is the same as specified in the Identification tab, under the
Network section of the Windows Control Panel. You specify this name on the computer
from which you are debugging.
The TCP/IP address (for example, 10.5.6.7 or plant.yourdomain.com) can be determined as
follows:
Go to the Command Prompt, type IPCONFIG, and press Enter.
[Debugger options] Save breakpoints between sessions
Save the location and states of breakpoints between running sessions of the Cicode Editor
and Debugger. This means breakpoints inserted using the Cicode Editor can later be re-
called when an error is detected - even though the file (and application) has been closed.
[Compile options] Incremental compile
Enables the incremental compilation of the project.
See Also
Debugging Cicode
This dialog displays the currently selected programming language that the editor will use
to format the syntax of the file being edited in the code window. If you open a Cicode file
(with a .Ci extension), the current language formatter changes to Cicode. If you open a Ci-
tectVBA file (with a .bas extension), the current language formatter changes to CitectVBA.
97
Chapter: 14 Editing and Debugging Code
Similarly, if you open a file with neither a Cicode nor a CitectVBA extension, say a text file
(with a .txt extension), the editor will not know which language type you intend to use, and
will not apply any formatting to the file. You can use this dialog to select which program-
ming language the file contains, and it will format the file appropriately for display in the
code window.
Note: The Cicode Editor can be used to edit any ASCII text based file, including Microsoft
JScript. The editor recognizes JScript files (with a .jav extension) and will change the current
language formatter to JScript. CitectSCADA does not support JScript, and will not compile
it into your project. However, the editor can still be used separately to edit or create a
JScript file or any other ASCII text based file.
Current
Displays the currently selected programming language formatter for appropriate syntax
coloring of the file displayed in the code window.
Selection
Displays the range of possible programming languages that can be chosen as the current
language for formatting and display in the code window.
Debugging Cicode
To help you locate Cicode errors, you can switch the Cicode Editor to debug mode to ana-
lyze running Cicode. You can toggle debugging on and off as required, but CitectSCADA
must be running for the debugger to work.
Note: The Cicode Editor cannot debug foreground Cicode. A break in a foreground Cicode
will result in the Foreground Cicode cannot break message.
See Also
Cicode Editor Options | Function Error handling | Debug Error Trapping
Debugging functions
To debug a function:
Run the Cicode Editor.
Open the file containing the function you wish to debug.
Click the Toggle Debug button, or choose Debug | Start Debugging.
Note: If the current project is not running, CitectSCADA compiles and runs it automat-
ically. The bug in the bottom right-hand corner is green when debugging.
Insert a breakpoint where you want to start debugging.
98
Chapter: 14 Editing and Debugging Code
From the View menu, select any debug windows you want to use. If you are unsure,
you can use them all.
Initiate the thread by calling the function. You can do this directly from the Cicode win-
dow in the Kernel, or by using a function, etc.
The function will break at the specified breakpoint. You can then use the step tools to
step through and trace your function.
Click the Toggle Debug button to stop debugging, or choose Debug | Stop Debugging.
Using breakpoints
There are three ways for a processing thread to halt:
Manually inserting a breakpoint.
Using the DebugBreak() Cicode function.
If a hardware error is detected.
To debug a function, you must first be able to stop it at a particular point in the code. You
can place a breakpoint on any line in the source code functions. Breakpoints may be insert-
ed or removed while editing or debugging and do not need to be saved with the file.
For a detected hardware error to halt a function, you must have either the Break on all
hardware errors or Break on hardware errors in active thread option set (Debug menu -
Options). When the break occurs, the default Cicode Editor will be launched (if it is not
open already), with the correct code file, function, and break point line displayed. To
99
Chapter: 14 Editing and Debugging Code
launch the debugger in this case, you must have the CitectSCADA will start debugger on
hardware errors option set.
Enabling/disabling breakpoints
You can enable or disable breakpoints you have inserted into your Cicode.
To enable/disable a breakpoint:
Open the Cicode Editing Window.
Position the cursor on the line where the breakpoint is located.
Press Ctrl + F9, or choose Debug | Enable/Disable Breakpoint.
Note: A disabled breakpoint appears as a large dark gray (disabled) dot at the beginning
of the line.
100
Chapter: 15 Using Cicode Programming Standards
Implementing programming practices results in Cicode that is more robust, manageable,
and predictable in execution, regardless of the author. Using programming standards en-
tails:
Adopting modular programming techniques.
Ensuring that programs are adequately described by suitable module headers.
Formatting code to improve readability.
The following topics are presented as a suggested means of achieving good programming
standards:
Variable Declaration Standards
Variable Scope Standards
Variable Naming Standards
Standards for Constants, Variable Tags, and Labels
Formatting Simple Declarations
Formatting Executable Statements
Formatting Expressions
Cicode Comments
Formatting Functions
Modular Programming
Defensive Programming
Function Error handling
Debug Error Trapping
See Also
Using Cicode Functions
Note: Parts contained within square brackets are optional. For example, you do not have to
specify the variable scope (it defaults to local if you do not). Parts contained within greater
than ( < ) and less than ( > ) signs should be replaced with the relevant text/value. For ex-
ample, you would replace <initial value> with an actual value. (You would not bracket
your value with greater than and less than signs.)
101
Chapter: 15 Using Cicode Programming Standards
When declaring your variables, all parts of each should align vertically (the scope part of
each should be vertically aligned, the type part of each should be aligned, etc.). Each part
of the declaration is allotted a set amount of space. If one part is missing, its space should
be left blank. The missing part should not affect the positioning of the next part:
ModuleintmiRecipeMax=100;
intiRecipeMax;
stringsRecipeDefault="Tasty";
See Also
Using Cicode Programming Standards
Variable names typically consist of up to three words. Each word in a variable name
should start with a capital letter, for example:
iTrendType, rPeriod, sFileName
Module variable names should be prefixed with an "m", for example:
miTrendType, mrPeriod, msFileName
Global variable names should be prefixed with a "g", for example:
102
Chapter: 15 Using Cicode Programming Standards
See Also
Using Cicode Programming Standards
Constants
In Cicode there is no equivalent of #defines of C language, or a type that will force variables
to be constants (read-only variables). However, the variable naming convention makes
constants easily identifiable so developers will treat those variables as read-only variables.
Constants must have the prefix ‘c’.
Constants must be declared and initialized at the beginning of the Cicode file and never
assigned a value again.
For example:
INT ciTrendTypePeriodic = 1;
INT ciTrendTypeEvent = 2;
STRING csPageName = "Mimic";
Variable tags
Variable tags that have been defined in the database (with the Variable Tags form) can be
used in all functions in the Cicode files. Variable tags are identifiable because they will not
have a prefix (also, they are generally in uppercase letters).
Labels
Labels, like variable tags, can be used in all functions in the Cicode files. They can be either
all upper case letters or mixed case. In order to differentiate them from the variable tags and
other Cicode variables they should have an ‘_’ (underscore) in front of them. For example:
_BILLING_EVENT, _UNIT_OFFLINE, _AfterHoursEvent
Note: There are a few labels without an underscore defined in the Labels form in the IN-
CLUDE project. Although they do not follow the guidelines set in this document their wide
usage makes changing those labels impractical. These labels are: TRUE, FALSE,
BAD_HANDLE, XFreak, XOutsideCL, XAboveUCL, XBelowLCL, XOutsideWL, XUp-
Trend, XDownTrend, XGradualUp, XGradualDown, XErratic, XStratification, XMixture,
ROutsideCL, RAboveUCL, RBelowLCL
103
Chapter: 15 Using Cicode Programming Standards
See Also
Using Cicode Programming Standards
See Also
Using Cicode Commands
Using Cicode Programming Standards
104
Chapter: 15 Using Cicode Programming Standards
IF statements can be used in one of the formats below. When indenting the IF state-
ments, a tab stop should be used. For example:
Simple IF block
IF <expression> THEN
...
END
IF-THEN-ELSE block
IF <expression> THEN
...
ELSE
...
END
For WHILE and FOR statements see Working with Conditional Executors.
See Also
Using Cicode Commands
Working with Conditional Executors
Using Cicode Programming Standards
Formatting Expressions
The following conventions should be observed when formatting Cicode functions:
When an expression forms a complete statement, it should, like any other statement, oc-
cupy one or more lines of its own and be indented to the current level. Operators should
be surrounded by spaces. For example:
i= i*10+c-’0’; // WRONG
i = i * 10 + c - ’0’; // RIGHT
105
Chapter: 15 Using Cicode Programming Standards
a = b * ( c - d ); // WRONG
a = b * (c - d); // RIGHT
The round brackets which surround the arguments of a function all attract no spaces,
for example:
DisplayText( "hello" ); // WRONG
DisplayText("hello"); // RIGHT
Commas, whether used as operators or separators, would be placed hard against the
previous symbol and followed by a space. For example:
DevSeek(hDev ,Offset); // WRONG
DevSeek(hDev, Offset); // RIGHT
See Also
Using Cicode Expressions
Using Cicode Commands
Using Cicode Programming Standards
Cicode Comments
Comments are designed to to aid understanding and maintenance of code. You should
place comments in the notes of the function header so as not to clutter up the code. Small
one-line comments are acceptable to explain some small part of the code which may be
hard to understand in the normal header comment.
See Also
Using Cicode Programming Standards
Formatting Functions
Cicode functions have up to seven parts: Scope, Type, Keyword, Name, Argument(s),
Statement(s), Keyword.
[Scope]
The scope of the function. If you do not specify a scope, the function will be Public by de-
fault. That is, it will be available to all Cicode files, pages, and CitectSCADA databases (for
example, Alarm.dbf). To make a function Private (that is only available within the file in
which it is declared), you must prefix it with the word PRIVATE.
[Type]
The return type of the function. This should be on a separate line.
Keyword
The keyword FUNCTION. This should be on a separate line.
Name
The function name. Function names should follow the Function Naming Standards. This
should be on a separate line.
106
Chapter: 15 Using Cicode Programming Standards
Argument(s)
The argument list. The arguments are separated by commas and they can have default val-
ues. The argument list is normally on the same line as the function name but multiple line
argument list is also acceptable if it improves readability.
Statement(s)
The statements. Each statement should be on a separate line.
Keyword
The keyword END which marks the end of the function. This should be on a separate line.
Note: Parts contained within square brackets - [ ] - are optional. For example, you do not
have to specify the function scope (it will default to Public if you do not). Parts contained
within greater than & less than signs - < > - should be replaced with the relevant text/value.
For example, you would replace <initial value> with an actual value. You would not brack-
et your value with greater than & less than signs.
For example:
FUNCTION
PlotInit()
<statements>
END
INT
FUNCTION
PlotOpen(STRING sName, INT nMode)
INThPlot = _BAD_HANDLE;
...
hPlot = .....;
...
RETURN hPlot;
END
PRIVATE
STRING
FUNCTION
WasteInfoName(INT nType, INT nMode)
STRINGsName = "Sydney";
...
sName = .....;
...
RETURN sName;
END
See Also
Writing Functions
Using Cicode Functions
Using Cicode Programming Standards
107
Chapter: 15 Using Cicode Programming Standards
See Also
Naming Functions
Note: Declare all module variables at the MODULE VARIABLES section at the beginning
of the file and initialize the module variables.
For example:
//** FILE: Recipe.CI
//**
//** DESCRIPTION: Contains all functions for gathering recipe data.
//**
//** FUNCTIONS: PUBLIC
//** OpenRecipeDatabase
//** CloseRecipeDatabase
//** ReadRecipeData
//** WriteRecipeData
//** GatherRecipeData
//** RecipeForm
//** OpenRecipeDatabase
//**
//** PRIVATE
//** ButtonCallback
//**
//*************** MODULE CONSTANTS***********************
module int cmiRecipeMax =100; //Maximum number of recipes
//**************** MODULE VARIABLES ***********************
module int miRecipeNumber =0; //Minimum number of recipes
//*********************************************************
108
Chapter: 15 Using Cicode Programming Standards
Function headers
Functions should have a descriptive header, formatted as follows:
//** FUNCTION : <name of function>
//**
//** DESCRIPTION : <suggests the operation, application source and
//** multi-tasking issues>
//** REVISION DATE BY COMMENTS
//** <revision number> <date> <author> <comments about the change>
//**
//** ARGUMENTS: <argument description>
//**
//** RETURNED VALUE: < description of possible return values>
//**
//** NOTES:
Modular Programming
One of the more effective programming practices involves partitioning large, complex pro-
gramming challenges into smaller and more manageable sub-tasks and reusable functions.
A similar approach should be taken when using a programming language like Cicode to
109
Chapter: 15 Using Cicode Programming Standards
complete a task. Reducing the task to smaller tasks (or functions) has the following advan-
tages:
Reduced Complexity - Once the function is created and tested, the detailed operation
about how it works need not be revisited. Users need only focus on the results produced
by the function.
Avoids Duplicate Code - Creating a generic function instead of copying similar code
reduces the total amount of code in the system. It also means the function can be reused
by separate code areas. This makes the code more maintainable because it is smaller in
size, and only one instance needs to be modified.
Hides Information - Information can be in the form of operations, data, or resources.
Access to information can be controlled when functions are written that provide a lim-
ited set of actions to be performed on the information. For example, if a user wishes to
log a message to a database, he or she should only send the message to a function, say
LogDBaseMessage("hello world"), and the function should control the database re-
source. The function then becomes the single interface to the database resource. Re-
sources that have multiple interfaces to them are harder to control. This is because in a
multitasking environment, the user cannot control or even know in advance the order
of code execution, and hence a resource may be modified at the same time by different
tasks. Information hiding can also smooth out any wrinkles in standard functions, min-
imizing possible misuse of resources such as semaphores, queues, devices, and files.
Functions that do this are often called ‘wrapper’ functions as they add a protective shell
to existing functions.
Improves Performance - Optimizing code that resides in one place immediately in-
creases the performance of code that calls this function. Scattered code will require all
areas to be modified should any optimization be necessary.
Isolates Complex Code - Code that requires complex operations such communications
protocols, complex algorithms, boolean logic, or complex data manipulation is suscep-
tible to errors. Placing this code in a separate function reduces the possibility of this code
corrupting or halting other code.
Improves Readability - A small function with meaningful parameter names assists
readability as it is a step towards self-documenting code and reduces the need to scan
multiple pages of code to establish what the operation is meant to achieve.
Modular programming has a few rules that define how functions should be structured -
Cohesion - and how they are related to other functions - Coupling.
See Also
Defensive Programming
Using Cicode Programming Standards
Cohesion
A goal of modular programming is to create simple functions that perform a single task,
but perform that task well. This can be described as how ’cohesive’ a function is.
Two factors that affect the level of cohesion are:
Number of tasks the function performs.
Similarity of the tasks.
110
Chapter: 15 Using Cicode Programming Standards
For example, the function Sin(x) will perform one task - return the trigonometric Sine value
of x. This is an example of a highly cohesive function. The function SinAndTan(x) performs
two tasks - calculate the trigonometric Sine and Tan of the value X. This function has lower
cohesion than Sin(x) because it performs two tasks.
Highly cohesive functions are more dependable, easier to modify, and easier to debug than
functions that have lower levels of cohesion and are hence acceptable and encouraged.
Low cohesion functions are typically complex, prone to errors, and are more costly to fix.
Low cohesion functions are regarded as poor programming practice and discouraged.
Coupling
Another rule of modular programming is to reduce the number of relationships between
functions. This is referred to as function coupling. Functions that have few, or no, relation-
ships between them are loosely coupled. Loosely coupled functions provide simple, visible
interfaces to the function. This makes the functions easier to use and modify. For example,
the Cicode function TimeCurrent() is a loosely coupled function. To use this function, a
user need only call its name, and the function will return with the desired result. The user
does not need to be aware of any relationships because there are no parameters passed to
the function, and it does not read from, or write to, any global data. There is very little like-
lihood of error with this function; it only returns a time/date variable and does not support
error codes. In the unlikely event that the function did not return the time/date variable, it
would be through no error of the calling function because it has no relationship to it.
Functions that have many relationships between them are tightly coupled. For example, a
user written function like AddCustomerRecord(hDatabase, sFirstName, sSurname, sAd-
dress, sAge, sPhone) has a higher level of coupling than the function TimeCurrent(). Tight-
ly coupled functions are inflexible in their use, less robust, and harder to maintain. The
AddCustomerRecord() function is less robust because it could experience an error of its
own accord, or if the function calling it passes bad data to it. Tightly coupled functions are
harder to maintain because modifying a function with many relationships in it may result
in modifications to other functions to accept the data.
The different types of function relationships are listed below:
Passed parameters. A simple, visible form of loose coupling that is encouraged. Once
the number of parameters passed to a function exceeds seven, you should consider par-
titioning the function into two smaller functions. These types of relationships are ac-
ceptable.
Control information. Control information causes the called function to behave in a dif-
ferent way. For example, the function ChangeData(iMode), behaves differently de-
pending on the value of the variable iMode that is passed into it. It may be responsible
for deleting, inserting, or updating data. In addition to being a tightly coupled function,
111
Chapter: 15 Using Cicode Programming Standards
it has low cohesion because it performs multiple tasks. This function could be broken
up into three separate functions to perform the separate tasks. These types of relation-
ships are moderately acceptable.
Shared common data. This is often referred to as global variable data. This is an invisi-
ble form of tight coupling that, particularly in pre-emptive, multi-tasking environ-
ments, can result in an unpredictable, hard-to-maintain program. When functions write
to the global variable data there is no monitoring of or restriction on who is writing to
the variable. Hence the value can be indeterminate. Global variables are acceptable
when they are used for read-only purposes, otherwise their use is discouraged. Similar-
ly, module variable data in CitectSCADA should be treated the same way. The use of
local function variables is encouraged to decrease function coupling.
Defensive Programming
Defensive programming is an approach to improve software and source code. It aims to
improve general quality by reducing the number of software bugs and problems. It pro-
motes making the source code readable and understandable. It aims to make your code be-
have in a predictable manner despite unexpected input or user actions.
You should try to:
Verify that your code does not produce unexplained hardware alarms.
Check that denominators in division are not zero.
Check that array indexes cannot go out of range.
Check that arguments from external sources are valid.
Check that loop terminations are obvious and achievable.
Do not write the same code twice. If you find that two sections of code look identical or
almost identical it is worth spending the time to re-write or re-design it. This will gen-
erally reduce the size of the code in question by a third or more, which reduces complex-
ity and therefore maintenance and debugging time. The most effective method to
achieve this is to convert the identical code to a new function.
Do not access the module data in any function other than the member functions.
Write the member functions whenever an array is defined. Do not try to pass arrays be-
tween functions, make the arrays the centre piece of the object.
Cicode is a multitasking language. Several tasks (commands, expressions and tasks cre-
ated by TaskNew function) can be executed concurrently. This powerful feature of
Cicode should be used with care as some of the functions may be modifying module da-
ta. It is important that the number of tasks running at any point in time be minimized.
This may require the use of semaphores to protect the module data from interference
and corruption. (For the use of semaphores, refer to SemOpen, SemClose, SemSignal
and SemWait functions in on-line help or the Cicode Reference manual).
See Also
Using Cicode Programming Standards
Modular Programming
Function Error handling
112
Chapter: 15 Using Cicode Programming Standards
If an error is detected in one of these functions, your Cicode task will generate a hardware
error and be halted. You may stop your Cicode task from being halted by using the ErrSet()
function and checking for errors using IsError().
The parameter [Code]HaltOnError allows you to stop any errors detected in these functions
from halting your Cicode. If you set. . .
[code]
HaltOnError=0
then your Cicode will continue to run after a hardware error is detected in these functions.
For example:
Example of error code only
INT
FUNCTION
ExampleInit()
INTnError = 0;
nError = ExampleOpen("MyForm");
IF nError = 0 THEN
...
END
END
INT
FUNCTION
ExampleOpen(STRING sName)
INTnError = 0;
...
IF <an error has been detected> THEN
nError = 299;
END
RETURN nError;
END
Example of handles
INT
FUNCTION
ExampleInit()
113
Chapter: 15 Using Cicode Programming Standards
INThFile= BAD_HANDLE;
...
hFile = ExampleFileOpen("MyFile.txt");
IF hFile <> BAD_HANDLE THEN
...
END
END
FUNCTION
ExampleFileOpen(STRING sName)
INThFile = BAD_HANDLE;
hFile = FileOpen(sName, "r+");
IF hFile = BAD_HANDLE THEN
hFile = FileOpen(sName, "r");
END
RETURN hFile;
END
See Also
Debugging Cicode
114
Chapter: 15 Using Cicode Programming Standards
DebugMsg function
DebugMsg() internally calls the TraceMsg() function if the debug switch is on. The imple-
mentation of this function can be found in DEBUG.CI in the INCLUDE project. You can
turn the debug switch on or off by doing any of the following:
Calling DebugMsgSet(INT bDebugMsg) on the Kernel Cicode window. (Or, this function
can be called from a keyboard command or something similar.)
Changing the [Code]DebugMessage parameter in the INI file.
For example:
INT
FUNCTION
FilePrint(STRING sDeviceName, STRING sFileName)
INT hFile;
INT hDev;
STRING Str1;
Assert function
Assert reports an error if the test passed by the argument does not return the expected val-
ue. The implementation of this function can be found in DEBUG.CI in the INCLUDE
project.
For example:
INT
FUNCTION
FileDisplayEx(STRING sFileName)
INThFile;
115
Chapter: 15 Using Cicode Programming Standards
See Also
Debugging Cicode
116
Part: 3
Functions Reference
Cicode includes the following function categories:
Accumulator Functions I/O Device Functions
ActiveX Functions Keyboard Functions
Alarm Functions Mail Functions
Clipboard Functions Math/Trigonometry Functions
Cluster Functions Miscellaneous Functions
Color Functions Page Functions
Communication Functions Plot Functions
DDE Functions Report Functions
Device Functions Security Functions
Display Functions SPC Functions
DLL Functions SQL Functions
Error Functions String Functions
Event Functions Super Genie Functions
File Functions Table (Array) Functions
Form Functions Tag Functions
Format Functions Task Functions
FTP Functions Time/Date Functions
FuzzyTech Functions Trend Functions
Group Functions Window Functions
118
Chapter: 16 Accumulator Functions
Accumulator functions enable you to programmatically browse and control Accumulators
and retrieve information from them.
Accumulator Functions
Following are functions relating to accumulators.
AccControl Controls accumulators for example, motor run
hours.
AccumBrowseClose Closes an accumulator browse session.
AccumBrowseFirst Gets the oldest accumulator entry.
AccumBrowseGetField Gets the field indicated by the cursor position in the
browse session.
AccumBrowseNext Gets the next accumulator entry in the browse ses-
sion.
AccumBrowseNumRecords Returns the number of records in the current browse
session.
AccumBrowseOpen Opens an accumulator browse session.
AccumBrowsePrev Gets the previous accumulator entry in the browse
session.
See Also
Functions Reference
AccControl
Controls accumulators, for example, motor run hours. You can reset the values of Run
Time, Totalizer Inc, and No. of Starts (defined in the Accumulator database), re-read these
values from the I/O device, or flush pending writes of these values to the I/O device.
Syntax
AccControl(sName, nMode [, ClusterName] )
sName:
The name of the accumulator or a mask for the names of accumulators. You can
use the following wildcards:
* matches all following characters, for example, "Motor*" matches all accumu-
lators starting with the word "Motor"
? matches any single character, for example, "Motor?10" matches "MotorA10"
and "MotorB10"
This argument can be prefixed by the name of the cluster for example Cluster-
Name.AccumulatorName.
nMode:
The mode of the control:
1 - Reset Run Time and Totalizer value
2 - Reset No. of Starts
119
Chapter: 16 Accumulator Functions
Return Value
0 (zero) if successful, otherwise an error is returned.
Example
! Reset all accumulator variables for accumulator "MCC123".
AccControl("MCC123", 3, "ClusterXYZ");
See Also
Accumulator Functions
AccumBrowseClose
The AccumBrowseClose function terminates an active data browse session and cleans up
all resources associated with the session.
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AccumBrowseClose(iSession)
iSession:
The handle to a browse session previously returned by a AccumBrowseOpen call.
Return Value
0 (zero) if the accumulator browse session exists, otherwise an error is returned.
Related Functions
AccumBrowseFirst, AccumBrowseGetField, AccumBrowseNext, AccumBrowseNum-
Records, AccumBrowseOpen, AccumBrowsePrev
See Also
Accumulator Functions
AccumBrowseFirst
The AccumBrowseFirst function places the data browse cursor at the first record.
This function is a blocking function. It blocks the calling Cicode task until the operation is
complete.
120
Chapter: 16 Accumulator Functions
Syntax
AccumBrowseFirst(iSession)
iSession:
The handle to a browse session previously returned by a AccumBrowseOpen call.
Return Value
0 (zero) if the accumulator browse session exists, otherwise an error is returned.
Related Functions
AccumBrowseClose, AccumBrowseGetField, AccumBrowseNext, AccumBrowseNum-
Records, AccumBrowseOpen, AccumBrowsePrev
See Also
Accumulator Functions
AccumBrowseGetField
The AccumBrowseGetField function retrieves the value of the specified field from the
record the data browse cursor is currently referencing.
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AccumBrowseGetField(iSession, sFieldName)
iSession:
The handle to a browse session previously returned by a AccumBrowseOpen call.
sFieldName:
The name of the field that references the value to be returned. Supported fields
are:
COMMENT, TAGGENLINK.
See Browse Function Field Reference for information about fields.
Return Value
The value of the specified field as a string. An empty string may or may not be an indication
that an error has been detected. The last error should be checked in this instance to deter-
mine if an error has actually occurred.
Related Functions
AccumBrowseClose, AccumBrowseFirst, AccumBrowseNext, AccumBrowseNum-
Records, AccumBrowseOpen, AccumBrowsePrev
Example
STRING fieldValue = "";
STRING fieldName = "TYPE";
INT errorCode = 0;
...
fieldValue = AccumBrowseGetField(iSession, sFieldName);
IF fieldValue <> "" THEN
// Successful case
121
Chapter: 16 Accumulator Functions
ELSE
// Function returned an error
END
...
See Also
Accumulator Functions
AccumBrowseNext
The AccumBrowseNext function moves the data browse cursor forward one record. If you
call this function after you have reached the end of the records, error 412 is returned
(Databrowse session EOF).
This function is a blocking function. It blocks the calling Cicode task until the operation is
complete.
Syntax
AccumBrowseNext(iSession)
iSession
The handle to a browse session previously returned by a AccumBrowseOpen call.
Return Value
0 (zero) if the accumulator browse session exists, otherwise an error is returned.
Related Functions
AccumBrowseClose, AccumBrowseFirst, AccumBrowseGetField, AccumBrowseNum-
Records, AccumBrowseOpen, AccumBrowsePrev
See Also
Accumulator Functions
AccumBrowseNumRecords
The AccumBrowseNumRecords function returns the number of records that match the fil-
ter criteria.
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AccumBrowseNumRecords(iSession)
iSession:
The handle to a browse session previously returned by a AccumBrowseOpen call.
Return Value
The number of records that have matched the filter criteria. A value of 0 denotes that no
records have matched. A value of -1 denotes that the browse session is unable to provide a
fixed number. This may be the case if the data being browsed changed during the browse
session.
122
Chapter: 16 Accumulator Functions
Related Functions
AccumBrowseClose, AccumBrowseFirst, AccumBrowseGetField, AccumBrowseNext, Ac-
cumBrowseOpen, AccumBrowsePrev
Example
INT numRecords = 0;
...
numRecords = AccumBrowseNumRecords(iSession);
IF numRecords <> 0 THEN
// Have records
ELSE
// No records
END
...
See Also
Accumulator Functions
AccumBrowseOpen
The AccumBrowseOpen function initiates a new browse session and returns a handle to
the new session that can be used in subsequent data browse function calls.
This function is a blocking function. It blocks the calling Cicode task until the operation is
complete.
Syntax
AccumBrowseOpen( [sFilter] [, sFields] [, sClusters] )
sFilter:
A filter expression specifying the records to return during the browse. An empty
string indicates that all records will be returned. Where a fieldname is not speci-
fied in the filter, it is assumed to be tagname. For example, the filter "AAA" is
equivalent to "name=AAA".
Note: Use the following fields with care in filters since they return the actual val-
ue of the variable tag which they refer to.
RUNNING, STARTS, TOTALISER, TRIGGER, VALUE.
sFields:
Specifies via a comma delimited string the columns to be returned during the
browse. An empty string indicates that the server will return all available col-
umns. Supported fields are:
COMMENT, TAGGENLINK.
See Browse Function Field Reference for information about fields.
sClusters:
An optional parameter that specifies via a comma delimited string the subset of
the clusters to browse. An empty string indicates that all connected clusters will
be browsed.
Return Value
Returns an integer handle to the browse session. Returns -1 when an error is detected.
123
Chapter: 16 Accumulator Functions
Related Functions
AccumBrowseClose, AccumBrowseFirst, AccumBrowseGetField, AccumBrowseNext, Ac-
cumBrowseNumRecords, AccumBrowsePrev
Example
INT iSession;
...
iSession = AccumBrowseOpen("NAME=ABC*", "NAME,AREA",
"ClusterA,ClusterB");
IF iSession <> -1 THEN
// Successful case
ELSE
// Function returned an error
END
...
See Also
Accumulator Functions
AccumBrowsePrev
The AccumBrowsePrev function moves the data browse cursor back one record. If you call
this function after you have reached the beginning of the records, error 412 is
returned (Databrowse session EOF).
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AccumBrowsePrev(iSession)
iSession:
The handle to a browse session previously returned by a AccumBrowseOpen call.
Return Value
0 (zero) if the accumulator browse session exists, otherwise an error is returned.
Related Functions
AccumBrowseClose, AccumBrowseFirst, AccumBrowseGetField, AccumBrowseNext, Ac-
cumBrowseNumRecords, AccumBrowseOpen
See Also
Accumulator Functions
124
Chapter: 17 ActiveX Functions
ActiveX functions enable you to create and interact with ActiveX objects, using CitectSCA-
DA as an ActiveX container.
ActiveX Functions
Following are functions relating to ActiveX objects:
_ObjectCallMethod Calls a specific method for an ActiveX object.
_ObjectGetProperty Retrieves a specific property of an ActiveX ob-
ject.
_ObjectSetProperty Sets a specific property of an ActiveX object.
AnByName Retrieves the animation point number of an
ActiveX object.
CreateControlObject Creates a new instance of an ActiveX object.
CreateObject Creates the automation component of an Ac-
tiveX object.
ObjectAssociateEvents Allows you to change the ActiveX object’s
event class.
ObjectAssociatePropertyWithTag Establishes an association between a variable
tag and an ActiveX object property.
ObjectByName Retrieves an ActiveX object.
ObjectHasInterface Queries the ActiveX component to determine if
its specific interface is supported.
ObjectIsValid Determines if the given handle for an object is
valid.
ObjectToStr Converts an object handle to a string.
See Also
Functions Reference
_ObjectCallMethod
Calls a specific method for an ActiveX object. (See the documentation for your ActiveX ob-
ject for details on methods and properties.)
Note: The parameter list passed to the control can only have Cicode variables or variable
tags; it cannot use values returned directly from a function because an ActiveX control may
modify parameters passed to it.
For example:
//Calculate a value and pass to ActiveX control
_ObjectCallMethod(hControl, "DoSomething" CalcValue());
is not allowed because the return value of a function cannot be modified. The following
should be used instead:
125
Chapter: 17 ActiveX Functions
INT nMyValue;
//Calculate Value
nMyValue = CalcValue();
//Pass Value to ActiveX control
_ObjectCallMethod(hControl, "DoSomething" nMyValue);
Syntax
_ObjectCallMethod(hObject, sMethod, vParameters)
hObject:
The handle for the object (as returned by the ObjectByName() function).
sMethod:
The name of the method.
vParameters:
A variable length parameter list of method arguments. The variables will be
passed however you enter them, and will then be coerced into appropriate auto-
mation types. Likewise, any values modified by the automation call will be writ-
ten back - with appropriate coercion - into the passed Cicode variable.
Return Value
The return value from the method - if successful, otherwise an error is returned.
Related Functions
ObjectByName, DspAnCreateControlObject, CreateObject, CreateControlObject
Example
See CreateControlObject.
See Also
ActiveX Functions
_ObjectGetProperty
Gets a specific property of an ActiveX object.
Syntax
_ObjectGetProperty(hObject, sProperty)
hObject:
The handle for the object (as returned by the ObjectByName() function).
sProperty:
The name of the property you want to get.
Return Value
The value of the property - if successful, otherwise an error is returned.
Related Functions
ObjectByName, DspAnCreateControlObject, CreateObject, CreateControlObject
126
Chapter: 17 ActiveX Functions
Example
See CreateControlObject
See Also
ActiveX Functions
_ObjectSetProperty
Sets a specific property of an ActiveX object.
Syntax
_ObjectSetProperty(hObject, sProperty, vValue)
hObject:
The handle for the object (as returned by the ObjectByName() function).
sProperty:
The name of the property you want to set.
vValue:
The value to which the property will be set. This value can be of any data type.
Appropriate coercion will take place when creating the equivalent automation
parameter.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
ObjectByName, DspAnCreateControlObject, CreateObject, CreateControlObject
Example
See CreateControlObject
See Also
ActiveX Functions
AnByName
Retrieves the animation point number of an ActiveX object.
Syntax
AnByName(sName)
sName:
The name for the object in the form of "AN" followed by its AN number, for ex-
ample, "AN35". This name is used to access the object.
Return Value
The animation point number of the object - if successful, otherwise an error is returned.
127
Chapter: 17 ActiveX Functions
Related Functions
CreateControlObject
See Also
ActiveX Functions
CreateControlObject
Creates a new instance of an ActiveX object.
An object created using this function remains in existence until the page is closed or the as-
sociated Cicode Object is deleted. This function does not require an existing animation
point. When the object is created, an animation point is created internally. This animation
point is freed when the object is destroyed.
Syntax
CreateControlObject(sClass, sName, x1, y1, x2, y2, sEventClass)
sClass:
The class of the object. You can use the object’s human readable name, its pro-
gram ID, or its GUID. If the class does not exist, the function will return an error
message.
For example:
"Calendar Control 8.0" - human readable name
"MSCAL.Calendar.7" - Program ID
"{8E27C92B-1264-101C-8A2F-040224009C02}" - GUID
sName:
The name for the object in the form of "AN" followed by its AN number, for ex-
ample, "AN35". This name is used to access the object.
x1:
The x coordinate of the object’s top left hand corner as it will appear in your Cit-
ectSCADA window.
y1:
The y coordinate of the object’s top left hand corner as it will appear in your Cit-
ectSCADA window.
x2:
The x coordinate of the object’s bottom right hand corner as it will appear in your
CitectSCADA window.
y2:
The y coordinate of the object’s bottom right hand corner as it will appear in your
CitectSCADA window.
sEventClass:
The string you would like to use as the event class for the object.
Return Value
The newly created object, if successful, otherwise an error is generated.
128
Chapter: 17 ActiveX Functions
Related Functions
DspAnCreateControlObject, CreateObject, AnByName
Example
// This function creates a single instance of the calendar control
at the designated location with an object name of "CalendarEvent"
and an event class of "CalendarEvent"//
FUNCTION
CreateCalendar()
OBJECT Calendar;
STRING sCalendarClass;
STRING sEventClass;
STRING sObjectName;
sCalendarClass = "MSCal.Calendar.7";
sEventClass = "CalendarEvent";
sObjectName = "MyCalendar";
Calendar = CreateControlObject(sCalendarClass, sObjectName, 16,
100, 300, 340, sEventClass);
END
// This function shows how to change the title font of the
calendar//
FUNCTION
CalendarSetFont(STRING sFont)
OBJECT Font;
OBJECT Calendar;
Calendar = ObjectByName("MyCalendar");
Font = _ObjectGetProperty(Calendar, "TitleFont");
_ObjectSetProperty(Font, "Name", sFont);
END
// This function shows how to change the background color of the
calendar//
FUNCTION
CalendarSetColour(INT nRed, INT nGreen, INT nBlue)
OBJECT Calendar;
Calendar = ObjectByName("MyCalendar");
_ObjectSetProperty(Calendar, "BackColor",
PackedRGB(nRed,nGreen,nBlue));
END
// This function shows how to call the NextDay method of the
calendar//
FUNCTION
CalendarNextDay()
OBJECTCalendar;
Calendar = ObjectByName("MyCalendar");
_ObjectCallMethod(Calendar, "NextDay");
END
// This function shows you how to write a mouse click event
handler for the calendar//
FUNCTION
CalendarEvent_Click(OBJECT This)
INT nDay;
INT nMonth;
INT nYear;
nDay = _ObjectGetProperty(This, "Day");
nMonth = _ObjectGetProperty(This, "Month");
nYear = _ObjectGetProperty(This, "Year");
...
Your code goes here...
...
129
Chapter: 17 ActiveX Functions
END
See Also
ActiveX Functions
CreateObject
Creates a new instance of an ActiveX object. If you use this function to create an ActiveX
object, it will have no visual component (only the automation component will be created).
If you assign an object created with the CreateObject() function to a local variable, that ob-
ject will remain in existence until the variable it is assigned to goes out of scope. This means
that such an object will only be released when the Cicode function that created it ends.
If you assign an object created with the CreateObject() function to a module or global scope
variable, then that object will remain in existence until the variable either has another object
assigned or is set to NullObject, provided the CreateObject() call is not made within a loop.
Objects created by calls to CreateObject() within WHILE or FOR loops are only released on
termination of the Cicode function in which they are created, regardless of the scope of the
variable to which the object is assigned. The use of CreateObject() within a loop may there-
fore result in the exhaustion of system resources, and is not generally recommended unless
performed as shown in the examples below.
Syntax
CreateObject(sClass)
sClass:
The class of the object. You can use the object’s human readable name, its pro-
gram ID, or its GUID. If the class does not exist, the function will return an error.
For example:
"Calendar Control 8.0" - human readable name
"MSCAL.Calendar.7" - Program ID
"{8E27C92B-1264-101C-8A2F-040224009C02}" - GUID
Return Value
The newly created object, if successful, otherwise an error is generated.
Related Functions
DspAnCreateControlObject, CreateControlObject
Example
The following examples show correct techniques for calling CreateObject() within a loop.
/* In the example below, the variable objTest is local. Resources
associated with calls to ProcessObject() will be released each
time that function ends. */
FUNCTION Forever()
WHILE 1 DO
ProcessObject();
Sleep(1);
END
130
Chapter: 17 ActiveX Functions
END
FUNCTION ProcessObject()
.OBJECT objTest;
objTest=CreateObject("MyObject");
- do something
END
/* In the example below, the variable objTest is global. Resources
associated with calls to ProcessObject() will be released when
objTest is set to NullObject. */
FUNCTION Forever()
WHILE 1 DO
ProcessObject();
Sleep(1);
END
END
FUNCTION ProcessObject()
objTest=CreateObject("MyObject");
- do something
objTest=NullObject;
END
See Also
ActiveX Functions
ObjectAssociateEvents
Allows you to change the ActiveX object’s event class. If you have inserted an object on a
graphics page using Graphics Builder, it allows you to change the event class to something
other than the default of PageName_ObjectName
Syntax
ObjectAssociateEvents(sEventClass, hSource)
sClass:
The class of the object. You can use the object’s human readable name, its pro-
gram ID, or its GUID. If the class does not exist, the function will report an error.
hSource:
The source object firing the events which are to be handled by the event handler.
For example:
"Calendar Control 8.0" - human readable name
"MSCAL.Calendar.7" - Program ID
"{8E27C92B-1264-101C-8A2F-040224009C02}" - GUID
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspAnCreateControlObject, CreateControlObject
Example
Inserting ActiveX objects using Cicode
131
Chapter: 17 ActiveX Functions
If you have created an ActiveX object using Cicode (for example, by calling the function
CreateControlObject()), the parameter ’sEventClass’ would have required you to define
an event class for the object to enable event handling. If you want to change the class you
used, you can call ObjectAssociateEvents().
Inserting ActiveX objects via Graphics Builder
If you have inserted an ActiveX object in Graphics Builder, runtime will automatically cre-
ate an event class for the object in the form PageName_ObjectName. If this is the case, you
may want to change the object’s event class.
Using the example of an ActiveX sludge tank controller, the default event class for the ob-
ject could be "PageName_AN35". This means any events handlers for the object would take
the form "PageName_AN35_Click" (presuming this example relates to a click event). You
may want to define this more clearly, in which case you can call the following:
// This function redefines the event class for the ActiveX sludge
tank controller at AN35 to "SludgeTank". //
ObjectAssociateEvents ("SludgeTank", ObjectByName(AN35));
..
With the event class for the object now defined as "SludgeTank", the event handlers can
take the form "SludgeTank_Click".
This would be useful if you define event handlers in relation to an object that will eventu-
ally be copied to other graphics pages, as it will reduce the need to redefine the event han-
dlers to identify the default event class associated with each new placement of the object.
See Also
ActiveX Functions
ObjectAssociatePropertyWithTag
Establishes an association between an ActiveX property and a variable tag. This means that
any changes made to an ActiveX object property will be mirrored in the variable tag.
Generally, ActiveX objects issue "property change notifications" to CitectSCADA whenev-
er a change occurs to a specific property value. This notification tells CitectSCADA when
to read the property value.
Note: An association will not succeed if property change notifications are not supported
and the OnChangeEvent argument is left blank. Verify that the scaling and units of the as-
sociated tag are compatible with the ActiveX property values. However, some property
changes do not trigger property change notifications. If this is the case, you need to choose
an appropriate "on change" event instead - an event fired by the ActiveX object in response
to a change. An "appropriate" event is one that happens to be fired whenever the property
value changes. For example, the MS Calendar Control fires an AfterUpdate event whenev-
er a day button is pressed.
Syntax
ObjectAssociatePropertyWithTag(sObject, sPropertyName, sTagName [, sOnChangeEvent] )
sObject:
The object instance that associates a property with a tag.
132
Chapter: 17 ActiveX Functions
sPropertyName:
The name of the ActiveX property to associate with the tag.
sTagName:
The name of the CitectSCADA variable tag to associate with the property.
sOnChangeEvent:
The name of the "on change" event that informs CitectSCADA of a change to the
ActiveX object. This is required where the ActiveX object does not automatically
generate a property change notification. Choose an event that happens to be fired
whenever the ActiveX object property changes, for example, the MS Calendar
Control fires an AfterUpdate event whenever a day button is pressed.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspAnCreateControlObject, CreateObject, CreateControlObject
See Also
ActiveX Functions
ObjectByName
Retrieves an ActiveX object. This is useful when you know the object by name only (this
will often be the case for objects created during configuration, rather than those created at
runtime using a Cicode function).
Syntax
ObjectByName(sName)
sName:
The name for the object in the form of "AN" followed by its AN number, for ex-
ample, "AN35". This name is used to access the object.
Return Value
The requested object, if successful, otherwise an error is generated.
Related Functions
DspAnCreateControlObject, CreateObject, CreateControlObject
Example
See CreateControlObject
See Also
ActiveX Functions
ObjectHasInterface
Queries the ActiveX component to determine if its specific interface is supported. (Refer to
the ActiveX object’s documentation for details of its interfaces.)
133
Chapter: 17 ActiveX Functions
Syntax
ObjectHasInterface(hObject, sInterface)
hObject:
The handle for the object (as returned by the ObjectByName() function).
sInterface:
The name of the interface (case sensitive).
Return Value
0 if the interface is not supported, otherwise 1.
Related Functions
ObjectByName, CreateObject, CreateControlObject
Example
hPen = _ObjectGetProperty(hControl, "Pen");
IF ObjectHasInterface(hPen, "IDigitalPen") THEN
//Fill is only supported on digital pen
_ObjectSetProperty(hPen, "Fill", 0)
END
See Also
ActiveX Functions
ObjectIsValid
Determines if the given handle for an object is a valid handle. This function is useful for
programmatically checking that an object was returned for a call.
Syntax
ObjectIsValid(hObject)
hObject:
The handle for the object (as returned by the ObjectByName() function).
Return Value
0 if the handle is not valid, otherwise 1.
Related Functions
ObjectByName, CreateObject, CreateControlObject
Example
hFont = _ObjectGetProperty(hControl, "Font");
IF ObjectIsValid(hFont) THEN
_ObjectSetProperty(hFont, "Size", 22)
END
134
Chapter: 17 ActiveX Functions
See Also
ActiveX Functions
ObjectToStr
Converts an object handle to a string.
Syntax
ObjectToStr(hObject)
hObject:
The handle for the object (as returned by the ObjectByName() function).
Return Value
A string containing the converted object handle
Related Functions
ObjectByName, CreateObject, CreateControlObject
See Also
ActiveX Functions
135
Chapter: 17 ActiveX Functions
136
Chapter: 18 Alarm Functions
Alarm functions display alarms and their related alarm help pages, and acknowledge, dis-
able, and enable alarms. They provide information about alarms and allow your operators
to add comments to alarm records. You can also access alarms at the record level (on the
alarms server) for more complex operations.
Alarm Functions
Following are functions relating to alarms:
AlarmAck Acknowledges alarms.
AlarmAckRec Acknowledges alarms by record number.
AlarmActive Determines if any alarms are active in the user’s area.
AlarmClear Clears acknowledged, inactive alarms from the active
alarm list.
AlarmClearRec Clear an alarm by its record number.
AlarmComment Allows users to add comments to alarm summary en-
tries.
AlarmDelete Deletes alarm summary entries.
AlarmDisable Disables alarms.
AlarmDisableRec Disables alarms by record number.
AlarmDsp Displays alarms.
AlarmDspLast Displays the most recent, unacknowledged alarms.
AlarmDspNext Displays the next page of alarms.
AlarmDspPrev Displays the previous page of alarms.
AlarmEnable Enables alarms.
AlarmEnableRec Enables alarms by record number.
AlarmEventQue Opens the alarm event queue.
AlarmFirstCatRec Searches for the first occurrence of an alarm category
and type.
AlarmFirstPriRec Searches for the first occurrence of an alarm priority
and type.
AlarmFirstTagRec Searches for the first occurrence of an alarm tag,
name, and description.
AlarmGetDelay Gets the delay setting for an alarm.
AlarmGetDelayRec Gets the delay setting for an alarm via the alarm
record number.
AlarmGetDsp Gets field data from the alarm record that is displayed
at the specified AN.
AlarmGetFieldRec Gets alarm field data from the alarm record number.
AlarmGetInfo Gets information about an alarm list displayed at an
AN.
AlarmGetOrderbyKey Retrieves the list of key(s) used to determine the or-
der of the alarm list.
AlarmGetThreshold Gets the thresholds of analog alarms.
137
Chapter: 18 Alarm Functions
138
Chapter: 18 Alarm Functions
See Also
Functions Reference
AlarmAck
Acknowledges alarms. You can acknowledge the alarm where the cursor is positioned, one
or more alarm lists on the active page, a whole category of alarms, or alarms of a particular
priority.
139
Chapter: 18 Alarm Functions
You would normally call this function from a keyboard command. No action is taken if the
specified alarms have already been acknowledged.
Syntax
AlarmAck(Mode, Value [, ClusterName])
Mode:
The type of acknowledgment:
0 - Acknowledge a single alarm where the cursor is positioned. Set Value to 0 (ze-
ro) - it is not used.
1 - Acknowledge a page of alarms. AN alarm page can contain more than one
alarm list:
Set Value to the AN where the alarm list is displayed.
Set Value to 0 to acknowledge the (displayed) alarm list (on the active
page) where the cursor is positioned.
Set Value to -1 to acknowledge all (displayed) alarm lists on the active
page.
2 - Acknowledge a category of alarms:
Set Value to the alarm category (0 to 16376) of the alarms to be acknowl-
edged. Please be aware that Alarm category 0 indicates all categories;
alarm category 255 indicates hardware alarms.
Set Value to the group number to acknowledge a group of categories.
3 - Acknowledge alarms of a specific priority.
Set Value to the alarm priority (0-255) of the alarms to be acknowledged.
Alarm priority 0 indicates all priorities.
Hardware alarms are not affected by priority.
Set Value to the group handle to acknowledge a group of alarms of differ-
ent priorities.
Value:
Used with Mode 1 and 2 to specify which alarms to acknowledge.
ClusterName:
Used with Mode 2 or 3 to specify the name of the cluster in which the alarms be-
ing acknowledged reside. This argument is optional if the client is connected to
only one cluster containing an Alarm Server or are resolving the alarm server via
the current cluster context.
This argument is not required where:
the mode is 2 and the value is 255 (hardware alarm category).
This argument is enclosed in quotation marks "".
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
GrpOpen
140
Chapter: 18 Alarm Functions
Example
System Keyboard
Key Sequence LeftButton
Command AlarmAck(0, 0)
Comment Acknowledge the alarm where the cursor is positioned
System Keyboard
Key Sequence ShiftLeftButton
Command AlarmAck(1, -1)
Comment Acknowledge a page of alarms
System Keyboard
Key Sequence AlarmAck ### Enter
Command AlarmAck(2, Arg1, "clusterXYZ")
Comment Acknowledge all alarms of a specified category in cluster XYZ
System Keyboard
Key Sequence AckPri ############# Enter
Command AlarmAck(3,Arg1, "clusterXYZ")
Comment Acknowledge all alarms of a specific priority in cluster XYZ
See Also
Alarm Functions
AlarmAckRec
Acknowledges alarms by record number on both the Primary and Standby Alarm Servers.
This function can be called from Alarm Server or Client and should not be used with a
MsgRPC() call to the Alarm Server.
Syntax
AlarmAckRec(Record [, ClusterName] )
Record:
The alarm record number, returned from any of the following alarm functions:
AlarmFirstCatRec() or AlarmNextCatRec(): used to search for a record by
alarm category, area, and type (acknowledged, disabled, etc.).
AlarmFirstPriRec() or AlarmNextPriRec(): used to search for a record by
alarm priority, area, and type (acknowledged, disabled, etc.).
AlarmFirstTagRec() or AlarmNextTagRec(): used to search for a record by
alarm tag, name, and description.
141
Chapter: 18 Alarm Functions
AlarmGetDsp(): used to find the record that is displayed at a specified AN, for
either an alarm list or alarm summary entry. Set the sField argument in
AlarmGetDsp() to "RecNo".
To store this value, use data type Int in Cicode or Long for variable tags (Long
needs 4 bytes).
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
AlarmFirstCatRec, AlarmFirstTagRec, AlarmNextTagRec, AlarmGetDelayRec, MsgRPC
Example
/* Acknowledge all unacknowledged (Type 1) alarms of the specified
alarm category. */
FUNCTION
AutoAccept(INT Category)
INT Current;
INT Next;
Current=AlarmFirstCatRec(Category,1);
WHILE Current<>-1 DO
Next=AlarmNextCatRec(Current,Category,1);
AlarmAckRec(Current);
Current=Next;
END
END
See Also
Alarm Functions
AlarmActive
Determines if any alarms are active in the user’s area. Call this function from the Page
Strings database, to display an alarm message at a specified AN on a graphics page. You
can specify the type of alarms, for example, active hardware alarms or disabled non-hard-
ware alarms.
Syntax
AlarmActive(Type [, ClusterName] )
Type:
The type of alarms to check:
Non-hardware alarms
0 - Active alarms
1 - Unacknowledged alarms, ON and OFF
3 - Disabled alarms
142
Chapter: 18 Alarm Functions
Hardware alarms
5 - Active alarms
6 - Unacknowledged alarms, ON and OFF
ClusterName:
The name of the cluster to check for active alarms. If this argument is blank or
empty, the function will check all connected clusters.
Return Value
1 or 0 for Non-hardware alarms (modes 0, 1, and 3).
The number of active alarms for Hardware alarms (modes 5 and 6).
Example
Strings
AN 9
Expression AlarmActive(5)
True Text "Hardware Alarms Active"
False Text "No Active Hardware Alarms"
Comment Display the alarm status at AN 9
See Also
Alarm Functions
AlarmClear
Clears an acknowledged (and off) alarm from the active alarm list. You can clear the alarm
where the cursor is positioned, one or more alarm lists on the active page, a whole category
of alarms, or alarms of a particular priority.
If you set the [Alarm]AckHold parameter to 1, alarms that go off and have been acknowl-
edged are not removed from the active list until this function is called.
Syntax
AlarmClear(Mode, Value [, ClusterName] )
Mode:
The type of clear:
0 - Clear a single alarm where the cursor is positioned:
Set Value to 0 (zero) - it is not used.
1 - Clear a page of alarms. AN alarm page can contain more than one alarm list:
Set Value to the AN where the alarm list is displayed.
Set Value to 0 to clear the (displayed) alarm list (on the active page) where
the cursor is positioned.
Set Value to -1 to clear all (displayed) alarm lists on the active page.
2 - Clear a category of alarms:
Set Value to the alarm category (0 to 16376) of the alarms to clear. Please be
aware that alarm category 0 indicates all categories; alarm category 255 in-
dicates hardware alarms.
Set Value to the group number to clear a group of categories.
143
Chapter: 18 Alarm Functions
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
AlarmAck
Example
System Keyboard
Key Sequence Clear
Command AlarmClear(0, 0)
Comment Clear the alarm where the cursor is positioned
System Keyboard
Key Sequence ClearAll
Command AlarmClear(1, -1)
Comment Clear a page of alarms
System Keyboard
Key Sequence AlarmClear ### Enter
Command AlarmClear(2, Arg1, "clusterXYZ")
Comment Clear all alarms of a specified category in cluster XYZ
System Keyboard
Key Sequence CtrlClear
Command AlarmClear(2, 0, "clusterXYZ")
Comment Clear all categories of inactive alarms in cluster XYZ
System Keyboard
Key Sequence ClearPri ########### Enter
Command AlarmClear(3,Arg1, "clusterXYZ")
Comment Clear all alarms of a specific priority in cluster XYZ
See Also
Alarm Functions
144
Chapter: 18 Alarm Functions
AlarmClearRec
Clears an alarm by its record number on both the Primary and Standby Alarms Servers.
This function can be called from Alarm Server or Client and should not be used with a
MsgRPC() call to the Alarm Server.
Syntax
AlarmClearRec(Record [, ClusterName] )
Record:
The alarm record number, returned from any of the following alarm functions:
AlarmFirstCatRec() or AlarmNextCatRec() - used to search for a record by
alarm category, area, and type (acknowledged, disabled, etc.).
AlarmFirstPriRec() or AlarmNextPriRec() - used to search for a record by
alarm priority, area, and type (acknowledged, disabled, etc.).
AlarmFirstTagRec() or AlarmNextTagRec() - used to search for a record by
alarm tag, name, and description.
AlarmGetDsp() - used to find the record that is displayed at a specified AN,
for either an alarm list or alarm summary entry. Set the sField argument in
AlarmGetDsp() to "RecNo".
To store this value, use data type Int in Cicode or Long for variable tags (Long
needs 4 bytes).
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
AlarmFirstCatRec, AlarmAck, AlarmFirstTagRec, AlarmNextTagRec, AlarmGetDelayRec,
MsgRPC
See Also
Alarm Functions
AlarmComment
Allows an operator to add a comment to a selected alarm summary entry during runtime.
You would normally call this function from a keyboard command.
Comments can only be added to alarm summary (Alarm Type 10) alarms.
Syntax
AlarmComment(sComment)
sComment:
The comment to add to the alarm summary entry. Comments have a maximum
of 128 characters.
145
Chapter: 18 Alarm Functions
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
AlarmDsp
Example
System Keyboard
Key Sequence Com ################## Enter
Command AlarmComment(Arg1)
Comment Add an alarm comment to the alarm where the cursor is positioned
See Also
Alarm Functions
AlarmDelete
Deletes alarm summary entries that are currently displayed. You can delete the alarm
where the cursor is positioned, one or more alarm lists on the active page, a whole category
of alarms, or alarms of a particular priority.
You would normally call this function from a keyboard command.
Syntax
AlarmDelete(Mode, Value [, ClusterName] )
Mode:
The type of deletion:
0 - Delete a single alarm where the cursor is positioned.
Set Value to 0 (zero) - it is not used.
1 - Delete a page of alarms. AN alarm page can contain more than one alarm list:
Set Value to the AN where the alarm list is displayed.
Set Value to 0 to delete the (displayed) alarm list (on the active page) where
the cursor is positioned.
Set Value to -1 to delete all (displayed) alarm lists on the active page.
2 - Delete a category of alarms.
Set Value to the alarm category (0-16376) of the alarms to delete. Please be
aware that alarm category 0 indicates all categories; alarm category 255 in-
dicates hardware alarms.
Set Value to the group number to delete a group of categories.
3 - Delete alarms of a specific priority.
Set Value to the alarm priority (0-255) of the alarms to be deleted.
Alarm priority 0 indicates all priorities. Hardware alarms are not affect-
ed by priority. Set Value to the group handle to delete a group of alarms
of different priorities.
Value:
Used with Mode 1 or 2 to specify which alarms to delete.
ClusterName:
146
Chapter: 18 Alarm Functions
Used with Mode 2 or 3 to specify the name of the cluster in which the alarms be-
ing deleted reside. This argument is optional if the client is connected to only one
cluster containing an Alarm Server or you are resolving the alarm server via the
current cluster context. This argument is enclosed in quotation marks "".
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
GrpOpen
Example
System Keyboard
Key Sequence DelSum
Command AlarmDelete(0, 0)
Comment Delete the alarm summary entry where the cursor is positioned
System Keyboard
Key Sequence ShiftDelSum
Command AlarmDelete(1, -1)
Comment Delete a page of alarm summary entries
System Keyboard
Key Sequence SumDelete ### Enter
Command AlarmDelete(2, Arg1, "clusterXYZ")
Comment Delete all alarm summary entries of a specified category in cluster XYZ
System Keyboard
Key Sequence DelSum ############# Enter
Command AlarmDelete(3,Arg1, "clusterXYZ")
Comment Delete all alarm summary entries of a specified priority in cluster XYZ
See Also
Alarm Functions
AlarmDisable
Disables alarms. You can disable the alarm where the cursor is positioned, one or more
alarm lists on the active page, a whole category of alarms, or alarms of a particular priority.
You would normally call this function from a keyboard command. No action is taken if the
alarms are already disabled. Use the AlarmEnable() function to re-enable an alarm.
After you disable an alarm, it does not display on the alarm page, alarm summary page, or
alarm log. If you set the [Alarm]DisplayDisable parameter to 1, logging of disabled alarms
continues, but the disabled alarms are not displayed on the alarm display or alarm summa-
ry pages.
Syntax
AlarmDisable(Mode, Value [, ClusterName] )
Mode:
147
Chapter: 18 Alarm Functions
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
GrpOpen, AlarmEnable, AlarmDisableRec
148
Chapter: 18 Alarm Functions
Example
System Keyboard
Key Sequence Disable
Command AlarmDisable(0, 0)
Comment Disable the alarm where the cursor is positioned
System Keyboard
Key Sequence ShiftDisable
Command AlarmDisable(1, -1)
Comment Disable a page of alarms
System Keyboard
Key Sequence AlarmDisable ### Enter
Command AlarmDisable(2, Arg1, "clusterXYZ")
Comment Disable all alarms of a specified category in cluster XYZ
System Keyboard
Key Sequence DisPri ############# Enter
Command AlarmDisable(3,Arg1,"clusterXYZ")
Comment Disable all alarms of a specific priority in cluster XYZ
See Also
Alarm Functions
AlarmDisableRec
Disables alarms by record number on both the Primary and Standby Alarms Servers. This
function can be called from Alarm Server or Client and should not be used with a
MsgRPC() call to the Alarm Server.
Syntax
AlarmDisableRec(Record [, ClusterName] )
Record:
The alarm record number, returned from any of the following alarm functions:
AlarmFirstCatRec() or AlarmNextCatRec() - used to search for a record by
alarm category, area, and type (acknowledged, disabled, etc.).
AlarmFirstPriRec() or AlarmNextPriRec() - used to search for a record by
alarm priority, area, and type (acknowledged, disabled, etc.).
AlarmFirstTagRec() or AlarmNextTagRec() - used to search for a record by
alarm tag, name, and description.
AlarmGetDsp() - used to find the record that is displayed at a specified AN,
for either an alarm list or alarm summary entry. Set the sField argument in
AlarmGetDsp() to "RecNo".
To store this value, use data type Int in Cicode or Long for variable tags (Long
needs 4 bytes).
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
149
Chapter: 18 Alarm Functions
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
AlarmFirstTagRec, AlarmNextTagRec, AlarmDisable, MsgRPC
Example
/* Disable/enable the specified "Pump" alarm. Flag determines
whether the alarm is disabled (Flag=0) or enabled (Flag=1). */
FUNCTION
DisablePumps(STRING sTag, INT Flag)
INT Current;
INT Next;
Current=AlarmFirstTagRec(sTag,"Pump","");
WHILE Current<>-1 DO
Next=AlarmNextTagRec(Current,sTag,"Pump","");
IF Flag=0 THEN
AlarmDisableRec(Current);
ELSE
AlarmEnableRec(Current);
END
Current=Next;
END
END
See Also
Alarm Functions
AlarmDsp
Displays an alarm list, starting at a specified AN and then on subsequent ANs. You specify
the number of alarms to display, the type of alarms and the name of the cluster the alarms
belong to, for example, active hardware alarms or disabled non-hardware alarms in cluster
XYZ. Before you call this function, you must first add animation points to the graphics page
for each alarm to be displayed.
If you only need to display the standard alarm page, use the PageAlarm function - it uses
this AlarmDsp() function to display alarms. If you need more control over the display of
alarms you can use this function, but only to display alarms on the alarm page. Use the
AlarmDspLast function to display alarms on another graphics page (it uses less memory).
Syntax
AlarmDsp(AN, Count [, Type] [, ClusterName] )
AN:
The AN where the first alarm is to display.
Count:
The number of alarms to display.
Type:
The type of alarms to display:
Non-hardware alarms
150
Chapter: 18 Alarm Functions
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
AlarmDspNext, AlarmDspPrev, AlarmDspLast, AlarmGetInfo, PageAlarm
Example
Advanced Animation
Command AlarmDsp(20,15,3)
Comment Display 15 disabled alarms at AN 20
See Also
Alarm Functions
AlarmDspLast
Displays the most recent unacknowledged alarms, at a specified AN with the cluster
named. Use this function to display the last alarms on all (or selected) pages. You can spec-
151
Chapter: 18 Alarm Functions
ify the number of alarms to display of a specified type, for example, active hardware alarms
or disabled non-hardware alarms.
Syntax
AlarmDspLast(AN [, Count] [, Type] [, ClusterName] )
AN:
The AN where the last alarms are to be displayed.
Count:
The number of alarms to display. If you do not specify a Count, the default is 1.
Type:
The type of alarms to display:
Non-hardware alarms
0 - All active alarms, that is Types 1 and 2
1 - All unacknowledged alarms, ON and OFF
2 - All acknowledged ON alarms
3 - All disabled alarms
4 - All configured (non-hardware) alarms, that is Types 0 to 3, plus acknowledged
OFF alarms.
Hardware alarms
5 - All active alarms, that is Types 6 and 7
6 - All unacknowledged alarms, ON and OFF
7 - All acknowledged ON alarms
8 - All disabled alarms
9 - All configured alarms, that is Types 5 to 8
Alarm Summary
10 - All summary alarms
Alarm General
11 - All ON alarms
12 - All OFF alarms
13 - All ON hardware alarms
14 - All OFF hardware alarms
If you do not specify a Type, the default is 1.
ClusterName:
The cluster name to which the alarms belong. This is optional if you have one
cluster or are resolving the alarm server via the current cluster context. The argu-
ment is enclosed in quotation marks "".
If a cluster name is not specified, alarms are returned for all clusters.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
AlarmDsp
152
Chapter: 18 Alarm Functions
Example
Advanced Animation
Command AlarmDspLast(11, ’ClusterXYZ’)
Comment Display the last alarm at AN 11
Advanced Animation
Command AlarmDspLast(21,3, ’ClusterXYZ’)
Comment Display the last 3 alarms at AN 21
See Also
Alarm Functions
AlarmDspNext
Displays the next page of alarms. This function pages down (scrolls) the alarms displayed
by the AlarmDsp() function. You would normally call this function from a keyboard com-
mand.
Syntax
AlarmDspNext(AN)
AN:
The AN where the alarm list is displayed, or:
-1 - Scroll all alarm lists displayed on the page.
0 - Scroll the alarm list where the cursor is positioned.
Note: An alarm page can contain more than one alarm list.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
AlarmDsp, AlarmDspPrev
Example
System Keyboard
Key Sequence NextAlarm
Command AlarmDspNext(20)
Comment Display the next page of alarms (from the alarm list) at AN20
See Also
Alarm Functions
AlarmDspPrev
Displays the previous page of alarms. This function pages up (scrolls) the alarms displayed
by the AlarmDsp() function. You would normally call this function from a keyboard com-
mand.
153
Chapter: 18 Alarm Functions
Syntax
AlarmDspPrev(AN)
AN:
The AN where the alarm list is displayed, or:
-1 - Scroll all alarm lists displayed on the page.
0 - Scroll the alarm list where the cursor is positioned.
Note: An alarm page can contain more than one alarm list.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
AlarmDsp, AlarmDspNext
Example
System Keyboard
Key Sequence PrevAlarm
Command AlarmDspPrev(20)
Comment Display the previous page of alarms (from the alarm list) at AN20
See Also
Alarm Functions
AlarmEnable
Enables an alarm on the active alarm list. You can enable the alarm where the cursor is po-
sitioned, one or more alarm lists on the active page, a whole category of alarms, or alarms
of a particular priority.
No action is taken if the alarms are already enabled. You would normally call this function
from a keyboard command.
Syntax
AlarmEnable(Mode, Value [, ClusterName] )
Mode:
The type of enable:
0 - Enable a single alarm where the cursor is positioned.
Set Value to 0 (zero) - it is not used.
1 - Enable a page of alarms. AN alarm page can contain more than one alarm list:
Set Value to the AN where the alarm list is displayed.
Set Value to 0 to enable the (displayed) alarm list (on the active page) where
the cursor is positioned.
Set Value to -1 to enable all (displayed) alarm lists on the active page.
2 - Enable a category of alarms.
Set Value to the alarm category (0-16376) of the alarms to be enabled. Please
be aware that alarm category 0 indicates all categories; alarm category 255
indicates hardware alarms.
154
Chapter: 18 Alarm Functions
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
GrpOpen, AlarmDisable, AlarmEnableRec
Example
System Keyboard
Key Sequence Enable
Command AlarmEnable(0, 0)
Comment Enable the alarm where the cursor is positioned
System Keyboard
Key Sequence ShiftEnable
Command AlarmEnable(1, -1)
Comment Enable a page of alarms
System Keyboard
Key Sequence AlarmEnable ### Enter
Command AlarmEnable(2, Arg1, "clusterXYZ")
Comment Enable all alarms of a specified category in cluster XYZ
System Keyboard
Key Sequence EnPri ############# Enter
Command AlarmEnable(3,Arg1, "clusterXYZ")
Comment Enable all alarms of a specific priority in cluster XYZ
See Also
Alarm Functions
AlarmEnableRec
155
Chapter: 18 Alarm Functions
Enables alarms by record number on both the Primary and Standby Alarms Servers. This
function can be called from Alarm Server or Client and should not be used with a
MsgRPC() call to the Alarm Server.
Syntax
AlarmEnableRec(Record [, ClusterName])
Record:
The alarm record number, returned from any of the following alarm functions:
AlarmFirstCatRec() or AlarmNextCatRec() - used to search for a record by
alarm category, area, and type (acknowledged, disabled, etc.).
AlarmFirstPriRec() or AlarmNextPriRec() - used to search for a record by
alarm priority, area, and type (acknowledged, disabled, etc.).
AlarmFirstTagRec() or AlarmNextTagRec() - used to search for a record by
alarm tag, name, and description.
AlarmGetDsp() - used to find the record that is displayed at a specified AN,
for either an alarm list or alarm summary entry. Set the sField argument in
AlarmGetDsp() to "RecNo".
To store this value, use data type Int in Cicode or Long for variable tags (Long
needs 4 bytes).
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
AlarmFirstTagRec, AlarmNextTagRec, AlarmEnable, AlarmDisableRec, MsgRPC
Example
See AlarmDisableRec
See Also
Alarm Functions
AlarmEventQue
Opens the alarm event queue. The Alarms Server writes events into this queue as they are
processed. These events include all activated, reset, acknowledged, enabled and disabled
alarms. To read events from this queue, use the QueRead() or QuePeek() functions. The
data put into the queue is the alarm record identifier (into the Type field) and the alarm
event format (into the Str field). The function puts all state changes into the queue and Ci-
tectSCADA does not use this queue for anything.
To use this function, you must enable the alarm event queue with the [Alarm]EventQue pa-
rameter. This parameter will tell the Alarms Server to start placing events into the queue.
The [Alarm]EventFmt parameter defines the format of the data placed into the string field.
You can enable the EventQue parameter without setting the event format so that the
Alarms Server does not place a formatted string into the queue.
156
Chapter: 18 Alarm Functions
Enabling this formatting feature can increase CPU loading and reduce performance of the
Alarms Server as every alarm is formatted and placed in the queue. You should reconsider
using this feature if a decrease in performance is noticeable.
The maximum length of each queue is controlled by the [Code]Queue parameter. You may
need to adjust this parameter so as not to miss alarm events. When the queue is full, the
Alarms Server will discard events.
Syntax
AlarmEventQue()
Return Value
The handle of the alarm event queue, or -1 if the queue cannot be opened.
Related Functions
QueRead, QuePeek, TagWriteEventQue
Example
hQue = AlarmEventQue()
WHILE TRUE DO
QueRead(hQue, nRecord, sAlarmFmt, 1);
/* do what ever with the alarm event */
...
Sleep(0);
END
See Also
Alarm Functions
AlarmFirstCatRec
Searches for the first occurrence of an alarm category and type. You can search all areas, the
current area only, or specify an area to limit the search. If calling this function from a re-
mote client, use the MsgRPC() function.
This function returns an alarm record identifier that you can use in other alarm functions,
for example, to acknowledge, disable, or enable the alarm, or to get field data on that alarm.
Note: Record numbers obtained from AlarmGetDsp must not be used with this function.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
Syntax
AlarmFirstCatRec(Category, Type [, Area] [, ClusterName] )
Category:
The alarm category or group number to match. Set Category to 0 (zero) to match
all alarm categories.
Type:
157
Chapter: 18 Alarm Functions
Return Value
The alarm record identifier or -1 if no match is found.
Related Functions
GrpOpen, AlarmNextCatRec, AlarmFirstPriRec, AlarmNextPriRec, AlarmGetFieldRec,
AlarmAckRec, AlarmDisableRec, AlarmEnableRec, AlarmGetThresholdRec, Alarm-
SetThresholdRec, MsgRPC
Example
See AlarmAckRec
See Also
Alarm Functions
AlarmFirstPriRec
Searches for the first occurrence of an alarm priority and type. You can search all areas, the
current area only, or specify an area to limit the search. If calling this function from a re-
mote client, use the MsgRPC() function.
This function returns an alarm record identifier that you can use in other alarm functions,
for example, to acknowledge, disable, or enable the alarm, or to get field data on that alarm.
Note: Record numbers obtained from AlarmGetDsp must not be used with this function.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
Note: This function will return a match for an Acknowledge Off alarm with [Alarm]Ack-
Hold=1 even after it has been cleared using AlarmClear or AlarmClearRec.
158
Chapter: 18 Alarm Functions
Syntax
AlarmFirstPriRec(Priority, Type [, Area] [, ClusterName] )
Priority:
The alarm Priority or group handle of a group of alarm priorities. Set Priority to
0 (zero) to match all alarm priorities.
Type:
The type of alarms to find:
Non-hardware alarms
0 - All active alarms, that is Types 1 and 2.
1 - All unacknowledged alarms, ON and OFF.
2 - All acknowledged ON alarms.
3 - All disabled alarms.
4 - All configured alarms, that is types 0 to 3, plus acknowledged OFF alarms. If
you do not specify a type, the default is 0.
Area:
The area in which to search for alarms. If you do not specify an area, or if you set
Area to -1, only the current area will be searched.
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
Return Value
The alarm record identifier or -1 if no match is found. If you do not specify an area, only
alarms in the current area on the alarms server are searched.
Related Functions
GrpOpen, AlarmNextCatRec, AlarmFirstPriRec, AlarmNextPriRec, AlarmGetFieldRec,
AlarmAckRec, AlarmDisableRec, AlarmEnableRec, AlarmGetThresholdRec, Alarm-
SetThresholdRec, MsgRPC
Example
/* Acknowledge all unacknowledged (Type 1) alarms of the specified
alarm priority. */
FUNCTION
AutoAccept(INT iPriority)
INT iCurrent;
INT iNext;
iCurrent=AlarmFirstPriRec(iPriority,1,-1);
WHILE iCurrent <>-1 DO
iNext=AlarmNextPriRec(iCurrent,iPriority,1,-1);
AlarmAckRec(iCurrent);
iCurrent=iNext;
END
END
159
Chapter: 18 Alarm Functions
See Also
Alarm Functions
AlarmFirstTagRec
Searches for the first occurrence of an alarm tag, name, and description. If calling this func-
tion from a remote client, use the MsgRPC() function.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
Note: Record numbers obtained from AlarmGetDsp must not be used with this function.
This function returns an alarm record identifier that you can use in other alarm functions,
for example, to acknowledge, disable, or enable the alarm, or to get field data on that alarm.
Note: This function will return a match for an Acknowledge Off alarm with [Alarm]Ack-
Hold=1 even after it has been cleared using AlarmClear or AlarmClearRec.
Syntax
AlarmFirstTagRec(Tag, Name, Description [, ClusterName] )
Tag:
The alarm tag to be matched. Specify an empty string (" ") to match all alarm tags.
Name:
The alarm name to be matched. Specify an empty string (" ") to match all alarm
names.
Description:
The alarm description to be matched. Specify an empty string (" ") to match all
alarm descriptions.
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
Return Value
The alarm record identifier or -1 if no match is found.
Related Functions
AlarmNextTagRec, AlarmGetFieldRec, AlarmAckRec, AlarmDisableRec, AlarmEna-
bleRec, AlarmGetThresholdRec, AlarmSetThresholdRec, MsgRPC
Example
See AlarmDisableRec
See Also
Alarm Functions
AlarmGetDelay
160
Chapter: 18 Alarm Functions
Gets the delay setting for the alarm the cursor is currently positioned over.
Syntax
AlarmGetDelay(Type)
Type:
The type of delay:
0 - Delay (digital alarm/advancedalarm)
1 - High high delay (analog alarm)
2 - High delay (analog alarm)
3 - Low delay (analog alarm)
4 - Low low delay (analog alarm)
5 - Deviation delay (analog alarm)
Return Value
The alarm delay if successful, otherwise -1 is returned. Use IsError() to retrieve extended
error information.
Related Functions
AlarmNotifyVarChange, AlarmSetDelayRec, AlarmGetDelayRec
See Also
Alarm Functions
AlarmGetDelayRec
Gets the delay setting for an alarm via the alarm record number.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
Syntax
AlarmGetDelayRec(Record, Type [, ClusterName] )
Record:
The alarm record number, returned from any of the following alarm functions:
AlarmFirstCatRec() or AlarmNextCatRec() - used to search for a record by
alarm category, area, and type (acknowledged, disabled, etc.).
AlarmFirstPriRec() or AlarmNextPriRec() - used to search for a record by
alarm priority, area, and type (acknowledged, disabled, etc.).
AlarmFirstTagRec() or AlarmNextTagRec() - used to search for a record by
alarm tag, name, and description.
AlarmGetDsp() - used to find the record that is displayed at a specified AN,
for either an alarm list or alarm summary entry. Set the sField argument in
AlarmGetDsp() to "RecNo".
Type:
The type of delay:
0 - Delay (digital alarm/advancedalarm)
161
Chapter: 18 Alarm Functions
Return Value
The alarm delay if successful, otherwise -1 is returned. Use IsError() to retrieve extended
error information.
Related Functions
AlarmNotifyVarChange, AlarmSetDelayRec, AlarmGetDelay
See Also
Alarm Functions
AlarmGetDsp
Gets field data from the alarm record that is displayed at the specified AN. You can use this
function for both Alarm Pages and Alarm Summaries (an Alarm Page or Alarm Summary
must be displayed before this function can be used).
You can call this function on an Alarms Server or a client to get the contents of any field in
the alarm record at that AN.
You can return the record number of the alarm record for use in other alarm functions, for
example, to acknowledge, disable, or enable an alarm (on an Alarms Server).
The AlarmGetDsp() function does not support hardware alarms.
Syntax
AlarmGetDsp(AN, sField)
AN:
The AN where the alarm entry is displayed.
sField:
The name of the field from which the data is retrieved. The contents of the follow-
ing fields can be retrieved when the Alarm Page is displayed:
Field Description
Category Alarm category
Desc Alarm description
Help Alarm help page
Name Alarm name
Tag Alarm tag
Time The time that the alarm changed state (hh:mm:ss)
162
Chapter: 18 Alarm Functions
Field Description
RecNo The alarm record number
Comment Operator comments attached to the Alarm Log entry (if any)
Date The date that the alarm changed state (mm/dd/yyyy)
DateExt The date that the alarm changed state in extended format
Type The type of alarm or condition
State The current state of the alarm
Value The current value of the alarm variable
High High Alarm trigger value (Only Valid on Analog Alarms)
HighHigh High High Alarm trigger value (Only Valid on Analog Alarms)
Low Low Alarm trigger value (Only Valid on Analog Alarms)
LowLow Low Low Alarm trigger value (Only Valid on Analog Alarms)
Rate Rate of change trigger value (Only Valid on Analog Alarms)
Deviation Deviation Alarm trigger value (Only Valid on Analog Alarms)
Deadband Deadband (Only Valid on Analog Alarms)
LogState The last state that the alarm passed through
AlmComment The text entered into the Comment field of the alarm properties
dialog.
Custom1..8 Custom Filter Fields
State_desc The configured description (for example, healthy or stopped) of
a particular state
The contents of the any of the above fields (except for State) and the following fields can
be retrieved when the Alarm Summary is displayed:
Field Description
UserName The name of the user (User Name) who was logged on
and performed some action on the alarm (for example,
acknowledging the alarm or disabling the alarm, etc.).
Note that when the alarm is first activated, the user
name is set to "system" (because the operator did not
trip the alarm).
FullName The full name of the user (Full Name) who was logged
on and performed some action on the alarm (for exam-
ple, acknowledging the alarm or disabling the alarm,
etc.). Note that when the alarm is first activated, the full
name is set to "system" (because the operator did not
trip the alarm).
UserDesc The text related to the user event
OnDate The date when alarm was activated
OnDateExt The date (in extended format) when the alarm was ac-
tivated (dd/mm/yyyy)
OffDate The date when the alarm returned to its normal state
OffDateExt The date (in extended format) when the alarm returned
to its normal state (dd/mm/yyyy)
OnTime The time when the alarm was activated
OffTime The time when the alarm returned to its normal state
DeltaTime The time difference between OnDate/OnTime and Off-
Date/OffTime, in seconds
163
Chapter: 18 Alarm Functions
Field Description
OnMilli Adds milliseconds to the time the alarm was activated.
OffMilli Adds milliseconds to the time the alarm returned to its
normal state.
AckTime The time when the alarm was acknowledged
AckDate The date when the alarm was acknowledged
AckDateExt The date (in extended format) when the alarm was ac-
knowledged (dd/mm/yyyy)
SumState Describes the state of the alarm when it occurred
SumDesc A description of the alarm summary
Native_SumDesc A description of the alarm summary, in the native lan-
guage
Native_Comment Native language comments the operator adds to an
Alarm Summary entry during runtime.
Return Value
Field data from the alarm entry (as a string).
Related Functions
AlarmDsp
Example
! Display the tag and category for the alarm at the specified AN.
FUNCTION
AlarmData(INT AN)
STRING Category;
STRING Tag;
Category=AlarmGetDsp(AN,"Category");
Tag=AlarmGetDsp(AN,"Tag");
Prompt("Alarm "+Tag+" is Category "+Category);
END
See Also
Alarm Functions
AlarmGetFieldRec
Gets the contents of the specified field in the specified alarm record. If calling this function
from a remote client, use the MsgRPC() function.
Note: Record numbers obtained from AlarmGetDsp must not be used with this function.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
Syntax
AlarmGetFieldRec(Record, sField [, nVer] [, ClusterName] )
Record:
164
Chapter: 18 Alarm Functions
The alarm record number, returned from any of the following alarm functions:
AlarmFirstCatRec() or AlarmNextCatRec() - used to search for a record by
alarm category, area, and type (acknowledged, disabled, etc.).
AlarmFirstPriRec() or AlarmNextPriRec() - used to search for a record by
alarm priority, area, and type (acknowledged, disabled, etc.).
AlarmFirstTagRec() or AlarmNextTagRec() - used to search for a record by
alarm tag, name, and description.
AlarmGetDsp() - used to find the record that is displayed at a specified AN,
for either an alarm list or alarm summary entry. Set the sField argument in
AlarmGetDsp() to "RecNo".
To store this value, use data type Int in Cicode or Long for variable tags (Long
needs 4 bytes).
sField:
The name of the field from which the data is retrieved.
Field Description
Category Alarm category
Desc Alarm description
Help Alarm help page
Name Alarm name
Tag Alarm tag
Time The time that the alarm changed state (hh:mm:ss)
Comment Operator comments attached to the Alarm Log entry (if
any)
Date The date that the alarm changed state (mm/dd/yyyy)
DateExt The date that the alarm changed state in extended for-
mat
Type The type of alarm or condition
State The current state of the alarm
Value The current value of the alarm variable
High High Alarm trigger value (Only Valid on Analog Alarms)
HighHigh High High Alarm trigger value (Only Valid on Analog
Alarms)
Low Low Alarm trigger value (Only Valid on Analog Alarms)
LowLow Low Low Alarm trigger value (Only Valid on Analog
Alarms)
Rate Rate of change trigger value (Only Valid on Analog
Alarms)
Deviation Deviation Alarm trigger value (Only Valid on Analog
Alarms)
Deadband Deadband (Only Valid on Analog Alarms)
LogState The last state that the alarm passed through
AlmComment The text entered into the Comment field of the alarm
properties dialog.
Custom1..8 Custom Filter Fields
State_desc The configured description (for example, healthy or
stopped) of a particular state
165
Chapter: 18 Alarm Functions
Field Description
UserName The name of the user (User Name) who was logged on
and performed some action on the alarm (for example,
acknowledging the alarm or disabling the alarm, etc.).
Note that when the alarm is first activated, the user
name is set to "system" (because the operator did not
trip the alarm).
FullName The full name of the user (Full Name) who was logged
on and performed some action on the alarm (for exam-
ple, acknowledging the alarm or disabling the alarm,
etc.). Note that when the alarm is first activated, the full
name is set to "system" (because the operator did not
trip the alarm).
UserDesc The text related to the user event
OnDate The date when alarm was activated
OnDateExt The date (in extended format) when the alarm was ac-
tivated (dd/mm/yyyy)
OffDate The date when the alarm returned to its normal state
OffDateExt The date (in extended format) when the alarm returned
to its normal state (dd/mm/yyyy)
OnTime The time when the alarm was activated
OffTime The time when the alarm returned to its normal state
DeltaTime The time difference between OnDate/OnTime and Off-
Date/OffTime, in seconds
OnMilli Adds milliseconds to the time the alarm was activated.
OffMilli Adds milliseconds to the time the alarm returned to its
normal state.
AckTime The time when the alarm was acknowledged
AckDate The date when the alarm was acknowledged
AckDateExt The date (in extended format) when the alarm was ac-
knowledged (dd/mm/yyyy)
SumState Describes the state of the alarm when it occurred
SumDesc A description of the alarm summary
Native_SumDesc A description of the alarm summary, in the native lan-
guage
Native_Comment Native language comments the operator adds to an
Alarm Summary entry during runtime.
nVer:
The version of an alarm.
If an alarm has been triggered more than once in a given period, the version lets
you distinguish between different instances of the alarm’s activity.
The version is used in filtering alarms for display. A query function passes a val-
ue to this parameter in order to get field information for a particular alarm.
This parameter is not needed when you use AlarmGetFieldRec() for purposes
other than filtering. It will default to 0 if you do not set a value.
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
166
Chapter: 18 Alarm Functions
Return Value
The alarm field data (as a string).
Related Functions
AlarmFirstTagRec, AlarmNextTagRec, MsgRPC
Example
FUNCTION
GetNameFromTag(STRING sTag)
INT record;
STRING sName
record = AlarmFirstTagRec(sTag, "", "");
IF record <> -1 THEN
sName = AlarmGetFieldRec(record,"NAME");
ELSE
sName = "";
END
RETURN sName;
END
See Also
Alarm Functions
AlarmGetInfo
Gets data on the alarm list displayed at a specified AN. Use this function to display the cur-
rent alarm list information on an alarm page. If only one alarm list has been configured on
an alarm page, modes 2 and 3 of this function return the current alarm page information.
Note: You cannot retrieve the order by key setting for an alarm list using this function, as
it can only returns numeric values. To retrieve this information, use the function AlarmGe-
tOrderbyKey
Syntax
AlarmGetInfo(AN, Type)
AN:
The AN where the alarm list (with the required information) is displayed. Set the
AN to 0 (zero) to get information on the alarm list where the cursor is positioned.
Type:
The type of data:
0 - Alarm page number. The vertical offset (in pages) from the AN where the
alarm list commenced. The alarm list must have scrolled off the first page
for this type to return a non-zero value.
1 - Alarm list offset. The vertical offset (in lines) from the AN where the alarm list
commenced. You must have scrolled off the first page of alarms for this
type to return a non zero value.
2 - Category of alarms displayed on the alarm list. You can use a group number
to display a group of categories.
3 - Type of alarms displayed on the alarm list. See AlarmDsp() for a list of these
types.
167
Chapter: 18 Alarm Functions
7 - Priority of alarms displayed on the alarm list. The return value may be a group
number if the alarm list contains alarms of more than one priority.
8 - Display mode of the alarm list.
9 - Sorting mode of the alarm list.
Return Value
Alarm list data as a numeric value.
Related Functions
AlarmDsp, AlarmSetInfo, AlarmGetOrderbyKey.
Example
/* In all of the following examples, data is returned on the alarm
list where the cursor is positioned. */
page = AlarmGetInfo(0,0);
! returns the alarm page number.
offset = AlarmGetInfo(0,1);
! returns the alarm list offset.
cat = AlarmGetInfo(0,2);
! returns the alarm category displayed.
type = AlarmGetInfo(0,3);
! returns the type of alarms displayed.
See Also
Alarm Functions
AlarmGetOrderbyKey
Retrieves the list of key(s) that are used to determine the order of the alarm list. These keys
can be set by the AlarmSetInfo() function.
Syntax
AlarmGetOrderbyKey(AN)
AN:
The AN where the alarm list (with the required information) is displayed.
Return Value
Order-by key (as a string).
Example
page = AlarmGetOrderbyKey(21);
! returns the order-by key string of the alarm list at AN ’21’.
See Also
Alarm Functions
168
Chapter: 18 Alarm Functions
AlarmGetThreshold
Gets the threshold of the analog alarm where the cursor is positioned.
Syntax
AlarmGetThreshold(Type)
Type:
The type of threshold:
0 - High high
1 - High
2 - Low
3 - Low low
4 - Deadband
5 - Deviation
6 - Rate of change
Return Value
The alarm threshold.
Related Functions
AlarmGetThresholdRec, AlarmSetThreshold, AlarmSetThresholdRec
See Also
Alarm Functions
AlarmGetThresholdRec
Gets the threshold of analog alarms by the alarm record number. If calling this function
from a remote client, use the MsgRPC() function.
Note: Record numbers obtained from AlarmGetDsp must not be used with this function.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
Syntax
AlarmGetThresholdRec(Record, Type [, ClusterName] )
Record:
The alarm record number, returned from any of the following alarm functions:
AlarmFirstCatRec() or AlarmNextCatRec() - used to search for a record by
alarm category, area, and type (acknowledged, disabled, etc.).
AlarmFirstPriRec() or AlarmNextPriRec() - used to search for a record by
alarm priority, area, and type (acknowledged, disabled, etc.).
AlarmFirstTagRec() or AlarmNextTagRec() - used to search for a record by
alarm tag, name, and description.
169
Chapter: 18 Alarm Functions
Return Value
The alarm threshold.
Related Functions
AlarmGetThreshold, AlarmSetThreshold, AlarmSetThresholdRec, MsgRPC
See Also
Alarm Functions
AlarmHelp
Displays the alarm help page (associated with the alarm) where the cursor is positioned.
You can assign a help page to each alarm when you define it (using the Digital Alarms or
the Analog Alarms database, depending on the type of alarm). You must also define the
help page in the Pages database.
Syntax
AlarmHelp()
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
PageAlarm
170
Chapter: 18 Alarm Functions
Example
System Keyboard
Key Sequence AlmHelp
Command AlarmHelp()
Comment Display the alarm help page
See Also
Alarm Functions
AlarmNextCatRec
Searches for the next occurrence of an alarm category and type, commencing with the spec-
ified alarm record identifier (returned from the previous search through the AlarmFirstC-
atRec function). You can search all areas, the current area only, or specify an area to limit
the search. If calling this function from a remote client, use the MsgRPC() function.
This function returns an alarm record identifier that you can use in other alarm functions,
for example, to acknowledge, disable, or enable the alarm, or to get field data on that alarm.
Note: Record numbers obtained from AlarmGetDsp must not be used with this function.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
Syntax
AlarmNextCatRec(Record, Category, Type [, Area] [, ClusterName] )
Record:
The alarm record number, returned from any of the following alarm functions:
AlarmFirstCatRec() or AlarmNextCatRec() - used to search for a record by
alarm category, area, and type (acknowledged, disabled, etc.).
AlarmFirstPriRec() or AlarmNextPriRec() - used to search for a record by
alarm priority, area, and type (acknowledged, disabled, etc.).
AlarmFirstTagRec() or AlarmNextTagRec() - used to search for a record by
alarm tag, name, and description.
AlarmGetDsp() - used to find the record that is displayed at a specified AN,
for either an alarm list or alarm summary entry. Set the sField argument in
AlarmGetDsp() to "RecNo". To store this value, use data type Int in Cicode or
Long for variable tags (Long needs 4 bytes).
Category:
The alarm category or group number to match. Set Category to 0 (zero) to match
all alarm categories.
Type:
The type of alarms to find:
Non-hardware alarms
0 - All active alarms, that is Types 1 and 2.
1 - All unacknowledged alarms, ON and OFF.
2 - All acknowledged ON alarms.
3 - All disabled alarms.
171
Chapter: 18 Alarm Functions
Return Value
The alarm record identifier or -1 if no match is found.
Related Functions
GrpOpen, AlarmFirstCatRec, AlarmFirstPriRec, AlarmNextPriRec, AlarmGetFieldRec,
AlarmAckRec, AlarmDisableRec, AlarmEnableRec, AlarmGetThresholdRec, Alarm-
SetThresholdRec, MsgRPC
Example
See AlarmAckRec
See Also
Alarm Functions
AlarmNextPriRec
Searches for the next occurrence of an alarm of a specified priority and type, commencing
with the specified alarm record identifier (returned from the previous search through the
AlarmFirstPriRec() function). You can search all areas, the current area only, or specify an
area to limit the search. If calling this function from a remote client, use the
MsgRPC() function.
This function returns an alarm record identifier that you can use in other alarm functions,
for example, to acknowledge, disable, or enable the alarm, or to get field data on that alarm.
Note: Record numbers obtained from AlarmGetDsp must not be used with this function.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
Syntax
AlarmNextPriRec(Record, Priority, Type [, Area] [, ClusterName] )
Record:
The alarm record number, returned from any of the following alarm functions:
AlarmFirstCatRec() or AlarmNextCatRec() - used to search for a record by
alarm category, area, and type (acknowledged, disabled, etc.).
AlarmFirstPriRec() or AlarmNextPriRec() - used to search for a record by
alarm priority, area, and type (acknowledged, disabled, etc.).
172
Chapter: 18 Alarm Functions
Return Value
The alarm record identifier or -1 if no match is found.
Related Functions
GrpOpen, AlarmFirstCatRec, AlarmFirstPriRec, AlarmNextCatRec, AlarmGetFieldRec,
AlarmAckRec, AlarmDisableRec, AlarmEnableRec, AlarmGetThresholdRec, Alarm-
SetThresholdRec, AlarmSetInfo, MsgRPC
See Also
Alarm Functions
AlarmNextTagRec
Searches for the next occurrence of an alarm tag, name, and description, starting with the
alarm record identifier (returned from the previous search through the AlarmFirstTagRec()
function). If calling this function from a remote client, use the MsgRPC() function.
This function returns an alarm record identifier that you can use in other alarm functions,
for example, to acknowledge, disable, or enable the alarm, or to get field data on that alarm.
173
Chapter: 18 Alarm Functions
Note: Record numbers obtained from AlarmGetDsp must not be used with this function.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
Syntax
AlarmNextTagRec(Record, Tag, Name, Description [, ClusterName] )
Record:
The alarm record number, returned from any of the following alarm functions:
AlarmFirstCatRec() or AlarmNextCatRec() - used to search for a record by
alarm category, area, and type (acknowledged, disabled, etc.).
AlarmFirstPriRec() or AlarmNextPriRec() - used to search for a record by
alarm priority, area, and type (acknowledged, disabled, etc.).
AlarmFirstTagRec() or AlarmNextTagRec() - used to search for a record by
alarm tag, name, and description.
AlarmGetDsp() - used to find the record that is displayed at a specified AN,
for either an alarm list or alarm summary entry. Set the sField argument in
AlarmGetDsp() to "RecNo".
To store this value, use data type Int in Cicode or Long for variable tags (Long
needs 4 bytes).
Tag:
The alarm tag to be matched. Specify an empty string (" ") to match all alarm tags.
Name:
The alarm name to be matched. Specify an empty string (" ") to match all alarm
names.
Description:
The alarm description to be matched. Specify an empty string (" ") to match all
alarm descriptions.
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
Return Value
The alarm record identifier or -1 if no match is found.
Related Functions
AlarmFirstTagRec, AlarmGetFieldRec, AlarmAckRec, AlarmDisableRec, AlarmEna-
bleRec, AlarmGetDelayRec, AlarmGetThresholdRec, AlarmSetThresholdRec, MsgRPC
Example
See AlarmDisableRec.
See Also
Alarm Functions
174
Chapter: 18 Alarm Functions
AlarmNotifyVarChange
This function is used to provide time-stamped digital and time-stamped analog alarms
with data. When called, it notifies the alarm server that the specified variable tag has
changed.
The alarm server will then check all time-stamped digital and time-stamped analog alarms
that use the variable tag to see if their alarm states need to be updated as a result of the
change. Any alarm state changes that result from this check will be given the timestamp
passed into this function as their time of occurrence.
Note: Although you can hardcode a value into the setpoint when using analog alarms, you
cannot use hardcoded values with time-stamped analog alarms. If the setpoint is hardcod-
ed, this function cannot be used to notify the alarm when the variable changes.
Syntax
AlarmNotifyVarChange(Tag, Value, Timestamp [, TimestampMS] [, ClusterName] )
Tag:
Name of the variable tag that has changed as a string. This name may include the
name of the tag’s cluster in the form cluster.tagname. This cluster name may be
different from the cluster of the alarm server indicated by ClusterName below.
The Tag parameter is resolved on the alarm server, so the alarm server should be
configured to connect to the tag’s cluster.
Value:
Value of the variable tag at the time of the change as a floating-point number
Timestamp:
Time/date at which the variable tag changed in the standard CitectSCADA time/
date variable format (Seconds since 1970).
TimestampMS:
Millisecond portion of the time at which the variable tag changed.
ClusterName:
Name of the cluster of the alarm server. This is optional if you have one cluster or
are resolving the alarm server via the current cluster context. The argument is en-
closed in quotation marks "".
Return Value
The error that was detected when the function was called.
Example
AlarmNotifyVarChange("LOOP_1_SP", 50.0, TimeCurrent() - 10, 550,
"ClusterXYZ");
This will tell the alarm server in cluster XYZ that the value of
variable tag LOOP_1_SP changed to 50.0 at 9.450 seconds ago.
See Also
Time-stamped Digital Alarm Properties, Time-stamped Analog Alarm Properties
Alarm Functions
175
Chapter: 18 Alarm Functions
AlarmQueryFirstRec
Searches for the first occurrence of an alarm category (or priority) and type. This is a wrap-
per function of AlarmFirstCatRec and AlarmFirstPriRec.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
Syntax
AlarmQueryFirstRec(Group, Type, Area, QueryType [, ClusterName] )
Group:
Alarm category if QueryType is 0 or alarm priority if QueryType is 1.
Type:
Type of alarms to find:
Non-hardware alarms
0 - All active alarms; that is, types 1 and 2.
1 - All unacknowledged alarms, ON and OFF.
2 - All acknowledged ON alarms.
3 - All disabled alarms.
4 - All configured alarms; that is, types 0 to 3, plus acknowledged OFF alarms.
Area:
Area in which to search for alarms. Set Area to -1 to search all areas.
QueryType:
Query type.
0 - Search by category.
1 - Search by priority.
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
Return Value
The alarm record identifier or -1 if no match is found.
Related Functions
AlarmQueryNextRec
See Also
Alarm Functions
AlarmQueryNextRec
Searches for the next occurrence of an alarm category (or priority) and type, commencing
with the specified alarm record identifier (returned from the previous search through the
alarm query functions).
176
Chapter: 18 Alarm Functions
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
This is wrapper function of AlarmNextCatRec and AlarmNextPriRec.
Syntax
AlarmQueryNextRec(Record, Group, Type, Area, QueryType [, ClusterName] )
Record:
Alarm record number.
Group:
Alarm Category if QueryType is 0 or alarm priority if QueryType is 1.
Type:
Type of alarms to find:
Non-hardware alarms
0 - All active alarms; that is, types 1 and 2.
1 - All unacknowledged alarms, ON and OFF.
2 - All acknowledged ON alarms.
3 - All disabled alarms.
4 - All configured alarms; that is, types 0 to 3, plus acknowledged OFF alarms.
Area:
Area in which to search for alarms. Set Area to -1 to search all areas.
QueryType:
Query type.
0 - Search by category.
1 - Search by priority.
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
Return Value
The alarm record identifier or -1 if no match is found.
Related Functions
AlarmQueryFirstRec
See Also
Alarm Functions
AlarmSetDelay
Changes the delay setting for an alarm (that is Delay, High High Delay, Deviation Delay,
etc.). This function acts on the alarm that the cursor is positioned over. Use this function
during runtime to change the delay values that were specified in the alarms database. De-
lay changes made using this process are permanent (that is they are saved to the project).
177
Chapter: 18 Alarm Functions
Syntax
AlarmSetDelay(Type, Value)
Type:
The type of delay:
0 - Delay (digital alarm/advanced alarm)
1 - High high delay (analog alarm)
2 - High delay (analog alarm)
3 - Low delay (analog alarm)
4 - Low low delay (analog alarm)
5 - Deviation delay (analog alarm)
Value:
The new value for the delay. Enter a blank value " " to remove the delay setting.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
AlarmGetDelay, AlarmSetDelayRec, AlarmGetDelayRec
See Also
Alarm Functions
AlarmSetDelayRec
Changes the delay setting for an alarm (that is Delay, High High Delay, Deviation Delay,
etc.) by the alarm record number. You can only call this function on an alarms server for
local alarms, or on a redundant server if one has been configured. However, a client can call
this function remotely by using the MsgPRC() function.
Syntax
AlarmSetDelayRec(Record, Type, Value)
Record:
The alarm record number, returned from any of the following alarm functions:
AlarmFirstCatRec() or AlarmNextCatRec() - used to search for a record by
alarm category, area, and type (acknowledged, disabled, etc.).
AlarmFirstPriRec() or AlarmNextPriRec() - used to search for a record by
alarm priority, area, and type (acknowledged, disabled, etc.).
AlarmFirstTagRec() or AlarmNextTagRec() - used to search for a record by
alarm tag, name, and description.
AlarmGetDsp() - used to find the record that is displayed at a specified AN,
for either an alarm list or alarm summary entry. Set the sField argument in
AlarmGetDsp() to "RecNo".
Type:
The type of delay:
0 - Delay (digital alarm/advanced alarm)
1 - High high delay (analog alarm)
178
Chapter: 18 Alarm Functions
Related Functions
AlarmGetDelay, AlarmNotifyVarChange, AlarmGetDelayRec
See Also
Alarm Functions
AlarmSetInfo
Controls different aspects of the alarm list displayed at a specified AN.
Syntax
AlarmSetInfo(AN, Type, Value)
AN:
The AN where the alarm list originally commenced. (AN alarm page can contain
more than one alarm list). You can also specify:
-1 - Change the display parameters of all alarm lists displayed on the page.
0 - Change the display parameters of the alarm list where the cursor is positioned.
Type:
The type of data. The aspects and related types are listed below:
Display aspect Types
Change display line and page offset 0, 1
Formatting of alarms in the alarm list 4, 5, 6
Filtering of alarms 2, 3, 7, 8
Sorting of alarms - to control the sorting as- 9, 10
pect of the alarm list, type 9 and 10 should
be used together.
0 - Alarm page number. The vertical offset (in pages) from the AN where the
alarm list commenced.
1 - Alarm list offset. The vertical offset (in lines) from the AN where the alarm list
commenced.
2 - Category of alarms displayed on the alarm list. To specify all categories use a
value of 0.
You can use a group handle to display a group of categories. (A group can be de-
fined using Groups - from the Project Editor System menu - or by using the
GrpOpen() function.) Before you can display a group of categories, you
must first open the group using the GrpOpen() function. You would usu-
ally do this by entering the GrpOpen() function as the Page entry com-
mand for your alarm page (set using Page Properties). Note, however, that
you should not close the group until you close the display page. If you do,
179
Chapter: 18 Alarm Functions
the group will be destroyed and the group handle will become invalid. The
page would then be unable to continue displaying the desired group. The
handle may be reused for another group, which means the page may dis-
play a different category, or display all alarms.
You would normally close the group by entering the GrpClose() function as the
Page exit command.
3 - Type of alarms displayed on the alarm list. See AlarmDsp() for a list of these
types.
4 - Display all alarms according to the format and fonts specified for one category
(specified in Value).
5 - The display format for all alarms specified by a format handle. All of the alarm
categories will display in the same format.
6 - The display font for all user alarms specified by a font handle. All of the user
alarms will appear in the same font and color.
7 - The priority of the alarms to be displayed in the alarm list. You can use a group
number to display a group of priorities.
You can use a group handle to display a group of priorities. (A group can be de-
fined using Groups - from the Project Editor System menu - or by using the
GrpOpen() function.) Before you can display a group of priorities, you
must first open the group using the GrpOpen() function. You would usu-
ally do this by entering the GrpOpen() function as the Page entry com-
mand for your alarm page (set using Page Properties). Note, however, that
you should not close the group until you close the display page. If you do,
the group will be destroyed and the group handle will become invalid. The
page would then be unable to continue displaying the desired group. You
would normally close the group by entering the GrpClose() function as the
Page exit command.
8 - Use the Value argument of the AlarmSetInfo() function to specify whether the
display mode of the alarm list is based on Alarm Category or Priority:
Set the Value argument to 0 (zero) to display by Category.
Set the Value argument to 1 to display by Priority.
9 - Use the Value argument of the AlarmSetInfo() function to specify the sorting
mode of the alarm list:
Set the Value argument to 0 (zero) to display alarms sorted by ON time
within their groups.
Set the Value argument to 1 to display alarms sorted by the order-by keys.
Please be aware that this option will only be meaningful if you have al-
ready called the AlarmSetInfo() function with a Type of 10 to set the order-
by keys.
10 - Use the Alarm Order-by key specified in the Value argument of the Alarm-
SetInfo() function to determine the order in which the alarm list will be dis-
played.
The AlarmSetInfo() function should then be called again using a Type of 9 and a
Value of 1 for CitectSCADA to sort the alarms in the order specified.
Value:
The meaning of the Value argument depends on the data type specified in the
Type argument.
180
Chapter: 18 Alarm Functions
If you set Type = 8, the Value argument determines whether alarms are dis-
played by category or priority:
0 - Alarm list displayed by Category.
1 - Alarm list displayed by Priority.
If you set Type = 10, the Value argument specifies the order-by keys to be used
in sorting. Up to sixteen keys may be specified:
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
GrpOpen, AlarmDsp, AlarmGetInfo
Examples
In the following example, the alarm list is set to display in the order of the order-by key.
Please be aware that this is a two-step process requiring two calls to the AlarmSetInfo()
function, and that it applies only to non-hardware alarm lists.
! Set the order-by key.
AlarmSetInfo(21,10,"{Time}");
! Set the sorting mode.
AlarmSetInfo(21,9,1);
Type 8 of the function is used to set the display mode to either category or priority. This is
helpful when filtering based on either of these fields. So In order to filter on category 2 we
should use:
AlarmSetInfo(21, 8, 0);
AlarmSetInfo(21, 2, 2);
Once we do this the alarms with category 2 will be displayed in the alarm list and remain-
ing although active will not be displayed.
Similarly if we want to filter on priority we set the mode to priority and then use type 7. For
example to filter on priority 4 we should use:
AlarmSetInfo(21, 8, 1); ! priority mode
AlarmSetInfo(21, 7, 4); ! apply filter
In the following examples, the display parameters of the alarm list where the cursor is po-
sitioned are changed.
! Change the vertical offset (pages) to 2.
AlarmSetInfo(0,0,2);
181
Chapter: 18 Alarm Functions
In the following examples, the display parameters of the alarm list at AN 20 are changed.
! Display all alarms with category 120 format and fonts
AlarmSetInfo(20, 4, 120);
! Display all alarms with a new format
hFmt=FmtOpen("MyFormat","{Name}{Desc,20}",0);
AlarmSetInfo(20, 5, hFmt);
! Display all alarms with a new font
hFont = DspFont("Times",-60,black,gray);
AlarmSetInfo(20, 6, hFont);
The following example displays all alarms with categories 1-10, 20, or 25. Before AlarmSet-
Info() is run, the page entry command for the alarm display page is configured as follows:
On page entry command hGrp=GrpOpen("MyGrp",1); StrToGrp(hGrp,"1..10,20,25");
Note: hGrp is defined in the variables database. The page exit command for the alarm dis-
play page is configured as follows:
On page exit command GrpClose(hGrp)
AlarmSetInfo(20, 2, hGrp);
See Also
Alarm Functions
AlarmSetQuery
Allows you to choose which alarms display on a page, by calling a user-defined query func-
tion to filter the alarms on specific criteria. The query function is called for each alarm, and
only alarms matching the criteria are displayed on the page.
There are two steps involved in using a query to display alarms:
Write the Cicode function that will be used as the query function.
Specify the query function and its arguments in a call to AlarmSetQuery().
Note: You can also use AlarmSetQuery() to remove filtering from an alarm list. Alarm-
SetQuery( -1, "", "" ) stops the query function filtering the display of alarms.
Syntax
AlarmSetQuery(AN, QueryFunction [, sArgs] [, iAlways] )
AN:
The AN where the alarm list originally commenced. (AN alarm page can contain
more than one alarm list). You can also specify:
-1 - Change the display parameters of all alarm lists displayed on the page.
182
Chapter: 18 Alarm Functions
0 - Change the display parameters of the alarm list where the cursor is positioned.
QueryFunction:
The name of the Cicode query function written by the user. Once this function has
been specified, it is called for each alarm, and determines whether or not the
alarm should be displayed.
The QueryFunction returns an INT value of 1 (TRUE) or 0 (FALSE). If a value of
TRUE is returned, the alarm will be displayed. If the query function returns
FALSE, the alarm will be ignored and not displayed.
The query function’s first parameter must be an INT. This parameter is initialized
with the record ID of the current alarm, providing the query function with infor-
mation about the alarm.
The query function’s second parameter must also be an INT. It represents the in-
stance or event of an alarm, and is used in filtering the alarms for display.
sArgs:
A list of arguments to be passed to the Cicode query function. The arguments are
enclosed by double quotes ("") and separated by commas. This parameter is op-
tional. If the query function does not require parameters other than the default
INT parameter, then the list of arguments may be left out as follows:
AlarmSetQuery(0, "AlarmQueryDate");
In this case, the default value of an empty string will be used for the third param-
eter.
If the query function requires values to be passed in by the user, the following
rules apply to determine the types of arguments:
Digits are interpreted as INT
Digits with decimals are interpreted as REAL
Anything enclosed by ^" ^" is interpreted as a STRING
For example, to pass an INT of 23, a string of "23/12/1999", and a REAL value of
23.45 to the query function MyQueryDate(), AlarmSetQuery() should be invoked
in the following way:
AlarmSetQuery(0, 1 ,"MyQueryDate", "23, ^"23/12/1999^", 23.45");
The query function MyQueryDate() would be defined as follows:
INT
FUNCTION
MyQueryDate(INT nRID, INT nVer, INT iOne, STRING sOne, REAL rOne)
..
..
END
The types of the arguments listed in AlarmSetQuery() should match the types of
the arguments defined in the query function.
iAlways:
Set to TRUE to so that the query is performed whenever it is called (no optimiza-
tion). Default value is 0 (FALSE).
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
AlarmGetFieldRec, AlarmSetInfo, QueryFunction
183
Chapter: 18 Alarm Functions
Example
!Sets MyQueryDate() as the query function and provides the
arguments 23, 23/12/1999, and 23.45
AlarmSetQuery(0, "MyQueryDate", "23, ^"23/12/1999^", 23.45");
!Removes filtering by the current query function from all alarm
lists on the page
AlarmSetQuery(-1, "", "");
See Also
Alarm Functions
AlarmSetThreshold
Changes the thresholds (that is High High, Low etc.) of analog alarms. This function acts
on the analog alarm where the cursor is positioned. Use this function to change (at run
time) the threshold values that were specified in the Analog Alarms database. Threshold
changes made using this function are permanent (that is they are saved to the project). The
display format currently specified for the record (in the Analog Alarms form) will be ap-
plied to these values.
Syntax
AlarmSetThreshold(Type, Value)
Type:
The type of threshold:
0 - High high
1 - High
2 - Low
3 - Low low
4 - Deadband
5 - Deviation
6 - Rate of change
Value:
The new value of the threshold. Enter a blank value "" to remove the threshold.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
AlarmSetThresholdRec
184
Chapter: 18 Alarm Functions
Example
System Keyboard
Key Sequence SetHighHigh ### Enter
Command AlarmSetThreshold(0, Arg1)
Comment Change the threshold of a high high alarm
System Keyboard
Key Sequence SetHigh ### Enter
Command AlarmSetThreshold(1, Arg1)
Comment Change the threshold of a high alarm
System Keyboard
Key Sequence SetLow ### Enter
Command AlarmSetThreshold(2, Arg1)
Comment Change the threshold of a low alarm
System Keyboard
Key Sequence SetlowLow ### Enter
Command AlarmSetThreshold(3, Arg1)
Comment Change the threshold of a low low alarm
See Also
Alarm Functions
AlarmSetThresholdRec
Changes the threshold (that is High High, Low etc.) of analog alarms by the alarm record
number. You can call this function only on an Alarms Server for alarms on that server, or
on the redundant server (if a redundant server is configured). If calling this function from
a remote client, use the MsgRPC() function.
Threshold changes made using this function are permanent (that is they are saved to the
project). The display format currently specified for the record (in the Analog Alarms form)
will be applied to these values.
Note: Record numbers obtained from AlarmGetDsp must not be used with this function.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
Syntax
AlarmSetThresholdRec(Record, Type, Value)
Record:
The alarm record number, returned from any of the following alarm functions:
AlarmFirstCatRec() or AlarmNextCatRec() - used to search for a record by
alarm category, area, and type (acknowledged, disabled, etc.).
AlarmFirstPriRec() or AlarmNextPriRec() - used to search for a record by
alarm priority, area, and type (acknowledged, disabled, etc.).
AlarmFirstTagRec() or AlarmNextTagRec() - used to search for a record by
alarm tag, name, and description.
185
Chapter: 18 Alarm Functions
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
AlarmSetThreshold, MsgRPC
See Also
Alarm Functions
AlarmSplit
Duplicates an entry (where the cursor is positioned) in the alarm summary display. You
can use this function to add another comment to an alarm summary entry. You would nor-
mally call this function from a keyboard command.
Syntax
AlarmSplit()
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
AlarmSumSplit
186
Chapter: 18 Alarm Functions
Example
System Keyboard
Key Sequence Split
Command AlarmSplit()
Comment Duplicates an alarm summary entry
See Also
Alarm Functions
AlarmSumAppend
Appends a new blank record to the alarm summary. Use this function to add new alarm
summary entries, either for actual alarms or as special user summary entries.
If you specify a valid alarm tag in the sTag field, the summary entry is linked to the actual
alarm. If you specify an asterisk ’*’ as the first letter of the tag, the summary entry becomes
a user event.
User events are not attached to alarm records, so their status will not change. You must
manually change the status of the user event, by calling the AlarmSumSet() function with
the index returned by AlarmSumAppend(). As user events are not attached to alarms, they
don’t have the alarm fields - so the AlarmSumGet() function will not return any field data.
You can use user events to keep a record of logins, or control operations that you need to
display in the alarm summary etc. To set the {ONTIME} {OFFTIME} etc. data, use the
AlarmSumSet() function.
This function can only be used if the Alarm Server is on the current machine. When the
Alarm Server is not in the calling process, this function will become blocking and cannot be
called from a foreground task. In this case, the return value will be undefined and a Cicode
hardware alarm will be raised.
Syntax
AlarmSumAppend(sTag [, ClusterName] )
sTag:
The alarm tag to append. Use an asterisk ’*’ as the first letter to append a user
event to the alarm summary. Please be aware that if you using this ’user event
mode’ the AlarmSumAppend function returns the alarm summary index - not
the error code.
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
Return Value
The index of the alarm summary entry, or -1 if the record could not be appended.
Related Functions
AlarmSumSet
187
Chapter: 18 Alarm Functions
Example
! Append alarm to summary display
AlarmSumAppend("CV101");
! Append user event
iIndex = AlarmSumAppend("*MyEvent");
AlarmSumSet(iIndex, "Comment", "My event comment");
AlarmSumSet(iIndex, "OnTime", TimeCurrent());
See Also
Alarm Functions
AlarmSumCommit
This command is deprecated in this version of CitectSCADA. Use the AlmSummaryCom-
mit command instead.
Commits the alarm summary record to the alarm summary device. Alarm summaries are
normally written to the alarm summary device just before they are deleted from the sum-
mary queue. The length of time that alarm summary entries remain in the alarm summary
queue is controlled by [Alarm]SummaryTimeout parameter.
This function allows you to commit the alarm summary records now, rather than when
they are deleted from the queue.
This function can only be used if the Alarm Server is on the current machine. When the
Alarm Server is not in the calling process, this function will become blocking and cannot be
called from a foreground task. In this case, the return value will be undefined and a Cicode
hardware alarm will be raised.
Syntax
AlarmSumCommit(Index [, ClusterName] )
Index:
The alarm summary index (returned from the AlarmSumFirst(), AlarmSum-
Next(), AlarmSumLast(), AlarmSumPrev(), AlarmSumAppend(), or AlarmSum-
Find() function).
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
AlarmSumFirst, AlarmSumNext, AlarmSumLast, AlarmSumPrev, AlarmSumGet, Alarm-
SumFind
188
Chapter: 18 Alarm Functions
Example
/* This function commits all alarm summary entries that match the
specified tag. */
FUNCTION
SumCommitTag(STRING sTag)
INT Next;
INT Index;
STRING Name;
Index=AlarmSumFirst();
WHILE Index<>-1 DO
Name=AlarmSumGet(Index,"Tag");
Next=AlarmSumNext(Index);
IF Name=sTag THEN
AlarmSumCommit(Index);
END
Index=Next;
END
END
See Also
Alarm Functions
AlarmSumDelete
This command is deprecated in this version of CitectSCADA. Use the AlmSummaryDelete
command instead.
Deletes an alarm summary entry. You identify the alarm summary entry by the Index, re-
turned by one of the alarm summary search functions.
By embedding this function in a loop, you can delete a series of alarm summary entries. To
start deleting from the oldest entry, call the AlarmSumFirst() function to get the index, and
then call AlarmSumNext() in a loop. To delete back from the most recent entry, call Alarm-
SumLast() and then AlarmSumPrev() in a loop.
You can also get the Index from the AlarmSumFind() function, which finds an alarm sum-
mary entry by its alarm record identifier and time of activation.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
Syntax
AlarmSumDelete(Index [, ClusterName] )
Index:
The alarm summary index (returned from the AlarmSumFirst(), AlarmSum-
Next(), AlarmSumLast(), AlarmSumPrev(), AlarmSumAppend(), or AlarmSum-
Find() function).
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
189
Chapter: 18 Alarm Functions
Return Value
0 (zero) if the specified alarm entry exists, otherwise an error is returned.
Related Functions
AlarmSumFirst, AlarmSumNext, AlarmSumLast, AlarmSumPrev, AlarmSumGet, Alarm-
SumFind
Example
/* This function deletes all alarm summary entries that match the
specified tag. */
FUNCTION
SumDelTag(STRING sTag)
INT Next;
INT Index;
STRING Name;
Index=AlarmSumFirst();
WHILE Index<>-1 DO
Name=AlarmSumGet(Index,"Tag");
Next=AlarmSumNext(Index);
IF Name=sTag THEN
AlarmSumDelete(Index);
END
Index=Next;
END
END
See Also
Alarm Functions
AlarmSumFind
This command is deprecated in this version of CitectSCADA. Use the AlmSummary com-
mands instead.
Finds the alarm summary index for an alarm that you specify by the alarm record identifier
and alarm activation time (OnTime). You can use this index in the AlarmSumGet() function
to get field data from an alarm record, in the AlarmSumSet() function to change the existing
data in that record, or in the AlarmSumDelete() function to delete the record. If calling this
function from a remote client, use the MsgRPC() function.
To work with a series of alarm summary records, call this function to get the index, and
then call either AlarmSumNext() to move forwards in the summary, or AlarmSumPrev() to
move backwards in the summary.
Note: Record numbers obtained from AlarmGetDsp must not be used with this function.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
Syntax
AlarmSumFind(Record, OnTime [, ClusterName] )
190
Chapter: 18 Alarm Functions
Record:
The alarm record number, returned from any of the following alarm functions:
AlarmFirstCatRec() or AlarmNextCatRec() - used to search for a record by
alarm category, area, and type (acknowledged, disabled, etc.).
AlarmFirstPriRec() or AlarmNextPriRec() - used to search for a record by
alarm priority, area, and type (acknowledged, disabled, etc.).
AlarmFirstTagRec() or AlarmNextTagRec() - used to search for a record by
alarm tag, name, and description.
AlarmGetDsp() - used to find the record that is displayed at a specified AN,
for either an alarm list or alarm summary entry. Set the sField argument in
AlarmGetDsp() to "RecNo".
To store this value, use data type Int in Cicode or Long for variable tags (Long
needs 4 bytes).
OnTime:
The ON time of the alarm associated with the Record, that is, the time that the
alarm was activated.
AlarmSumFind() requires that the OnTime argument contains the number of sec-
onds from Midnight, so the formulation:
iOnTime = StrToTime(AlarmSumGet(iIndex, "OnTime"));
will NOT yield the correct result. The correct formulation for this calculation is:
OnTime = StrToTime(AlarmSumGet(iIndex, "OnTime")) + TimeMidnight(TimeCur-
rent());
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
Return Value
The index of the alarm summary entry, or -1 if no alarm summary entry is found.
Related Functions
AlarmSumNext, AlarmSumSet, AlarmSumDelete, AlarmSumFirst, AlarmSumNext,
AlarmSumLast, AlarmSumPrev, MsgRPC
Example
/* This function sets the summary comment from the alarm record
number and the ontime of the summary event. */
FUNCTION
SumSetComment(INT AN, STRING sComment)
INT nRecord;
INT iOnTime;
INT Index;
iOnTime=StrToDate(AlarmGetDsp(AN,"OnDate"))+StrToTime(AlarmGetDsp(AN,"On-
Time"));
nrecord=StrToInt(AlarmGetDsp(AN,"RecNo"));
Index = AlarmSumFind(nRecord, iOnTime);
IF Index<>-1 THEN
AlarmSumSet(Index,"Comment", sComment);
END
END
191
Chapter: 18 Alarm Functions
See Also
Alarm Functions
AlarmSumFirst
This command is deprecated in this version of CitectSCADA. Use the AlmSummaryFirst
command instead.
Gets the index of the oldest alarm summary entry. You can use this index in the Alarm-
SumGet() function to get field data from an alarm record, in the AlarmSumSet() function to
change the existing data in that record, or in the AlarmSumDelete() function to delete the
record.
To work with a series of alarm summary records, call this function to get the index, and
then call AlarmSumNext() within a loop, to move forwards in the alarm summary.
This function can only be used if the Alarm Server is on the current machine. When the
Alarm Server is not in the calling process, this function will become blocking and cannot be
called from a foreground task. In this case, the return value will be undefined and a Cicode
hardware alarm will be raised.
Syntax
AlarmSumFirst( [ClusterName] )
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
Return Value
The index of the oldest alarm summary entry, or -1 if no alarm summary entry is found.
Related Functions
AlarmSumGet, AlarmSumSet, AlarmSumDelete, AlarmSumNext, AlarmSumLast, Alarm-
SumPrev
Example
/* This function finds all alarm summary entries that match the
specified tag and sets the "OffTime" to the time specified. The
alarm entry is not acknowledged or set to the off state, the alarm
summary "OffTime" field is all that is affected. */
FUNCTION
SumSetTime(STRING sTag, INT Time)
INT Index;
STRING Name;
Index=AlarmSumFirst();
WHILE Index<>-1 DO
Name=AlarmSumGet(Index,"Tag");
IF Name=sTag THEN
AlarmSumSet(Index,"OffTime",Time);
END
Index=AlarmSumNext(Index);
END
END
192
Chapter: 18 Alarm Functions
See Also
Alarm Functions
AlarmSumGet
This command is deprecated in this version of CitectSCADA. Use the AlmSummaryGet-
Field command instead.
Gets field data from an alarm summary entry. The data is returned as a string. You identify
the alarm summary entry by the Index, returned by one of the alarm summary search
functions. If calling this function from a remote client, use the MsgRPC() function.
By embedding this function in a loop, you can get data from a series of alarm summary en-
tries. To start from the oldest entry, call the AlarmSumFirst() function to get the index, and
then call AlarmSumNext() in a loop. To work back from the most recent entry, call Alarm-
SumLast() and then AlarmSumPrev() in a loop.
You can also get the Index from the AlarmSumFind() function, which finds an alarm sum-
mary entry by its alarm record identifier and time of activation.
Note: Record numbers obtained from AlarmGetDsp must not be used with this function.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
Syntax
AlarmSumGet(Index, sField [, ClusterName] )
Index:
The alarm summary index (returned from the AlarmSumFirst(), AlarmSum-
Next(), AlarmSumLast(), AlarmSumPrev(), AlarmSumAppend(), or AlarmSum-
Find() function).
sField:
The name of the field from which to extract the data:
Tag Alarm tag
AckDate Alarm acknowledged date
AckTime Alarm acknowledged time
Category Alarm category
Comment Alarm comment
DeltaTime Alarm active time
Desc Alarm description
Help Help page
Name Alarm name
OffDate Alarm OFF date
OffTime Alarm OFF time
OnDate Alarm ON date
OnTime Alarm ON time
193
Chapter: 18 Alarm Functions
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
Return Value
Field data from the alarm summary entry (as a string).
Related Functions
AlarmSumSet, AlarmSumFirst, AlarmSumNext, AlarmSumLast, AlarmSumPrev, Alarm-
SumFind, MsgRPC
Example
See AlarmSumFirst
See Also
Alarm Functions
AlarmSumLast
This command is deprecated in this version of CitectSCADA. Use the AlmSummaryLast
command instead.
Gets the index of the most recent alarm summary entry. You can use this index in the
AlarmSumGet() function to get field data from an alarm record, in the AlarmSumSet()
function to change the existing data in that record, or in the AlarmSumDelete() function to
delete the record.
To work with a series of alarm summary records, call this function to get the index, and
then call AlarmSumPrev() within a loop, to move backwards in the alarm summary.
This function can only be used if the Alarm Server is on the current machine. When the
Alarm Server is not in the calling process, this function will become blocking and cannot be
called from a foreground task. In this case, the return value will be undefined and a Cicode
hardware alarm will be raised.
Syntax
AlarmSumLast( [ClusterName] )
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
Return Value
The index of the most recent alarm summary entry, or -1 if no alarm summary entry is
found.
194
Chapter: 18 Alarm Functions
Related Functions
AlarmSumGet, AlarmSumSet, AlarmSumDelete, AlarmSumPrev, AlarmSumFirst, Alarm-
SumNext
Example
/* This function finds all alarm summary entries that match the
specified tag and sets the "OffTime" to the time specified. The
alarm entry is not acknowledged or set to the off state, the alarm
summary "OffTime" field is all that is affected. */
FUNCTION
SumSetTime(STRING sTag, INT Time)
INT Index;
STRING Name;
Index=AlarmSumLast();
WHILE Index<>-1 DO
Name=AlarmSumGet(Index,"Tag");
IF Name=sTag THEN
AlarmSumSet(Index,"OffTime",Time);
END
Index=AlarmSumPrev(Index);
END
END
See Also
Alarm Functions
AlarmSumNext
This command is deprecated in this version of CitectSCADA. Use the AlmSummaryNext
command instead.
Gets the index of the next alarm summary entry, that is, the entry that occurred later than
the entry specified by Index. You can use this index in the AlarmSumGet() function to get
field data from an alarm record, in the AlarmSumSet() function to change the existing data
in that record, or in the AlarmSumDelete() function to delete the record.
You can use this function to work with a series of alarm summary records. Call the Alarm-
SumFirst() or AlarmSumFind() function to get the index, and then call AlarmSumNext()
within a loop, to move forwards in the alarm summary.
You can also get the index of an entry as soon as it displays on the alarm summary. Alarm
summary entries are recorded with the most recent entry at the end of the list. Call Alarm-
SumLast() to get the index for the most recent entry, and then call AlarmSumNext() to get
the index for the next entry that occurs.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
Syntax
AlarmSumNext(Index [, ClusterName] )
Index:
195
Chapter: 18 Alarm Functions
Return Value
The index of the next alarm summary entry or -1 if no more alarm summary entries are
found.
Related Functions
AlarmSumGet, AlarmSumSet, AlarmSumDelete, AlarmSumFirst, AlarmSumLast, Alarm-
SumPrev, AlarmSumFind
Example
See AlarmSumFirst
See Also
Alarm Functions
AlarmSumPrev
This command is deprecated in this version of CitectSCADA. Use the AlmSummaryPrev
command instead.
Gets the index of the previous alarm summary entry, that is, the entry that occurred before
the entry specified by Index. You can use this index in the AlarmSumGet() function to get
field data from an alarm record, in the AlarmSumSet() function to change the existing data
in that record, or in the AlarmSumDelete() function to delete the record.
You can use this function to work with a series of alarm summary records. Call the Alarm-
SumLast() or AlarmSumFind() function to get the index, and then call AlarmSumPrev()
within a loop, to move backwards in the alarm summary.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
Syntax
AlarmSumPrev(Index [, ClusterName] )
Index:
The alarm summary index (returned from the AlarmSumFirst(), AlarmSum-
Next(), AlarmSumLast(), AlarmSumPrev(), AlarmSumAppend(), or AlarmSum-
Find() function).
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
196
Chapter: 18 Alarm Functions
Return Value
0 (zero) if the alarm summary entry exists, otherwise an error is returned.
Related Functions
AlarmSumGet, AlarmSumSet, AlarmSumDelete, AlarmSumFirst, AlarmSumNext, Alarm-
SumLast, AlarmSumFind
Example
See AlarmSumLast.
See Also
Alarm Functions
AlarmSumSet
This command is deprecated in this version of CitectSCADA. Use the AlmSummarySet-
FieldValue command instead.
Sets field information in an alarm summary entry. You identify the alarm summary entry
by the Index, returned by one of the alarm summary search functions.
By embedding this function in a loop, you can change field data in a series of alarm sum-
mary entries. To start from the oldest entry, call the AlarmSumFirst() function to get the in-
dex, and then call AlarmSumNext() in a loop. To work back from the most recent entry, call
AlarmSumLast() and then AlarmSumPrev() in a loop.
You can also get the Index from the AlarmSumFind() function, which finds an alarm sum-
mary entry by its alarm record identifier and time of activation.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
Syntax
AlarmSumSet(Index, sField, sData [, ClusterName] )
Index:
The alarm summary index (returned from the AlarmSumFirst(), AlarmSum-
Next(), AlarmSumLast(), AlarmSumPrev(), AlarmSumAppend(), or AlarmSum-
Find() function).
sField:
The name of the field in which data is to be set:
AckTime Alarm acknowledged time
Comment Alarm comment
OffMilli Alarm millisecond off time
OffTime Alarm OFF time
OnMilli Alarm millisecond on time
OnTime Alarm ON time
State Alarm state
sData:
197
Chapter: 18 Alarm Functions
Return Value
0 (zero) if the alarm summary entry exists, otherwise an error is returned.
Related Functions
AlarmSumGet, AlarmSumFirst, AlarmSumNext, AlarmSumLast, AlarmSumPrev, Alarm-
SumFind
Example
See AlarmSumFirst
See Also
Alarm Functions
AlarmSumSplit
Duplicates the alarm summary entry identified by Index. You can use this function to add
another comment to an alarm summary entry.
When the Alarm Server is not in the calling process, this function will become blocking and
cannot be called from a foreground task. In this case, the return value will be undefined and
a Cicode hardware alarm will be raised.
To duplicate an alarm summary entry on a Control Client, use the AlarmSplit() function -
the entry at the cursor position is duplicated.
Syntax
AlarmSumSplit(Index [, ClusterName] )
Index:
The alarm summary index (returned from the AlarmSumFirst(), AlarmSum-
Next(), AlarmSumLast(), AlarmSumPrev(), AlarmSumAppend(), or AlarmSum-
Find() function).
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
Return Value
The Index of the new entry, or -1 on error.
Related Functions
AlarmSumGet, AlarmSumFirst, AlarmSumNext, AlarmSumLast, AlarmSumPrev, Alarm-
SumFind, AlarmSplit
198
Chapter: 18 Alarm Functions
Example
/* This function finds the first alarm summary entry that matches
the specified tag, splits that entry and then adds the specified
comment to the new entry. */
FUNCTION
AlarmSplitAdd(STRING Tag, STRING Comment)
INT Index;
STRING Name;
Index=AlarmSumFirst();
WHILE Index<>-1 DO
Name=AlarmSumGet(Index,"Tag");
IF Name=sTag THEN
AlarmSumSplit(Index);
Index=AlarmSumFirst();
AlarmSumSet(Index,"Comment",Comment);
Index=-1;
ELSE
Index=AlarmSumNext(Index);
END
END
END
See Also
Alarm Functions
AlarmSumType
This command is deprecated in this version of CitectSCADA. Use the AlmSummary com-
mands instead.
Retrieves a value that indicates a specified alarm’s type, that is whether it’s a digital alarm,
an analog alarm, hardware alarm, etc.
This function can only be used if the Alarm Server is on the current machine. When the
Alarm Server is not in the calling process, this function will become blocking and cannot be
called from a foreground task. In this case, the return value will be undefined and a Cicode
hardware alarm will be raised.
Syntax
AlarmSumType(Index [, ClusterName] )
Index:
The alarm summary index (returned from the AlarmSumFirst(), AlarmSum-
Next(), AlarmSumLast(), AlarmSumPrev(), AlarmSumAppend(), or AlarmSum-
Find() function).
ClusterName:
Specifies the name of the cluster in which the Alarm Server resides. This is option-
al if you have one cluster or are resolving the alarm server via the current cluster
context. The argument is enclosed in quotation marks "".
Return Value
A number that represents one of the following alarm types:
0 = digital alarm
199
Chapter: 18 Alarm Functions
1 = analog alarm
2 = advanced alarm
3 = Multi-Digital alarm
4 = Argyle analog alarm
5 = user-generated event
6 = high resolution alarm
8 = time-stamped digital alarm
9 = time-stamped analog alarm
-1 indicates an invalid response to the request.
Related Functions
AlarmSumGet, AlarmSumFirst, AlarmSumNext, AlarmSumLast, AlarmSumPrev, Alarm-
SumFind, AlarmSplit
See Also
Alarm Functions
AlmSummaryAck
The AlmSummaryAck function acknowledges the alarm at the current cursor position in
an active data browse session.
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AlmSummaryAck(iSession)
iSession:
The handle to a browse session previously returned by a AlmSummaryOpen call.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmSummaryClear, AlmSummaryClose, AlmSummaryCommit, AlmSummaryDelete,
AlmSummaryDeleteAll, AlmSummaryDisable, AlmSummaryEnable, AlmSummaryFirst,
AlmSummaryGetField, AlmSummaryLast, AlmSummaryNext, AlmSummaryOpen, Alm-
SummaryPrev, AlmSummarySetFieldValue
See Also
Alarm Functions
AlmSummaryClear
The AlmSummaryClear function clears the alarm at the current cursor position in an active
data browse session.
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AlmSummaryClear(iSession)
200
Chapter: 18 Alarm Functions
iSession:
The handle to a browse session previously returned by a AlmSummaryOpen call.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmSummaryAck, AlmSummaryClose, AlmSummaryCommit, AlmSummaryDelete,
AlmSummaryDeleteAll, AlmSummaryDisable, AlmSummaryEnable, AlmSummaryFirst,
AlmSummaryGetField, AlmSummaryLast, AlmSummaryNext, AlmSummaryOpen, Alm-
SummaryPrev, AlmSummarySetFieldValue
See Also
Alarm Functions
AlmSummaryClose
The AlmSummaryClose function terminates an active data browse session and cleans up
all resources associated with the session.
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AlmSummaryClose(iSession)
iSession:
The handle to a browse session previously returned by a AlmSummaryOpen call.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmSummaryAck, AlmSummaryClear, AlmSummaryCommit, AlmSummaryDelete,
AlmSummaryDeleteAll, AlmSummaryDisable, AlmSummaryEnable, AlmSummaryFirst,
AlmSummaryGetField, AlmSummaryLast, AlmSummaryNext, AlmSummaryOpen, Alm-
SummaryPrev, AlmSummarySetFieldValue
See Also
Alarm Functions
AlmSummaryCommit
The AlmSummaryCommit function triggers the actual write of the value for the field pre-
viously specified by AlmSummarySetFieldValue.
This function is a blocking function. It blocks the calling Cicode task until the operation is
complete.
Syntax
AlmSummaryCommit(iSession)
iSession:
201
Chapter: 18 Alarm Functions
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmSummaryAck, AlmSummaryClear, AlmSummaryClose, AlmSummaryDelete, Alm-
SummaryDeleteAll, AlmSummaryDisable, AlmSummaryEnable, AlmSummaryFirst,
AlmSummaryGetField, AlmSummaryLast, AlmSummaryNext, AlmSummaryOpen, Alm-
SummaryPrev, AlmSummarySetFieldValue
Example
INT errorCode = 0;
...
errorCode = AlmSummaryCommit(iSession);
IF errorCode = 0 THEN
// Successful case
ELSE
// Function returned an error
END
...
See Also
Alarm Functions
AlmSummaryDelete
The AlmSummaryDelete function deletes the record that the browse cursor is currently ref-
erencing.
This function is a blocking function. It blocks the calling Cicode task until the operation is
complete.
Syntax
AlmSummaryDelete(iSession)
iSession:
The handle to a browse session previously returned by a AlmSummaryOpen call.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmSummaryAck, AlmSummaryClear, AlmSummaryClose, AlmSummaryCommit, Alm-
SummaryDeleteAll, AlmSummaryDisable, AlmSummaryEnable, AlmSummaryFirst,
AlmSummaryGetField, AlmSummaryLast, AlmSummaryNext, AlmSummaryOpen, Alm-
SummaryPrev, AlmSummarySetFieldValue
202
Chapter: 18 Alarm Functions
Example
INT errorCode = 0;
...
errorCode = AlmSummaryDelete(iSession);
IF errorCode = 0 THEN
// Successful case
ELSE
// Function returned an error
END
...
See Also
Alarm Functions
AlmSummaryDeleteAll
The AlmSummaryDeleteAll function deletes all of the records from the data browse source.
This function is a blocking function. It blocks the calling Cicode task until the operation is
complete.
Syntax
AlmSummaryDeleteAll(iSession)
iSession:
The handle to a browse session previously returned by a AlmSummaryOpen call.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmSummaryAck, AlmSummaryClear, AlmSummaryClose, AlmSummaryCommit, Alm-
SummaryDelete, AlmSummaryDisable, AlmSummaryEnable, AlmSummaryFirst, Alm-
SummaryGetField, AlmSummaryLast, AlmSummaryNext, AlmSummaryOpen,
AlmSummaryPrev, AlmSummarySetFieldValue
Example
INT errorCode = 0;
...
errorCode = AlmSummaryDeleteAll(iSession);
IF errorCode = 0 THEN
// Successful case
ELSE
// Function returned an error
END
...
See Also
Alarm Functions
203
Chapter: 18 Alarm Functions
AlmSummaryDisable
The AlmSummaryDisable function disables the alarm at the current cursor position in an
active data browse session.
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AlmSummaryDisable(iSession)
iSession:
The handle to a browse session previously returned by a AlmSummaryOpen call.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmSummaryAck, AlmSummaryClear, AlmSummaryClose, AlmSummaryCommit, Alm-
SummaryDelete, AlmSummaryDeleteAll, AlmSummaryEnable, AlmSummaryFirst, Alm-
SummaryGetField, AlmSummaryLast, AlmSummaryNext, AlmSummaryOpen,
AlmSummaryPrev, AlmSummarySetFieldValue
See Also
Alarm Functions
AlmSummaryEnable
The AlmSummaryEnable function enables the alarm at the current cursor position in an ac-
tive data browse session.
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AlmSummaryEnable(iSession)
iSession:
The handle to a browse session previously returned by a AlmSummaryOpen call.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmSummaryAck, AlmSummaryClear, AlmSummaryClose, AlmSummaryCommit, Alm-
SummaryDelete, AlmSummaryDeleteAll, AlmSummaryDisable, AlmSummaryFirst, Alm-
SummaryGetField, AlmSummaryLast, AlmSummaryNext, AlmSummaryOpen,
AlmSummaryPrev, AlmSummarySetFieldValue
See Also
Alarm Functions
AlmSummaryFirst
204
Chapter: 18 Alarm Functions
The AlmSummaryFirst function places the data browse cursor at the first record.
This function is a blocking function. It blocks the calling Cicode task until the operation is
complete.
Syntax
AlmSummaryFirst(iSession)
iSession:
The handle to a browse session previously returned by a AlmSummaryOpen call.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmSummaryAck, AlmSummaryClear, AlmSummaryClose, AlmSummaryCommit, Alm-
SummaryDelete, AlmSummaryDeleteAll, AlmSummaryDisable, AlmSummaryEnable,
AlmSummaryGetField, AlmSummaryLast, AlmSummaryNext, AlmSummaryOpen, Alm-
SummaryPrev, AlmSummarySetFieldValue
See Also
Alarm Functions
AlmSummaryGetField
The AlmSummaryGetField function retrieves the value of the specified field from the
record the data browse cursor is currently referencing.
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AlmSummaryGetField(iSession, sFieldName)
iSession:
The handle to a browse session previously returned by a AlmSummaryOpen call.
sFieldName:
The name of the field that references the value to be returned. Supported fields
are:
CUSTOM1, CUSTOM2, CUSTOM3, CUSTOM4, CUSTOM5, CUSTOM6,
CUSTOM7, CUSTOM8, DATEEXT, ERRDESC, ERRPAGE, FORMAT,
GROUP, LOCALTIMEDATE, LOGSTATE, NATIVE_DESC,
NATIVE_NAME, NODE, OFFTIMEDATE, ONTIMEDATE, ORATO-
DATE, ORATOOFFDATE, ORATOONDATE, PRIV, SUMTYPE, TAGEX,
TIMEDATE, TYPE, TYPENUM.
See Browse Function Field Reference for information about fields.
Return Value
The value of the specified field as a string. An empty string may or may not be an indication
that an error has been detected. The last error should be checked in this instance to deter-
mine if an error has actually occurred.
205
Chapter: 18 Alarm Functions
Related Functions
AlmSummaryAck, AlmSummaryClear, AlmSummaryClose, AlmSummaryCommit, Alm-
SummaryDelete, AlmSummaryDeleteAll, AlmSummaryDisable, AlmSummaryEnable,
AlmSummaryFirst, AlmSummaryLast, AlmSummaryNext, AlmSummaryOpen, AlmSum-
maryPrev, AlmSummarySetFieldValue
Example
STRING fieldValue = "";
STRING fieldName = "TYPE";
INT errorCode = 0;
...
fieldValue = AlmSummaryGetField(iSession, sFieldName);
IF fieldValue <> "" THEN
// Successful case
ELSE
// Function returned an error
END
...
See Also
Alarm Functions
AlmSummaryLast
The AlmSummaryLast function places the data browse cursor at the most recent summary
record from the last cluster of the available browsing cluster list.
This function is a blocking function. It blocks the calling Cicode task until the operation is
complete.
Syntax
AlmSummaryLast(iSession)
iSession:
The handle to a browse session previously returned by a AlmSummaryOpen call.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmSummaryAck, AlmSummaryClear, AlmSummaryClose, AlmSummaryCommit, Alm-
SummaryDelete, AlmSummaryDeleteAll, AlmSummaryDisable, AlmSummaryEnable,
AlmSummaryFirst, AlmSummaryGetField, AlmSummaryNext, AlmSummaryOpen, Alm-
SummaryPrev, AlmSummarySetFieldValue
See Also
Alarm Functions
AlmSummaryNext
206
Chapter: 18 Alarm Functions
The AlmSummaryNext function moves the data browse cursor forward one record. If you
call this function after you have reached the end of a summary, error 412 is
returned (Databrowse session EOF).
This function is a blocking function. It blocks the calling Cicode task until the operation is
complete.
Syntax
AlmSummaryNext(iSession)
iSession:
The handle to a browse session previously returned by a AlmSummaryOpen call.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmSummaryAck, AlmSummaryClear, AlmSummaryClose, AlmSummaryCommit, Alm-
SummaryDelete, AlmSummaryDeleteAll, AlmSummaryDisable, AlmSummaryEnable,
AlmSummaryFirst, AlmSummaryGetField, AlmSummaryLast, AlmSummaryOpen, Alm-
SummaryPrev, AlmSummarySetFieldValue
See Also
Alarm Functions
AlmSummaryOpen
The AlmSummaryOpen function initiates a new browse session and returns a handle to the
new session that can be used in subsequent data browse function calls.
This function is a blocking function. It blocks the calling Cicode task until the operation is
complete.
Syntax
AlmSummaryOpen( [sFilter] [, sFields] [, sClusters] )
sFilter:
A filter expression specifying the records to return during the browse. An empty
string indicates that all records will be returned. Where a fieldname is not speci-
fied in the filter, it is assumed to be tagname. For example, the filter "AAA" is
equivalent to "TAG=AAA".
sFields:
Specifies via a comma delimited string the columns to be returned during the
browse. An empty string indicates that the server will return all available col-
umns. Supported fields are:
ACKDATE, ACKDATEEXT, ACKTIME, ALARMTYPE, ALMCOMMENT, AR-
EA, CATEGORY, CLUSTER, COMMENT, CUSTOM1, CUSTOM2,
CUSTOM3, CUSTOM4, CUSTOM5, CUSTOM6, CUSTOM7, CUSTOM8,
DATE, DATEEXT, DEADBAND, DELTATIME, DESC, DEVIATION, ER-
RDESC, ERRPAGE, FORMAT, FULLNAME, GROUP, HELP, HIGH,
HIGHHIGH, LOCALTIMEDATE, LOGSTATE, LOW, LOWLOW, MIL-
207
Chapter: 18 Alarm Functions
Return Value
Returns an integer handle to the browse session. Returns -1 on error.
Related Functions
AlmSummaryAck, AlmSummaryClear, AlmSummaryClose, AlmSummaryCommit, Alm-
SummaryDelete, AlmSummaryDeleteAll, AlmSummaryDisable, AlmSummaryEnable,
AlmSummaryFirst, AlmSummaryGetField, AlmSummaryLast, AlmSummaryNext, Alm-
SummaryPrev, AlmSummarySetFieldValue
Example
INT iSession;
...
iSession = AlmSummaryOpen("NAME=ABC*", "NAME,TYPE",
"ClusterA,ClusterB");
IF iSession <> -1 THEN
// Successful case
ELSE
// Function returned an error
END
...
See Also
Alarm Functions
AlmSummaryPrev
The AlmSummaryPrev function moves the data browse cursor back one record. If you call
this function after you have reached the beginning of a summary, error 412 is
returned (Databrowse session EOF).
This function is a blocking function. It blocks the calling Cicode task until the operation is
complete.
208
Chapter: 18 Alarm Functions
Syntax
AlmSummaryPrev(iSession)
iSession:
The handle to a browse session previously returned by a AlmSummaryOpen call.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmSummaryAck, AlmSummaryClear, AlmSummaryClose, AlmSummaryCommit, Alm-
SummaryDelete, AlmSummaryDeleteAll, AlmSummaryDisable, AlmSummaryEnable,
AlmSummaryFirst, AlmSummaryGetField, AlmSummaryLast, AlmSummaryNext, Alm-
SummaryOpen, AlmSummarySetFieldValue
See Also
Alarm Functions
AlmSummarySetFieldValue
The AlmSummarySetFieldValue function sets a new value for the specified field for the
record the data browse cursor is currently referencing. The value is not committed until a
call to AlmSummaryCommit is made.
This function is a blocking function. It blocks the calling Cicode task until the operation is
complete.
Syntax
AlmSummarySetFieldValue(iSession, sFieldname, sFieldValue)
iSession:
The handle to a browse session previously returned by a AlmSummaryOpen call.
sFieldName:
The name of the field whose value is to be updated. Supported fields are:
ACKTIME, COMMENT, OFFMILLI, OFFTIME, ONMILLI, ONTIME.
See Browse Function Field Reference for information about fields.
sFieldValue:
The field value to update.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmSummaryAck, AlmSummaryClear, AlmSummaryClose, AlmSummaryCommit, Alm-
SummaryDelete, AlmSummaryDeleteAll, AlmSummaryDisable, AlmSummaryEnable,
AlmSummaryFirst, AlmSummaryGetField, AlmSummaryLast, AlmSummaryNext, Alm-
SummaryOpen, AlmSummaryPrev
209
Chapter: 18 Alarm Functions
Example
STRING sFieldValue = "NEW_COMMENT";
STRING sFieldName = "COMMENT";
INT errorCode = 0;
...
errorCode = AlmSummarySetFieldValue(iSession, sFieldname,
sFieldValue);
IF errorCode = 0 THEN
// Successful case
ELSE
// Function returned an error
END
...
See Also
Alarm Functions
AlmTagsAck
The AlmTagsAck function acknowledges the alarm tag at the current cursor position in an
active data browse session.
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AlmTagsAck(iSession)
iSession:
The handle to a browse session previously returned by a AlmTagsOpen call.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmTagsClear, AlmTagsDisable, AlmTagsEnable, AlmTagsClose, AlmTagsFirst,
AlmTagsGetField, AlmTagsNext, AlmTagsNumRecords, AlmTagsOpen, AlmTagsPrev
See Also
Alarm Functions
AlmTagsClear
The AlmTagsClear function clears the alarm tag at the current cursor position in an active
data browse session.
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AlmTagsClear(iSession)
iSession:
The handle to a browse session previously returned by a AlmTagsOpen call.
210
Chapter: 18 Alarm Functions
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmTagsAck, AlmTagsDisable, AlmTagsEnable, AlmTagsClose, AlmTagsFirst, AlmTags-
GetField, AlmTagsNext, AlmTagsNumRecords, AlmTagsOpen, AlmTagsPrev
See Also
Alarm Functions
AlmTagsClose
The AlmTagsClose function terminates an active data browse session and cleans up all re-
sources associated with the session.
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AlmTagsClose(iSession)
iSession:
The handle to a browse session previously returned by a AlmTagsOpen call.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmTagsAck, AlmTagsClear, AlmTagsDisable, AlmTagsEnable, AlmTagsFirst, AlmTags-
GetField, AlmTagsNext, AlmTagsNumRecords, AlmTagsOpen, AlmTagsPrev
See Also
Alarm Functions
AlmTagsDisable
The AlmTagsDisable function disables the alarm tag at the current cursor position in an ac-
tive data browse session.
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AlmTagsDisable(iSession)
iSession:
The handle to a browse session previously returned by a AlmTagsOpen call.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
211
Chapter: 18 Alarm Functions
Related Functions
AlmTagsAck, AlmTagsClear, AlmTagsEnable, AlmTagsClose, AlmTagsFirst, AlmTags-
GetField, AlmTagsNext, AlmTagsNumRecords, AlmTagsOpen, AlmTagsPrev
See Also
Alarm Functions
AlmTagsEnable
The AlmTagsEnable function enables the alarm tag at the current cursor position in an ac-
tive data browse session.
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AlmTagsEnable(iSession)
iSession:
The handle to a browse session previously returned by a AlmTagsOpen call.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmTagsAck, AlmTagsClear, AlmTagsDisable, AlmTagsClose, AlmTagsFirst, AlmTags-
GetField, AlmTagsNext, AlmTagsNumRecords, AlmTagsOpen, AlmTagsPrev
See Also
Alarm Functions
AlmTagsFirst
The AlmTagsFirst function places the data browse cursor at the first record.
This function is a blocking function. It blocks the calling Cicode task until the operation is
complete.
Syntax
AlmTagsFirst(iSession)
iSession:
The handle to a browse session previously returned by a AlmTagsOpen call.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmTagsAck, AlmTagsClear, AlmTagsDisable, AlmTagsEnable, AlmTagsClose,
AlmTagsGetField, AlmTagsNext, AlmTagsNumRecords, AlmTagsOpen, AlmTagsPrev
212
Chapter: 18 Alarm Functions
See Also
Alarm Functions
AlmTagsGetField
The AlmTagsGetField function retrieves the value of the specified field from the record the
data browse cursor is currently referencing.
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AlmTagsGetField(iSession, sFieldName)
iSession:
The handle to a browse session previously returned by a AlmTagsOpen call.
sFieldName:
The name of the field that references the value to be returned. Supported fields
are:
CUSTOM1, CUSTOM2, CUSTOM3, CUSTOM4, CUSTOM5, CUSTOM6,
CUSTOM7, CUSTOM8, DATEEXT, ERRDESC, ERRPAGE, FORMAT,
GROUP, LOCALTIMEDATE, LOGSTATE, NATIVE_DESC,
NATIVE_NAME, NODE, OFFTIMEDATE, ONTIMEDATE, ORATO-
DATE, ORATOOFFDATE, ORATOONDATE, PRIV, SUMTYPE, TAGEX,
TIMEDATE, TYPE, TYPENUM.
See Browse Function Field Reference for information about fields.
Return Value
The value of the specified field as a string. An empty string may or may not be an indication
that an error has been detected. The last error should be checked in this instance to deter-
mine if an error has actually occurred.
Related Functions
AlmTagsAck, AlmTagsClear, AlmTagsDisable, AlmTagsEnable, AlmTagsClose,
AlmTagsFirst, AlmTagsNext, AlmTagsNumRecords, AlmTagsOpen, AlmTagsPrev
Example
STRING fieldValue = "";
STRING fieldName = "TYPE";
INT errorCode = 0;
...
fieldValue = AlmTagsGetField(iSession, sFieldName);
IF fieldValue <> "" THEN
// Successful case
ELSE
// Function returned an error
END
...
See Also
Alarm Functions
213
Chapter: 18 Alarm Functions
AlmTagsNext
The AlmTagsNext function moves the data browse cursor forward one record. If you call
this function after you have reached the end of the records, error 412 is returned
(Databrowse session EOF).
This function is a blocking function. It blocks the calling Cicode task until the operation is
complete.
Syntax
AlmTagsNext(iSession)
iSession:
The handle to a browse session previously returned by a AlmTagsOpen call.
Return Value
0 (zero) if the browse has successfully been moved to the next record, otherwise an error is
returned.
Related Functions
AlmTagsAck, AlmTagsClear, AlmTagsDisable, AlmTagsEnable, AlmTagsClose,
AlmTagsFirst, AlmTagsGetField, AlmTagsNumRecords, AlmTagsOpen, AlmTagsPrev
See Also
Alarm Functions
AlmTagsNumRecords
The AlmTagsNumRecords function returns the number of records that match the filter cri-
teria.
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AlmTagsNumRecords(iSession)
iSession:
The handle to a browse session previously returned by a AlmTagsOpen call.
Return Value
The number of records that have matched the filter criteria. A value of 0 denotes that no
records have matched. A value of -1 denotes that the browse session is unable to provide a
fixed number. This may be the case if the data being browsed changed during the browse
session.
Related Functions
AlmTagsAck, AlmTagsClear, AlmTagsDisable, AlmTagsEnable, AlmTagsClose,
AlmTagsFirst, AlmTagsGetField, AlmTagsNext, AlmTagsOpen, AlmTagsPrev
Example
INT numRecords = 0;
...
214
Chapter: 18 Alarm Functions
numRecords = AlmTagsNumRecords(iSession);
IF numRecords <> 0 THEN
// Have records
ELSE
// No records
END
...
See Also
Alarm Functions
AlmTagsOpen
The AlmTagsOpen function initiates a new browse session and returns a handle to the new
session that can be used in subsequent data browse function calls.
This function is a blocking function. It blocks the calling Cicode task until the operation is
complete.
Syntax
AlmTagsOpen( [sFilter] [, sFields] [, sClusters] )
sFilter:
A filter expression specifying the records to return during the browse. An empty
string indicates that all records will be returned. Where a fieldname is not speci-
fied in the filter, it is assumed to be tagname. For example, the filter "AAA" is
equivalent to "name=AAA".
sFields:
Specifies via a comma delimited string the columns to be returned during the
browse. An empty string indicates that the server will return all available col-
umns. Supported fields are:
ACKDATE, ACKDATEEXT, ACKTIME, ALARMTYPE, ALMCOMMENT, AR-
EA, CATEGORY, CLUSTER, COMMENT, CUSTOM1, CUSTOM2,
CUSTOM3, CUSTOM4, CUSTOM5, CUSTOM6, CUSTOM7, CUSTOM8,
DATE, DATEEXT, DEADBAND, DELTATIME, DESC, DEVIATION, ER-
RDESC, ERRPAGE, FORMAT, FULLNAME, GROUP, HELP, HIGH,
HIGHHIGH, LOCALTIMEDATE, LOGSTATE, LOW, LOWLOW, MIL-
LISEC, NAME, NATIVE_COMMENT, NATIVE_DESC, NATIVE_NAME,
NATIVE_SUMDESC, NODE, OFFDATE, OFFDATEEXT, OFFMILLI,
OFFTIME, OFFTIMEDATE, OLD_DESC, ONDATE, ONDATEEXT, ON-
MILLI, ONTIME, ONTIMEDATE, ORATODATE, ORATOOFFDATE, OR-
ATOONDATE, PAGING, PAGINGGROUP, PRIORITY, PRIV, RATE,
STATE, STATE_DESC, STATE_DESC0, STATE_DESC1, STATE_DESC2,
STATE_DESC3, STATE_DESC4, STATE_DESC5, STATE_DESC6,
STATE_DESC7, SUMDESC, SUMSTATE, SUMTYPE, TAG, TAGEX,
TIME, TIMEDATE, TYPE, TYPENUM, USERDESC, USERNAME, VAL-
UE.
See Browse Function Field Reference for information about fields.
sClusters:
215
Chapter: 18 Alarm Functions
An optional parameter that specifies via a comma delimited string the subset of
the clusters to browse. An empty string indicates that all connected clusters will
be browsed.
Return Value
Returns an integer handle to the browse session. Returns -1 when an error is detected.
Related Functions
AlmTagsAck, AlmTagsClear, AlmTagsDisable, AlmTagsEnable, AlmTagsClose,
AlmTagsFirst, AlmTagsGetField, AlmTagsNext, AlmTagsNumRecords, AlmTagsPrev
Example
INT iSession;
...
iSession = AlmTagsOpen("NAME=ABC*", "NAME,TYPE",
"ClusterA,ClusterB");
IF iSession <> -1 THEN
// Successful case
ELSE
// Function returned an error
END
...
See Also
Alarm Functions
AlmTagsPrev
The AlmTagsPrev function moves the data browse cursor back one record. If you call this
function after you have reached the beginning of the records, error 412 is
returned (Databrowse session EOF).
This function is a non-blocking function. It does not block the calling Cicode task.
Syntax
AlmTagsPrev(iSession)
iSession:
The handle to a browse session previously returned by a AlmTagsOpen call.
Return Value
0 (zero) if the alarm browse session exists, otherwise an error is returned.
Related Functions
AlmTagsAck, AlmTagsClear, AlmTagsDisable, AlmTagsEnable, AlmTagsClose,
AlmTagsFirst, AlmTagsGetField, AlmTagsNext, AlmTagsNumRecords, AlmTagsOpen
See Also
Alarm Functions
216
Chapter: 18 Alarm Functions
QueryFunction
The user-defined query function set in AlarmSetQuery. Called for each active alarm, the
query function can be written to display an alarm based on specific information (for exam-
ple, OnDate). To examine the information in an alarm field, call the function AlarmGetFiel-
dRec from within your query function.
Note: The function name "QueryFunction" can be any valid Cicode function name specified
by the user.
Syntax
QueryFunction(nRID, nVer [, Arg01, Arg02, ....] )
nRID:
The record number of the alarm currently being filtered. This provides the query
function with access to information about the alarm. This parameter is represent-
ed with an INT, and must be the first parameter of your query function.
nVer:
The version of an alarm.
If an alarm is triggered more than once in a given period, the version lets you dis-
tinguish between different instances of the alarm’s activity.
Since you may wish to display on a page alarms which have more than one in-
stance, this parameter must be passed to AlarmGetFieldRec in order to correctly
filter the alarms.
The version is represented with an INT, and must be the second parameter of
your query function.
Arg01, Arg02:
A list of arguments, separated by commas.
The query function is passed the arguments specified in the call to AlarmSetQue-
ry(). For this reason, the arguments listed in AlarmSetQuery() must be of the
same type as those defined in the query function.
Return Value
The return value must be defined as an INT with a value of either 1 (TRUE) or 0 (FALSE).
If the function returns a value of TRUE, the alarm being filtered is displayed, otherwise it
is excluded from the alarms list.
Related Functions
AlarmSetQuery, AlarmGetFieldRec, AlarmSetInfo
Example
! The query function AlarmQueryDate() compares sDate with the
OnDate of each alarm.AlarmGetFieldRec() is used to check the
contents of the "OnDate" field for each alarm.
! If they are the same, the alarm is displayed.
INT
FUNCTION
AlarmQueryDate(INT nRID, INT nVer, STRING sDate)
INT bResult;
IF sDATE = AlarmGetFieldRec(nRID, "OnDate", nVer) THEN
bResult = TRUE;
ELSE
217
Chapter: 18 Alarm Functions
bResult = FALSE;
END
RETURN bResult;
END
See Also
Alarm Functions
218
Chapter: 19 Clipboard Functions
With the Clipboard functions, you can copy data to, and paste data from, the Windows
Clipboard.
Clipboard Functions
Following are functions relating to the Windows clipboard:
ClipCopy Copies a string to the Windows clipboard.
ClipPaste Pastes a string from the Windows clipboard.
ClipReadLn Reads a line of text from the Windows clipboard.
ClipSetMode Sets the format of data sent to the Windows clipboard.
ClipWriteLn Writes a line of text to the Windows clipboard.
See Also
Functions Reference
ClipCopy
Copies a string to the Windows clipboard. When the string is in the clipboard, you can
paste it to any Windows program.
Syntax
ClipCopy(sText)
sText:
The string to copy to the clipboard.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
ClipWriteLn
Example
ClipCopy("put this in clipboard");
See Also
Clipboard Functions
ClipPaste
Pastes a string from the Windows clipboard.
219
Chapter: 19 Clipboard Functions
Syntax
ClipPaste()
Return Value
The contents of the clipboard (as a string). If the clipboard is empty, an empty string is re-
turned.
Related Functions
ClipReadLn
Example
/* Get string from clipboard into sText. */
sText = ClipPaste();
See Also
Clipboard Functions
ClipReadLn
Reads a single line of text from the Windows clipboard. With this function, you can read a
block of text from the clipboard - line by line. Call the function once to read each line of text
from the clipboard. When the end of the clipboard is reached, an empty string is returned.
Syntax
ClipReadLn()
Return Value
One line of text from the clipboard (as a string). If the clipboard is empty, an empty string
is returned.
Related Functions
ClipPaste
Example
/* Get first line of text from clipboard. */
sText = ClipReadLn();
WHILE StrLength(sText) > 0 DO
! Do something with text
...
! Read next line of clipboard
sText = ClipReadLn();
END
See Also
Clipboard Functions
220
Chapter: 19 Clipboard Functions
ClipSetMode
Sets the format of data sent to the Windows clipboard.
Syntax
ClipSetMode(nMode)
nMode:
The mode of the data:
1 - ASCII Text
2 - CSV (Comma separated values) format
You can select multiple modes by adding modes together.
Return Value
The value of the previous mode.
Related Functions
ClipCopy, ClipWriteLn
Example
/* Set the clipboard to CSV mode, write two values, and reset the
clipboard to the original mode. */
nOldMode = ClipSetMode(2);
ClipCopy("100,200");
ClipSetMode(nOldMode);
See Also
Clipboard Functions
ClipWriteLn
Writes a line of text to the Windows clipboard. With this function, you can write any
amount of text to the clipboard. Call this function once for each line of text. To terminate
the block of text, call this function and pass an empty string.
Syntax
ClipWriteLn(sText)
sText:
The line of text to write to the clipboard, or an empty string ("") to end the write
operation.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
ClipCopy
221
Chapter: 19 Clipboard Functions
Example
ClipWriteLn("first line of text");
ClipWriteLn("second line of text");
ClipWriteLn(""); ! End of write operation
See Also
Clipboard Functions
222
Chapter: 20 Cluster Functions
This section describes functions for manipulating clusters, checking their status, getting in-
formation, activating and deactivating them.
Cluster Functions
Following are functions relating to clusters:
ClusterActivate Allows the user to activate an inactive cluster.
ClusterDeactivate Allows the user to deactivate an active cluster.
ClusterFirst Allows the user to retrieve the first configured cluster in the
project.
ClusterGetName Returns the names of the primary and standby cluster serv-
ers.
ClusterIsActive Allows the user to determine if a cluster is active.
ClusterNext Allows the user to retrieve the next configured cluster in the
project.
ClusterSetName Connects to a specific cluster server.
ClusterServerTypes Allows the user to determine which servers are defined for a
given cluster.
ClusterStatus Allows the user to determine the connection status from the
client to a server on a cluster.
ClusterSwapActive Allows the user to deactivate an active cluster at the same
time as activating a deactive cluster.
See Also
Functions Reference
ClusterActivate
This function allows the user to activate an inactive cluster. When a cluster is made active,
all data associated with that cluster is available to the client, and hardware alarms will oc-
cur if no connections can be made to the servers in the cluster.
Syntax
ClusterActivate(ClusterName)
ClusterName:
The name of the cluster to activate enclosed in quotation marks "".
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
ClusterDeactivate, ClusterFirst, ClusterGetName, ClusterIsActive, ClusterNext, Clus-
terServerTypes, ClusterSetName, ClusterStatus, ClusterSwapActive, TaskCluster
223
Chapter: 20 Cluster Functions
See Also
Cluster Functions
"About cluster context" in the CitectSCADA User Guide
ClusterDeactivate
This function allows the user to deactivate an active cluster. When a cluster is made inac-
tive, no data associated with that cluster is available to the client, and hardware alarms will
not occur if no connections can be made to the servers in the cluster.
Syntax
ClusterDeactivate(ClusterName)
ClusterName:
The name of the cluster to deactivate enclosed in quotation marks "".
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
ClusterActivate, ClusterFirst, ClusterGetName, ClusterIsActive, ClusterNext, ClusterServ-
erTypes, ClusterSetName, ClusterStatus, ClusterSwapActive, TaskCluster
See Also
Cluster Functions
"About cluster context" in the CitectSCADA User Guide
ClusterFirst
This function allows the user to retrieve the first configured cluster in the project.
Syntax
ClusterFirst()
Return Value
The name of the first configured cluster.
Related Functions
ClusterActivate, ClusterDeactivate, ClusterGetName, ClusterIsActive, ClusterNext, Clus-
terServerTypes, ClusterSetName, ClusterStatus, ClusterSwapActive, TaskCluster
See Also
Cluster Functions
"About cluster context" in the CitectSCADA User Guide
ClusterGetName
ClusterGetName is deprecated in this version of CitectSCADA.
224
Chapter: 20 Cluster Functions
Syntax
ClusterGetName(sPrimary, sStandby, nMode)
sPrimary:
The variable containing the name of the cluster’s primary server (that is that
which was set as sPrimary using the ClusterSetName() function).
sStandby:
The variable containing the name of the cluster’s standby server (that is that
which was set as sStandby using the ClusterSetName() function).
nMode:
The mode is for future expansion of the function - set to 0 (zero).
Return Value
The status of the get name.
Related Functions
ClusterActivate, ClusterDeactivate, ClusterFirst, ClusterIsActive, ClusterNext, Clus-
terServerTypes, ClusterSetName, ClusterStatus, ClusterSwapActive, TaskCluster
Example
// Return and display the server names.//
ClusterGetName(sPrimary, sStandby, 0);
Prompt("Name of Cluster" + sPrimary);
See Also
Cluster Functions
"About cluster context" in the CitectSCADA User Guide
ClusterIsActive
This function allows the user to determine if a cluster is active.
Syntax
ClusterIsActive(ClusterName)
ClusterName:
The name of the cluster to query enclosed in quotation marks "".
Return Value
TRUE if active, FALSE otherwise. If the cluster name was invalid, this function will return
FALSE and a hardware alarm will be generated.
Related Functions
ClusterActivate, ClusterDeactivate, ClusterFirst, ClusterGetName, ClusterNext, Clus-
terServerTypes, ClusterSetName, ClusterStatus, ClusterSwapActive, TaskCluster
225
Chapter: 20 Cluster Functions
See Also
Cluster Functions
"About cluster context" in the CitectSCADA User Guide
ClusterNext
This function allows the user to retrieve the next configured cluster in the project.
Syntax
ClusterNext(ClusterName)
ClusterName:
Any configured cluster name enclosed in quotation marks "", this will usually be
the name of the previous cluster as returned from ClusterFirst, or a previous call
to ClusterNext.
Return Value
The name of the next configured cluster or an empty string if there is no more clusters.
Related Functions
ClusterActivate, ClusterDeactivate, ClusterFirst, ClusterGetName, ClusterIsActive, Clus-
terServerTypes, ClusterSetName, ClusterStatus, ClusterSwapActive, TaskCluster
See Also
Cluster Functions
"About cluster context" in the CitectSCADA User Guide
ClusterServerTypes
This function allows the user to determine which servers are defined for a given cluster.
Syntax
ClusterServerTypes(ClusterName)
ClusterName:
The name of the cluster to query enclosed in quotation marks "".
Return Value
Logical OR of the following server flags:
0001 - 1st bit set means an Alarm Server is configured
0010 - 2nd bit set means a Trend Server is configured
0100 - 3rd bit set means a Report Server is configured
1000 - 4th bit set means an IO Server is configured
For example, a return value of 14 indicates an IO Server, a Report Server, and a Trend Serv-
er are configured.
Related Functions
ClusterActivate, ClusterDeactivate, ClusterFirst, ClusterGetName, ClusterIsActive, Clus-
terNext, ClusterSetName, ClusterStatus, ClusterSwapActive, TaskCluster
226
Chapter: 20 Cluster Functions
See Also
Cluster Functions
"About cluster context" in the CitectSCADA User Guide
ClusterSetName
ClusterSetName is deprecated in this version of CitectSCADA.
Syntax
ClusterSetName(sPrimary, sStandby, nMode)
sPrimary:
The name of the cluster’s primary server (Reports Server, Alarms Server etc.), as
defined using the Computer Setup Wizard. When the ClusterSetName() function
is used, CitectSCADA will attempt to connect to this server.
sStandby:
The name of the cluster’s standby server (Reports Server, Alarms Server etc.), as
defined using the Computer Setup Wizard. If the sPrimary server is unavailable
when the ClusterSetName() function is used, CitectSCADA will attempt to con-
nect to this server.
If there is no standby server, enter an empty string for sStandby.
nMode:
The mode of the connection:
0 - If you select this mode, CitectSCADA will renew the last connection. If it was
connected to the sPrimary server, when this function was last used, it will
attempt to connect to it again. If it was last connected to the sStandby serv-
er, it will attempt to connect to it again.
This mode is useful when a server is known to be unavailable, as it facilitates fast-
er cluster switching.
1 - CitectSCADA will attempt to connect to the sPrimary server first, each time
this function is used. If the sPrimary server is unavailable, CitectSCADA
will try the sStandby server.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
ClusterActivate, ClusterDeactivate, ClusterFirst, ClusterGetName, ClusterIsActive, Clus-
terNext, ClusterServerTypes, ClusterStatus, ClusterSwapActive, TaskCluster
Example
// Connect to Cluster A, with server CITECTA1 as primary server,
and CITECTA2 as standby.//
ClusterSetName("CITECTA1", "CITECTA2", 0);
// Display the menu page for Cluster A Project.//
PageDisplay("MenuA");
227
Chapter: 20 Cluster Functions
See Also
Cluster Functions
"About cluster context" in the CitectSCADA User Guide
ClusterStatus
This function allows the user to determine the connection status from the client to a server
on a cluster.
Syntax
ClusterStatus(clusterName, serverType)
clusterName:
The name of the cluster to query enclosed in quotation marks "".
serverType:
The type of server (not a bit mask):
1 - Alarm Server
2 - Trend Server
4 - Report Server
8 - IO Server
Return Value
One of the following values:
-1 - if the cluster does not contain a server of the given type.
-2 - if the cluster does not exist"
0 - if the cluster contains the server but the cluster is inactive.
1 - if the cluster is active but the connection to the server is offline.
2 - if the cluster is active and the connection to the server is online.
Related Functions
ClusterActivate, ClusterDeactivate, ClusterFirst, ClusterGetName, ClusterIsActive, Clus-
terNext, ClusterServerTypes, ClusterSetName, ClusterSwapActive, TaskCluster
See Also
Cluster Functions
"About cluster context" in the CitectSCADA User Guide
ClusterSwapActive
This function allows the user to deactivate an active cluster at the same time as activating
an inactive cluster. The arguments may be passed in any order, but one cluster must be ac-
tive and the other must be inactive.
Syntax
ClusterSwapActive(clusterNameA, clusterNameB)
clusterNameA:
The name of the cluster to activate or deactivate enclosed in quotation marks "".
clusterNameB:
228
Chapter: 20 Cluster Functions
The name of the cluster to activate or deactivate enclosed in quotation marks "".
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
ClusterActivate, ClusterDeactivate, ClusterFirst, ClusterGetName, ClusterIsActive, Clus-
terNext, ClusterServerTypes, ClusterSetName, ClusterStatus, TaskCluster
See Also
Cluster Functions
"About cluster context" in the CitectSCADA User Guide
229
Chapter: 20 Cluster Functions
230
Chapter: 21 Color Functions
Allow manipulation of colors (for example, to convert CitectSCADA colors to the format
required by ActiveX objects).
Color Functions
Following are functions relating to colors:
CitectColourToPackedRGB Converts a CitectSCADA color into a packed RGB color
value that can be used by an ActiveX object.
GetBlueValue Returns the Blue component of a packed RGB color.
GetGreenValue Returns the Green component of a packed RGB color.
GetRedValue Returns the Red component of a packed RGB color.
MakeCitectColour Creates a color from red, green and blue component
parts.
PackedRGB Returns a packed RGB color based on specified red,
green, and blue values.
PackedRGBToCitectColour Converts a packed RGB color into the nearest equiva-
lent CitectSCADA color.
See Also
Functions Reference
CitectColourToPackedRGB
Converts a CitectSCADA color value into a packed RGB color value that can be understood
by an ActiveX object.
Syntax
CitectColourToPackedRGB(nCitectColour)
nCitectColour:
The CitectSCADA color value to be converted into a packed RGB color. Cit-
ectSCADA colors are defined in the labels database, or calculated by the function
MakeCitectColour
Return Value
The packed RGB color value - if successful, otherwise an error is returned.
Related Functions
PackedRGBToCitectColour
See Also
Color Functions
GetBlueValue
Returns the Blue component of a packed RGB color.
231
Chapter: 21 Color Functions
Syntax
GetBlueValue(nPackedRGB)
nPackedRGB:
The packed RGB color.
Return Value
The red value (0-255) - if successful, otherwise an error is returned.
Related Functions
GetRedValue, GetGreenValue
See Also
Color Functions
GetGreenValue
Returns the green component of a packed RGB color.
Syntax
GetGreenValue(nPackedRGB)
nPackedRGB:
The packed RGB color.
Return Value
The red value (0-255) - if successful, otherwise an error is returned.
Related Functions
GetRedValue, GetBlueValue
See Also
Color Functions
GetRedValue
Returns the red component of a packed RGB color.
Syntax
GetRedValue(nPackedRGB)
nPackedRGB:
The packed RGB color.
Return Value
The red value (0-255) - if successful, otherwise an error is returned.
Related Functions
GetGreenValue, GetBlueValue
232
Chapter: 21 Color Functions
See Also
Color Functions
MakeCitectColour
Creates a color from red, green and blue component parts.
Note: To define a transparent color, use the label TRANSPARENT.
Syntax
MakeCitectColour(nRed,nGreen,nBlue)
nRed:
The color value for red, from 0-255
nGreen:
The color value for green, from 0-255
nBlue:
The color value for blue, from 0-255
Return Value
An integer that is an encoded representation of the color created.
Examples
! creates the color red
MakeCitectColour(255,0,0)
! creates the color white
MakeCitectColour(255,255,255)
See Also
Color Functions
PackedRGB
Returns a packed RGB color based on specified red, green, and blue values.
Syntax
PackedRGB(nRed, nGreen, nBlue)
nRed:
The red component of the desired packed RGB color.
nGreen:
The green component of the desired packed RGB color.
nBlue:
The blue component of the desired packed RGB color.
Return Value
The packed RGB color value - if successful, otherwise an error is returned.
233
Chapter: 21 Color Functions
Related Functions
CitectColourToPackedRGB
See Also
Color Functions
PackedRGBToCitectColour
Converts a packed RGB color into a calculated CitectSCADA color value.
Syntax
PackedRGBToCitectColour(nPackedRGB)
nPackedRGB:
The packed RGB color.
Return Value
The CitectSCADA color value if successful; otherwise an error is returned.
Related Functions
CitectColourToPackedRGB
See Also
Color Functions
234
Chapter: 22 Communication Functions
The communication functions give you direct access to the communication ports on your
computer(s). You can use these functions to communicate with external equipment, such
as low speed devices (e.g. bar code readers), serial keyboards, and dumb terminals.
You should not use these functions to communicate with high speed PLCs, as they are de-
signed for low-level communication on a COM port and the performance may not be ade-
quate. To communicate with a PLC, a standard I/O device setup should be configured
using the required driver.
Note: The Communication functions can only be called from an I/O server.
Communication Functions
Following are functions relating to communications:
ComClose Closes a communication port.
ComOpen Opens a communication port for access.
ComRead Reads characters from a communication port.
ComReset Resets the communication port.
ComWrite Writes characters to a communication port.
SerialKey Redirects all serial characters from a port to the keyboard.
See Also
Functions Reference
ComClose
Closes a communication port. Any Cicode tasks that are waiting for a read or write opera-
tion to complete (or that are retrying to read or write) return with a range error. CitectSCA-
DA automatically closes all communication ports at shutdown.
This function can only be called from an I/O Server.
Syntax
ComClose(hPort)
hPort:
The communication port handle, returned from the ComOpen() function. This
handle identifies the table where all data on the associated communication port
is stored.
Return Value
0 if the port is successfully closed, or an error if the port is already closed or if the port num-
ber is invalid.
Related Functions
ComOpen, ComRead, ComWrite
235
Chapter: 22 Communication Functions
Example
See ComOpen
See Also
Communication Functions
ComOpen
Opens a communication port for access. The board and port must both be defined in the
database (using the Boards and Ports forms from the Communication menu).
If you try to open the same COM port twice with ComOpen(), the second open will not suc-
ceed and return -1. If this is passed without checking other Com functions, the COM port
may not do anything. For this reason, do not open COM ports twice, and always check the
return value from ComOpen().
The communication system should be used for low speed communications only. You
should not use the communication functions to communicate with high speed PLCs - the
performance may not be adequate. If you need high speed communication (for communi-
cating with PLCs, etc.), you should write a protocol driver. Refer to the CitectSCADA
"Driver Development Kit".
This function can only be called from an I/O Server.
Syntax
ComOpen(sPort, iMode)
sPort:
The port name as specified in the Ports database.
iMode:
The mode of the open:
0 - Take control of the port from CitectSCADA. In this non-shared mode, you
have complete access to the port - CitectSCADA cannot use the port. Com-
munication will be restored when the port is closed.
1 - Share the port with CitectSCADA. In this mode, you can write to the port, and
CitectSCADA can also use it. Please be aware that ComRead will be unre-
liable if the communication port is opened as shared.
Return Value
A communication port handle if the communication system is opened successfully, other-
wise -1 is returned. The handle identifies the table where all data on the associated port is
stored. You can use the handle in the other communication functions, to send and receive
characters from the port.
Related Functions
ComClose, ComRead, ComWrite
Example
INT
FUNCTION
StartSerial(STRING sPort)
236
Chapter: 22 Communication Functions
INT hPort;
hPort = ComOpen(sPort, 0);
IF hPort < 0 THEN
Prompt("Cannot open port " + sPort);
RETURN -1;
END
TaskNew("SerialRead", hPort, 0);
TaskNew("SerialWrite", hPort, 0);
ComClose(hPort);
RETURN 0;
END
INT
FUNCTION
SerialWrite(INT hPort)
STRING buffer;
INT SerialWriteError;
INT length;
WHILE 1 DO
! put data into buffer and set length
.
.
SerialWriteError = ComWrite(hPort, buffer, length, 2);
IF SerialWriteError THEN
Prompt("Error Writing port");
ComReset(hPort);
END
END
RETURN 0;
END
INT
FUNCTION
SerialRead(INT hPort)
STRING buffer;
INT length;
INT total;
INT SerialReadError;
total = 0;
WHILE 1 DO
length = 128; ! must set length as read modifies
SerialReadError = ComRead(hPort, buffer, length, 2);
IF SerialReadError THEN
Prompt("Error from port " + SerialReadError : ####);
ComReset(hPort);
ELSE
! get data from buffer, length is set to number read
.
.
END
END
RETURN 0;
END
See Also
Communication Functions
ComRead
237
Chapter: 22 Communication Functions
Reads characters from a communication port. The characters are read from the communi-
cation port into a string buffer. If no characters have arrived after the specified timeout, the
function returns with a timeout error. If the timeout is 0, the function gets any characters
that have arrived from the last call, and returns immediately.
You use the iLength variable to specify the length of the buffer, or the maximum number
of characters to read when ComRead() is called. When ComRead() returns, iLength is set to
the actual number of characters read. Because iLength is modified by this function, you
must reset it before each call.
You should not treat the string buffer as a normal string - it has no string terminator. Use
the StrGetChar() function to extract characters from the buffer.
Do not call ComRead() while another ComRead() is still pending on the same port, because
it can produce unexpected results.
This function is a blocking function. It blocks the calling Cicode task until the operation is
complete. This function can only be called from an I/O Server.
Syntax
ComRead(hPort, sBuffer, iLength, iTimeOut)
hPort:
The communication port handle, returned from the ComOpen() function. This
handle identifies the table where all data on the associated communication port
is stored.
sBuffer:
The buffer into which to put the characters. The actual number of characters read
is returned in iLength.
iLength:
The number of characters to read into the buffer. The maximum length you may
read in one call is 128 characters. When the function returns, this variable is set to
the actual number of characters read.
iTimeOut:
The timeout for the read to complete:
If iTimeOut = 0 (zero), the function checks for characters in the buffer and re-
turns.
If iTimeOut > 0, the function returns after this number of seconds - if no char-
acters have been received.
If iTimeOut < 0, the function waits forever for characters.
Return Value
0 (zero) if the read is successful, otherwise an error is returned.
Related Functions
ComOpen, ComClose, ComWrite, StrGetChar
Example
See ComOpen
238
Chapter: 22 Communication Functions
See Also
Communication Functions
ComReset
Resets the communication port. This function can only be called from an I/O Server.
Syntax
ComReset(hPort)
hPort:
The communication port handle, returned from the ComOpen() function. This
handle identifies the table where all data on the associated communication port
is stored.
Return Value
0 (zero) if the write is successful, otherwise an error is returned.
Related Functions
ComOpen, ComClose, ComRead, StrGetChar
Example
See ComOpen
See Also
Communication Functions
ComWrite
Writes characters to a communication port. The characters are written from the string buff-
er to the port. If the characters have not been transmitted after the specified timeout, the
function returns with a timeout error. If the timeout is 0, the function returns immediately
and the characters are transmitted in the background.
ComWrite() does not treat the buffer as a true string, but rather as an array of characters of
the length specified - you can send any character to the communication port. Use the StrSet-
Char() function to build the buffer. Do not call ComWrite() while another ComWrite() is
still pending on the same port, because it can produce unexpected results.
You use the iLength variable to specify the length of the buffer, or the maximum number
of characters to write when ComWrite() is called. When ComWrite() returns, iLength is re-
set to zero.
This function is a blocking function. It blocks the calling Cicode task until the operation is
complete.
This function can only be called from an I/O Server.
Syntax
ComWrite(hPort, sBuffer, iLength, iTimeOut)
hPort:
239
Chapter: 22 Communication Functions
The communication port handle, returned from the ComOpen() function. This
handle identifies the table where all data on the associated communication port
is stored.
sBuffer:
The buffer from which to write the characters.
iLength:
The number of characters to write from the buffer. The maximum number of
characters you can write is 128.
iTimeOut:
The timeout for the write to complete.
If iTimeOut = 0 (zero), the characters are copied to the communication buffer
and the function returns immediately - the characters are transmitted in the
background.
If iTimeOut > 0, the function returns after this number of seconds - if the char-
acters cannot be transmitted.
If iTimeOut < 0, the function waits forever to transmit the characters.
Return Value
0 (zero) if the write is successful, otherwise an error is returned.
Related Functions
ComOpen, ComClose, ComRead, StrGetChar
Example
See ComOpen
See Also
Communication Functions
SerialKey
Redirects all serial characters from a port to the keyboard. If using a keyboard attached to
a serial port, you should call this function at startup, so that CitectSCADA copies all char-
acters (read from the port) to the keyboard. The Port must be defined in the Ports database.
If the port is not on an I/O server, you must create a dummy I/O server record (for example,
name the server DServer1). Complete the Boards and Ports records. Set the following pa-
rameters in the CITECT.INI file:
[IOServer]Name to the server name (for example, DServer1)
[IOServer]Server to 0
This method enables the port without making the computer an I/O server. (If the I/O server
is enabled (and not required as an I/O server), extra overhead and memory are used.)
This function can only be called from an I/O server.
Syntax
SerialKey(sPort)
240
Chapter: 22 Communication Functions
sPort:
The name of the port connected to the serial keyboard.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
ComOpen
Example
SerialKey("Port1"); ! enable the serial keyboard
See Also
Communication Functions
241
Chapter: 22 Communication Functions
242
Chapter: 23 Dynamic Data Exchange Functions
The Cicode DDE (Dynamic Data Exchange) functions permit you to exchange data be-
tween CitectSCADA and other Windows applications running on the same computer in
real time, continuously, and with no operator intervention. For example, you can send your
run-time data to a DDE compliant spreadsheet or word processing application, either by
posting the data to memory for DDE access by other applications, or by writing the data
directly into another application. Conversely, you could read data from a DDE compliant
application like a spreadsheet or document directly into a CitectSCADA variable.
You could also run processes in any DDE compliant Windows application running on the
same computer by using the Cicode DDEExec() function to send commands to that appli-
cation. Similarly, you can call any Cicode function (built-in or user-written) in CitectSCA-
DA from any Windows application (running on the same computer), that supports a DDE
Execute command.
The DDERead(), DDEPost(), DDEWrite(), and DDEExec() functions each perform a single
exchange of data. Each of these functions starts a DDE conversation with the external ap-
plication, sends or receives the data (or command), and ends the conversation - all in one
operation.
The DDE handle (DDEh...) functions return a handle to the conversation - a DDE channel
number. You should use the DDE handle functions for Network DDE, in particular for Ac-
cess DDE.
Note:CitectSCADA runtime automatically behaves as a DDE Server and makes its variable
tag database available for DDE Client applications to link with.
DDE Functions
Following are functions relating to Dynamic Data Exchange:
DDEExec Executes a command in an external DDE compliant Windows ap-
plication.
DDEPost Makes a CitectSCADA variable available for DDE linking by other
DDE compliant Windows applications.
DDERead Reads a variable from a DDE compliant Windows application.
DDEWrite Writes a variable to a DDE compliant Windows application.
DDEhExecute Executes a command in an external DDE compliant Windows ap-
plication.
DDEhGetLastError Gets the most recent Windows DDE error code.
DDEhInitiate Starts a DDE conversation with an external DDE compliant Win-
dows application.
DDEhPoke Writes data to a DDE compliant Windows application.
DDEhReadLn Reads a line of text from a DDE Conversion.
DDEhRequest Requests data from a DDE compliant Windows application.
DDEhSetMode Set the mode of a DDE conversation.
DDEhTerminate Closes a DDE conversation with a Windows application.
DDEhWriteLn Writes a line of text to the DDE conversation.
243
Chapter: 23 Dynamic Data Exchange Functions
See Also
Functions Reference
DDEExec
Executes a command in an external Windows application running on the same computer.
With this function, you can control other applications that support DDE. Refer to the doc-
umentation provided with the external Windows application to determine if DDE is sup-
ported and what functions can be called.
You cannot use DDEExec() to call macros on a remote computer or to call Access SQLs. For
these calls, Network DDE needs to pass the sDocument argument, so you must use the
DDEh... functions, passing sDocument in the DDEhInitiate() function.
Syntax
DDEExec(sApplication, sCommand)
sApplication:
Application name (.EXE filename), for example, "WinWord".
sCommand:
The command that the application will execute.
Return Value
1 (one) if successful, otherwise an error is returned.
Related Functions
DDEPost, DDERead, DDEWrite, DDEhExecute
Example
/* Instruct the Excel application to recalculate its spreadsheet
immediately. */
DDEExec("Excel","[Calculate.Now()]");
See Also
DDE Functions
DDEhExecute
Executes a command in an external Windows application. You must first start a conversa-
tion with the DDEhInitiate function, and use the handle returned by that function to iden-
tify the conversation.
With this function, you can control other applications that support DDE. Refer to the doc-
umentation provided with your other Windows application to determine if DDE is sup-
ported and what functions can be called.
This function is a blocking function. It will block the calling Cicode task until the operation
is complete.
244
Chapter: 23 Dynamic Data Exchange Functions
Syntax
DDEhExecute(Handle, sCommand)
Handle:
The integer handle that identifies the DDE conversation, returned from the DDE-
hInitiate function.
sCommand:
The command that the application will execute.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DDEhInitiate, DDEhRequest, DDEhPoke, DDEhTerminate, DDEhGetLastError
Example
See DDEhInitiate
See Also
DDE Functions
DDEhGetLastError
Gets the latest error code issued from Windows for the conversation identified by the han-
dle.
Syntax
DDEhGetLastError(Handle)
Handle:
The integer handle that identifies the DDE conversation, returned from the DDE-
hInitiate function.
Return Value
The error code last issued from Windows DDEML (for that conversation):
DMLERR_ADVACKTIMEOUT 0x4000
DMLERR_BUSY 0x4001
DMLERR_DATAACKTIMEOUT 0x4002
DMLERR_DLL_NOT_INITIALIZED 0x4003
DMLERR_DLL_USAGE 0x4004
DMLERR_EXECACKTIMEOUT 0x4005
DMLERR_INVALIDPARAMETER 0x4006
DMLERR_LOW_MEMORY 0x4007
DMLERR_MEMORY_ERROR 0x4008
DMLERR_NOTPROCESSED 0x4009
DMLERR_NO_CONV_ESTABLISHED 0x400a
DMLERR_POKEACKTIMEOUT 0x400b
245
Chapter: 23 Dynamic Data Exchange Functions
DMLERR_POSTMSG_FAILED 0x400c
DMLERR_REENTRANCY 0x400d
DMLERR_SERVER_DIED 0x400e
DMLERR_SYS_ERROR 0x400f
DMLERR_UNADVACKTIMEOUT 0x4010
DMLERR_UNFOUND_QUEUE_ID 0x4011
Related Functions
DDEhInitiate, DDEhExecute, DDEhRequest, DDEhPoke, DDEhTerminate
Example
See DDEhInitiate
See Also
DDE Functions
DDEhInitiate
Starts a conversation with an external Windows application. When the data exchange is
complete, you should terminate the conversation to free system resources.
Syntax
DDEhInitiate(sApplication, sDocument)
sApplication:
The application name (.EXE filename), for example, "WinWord".
sDocument:
The document, topic, or file name.
Return Value
An integer handle for the conversation between CitectSCADA and the other application, or
-1 if the conversation is not started successfully. The handle is used by the other DDEh...
functions, to identify the conversation.
Related Functions
DDEhExecute, DDEhRequest, DDEhPoke, DDEhTerminate, DDEhGetLastError
Example
! Read from Excel spreadsheet
STRING FUNCTION GetExcelData();
INT hChannel;
STRING sData;
hChannel = DDEhInitiate("EXCEL", "DATA.XLS");
IF hChannel > -1 THEN
sData = DDEhRequest(hChannel, "R1C1");
DDEhTerminate(hChannel);
hChannel = -1;
END;
RETURN sData;
END
246
Chapter: 23 Dynamic Data Exchange Functions
See Also
DDE Functions
DDEhPoke
Writes a value to an external Windows application, for example, an Excel spreadsheet. The
value is written once to the application. (To write the value dynamically, you must call this
function at the rate at which the data must be updated.)
You must first start a conversation with the DDEhInitiate function, and use the handle re-
turned by that function to identify the conversation.
This function is a blocking function. It will block the calling Cicode task until the operation
is complete.
Syntax
DDEhPoke(Handle, sItem, sValue)
Handle:
The integer handle that identifies the DDE conversation, returned from the DDE-
hInitiate function.
sItem:
A unique name for the item; for example, the variable name, field name, or
spreadsheet cell position.
sValue:
The value of the item.
Return Value
0 (zero) if successful, otherwise an error is returned.
247
Chapter: 23 Dynamic Data Exchange Functions
Related Functions
DDEhInitiate, DDEhExecute, DDEhRequest, DDEhTerminate, DDEhGetLastError
Example
See DDEhInitiate
See Also
DDE Functions
DDEhReadLn
Reads a line of text from a DDE Conversion, for example, from an Excel spreadsheet. You
must first start a conversation with the DDEhInitiate function, and use the handle returned
by that function to identify the conversation. This function allows you to read a large
amount of data via DDE. Keep calling the function until an empty string is returned to ver-
ify that all the data has been read.
This function is a blocking function. It will block the calling Cicode task until the operation
is complete.
Syntax
DDEhReadLn(Handle, sTopic)
Handle:
The integer handle that identifies the DDE conversation, returned from the DDE-
hInitiate function.
sTopic:
A unique topic name for the item; for example, the variable name, field name, or
spreadsheet cell position.
Return Value
A line of data, or an empty string when all data has been read.
Related Functions
DDEhSetMode, DDEhWriteLn, DDEhInitiate, DDEhExecute, DDEhRequest, DDEhTermi-
nate, DDEhGetLastError
Example
See DDEhWriteLn
See Also
DDE Functions
DDEhRequest
Reads a value from an external Windows application, for example, from an Excel spread-
sheet. You must first start a conversation with the DDEhInitiate function, and use the han-
dle returned by that function to identify the conversation.
This function is a blocking function. It will block the calling Cicode task until the operation
is complete.
248
Chapter: 23 Dynamic Data Exchange Functions
Syntax
DDEhRequest(Handle, sItem)
Handle:
The integer handle that identifies the DDE conversation, returned from the DDE-
hInitiate function.
sItem:
A unique name for the item; for example, the variable name, field name, or
spreadsheet cell position.
Return Value
A string of data, or an empty string if the function cannot read the value.
Related Functions
DDEhInitiate, DDEhExecute, DDEhPoke, DDEhTerminate, DDEhGetLastError
Example
See DDEhInitiate
See Also
DDE Functions
DDEhSetMode
Set the mode of the DDE conversation. The default mode of a DDE conversation is to use
TEXT data format - a simple string of data. This function allows you to set the mode to CSV
(Comma Separated Values). Some Windows applications support this mode of data as it
helps them to separate the data. For example, when you send CSV format to Excel, each val-
ue will be placed into a unique cell. If you use TEXT mode all the data will be placed into
the same cell.
Syntax
DDEhSetMode(Handle, sMode)
Handle:
The integer handle that identifies the DDE conversation, returned from the DDE-
hInitiate function.
sMode:
The mode of the DDE conversation:
1 - Text (default)
2 - CSV
Return Value
The error code.
Related Functions
DDEhInitiate, DDEhExecute, DDEhRequest, DDEhTerminate, DDEhGetLastError, DDEh-
Poke, DDEhReadLn, DDEhWriteLn, DDEhSetMode
249
Chapter: 23 Dynamic Data Exchange Functions
Example
See DDEhWriteLn
See Also
DDE Functions
DDEhTerminate
Closes the conversation identified by the handle, and frees the resources associated with
that conversation. After you call this function, the handle is no longer valid.
With Network DDE, you might need to terminate and re-initiate a conversation. For exam-
ple, if you delete rows on an MS Access sheet, the deleted rows display as #DELETED until
you terminate and re-initiate the conversation.
Syntax
DDEhTerminate(Handle)
Handle:
The integer handle that identifies the DDE conversation, returned from the DDE-
hInitiate function.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DDEhInitiate, DDEhExecute, DDEhPoke, DDEhRequest, DDEhGetLastError
Example
See DDEhInitiate
See Also
DDE Functions
DDEhWriteLn
Writes a line of text to the DDE conversation. With this function, you can write any amount
of text to the DDE conversation. Call this function once for each line of text. To terminate
the block of text, call this function and pass an empty string.
Syntax
DDEhWriteLn(Handle, sTopic, sData)
Handle:
The integer handle that identifies the DDE conversation, returned from the DDE-
hInitiate function.
sTopic:
A unique name for the topic the data will be written to; for example, the spread-
sheet cell position. The topic is only used when you complete the write by passing
an empty string for data.
250
Chapter: 23 Dynamic Data Exchange Functions
sData:
The line of data to write. To terminate the data and make CitectSCADA send the
data, set the data to an empty string.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DDEhInitiate, DDEhExecute, DDEhRequest, DDEhTerminate, DDEhGetLastError, DDEh-
Poke, DDEhReadLn, DDEhWriteLn, DDEhSetMode
Example
! Write to Excel spreadsheet
! write the numbers 1..8 into 8 unique cells in Excel.
FUNCTION WriteExcelData(STRING sData);
INT hChannel;
hChannel = DDEhInitiate("EXCEL", "DATA.XLS");
IF hChannel > -1 THEN
// set to CSV mode so EXCEL will put each value in a cell
DDEhSetMode(hChannel, 2);
DDEhWriteLn(hChannel, "", "1,2,3,4");
DDEhWriteLn(hChannel, "R1C1:R2C4", "5,6,7,8");
DDEhWriteLn(hChannel,"R1C1:R2C4","");
DDEhTerminate(hChannel);
hChannel = -1;
END;
END
See Also
DDE Functions
DDEPost
Makes a CitectSCADA variable value available for DDE linking (that is posts a DDE link so
that it can be read by other DDE compliant applications running on the same computer).
This sets-up CitectSCADA to behave as a DDE Server for this DDE channel.
After a value is posted, other Windows applications running on the same computer can
read the value by using their own DDE Client functions. If the value of the posted variable
changes, any linked applications are informed of the new value.
To link to this value from any DDE Client applications running on the same computer, they
must appropriately use the DDE Client syntax with:
"Citect" as the <DDE Server application name>
"Data" as the <DDE Topic name>
The name used for the first parameter sItem in this DDEPost() function as the <DDE
data item name>.
Unlike the DDERead() and DDEWrite() Cicode functions which are static, the DDEPost()
function can be used to create a dynamic DDE link, providing the DDE Client applications
appropriately set their side of the DDE channel to be automatically updated.
251
Chapter: 23 Dynamic Data Exchange Functions
Syntax
DDEPost(sItem, sValue)
sItem:
A unique name for the item; for example, the variable name, field name, or
spreadsheet cell position.
sValue:
The value of the item.
Return Value
The value that is posted, or 0 (zero) if the function does not succeed in posting the link.
Related Functions
DDEExec, DDERead, DDEWrite
Example
! In Citect Project Editor, create a variable tag named PV1
! In Cicode, post a link to the tag PV1 for external DDE
applications to connect with DDEPost("TAGONE",PV1);
/* To link to this posted tag from a cell in Excel, set the cell to
=Citect|Data!TAGONE. This will set the value of the Excel cell to
the value of tag PV1. */
/* To link to this posted tag from a field in Word, set the field
to{DDEAuto Citect Data TAGONE}. This will set the value of the
field link to the value of tag PV1. */
See Also
DDE Functions
DDERead
Reads values from an external DDE compliant Windows application running on the same
computer, (for example, from an Excel spreadsheet cell or a Word document).
This is a one-way static communication which is read once from the application per call. To
read the value dynamically, call this function at the rate at which the data is required to be
updated.
Use this function when you want precise control over exactly what you want from the DDE
exchange.
Syntax
DDERead(sApplication, sDocument, sItem [, Mode] )
sApplication:
The application name (.EXE filename), for example, "WinWord".
sDocument:
The document, topic, or file name.
sItem:
252
Chapter: 23 Dynamic Data Exchange Functions
A unique name for the item; for example, the variable name, field name, or
spreadsheet cell position.
Mode:
A flag that tells the application whether or not to set up an advise loop:
0 - Do not set up advise loop.
1 - Set up advise loop (default).
Return Value
The value (from the external application) as a string, or an empty string if the function can-
not read the desired values.
Related Functions
DDEExec, DDEPost, DDEWrite
Example
/* Read the value from R1C1 (Row1,Column1) of an Excel spreadsheet
named "Sheet1". */
DDERead("Excel","Sheet1","R1C1");
/* Read the value from the Item1 bookmark of the Word document
named "Recipes.doc". */
DDERead("Winword","Recipes","Item1");
See Also
DDE Functions
DDEWrite
Writes a value to an external Windows application, for example, to an Excel spreadsheet.
The value is written once to the application. To write the value dynamically, you must call
this function at the rate at which the data must be updated.
Use DDEWrite() to cause CitectSCADA runtime to initiate the DDE conversation with a
DDE compliant application running on the same computer.
Syntax
DDEWrite(sApplication, sDocument, sItem, sValue)
sApplication:
The application name (.EXE filename), for example, "WinWord".
sDocument:
The document, topic, or file name.
sItem:
A unique name for the item; for example, the variable name, field name, or
spreadsheet cell position.
sValue:
The value of the item.
253
Chapter: 23 Dynamic Data Exchange Functions
Return Value
The value that is sent to the other application, or an empty string if the function does not
successfully write the value.
Related Functions
DDEExec, DDEPost, DDERead
Example
/* Write the value of a CitectSCADA variable named
TAGONE to R1C1 (Row1,Column1) of an Excel spreadsheet named
"Sheet1". The value is in string format. */
DDEWrite("Excel","Sheet1","R1C1",TAGONE);
See Also
DDE Functions
254
Chapter: 24 Device Functions
The device functions provide access to devices. They allow access to SQL, dBASE, and
ASCII files through database-like operations, and provide more control over output to
printers.
With these functions you can open and close any device, and read from and write to any
record or field in the device. You can store recipes or any other data in a database, and then
down-load or up-load the data as required to an I/O device on the plant floor, or to the op-
erator. You can also update the database with real-time data for data exchange with other
applications.
Device Functions
Following are functions relating to devices:
DevAppend Appends a blank record to the end of a device.
DevClose Closes a device.
DevControl Controls a dBASE or SQL device.
DevCurr Gets the current device number.
DevDelete Deletes the current record in a database device.
DevDisable Disables (and re-enables) a device from any access.
DevEOF Checks for the end of a file.
DevFind Finds a record in a device.
DevFirst Finds the first record in a device.
DevFlush Flushes buffered data to a device.
DevGetField Gets field data from the current record.
DevHistory Renames a device file and any subsequent history files.
DevInfo Gets device information.
DevModify Modifies the attributes of a device.
DevNext Gets the next record in a device.
DevOpen Opens a device for access.
DevOpenGrp Opens a group of devices.
DevPrev Gets the previous record in a device.
DevPrint Prints free-format data to a group of devices.
DevRead Reads characters from a device.
DevReadLn Reads a line of characters from a device.
DevRecNo Gets the current record number of a device.
DevSeek Moves to any record in a device.
DevSetField Sets new field data in the current record.
DevSize Gets the size of a device.
DevWrite Writes a string to a device.
DevWriteLn Writes a string with a newline character to a device.
DevZap Zaps a device.
Print Prints a string in a report.
255
Chapter: 24 Device Functions
See Also
Functions Reference
DevAppend
Appends a blank record to the end of a device. After the record is appended, you can use
the DevSetField() function to add data to fields in the record.
You must first call the DevOpen() function to get the device handle (hDev).
Syntax
DevAppend(hDev)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
Return Value
0 (zero) if the record is successfully appended, otherwise an error is returned.
Related Functions
DevOpen, DevSetField
Example
INT
FUNCTION WriteAlarmCount( INT hDevice, STRING sAlarm,
INT iCount, INT iTime )
DevAppend(hDevice);
DevSetField(hDevice, "ALARM", sAlarm);
DevSetField(hDevice, "TIME", IntToStr(iTime));
DevSetField(hDevice, "COUNT", IntToStr(iCount));
END
See Also
Device Functions
DevClose
Closes a device. Any data in the buffer is flushed to the device before it is closed. After a
device is closed, its device handle becomes invalid and cannot be used.
Syntax
DevClose(hDev, Mode)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
256
Chapter: 24 Device Functions
Mode:
Set to TRUE to keep logging or FALSE to remove logging. Default value is 0
(FALSE).
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DevOpen
Example
DevClose(hDev);
See Also
Device Functions
DevControl
Controls a dBASE or SQL device. You can pack a dBASE device to physically remove de-
leted records, or re-index a dBASE device to regenerate the keys. You can issue queries to
an SQL device, or get the error status of the last SQL query.
Syntax
DevControl(hDev, Type [, sData])
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
Type:
The type of command:
0 - Re-index the device based on the key defined in the device record (dBASE de-
vices only).
1 - Pack the database file - all deleted records are removed (dBASE devices only).
2 - Issue a direct SQL query to the device (SQL devices only).
3 - Get error status of the last SQL query (SQL devices only).
Note: ASCII files and printers are not supported.
sData:
The command data, that is the SQL query to be issued. Used only for Type 2 com-
mands.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DevOpen, DevZap
257
Chapter: 24 Device Functions
Example
! pack a dBASE file device
DevControl(hDev, 1, "");
See Also
Device Functions
DevCurr
Gets the current device handle. You can only call this function in a report, to get the handle
of the device where the report is logging. You can then use the other device functions (for
example, DevPrint()) to access that logging device. (To get the handle of a device other than
a logging device, you must use the DevOpen() function.)
If the report is logging to a group of devices, this function will return the group handle.
However, not all device functions support group handles, for example, you cannot read
from a group of devices.
Syntax
DevCurr()
Return Value
The current device handle or group handle. If no device is configured, -1 is returned.
Related Functions
DevOpen, DevPrint
Example
! Get the report device number.
hDev=DevCurr();
See Also
Device Functions
DevDelete
Deletes the current record in a dBASE database device. The record is not physically deleted,
but is marked for deletion. You can physically delete the record by packing the database
with the DevControl() function.
Syntax
DevDelete(hDev)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
258
Chapter: 24 Device Functions
Return Value
0 (zero) if the record is successfully deleted, otherwise an error is returned.
Related Functions
DevOpen, DevClose, DevControl
Example
! Delete the current record.
DevDelete(hDev);
See Also
Device Functions
DevDisable
Disables (and re-enables) a device from all access, and discards any data written to the de-
vice. When a device is disabled, it cannot be opened, and data cannot be read from the de-
vice. Use this function to disable logging to a database or printer.
The State argument is a toggle. A State of 1 disables the device(s), but you can then re-enable
the device(s) by repeating the function with State = 0.
Syntax
DevDisable(sName, State)
sName:
The device name, or * (asterisk) for all devices.
State:
The disable state:
0 - Enable the device.
1 - Disable the device.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DevOpen
Example
! Disable the AlarmLog device.
DevDisable("AlarmLog",1);
:
DevDisable("AlarmLog",0); ! Re-enable the device.
See Also
Device Functions
259
Chapter: 24 Device Functions
DevEOF
Gets the status of the end of file (EOF) flag for a device. When you use the DevPrev(),
DevNext(), or DevSeek() function, the start or end of the device will eventually be reached,
and the EOF flag will be set. Use this function to test the EOF flag.
Syntax
DevEOF(hDev)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
Return Value
1 if the EOF flag has been set, otherwise 0 (zero).
Related Functions
DevOpen, DevPrev, DevNext, DevSeek, DevReadLn
Example
hDev = DevOpen("Log", 0);
WHILE NOT DevEOF(hDev) DO
Prompt(DevGetField(hDev,"Tag"));
DevNext(hDev);
END
DevClose(hDev);
See Also
Device Functions
DevFind
Searches a device for a record that contains specified data in a specified field. The search
starts at the current record and continues forward until the matched data is found or the
end of the database is reached. If the file has a keyed index, an indexed search is used.
Syntax
DevFind(hDev, sFind, sField)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
sFind:
The data to find in sField, as a string.
For SQL devices: The DevFind() function can distinguish between numbers,
strings, and dates, so you do not need to enclose the data in quote marks. Dates
and times must be in the correct format:
Date: YYYY-MM-DD
Time: HH:MM:SS
DateTime: YYYY-MM-DD HH:MM:SS[.F...] (The fraction .F... is optional.)
260
Chapter: 24 Device Functions
sField:
The field name to match.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DevOpen, DevSeek
Example
! Find the Ice cream recipe.
DevNotFount=DevFind(hDev,"Ice cream","Recipe");
IF DevNotFount=0 THEN
! Get the recipe values.
..
ELSE
Prompt("Ice cream not found");
END
See Also
Device Functions
DevFirst
Finds the first record in a device.
Syntax
DevFirst(hDev)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
Return Value
The first indexed record (if the device is an indexed database), otherwise the first record in
the device.
Related Functions
DevOpen, DevClose
Example
! Find the first record.
FirstRec = DevFirst(hDev);
See Also
Device Functions
261
Chapter: 24 Device Functions
DevFlush
Flushes all buffered data to the physical device. CitectSCADA normally optimizes the writ-
ing of data for maximum performance, so use this function only if it is really necessary.
Syntax
DevFlush(hDev)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DevOpen, DevClose
Example
! Flush device to disk.
DevFlush(hDev);
See Also
Device Functions
DevGetField
Gets field data from the current record in a device.
Syntax
DevGetField(hDev, Field)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
Field:
The field name, as a string of up to 10 characters. (The dBASE file format limits
all field names to a maximum of 10 characters.)
Return Value
The field data (as a string). If the field is not found an empty string is returned.
Related Functions
DevOpen, DevSetField
Example
INT
FUNCTION
262
Chapter: 24 Device Functions
GetRecipe(STRING sName)
INT hDev;
hDev = DevOpen("Recipe", 0);
IF hDev >= 0 THEN
DevSeek(hDev, 1);
IF DevFind(hDev, sName, "NAME") = 0 THEN
PLC_FLOUR = DevGetField(hDev, "FLOUR");
PLC_WATER = DevGetField(hDev, "WATER");
PLC_SALT = DevGetField(hDev, "SALT");
PLC_MILK = DevGetField(hDev, "MILK");
ELSE
DspError("Cannot Find Recipe " + sName);
END
DevClose(hDev);
ELSE
DspError("Cannot open recipe database");
END
END
See Also
Device Functions
DevHistory
Renames a device file and any subsequent history files. The current device is closed and re-
named as the first history file. For example, the device file ’Templog.txt’ is renamed as
’Templog.001’. If a history file ’Templog.001’ already exists, it is renamed as ’Templog.002’,
and so on. The next time data is written to the device, a new device file is created.
Note: If the device file has not been created (that is data has not been written to the device),
only existing history files are renamed. Use this function for direct control of the device his-
tory process.
Syntax
DevHistory(hDev)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DevOpen, DevControl
Example
! Create history file
DevHistory(hDev);
263
Chapter: 24 Device Functions
See Also
Device Functions
DevInfo
Gets information on a device.
Syntax
DevInfo(hDev, Type)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
Type:
Type of information:
-n: Name of field n (where n is any number up to the total number of fields). For
example, if there are 10 fields, -7 will return the name of field 7.
- (Total no. of fields + n): Length of field n (where n is any number up to the total
number of fields). For example, if there are 10 fields, -15 will return the length of
field 5.
0: Device Name
1: Format
2: Header
3: File Name
4: Number of history files
5: Form length
6: Number of fields
7: Disable flag
8: Device type
9: Record size
10: Format number
11: Type of history schedule:
0: Event triggered
1: Daily
2: Weekly
3: Monthly
4: Yearly
12: The history period, in seconds, or week day, month or year, for example, if his-
tory is weekly then this is the day of the week, that is 1 to 7
13: Synchronisation time of day of the history in seconds, for example, 36000 (that
is, 10:00:00)
14: The time the next history file will be created in seconds
Return Value
The device information as a string if successful, otherwise an empty string is returned.
Related Functions
DevControl
264
Chapter: 24 Device Functions
Example
! Get the number of fields in a device.
NoFields=DevInfo(hDev,6);
FOR I=1 TO NoFields DO
! Get and display the name of each field.
sField=DevInfo(hDev,-I);
nLength=DevInfo(hDev,-I - NoFields);
Prompt("Field Name "+sField + "Length " + nLength:##);
END
See Also
Device Functions
DevModify
Modifies the attributes of a device. The device must be closed before you can modify a de-
vice.
This function allows you to dynamically change the file name or other attributes of a device
at run time. You can use a single device to access many files. For example, you can create a
device called Temp with a file name of TEMP.DBF. Using this function you could dynam-
ically change the file name to access any dBASE file.
This function is useful in conjunction with the FormOpenFile() or FormSaveAsFile() func-
tions. (These functions allow the operator to select file names easily.)
When using this function, you should be careful that no other Cicode function is already
using the same device. Always check the return value of this function before opening the
device or you will destroy the data in the device to which it is already attached. Use a sema-
phore to protect your Cicode.
When using this function, you should be careful that no other Cicode function is already
using the same device. Always check the return value of this function before opening the
device or you will destroy the data in the device to which it is already attached. If the device
is already open, calling DevModify will return an error (and raise a hardware alarm to no-
tify user).
If DevModify returns error, it means it has not modified the device and the device param-
eters will remain as they were before the call to DevModify.
Use a semaphore to protect your Cicode.
Syntax
DevModify(Name, Format, Header, FileName, Type)
Name:
The name of the device.
Format:
A new format for the device or "*" to use the existing format.
Header:
A new header for the device or "*" to use the existing header.
FileName:
265
Chapter: 24 Device Functions
A new file name for the device or "*" (asterisk) to use the existing filename.
Type:
A new device type.
Device Type Device
ASCII_DEV ASCII file
PRINTER_DEV Printer
dBASE_DEV dBASE file
SQL_DEV SQL database
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DevOpen, DevClose, DevSetField, DevInfo, DevAppend, FormOpenFile
Example
! change the file name of MyDev
DevModify("MyDev", "*", "*", "c:\data\newfile.dbf", -1);
! change the fields and file name of MyDev
DevModify("MyDev", "{time}{date}{tags}", "*",
"C:\DATA\OLDFILE.DBF", -1);
! change the device to TXT file
DevModify("MyDev", "*", "*", "C:\DATA\OLDFILE.TXT", ASCII_DEV);
See Also
Device Functions
DevNext
Gets the next record in a device. If the end of the database is reached, the EOF flag is set and
an error code is returned.
Syntax
DevNext(hDev)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
Return Value
0 if the next record is read, or an error if the end of the database is reached.
Related Functions
DevEOF, DevPrev
266
Chapter: 24 Device Functions
Example
Status=0;
I = 0;
hDev = DevOpen("Log", 0);
WHILE Status = 0 DO
DspText(20 + I, 0, DevGetField(hDev,"Tag"));
I = I + 1;
Status = DevNext(hDev);
END
DevClose(hDev);
See Also
Device Functions
DevOpen
Opens a device and returns the device handle. The device must be defined in the Cit-
ectSCADA database. If the device cannot be opened, and user error checking is not en-
abled, the current Cicode task is halted.
You can use this function to return the handle of a device that is already open. The De-
vOpen() function does not physically open another device - it returns the same device han-
dle as when the device was opened. The mode of the second open call is ignored. To re-
open an open device in a different mode, you must first close the device and then re-open
it in the new mode.
When using an ODBC driver to connect to an SQL server or database, experience has
shown that connecting only once on startup and not closing the device yields the best per-
formance. ODBC connection is slow and if used on demand may affect your system’s per-
formance. Also, some ODBC drivers may leak memory on each connection and may cause
errors after a number of re-connects.
Note: If you are opening a database device in indexed mode (nMode=2), an index file will
automatically be created by CitectSCADA if one does not already exist. If you feel a device
index has become corrupt, delete the existing index file and a new one will be created the
next time the DevOpen function is run.
Syntax
DevOpen(Name [, nMode] )
Name:
The name of the device.
nMode:
The mode of the open:
0 - Open the device in shared mode - the default mode when opening a device if
none is specified.
1 - Open the device in exclusive mode. In this mode only one user can have the
device open. The open will return an error if another user has the device
open in shared or exclusive mode.
2 - Open the device in indexed mode. In this mode the device will be accessed in
index order. This mode is only valid if the device is a database device and
267
Chapter: 24 Device Functions
has an index configured in the Header field at the Devices form. Please be
aware that specifying mode 2 when opening an ASCII device is ignored in-
ternally.
4 - Open the device in ’SQL not select’ mode. If opened in this mode, you must
not attempt to read from an SQL device.
8 - Open the device in logging mode. In this mode the history files will be created
automatically.
16 - Open the device in read only mode. In this mode data can be viewed, but not
written. This mode is supported only by DBF and ASCII files - it is ignored
by printers and SQL/ODBC databases.
Return Value
The device handle. If the device cannot be opened, -1 is returned. The device handle iden-
tifies the table where all data on the associated device is stored.
Related Functions
DevClose, DevOpenGrp
Example
INT
FUNCTION
PrintRecipe(STRING sCategory)
STRING sRecipe;
INT hRecipe, hPrinter;
ErrSet(1); ! enable user error checking
hRecipe = DevOpen("Recipe", 0);
IF hRecipe = -1 THEN
DspError("Cannot open recipe");
RETURN FALSE;
END
hPrinter = DevOpen("Printer1", 0);
IF hPrinter = -1 THEN
DspError("Cannot open printer");
RETURN FALSE;
END
ErrSet(0); ! disable user error checking
WHILE NOT DevEof(hRecipe) DO
sRecipe = DevReadLn(hRecipe);
DevWriteLn(hPrinter, sRecipe);
END
DevClose(hRecipe);
DevClose(hPrinter);
RETURN TRUE;
END
See Also
Device Functions
DevOpenGrp
Opens a group of devices.
268
Chapter: 24 Device Functions
Syntax
DevOpenGrp(hGrp [, nMode] )
hGrp:
The handle to a database containing a group of devices.
nMode:
The mode of the open:
0 - Open the device in shared mode - the default mode when opening a device.
1 - Open the device in exclusive mode. In this mode only one user can have the
device open. The open will return an error if another user has the device
open in shared or exclusive mode.
2 - Open the device in indexed mode. In this mode the device will be accessed in
index order. This mode is only valid if the device is a database device and
has an index configured in the Header field at the Devices form. Please be
aware that specifying mode 2 when opening an ASCII device is ignored in-
ternally.
4 - Open the device in ’SQL not select’ mode. If opened in this mode, you must
not attempt to read from an SQL device.
8 - Open the device in logging mode. In this mode the history files will be created
automatically.
16 - Open the device in read only mode. In this mode data can be viewed, but not
written. This mode is supported only by DBF and ASCII files - it is ignored
by printers and SQL/ODBC databases.
Return Value
Returns 0 if successful or -1 if the function is provided with a bad handle and cannot open
the group.
Related Functions
DevClose, DevOpen
DevPrev
Gets the previous record in a device. If the start of the database is reached, the EOF flag is
set and an error code is returned.
Syntax
DevPrev(hDev)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
Return Value
0 if the record is read successfully, or an error if the start of the database is reached.
Related Functions
DevOpen, DevEOF, DevNext
269
Chapter: 24 Device Functions
Example
Status=0;
I = 0;
hDev = DevOpen("Log", 0);
iError = DevSeek(hDev, DevSize(hDev)); ! seek to end
WHILE iError = 0 DO
DspText(20 + I, 0, DevGetField(hDev,"Tag"));
I = I + 1;
iError = DevPrev(hDev);
END
DevClose(hDev);
See Also
Device Functions
DevPrint
Prints free-format data to groups of devices. Using this function, you can write data to
many devices at the same time. You would normally use this function in a report.
Syntax
DevPrint(hGrp, sData, NewLine)
hGrp:
The device handle, or the group handle for a group of devices.
sData:
The data to print to the group of devices.
NewLine:
The newline flag:
0 - Do not insert a newline character.
1 - Insert a newline character.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DevWriteLn, DevCurr
Example
! Get the report device number or group number (for a group of
devices).
hGrp=DevCurr();
! Print PV123 to a group of devices.
DevPrint(hGrp,"PV123="+PV123:###,1);
See Also
Device Functions
270
Chapter: 24 Device Functions
DevRead
Reads characters from a device. If the device is record-based, the current field is read. If the
device is free-format, the specified number of characters is read. If the number of characters
specified is greater than the number of characters remaining in the device, only the remain-
ing characters are read.
Syntax
DevRead(hDev, Length)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
Length:
The number of characters to read.
Return Value
The data (in string format). If the end of the device is found, an empty string is returned.
Related Functions
DevOpen, DevReadLn, DevFind
Example
! Read 20 characters from a device.
Str=DevRead(hDev,20);
See Also
Device Functions
DevReadLn
Reads data from the current record of a device until the end of the line, or end of the record.
If the device is record-based, the record number is incremented. The carriage return and
newline characters are not returned.
Syntax
DevReadLn(hDev)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
Return Value
The data (in string format). If the end of the device is found, an empty string is returned
and the EOF flag is set.
Related Functions
DevOpen, DevRead, DevEOF, DevFind
271
Chapter: 24 Device Functions
Example
Str=DevReadLn(hDev);
See Also
Device Functions
DevRecNo
Gets the current record number of a device. If the device is record-based, the record number
ranges from 1 to the maximum size of the file. If the device is free-format, the record num-
ber ranges from 0 to the maximum byte size -1.
Syntax
DevRecNo(hDev)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
Return Value
The record number. If an error is detected while getting the record number, -1 is returned.
Related Functions
DevOpen, DevSeek
Example
! Get the current record number.
Rec=DevRecNo(hDev);
See Also
Device Functions
DevSeek
Moves the device pointer to a specified position in the device. If the device is a database,
and it is opened in indexed mode, DevSeek will seek to the record number - not through
the index. To locate the first record in an indexed device, call the DevFirst() function.
Syntax
DevSeek(hDev, Offset)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
Offset:
272
Chapter: 24 Device Functions
The offset in the device. If the device is a database device, the offset is the record
number. If the device is a binary device, the offset is in bytes (from 0 to the max-
imum file size -1).
Note: If offset causes a seek past the end of the file, DevSeek returns no error, but
sets the EOF flag (that is, a subsequent DevEOF() call will return true).
Return Value
0 (zero) if the seek was successful, otherwise an error code is returned.
Related Functions
DevOpen, DevEOF, DevRecNo, DevFirst
Example
hDev=DevOpen("Log", 0);
DevSeek(hDev,100);
DevGetField(hDev,"Tag");
! Gets the value of the "Tag" field at record 100.
See Also
Device Functions
DevSetField
Sets new field data in the current record in a device.
Syntax
DevSetField(hDev, Field, sData)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
Field:
The field name, as a string of up to 10 characters. (The dBASE file format limits
all field names to a maximum of 10 characters.)
sData:
New field data, in string format. CitectSCADA converts any other data type into
a string before setting the data.
Return Value
0 (zero) if the data is successfully set, otherwise an error is returned.
Related Functions
DevOpen, DevAppend, DevGetField
Example
! Set the fields in the "Recipe" device.
hDev=DevOpen("Recipe", 0);
DevSeek(hDev, 1);
273
Chapter: 24 Device Functions
DevSetField(hDev,"Name", "WhiteBread");
DevSetField(hDev,"Flour", IntToStr(iFlour));
DevSetField(hDev,"Water", iWater:####);
DevSetField(hDev,"Salt", iSalt);
DevClose(hDev);
See Also
Device Functions
DevSize
Gets the size of a physical device.
Syntax
DevSize(hDev)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
Return Value
If the device is a database device, the number of records is returned. If the device is a binary
device, the number of bytes in the file is returned. If an error is detected, -1 is returned.
Related Functions
DevRecNo, DevSeek
Example
INT NoRec;
NoRec=DevSize(hDev);
! Seek to the last record.
DevSeek(hDev,NoRec);
See Also
Device Functions
DevWrite
Writes a string to a device. If the device is free-format, the data is written to the device as
specified. If the device is record-based, the data is written to the current field, and the field
pointer is moved to the next field.
Writing to a DBF device appends the data to the device.
DevWrite(hDev, sData)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
sData:
274
Chapter: 24 Device Functions
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DevOpen, DevWriteLn
Example
! Write PV123 to the device.
DevWrite(hDev,"PV123="+PV123:###.#);
For SQL devices: The DevWrite() function can distinguish between numbers, strings, and
dates, so you do not need to enclose the data in quote marks. Dates and times must be in
the correct format:
Date: YYYY-MM-DD
Time: HH:MM:SS
DateTime: YYYY-MM-DD HH:MM:SS[.F...] (The fraction .F... is optional.)
See Also
Device Functions
DevWriteLn
Writes a string to a device. If the device is free-format, the data is written to the device, fol-
lowed by a newline character. If the device is record-based, a new record is appended to
the device and the data is written to this record. The record pointer is then moved to the
next record.
Syntax
DevWriteLn(hDev, sData)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
sData:
The data to write, as a string.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DevOpen, DevWrite
Example
/* Write PV123 to the device followed by a newline character */
DevWriteLn(hDev,"PV123="+PV123:###.#);
275
Chapter: 24 Device Functions
See Also
Device Functions
DevZap
Zaps a device. If a database device is zapped, all records are deleted. If an ASCII file is
zapped, the file is truncated to 0 (zero) length. Use this function when you want to delete
all records in a database or file without deleting the actual file.
Syntax
DevZap(hDev)
hDev:
The device handle, returned from the DevOpen() function. The device handle
identifies the table where all data on the associated device is stored.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DevDelete
Example
! Delete all records in the alarm log database.
hDev = DevOpen("AlarmLog", 0);
DevZap(hDev);
See Also
Device Functions
Print
Prints a string on the current device. You should call this function only in a report. The out-
put is sent to the device (or group of devices) defined in the Reports database (in the output
device field).
Note: To print a new line in an RTF report, use the "\par" special character. For example,
Print("String" + "\par").
Syntax
Print(String)
String:
The string (data) to print.
Return Value
0 (zero) if successful, otherwise an error is returned.
276
Chapter: 24 Device Functions
Related Functions
PrintLn
Example
! Print "Testvar" and stay on the same line.
Print("Value of Testvar="+Testvar:##.#);
See Also
Device Functions
PrintFont
Changes the printing font on the current device. You should call this function only in a re-
port. It will change the font style for the device (or group of devices) defined in the Reports
database (output device field). It has effect only on reports being printed to a
PRINTER_DEV - it has no effect on other types of devices, such as ASCII_DEV and
dBASE_DEV.
Syntax
PrintFont(Font)
Font:
The CitectSCADA font (defined in the Fonts database).
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
Print
Example
The following report file...
{! example.rpt }
-------------------------------------
AN example Report
-------------------------------------
{CICODE}
PrintFont("HeadingFont");
{END}
Plant Area 1
{CICODE}
PrintFont("ReportFont");
{END}
{Time(1) } {Date(2) }
PV_1 {PV_1:#####.##}
PV_2 {PV_2:#####.##}
----------End of Report---------------
277
Chapter: 24 Device Functions
-------------------------------------
AN example Report
-------------------------------------
Plant Area 1
04:41:56 19-10-93
PV_1 49.00
PV_2 65.00
----------End of Report---------------
See Also
Device Functions
PrintLn
Prints a string on the current device, followed by a newline character. You should call this
function only in a report. The output will be sent to the device or group of devices defined
in the Reports database (in the output device field).
Note: To print a new line in an RTF report, use the "\par" special character. For example,
PrintLn("String" + "\par").
Syntax
PrintLn(String)
String:
The string (data) to print.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
Print
Example
! Print "Testvar" followed by a new line.
PrintLn("Value of Testvar="+Testvar:##.#);
See Also
Device Functions
278
Chapter: 25 Display Functions
Display functions control the display and processing of graphics pages and objects. You
can use these functions to display graphics pages, print them on your printer, send them to
a file, or copy them to the Windows Clipboard. You can also display text files on screen.
Note: The properties defined for an object will override any conflicting Cicode Display
functions.
You can create and move ANs (animation-point numbers), and obtain runtime information
about graphics pages and their associated ANs.
Display Functions
Following are functions relating to the display of graphics pages and objects:
DspAnCreateControlObject Creates a new instance of an ActiveX object. If the ob-
ject already exists for the given Animation Point Num-
ber, then that object will be used (a new object is not
created).
DspAnFree Frees (removes) an AN from the current page.
DspAnGetArea Gets the area configured for an object at a specific AN
(animation-point number).
DspAnGetPos Gets the x and y coordinates of an AN (animation-point
number).
DspAnGetPrivilege Gets the privileges configured for an object at a specific
AN (animation-point number).
DspAnInfo Gets information on the state of the animation at an
AN.
DspAnInRgn Checks if an AN is within a specified region.
DspAnMove Moves an AN.
DspAnMoveRel Moves an AN relative to its current position.
DspAnNew Creates an AN.
DspAnNewRel Creates an AN relative to another AN.
DspBar Displays a bar graph at an AN.
DspBmp Displays a bitmap at a specified AN.
DspButton Displays a button at an AN and puts a key into the key
command line (when the button is selected).
DspButtonFn Displays a button at an AN and calls a function when
the button is selected.
DspChart Displays a chart at an AN.
DspCol DspCol is deprecated in this version.
DspDel Deletes all objects at an AN.
DspDelayRenderBegin Delays screen updating until DspDelayRenderEnd() is
called.
DspDelayRenderEnd Ends the screen update delay set by DspDelayRender-
Begin().
DspDirty Forces an update to an AN.
279
Chapter: 25 Display Functions
280
Chapter: 25 Display Functions
See Also
Functions Reference
DspAnCreateControlObject
Creates a new instance of an ActiveX object. If the object already exists for the given Ani-
mation Point Number, then that object will be used, that is a new object will not be created,
the existing object will merely be refreshed.
AN object created using this function remains in existence until the page is closed or the
associated Cicode Object is deleted.
281
Chapter: 25 Display Functions
Syntax
DspAnCreateControlObject(AN, sClass, Width, Height [, sEventClass] )
AN:
The animation-point number.
sClass:
The class of the object. You can use the object’s human readable name, its pro-
gram ID, or its GUID. If the class does not exist, the function will return an error.
For example:
"Calendar Control 8.0" - human readable name
"MSCAL.Calendar.7" - Program ID
"{8E27C92B-1264-101C-8A2F-040224009C02}" - GUID
Width:
The width of the ActiveX object.
Height:
The height of the ActiveX object.
sEventClass:
The string you would like to use as the event class for the object.
Return Value
The newly created object, if successful, otherwise an error is generated.
Related Functions
CreateObject, CreateControlObject
Example
See CreateControlObject
See Also
Display Functions
DspAnFree
Note: This function is only used for V3.xx and V4.xx animations, and will be superseded in
future releases.
Frees (removes) an AN from the current page. If an animation exists at the animation num-
ber, it is deleted before the AN is freed. Use this function to free existing ANs or ANs cre-
ated with the DspAnNew() function. Please be aware that the ANs are only freed in
memory - the change is not permanent. The next time the page is opened it will display the
AN.
Syntax
DspAnFree(AN)
AN:
The animation-point number.
282
Chapter: 25 Display Functions
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspAnNew
Example
/* Remove AN20 from the current page. */
DspAnFree(20);
See Also
Display Functions
DspAnGetArea
Gets the area configured for an object at a specific AN (animation-point number). The area
is returned as an integer.
Note: This function does not return the areas of keyboard commands associated with the
object.
Syntax
DspAnGetArea(AN)
AN:
The animation-point number.
Return Value
The area if successful, otherwise an error is returned. If the object is configured with ’Same
area as page’ checked, the area of the page will be returned. AN area of 0 (zero) means no
areas are configured for the object.
Related Functions
DspAnGetPrivilege
Example
/* Get the area configured for the object at AN60. /
DspAnGetArea(60);
See Also
Display Functions
DspAnGetPos
Gets the x and y coordinates of an AN, in pixels, relative to the top-left corner of the win-
dow.
283
Chapter: 25 Display Functions
Syntax
DspAnGetPos(AN, X, Y)
AN:
The animation-point number.
X, Y:
The variables used to store the x and y pixel coordinates of the AN, returned from
this function.
Return Value
0 (zero) if successful, otherwise an error is returned. The X and Y variables are set to the
AN’s position if successful, or to -1 if an error has been detected.
Related Functions
DspAnMove, DspAnInRgn, DspGetAnCur, DspGetMouse, DspGetNearestAn
Example
/* Get the position of AN20 into X and Y. /
DspAnGetPos(20,X,Y);
See Also
Display Functions
DspAnGetPrivilege
Gets the privileges configured for an object at a specific AN (animation-point number). The
privilege is returned as an integer.
Note: This function does not return the privileges of keyboard commands associated with
the object.
Syntax
DspAnGetPrivilege(AN)
AN:
The animation-point number.
Return Value
The privilege if successful, otherwise an error is returned. A privilege of 0 (zero) means no
privileges are configured for the object.
Related Functions
DspAnGetArea
Example
/* Get the privileges of the object at AN45. /
DspAnGetPrivilege(45);
284
Chapter: 25 Display Functions
See Also
Display Functions
DspAnInfo
Note: This function is only used for V3.xx and V4.xx animations, and has been superseded
by future releases.
Gets information on an AN - the type or state of the animation that is currently displayed.
Syntax
DspAnInfo(AN, Type)
AN:
The animation-point number.
Type:
The type of information:
0 - The type of animation currently displayed at the AN. The following is re-
turned:
1 - No animation is displayed.
2 - Color is displayed.
3 - A bar graph is displayed.
4 - Text is displayed.
5 - A symbol is displayed.
6 - AN animation symbol is displayed.
7 - A trend is displayed.
8 - A button is displayed.
9 - A slider is displayed.
10 - A plot is displayed.
11 - The state of the animation currently displayed. If color is displayed, the color
is returned. If a bar graph, trend, or symbol is displayed, the bar, trend, or
symbol name is returned. If text is displayed, the font handle is returned.
Return Value
The animation information, as a string.
Related Functions
DspGetAnCur
Example
IF DspAnInfo(25,0) = "1" THEN
/* If color on AN 25, then get the color */
col = DspAnInfo(25,1);
END
285
Chapter: 25 Display Functions
See Also
Display Functions
DspAnInRgn
Checks if an AN is within a region bounded by two ANs.
Syntax
pAnInRgn(AN, One, Two)
AN:
The animation-point number.
One, Two:
One - the AN at a corner of the region; two - the AN at the opposite corner of the
region.
Return Value
1 if the AN is within the region, or 0 (zero) if it is not.
Example
DspGetMouse(X,Y);
DspAnMove(250,X,Y);
IF DspAnInRgn(250,20,30) THEN
Prompt("Mouse in region bounded by AN20 and AN30");
ELSE
Prompt("Mouse not in region");
END
See Also
Display Functions
DspAnMove
Note: This function is only used for V3.xx and V4.xx animations, and was superseded by
future releases.
Moves an AN to a new position. Any animation at this AN is also moved.
Syntax
DspAnMove(AN, X, Y)
AN:
The animation-point number.
X:
The x pixel coordinates of the new position.
Y:
The y pixel coordinates of the new position.
286
Chapter: 25 Display Functions
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspAnMoveRel
Example
DspAnMove(25,100,200);
! Moves AN25 to pixel location 100,200.
See Also
Display Functions
DspAnMoveRel
Note: This function is only used for V3.xx and V4.xx animations, and was superseded by
future releases.
Moves an AN relative to its current position. Any animation at this AN is also moved.
Syntax
DspAnMoveRel(AN, X, Y)
AN:
The animation-point number.
X:
The number of pixels to move the AN in the x plane.
Y:
The number of pixels to move the AN in the y plane.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspAnMove
Example
DspAnMoveRel(25,10,20);
/* Moves AN25 by 10 pixels to the right and 20 pixels downward,
relative to its current position. */
See Also
Display Functions
DspAnNew
287
Chapter: 25 Display Functions
Note: This function is only used for V3.xx and V4.xx animations, and was superseded in
later releases.
Creates an AN at the specified x and y coordinates.
Syntax
DspAnNew(X, Y)
X:
The x pixel coordinate where the new AN is created.
Y:
The y pixel coordinate where the new AN is created.
Return Value
If successful, the new AN is returned. If the AN cannot be created, -1 is returned. If an AN
already exists at this location, that AN is returned.
Related Functions
DspAnNewRel, DspAnFree
Example
AN=DspAnNew(100,200);
DspSym(AN,20);
/* Displays symbol 20 at pixel location 100,200 */
See Also
Display Functions
DspAnNewRel
Note: This function is only used for V3.xx and V4.xx animations, and was superseded in
later releases.
Creates an AN at a distance of x,y pixels from a specified AN.
Syntax
DspAnNewRel(AN, X, Y)
AN:
The AN used as a reference for the new AN.
X:
The distance in the x plane (in pixels) from the reference AN to the new AN.
Y:
The distance in the y plane (in pixels) from the reference AN to the new AN.
Return Value
If successful, the new AN is returned. If the AN cannot be created, -1 is returned. If an AN
already exists at this location, that AN is returned.
288
Chapter: 25 Display Functions
Related Functions
DspAnNew, DspGetAnCur
Example
AN=DspAnNewRel(20,100,200);
/* Creates an AN at 100x and 200y pixels from AN20 */
See Also
Display Functions
DspBar
Displays a bar graph (on a graphics page) at a specified AN. To scale a tag into the correct
range, use the EngToGeneric() function.
Note: This function is only used for V3.xx and V4.xx animations, and was superseded in
later releases.
Syntax
DspBar(AN, Bar, Value)
AN:
The AN where the bar graph will be displayed.
Bar:
The name of the bar graph to display in the format <[LibName.]BarName>. If you
do not specify the library name, a bar graph from the Global library displays (if it
exists). To display a Version 1.xx bar graph, specify the bar definition (1 to 255).
For example, if you specify bar 1, CitectSCADA displays the bar graph Glo-
bal.Bar001.
Value:
The value to display on the bar graph. The value must be from 0 to 32000 to give
0 to full-scale range on the bar.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
EngToGeneric
Example
DspBar(25,"Bars.Loops",320);
/* Displays a value of 320 (that is 10%) on the loops bar (from the
bars library) at AN25. */
DspBar(25,3,320);
/* Displays a value of 320 (that is 10%) on bar definition 3
(CitectSCADA Version 1.xx) at AN25. */
DspBar(26,"Loops_Bar",EngToGeneric(Tag1,0,100));
/* Displays Tag1 on the loops_bar (from the global library) at
AN26. Tag1 has an engineering scale of 0 to 100. */
289
Chapter: 25 Display Functions
See Also
Display Functions
DspBmp
Displays a bitmap at a specified AN. This function allows you to display any bitmap file at
run time. (You can get a new bitmap file from operator input or from the plant, and display
it dynamically.)
Note: This function is only used for V3.xx and V4.xx animations, and was superseded in
later releases.
Syntax
DspBmp(AN, sFile, Mode)
AN:
The animation-point number.
sFile:
The name of the bitmap (.BMP) file. The file must be in the user project path.
(Does not support 1 bit, 24 bit or OS/2 bitmaps.)
Mode:
The mode of bitmap display:
0 - Erase the existing bitmap and display this bitmap.
1 - Do not erase the existing bitmap, just draw the new bitmap. (This mode pro-
vides smoother animation than Mode 0, but the bitmaps must be the same
size).
2 - Do not erase the existing bitmap, just draw the new bitmap. This mode is sim-
ilar to mode 1, but it displays the bitmap about 3 times faster. However, the
bitmap should not contain any transparent color, or it will display as a ran-
dom color. Use this mode for fast, smooth animation.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspDel
Example
// Display the bitmap "MyImage.bmp" at AN 60
DspBMP(60, "MyImage.bmp", 0)
See Also
Display Functions
DspButton
290
Chapter: 25 Display Functions
Displays a button at a specified AN. When the button is selected, the key definition is put
into the key command line. The font, width, height, and down and repeat keys of the button
are optional. If you do not specify a width and height, the button adjusts to the size of the
button Name.
Note: This function is only used for V3.xx and V4.xx animations, and was superseded in
later releases.
Syntax
DspButton(AN, UpKey, Name [, hFont] [, Width] [, Height] [, DownKey] [, RepeatKey] [, Style])
AN:
The animation-point number.
UpKey:
The key generated when the command button is selected (when the mouse but-
ton is released after being clicked down). This is the default operation for com-
mands activated by a button.
Name:
The name to display on the button.
hFont:
The handle of the font used to display the button name. Use the DspFont() func-
tion to create a new font and return the font handle. Use the DspFontHnd() func-
tion to return the font handle of an existing font. The Windows button font is used
if the font is omitted or is not defined in the database.
Width:
The width of the button in pixels.
Height:
The height of the button in pixels.
DownKey:
The key generated when the mouse button is clicked down (over the command
button). Normally this parameter is not used, because most buttons are config-
ured to activate a command when the mouse button is released (returning to the
‘up’ position).
RepeatKey:
The key generated repetitively, while the mouse button is being held down (over
the command button).
Style:
A number indicating the visibility style of the button:
0 - NORMAL: The button appears as a standard button.
1 - BORDER_3D: The button is drawn with only the 3-D border (transparent
face).
2 - BORDER: The button is drawn with only a thin line border.
3 - TARGET: The button is totally transparent - this constitutes a screen target.
Return Value
0 (zero) if successful, otherwise an error is returned.
291
Chapter: 25 Display Functions
Related Functions
DspButtonFn, KeySetSeq, DspFont, DspFontHnd
Example
/* Display a self-sizing button at AN20 using the default font.
The button is named "Help". When selected, the Key Code "KEY_F1"
is put into the key command line. */
DspButton(20,KEY_F1,"Help");
/* Display the same button at AN20, but in an existing font called
"BigFont". */
DspButton(20,KEY_F1,"Help",DspFontHnd("BigFont");
See Also
Display Functions
DspButtonFn
Displays a button at a specified AN. When the button is selected, a user function is called.
If the width and height are 0 (zero), then the button adjusts to the size of the button Name.
Note: This function is only used for V3.xx and V4.xx animations, and was superseded in
later releases.
Syntax
DspButtonFn(AN, UpFunction, Name [, hFont] [, Width] [, Height] [, DownFunction] [, Repeat-
Function] )
AN:
The animation-point number.
UpFunction:
The user function called when the command button is selected (when the mouse
button is released after being clicked down). This is the default operation for com-
mands activated by a button. This callback function can have no arguments, so
specify the function with no parentheses (). The callback function must return
INT as its return data type. You cannot specify a CitectSCADA built-in function
for this argument.
Name:
The name to display on the button.
hFont:
The handle of the font used to display the button name. Use the DspFont() func-
tion to create a new font and return the font handle. Use the DspFontHnd() func-
tion to return the font handle of an existing font. The Windows button font is used
if the font is omitted or is not defined in the database.
Width:
The width of the button in pixels.
Height:
The height of the buton in pixels.
292
Chapter: 25 Display Functions
DownFunction:
The user function called when the mouse button is clicked down (over the com-
mand button). Normally this parameter is not used, because most buttons are
configured to activate when the mouse button is released (returning to the ‘up’
position). The callback function must have no arguments, so specify the function
with no parentheses (). The callback function must return INT as its return data
type. You cannot specify a CitectSCADA built-in function for this argument.
RepeatFunction:
The user function called repetitively, while the mouse button is being held down
(over the command button) The callback function must have no arguments, so
specify the function with no parentheses (). The callback function must return
INT as its return data type. You cannot specify a CitectSCADA built-in function
for this argument.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspButton, DspFont, DspFontHnd
Example
DspButtonFn(20,MyFunc,"Help",0,50,10);
! Call this function when the button is selected.
INT
FUNCTION
MyFunc()
PageDisplay("Help");
RETURN 0;
END
See Also
Display Functions
DspChart
Displays a chart at an AN. Charts are trend lines with markers on them. Values are plotted
on the chart pens. You must specify Value1, but Value2 to Value8 are optional.
If more values (than the configured pens) are specified, the additional values are ignored.
If fewer values (than the configured pens) are specified, the pens that have no values are
not displayed.
You should use this function only if you want to control the display of charts directly.
Syntax
DspChart(AN, Chart, Value1 [, Value2 ... Value8] )
AN:
The AN where the chart will be displayed.
Chart:
293
Chapter: 25 Display Functions
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspDel, DspTrend
Example
/* Using chart definition 5 at AN25, display a value of 10 on
Pen1, 20 on Pen2, 30 on Pen3 and 40 on Pen4 of the chart. */
DspChart(25,5,10,20,30,40);
/* Using chart definition 6 at AN26, display a value of 100 on Pen1
and 500 on Pen2 of the chart. */
DspChart(26,6,100,500);
See Also
Display Functions
DspCol
DspCol is deprecated in this version of CitectSCADA.
Syntax
DspCol(AN, Color)
AN:
The animation-point number.
Color:
The color to display at the AN.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspDel
Example
DspCol(25,RED);
/* Displays the color red at AN25. */
294
Chapter: 25 Display Functions
See Also
Display Functions
DspDel
Deletes all objects from a specified AN.
Note: This function is only used for V3.xx and V4.xx animations, and was superseded in
later releases.
Syntax
DspDel(AN)
AN:
The animation-point number.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspDirty
Example
DspDel(25);
! Deletes all animation at AN25.
See Also
Display Functions
DspDelayRenderBegin
Delays screen updating until DspDelayRenderEnd is called. This function should be used
with DspDelayRenderEnd() to "sandwich" Cicode that will modify the appearance of a
page. The code should be preceded by DspDelayRenderBegin(), and followed by DspDe-
layRenderEnd(). This will reduce screen update times, because the modifying code is given
time to execute before the page is updated with the changes, and the changes are all made
in a single re-draw.
Note: If you have not changed the [Page]DelayRenderAll parameter from its default
(TRUE), then you do not need to use this function.
You can call this function as many times in a row as you like, as long as each is ended with
a call to DspDelayRenderEnd.
Because your display will stop updating while the "sandwiched" code runs, you should try
to make that code as efficient as possible. Do not call Sleep() or any other Cicode functions
that will take a long time to run.
Do not call WinSelect within the "sandwiched" code. Do not call this function directly from
the Kernel.
295
Chapter: 25 Display Functions
Syntax
DspDelayRenderBegin()
Related Functions
DspDelayRenderEnd
Example
/* Begin delay so the following code can be executed before the
images are re-drawn. */
DspDelayRenderBegin();
DspBMP(50, "Image1.bmp", 0) ! Display the bitmap "Image1.bmp"
at AN 50
DspBMP(100, "Image2.bmp", 0) ! Display the bitmap "Image2.bmp"
at AN 100
DspBMP(150, "Image3.bmp", 0) ! Display the bitmap "Image3.bmp"
at AN 150
DspBMP(200, "Image4.bmp", 0) ! Display the bitmap "Image4.bmp"
at AN 200
DspBMP(250, "Image5.bmp", 0) ! Display the bitmap "Image5.bmp"
at AN 250
/* End delay so the images can be re-drawn. */
DspDelayRenderEnd();
See Also
Display Functions
DspDelayRenderEnd
Ends the screen update delay set by DspDelayRenderBegin. This function should be used
with DspDelayRenderBegin() to "sandwich" Cicode that will modify the appearance of a
page. The code should be preceded by DspDelayRenderBegin(), and followed by DspDe-
layRenderEnd(). This will reduce screen update times, because the modifying code is given
time to execute before the page is updated with the changes, and the changes are all made
in a single re-draw.
Because your display will stop updating while the "sandwiched" code runs, you should try
to make that code as efficient as possible. Do not call Sleep() or any other Cicode functions
that will take a long time to run.
Do not call WinSelect within the "sandwiched" code. Do not call this function directly from
the Kernel.
Note: If you have not changed the [Page]DelayRenderAll parameter from its default
(TRUE), then you do not need to use this function.
Syntax
DspDelayRenderEnd()
Return Value
No value is returned.
296
Chapter: 25 Display Functions
Related Functions
DspDelayRenderBegin
Example
/* Begin delay so the following code can be executed before the
images are re-drawn. */
DspDelayRenderBegin();
DspBMP(50, "Image1.bmp", 0) ! Display the bitmap "Image1.bmp"
at AN 50
DspBMP(100, "Image2.bmp", 0) ! Display the bitmap "Image2.bmp"
at AN 100
DspBMP(150, "Image3.bmp", 0) ! Display the bitmap "Image3.bmp"
at AN 150
DspBMP(200, "Image4.bmp", 0) ! Display the bitmap "Image4.bmp"
at AN 200
DspBMP(250, "Image5.bmp", 0) ! Display the bitmap "Image5.bmp"
at AN 250
/* End delay so the images can be re-drawn. */
DspDelayRenderEnd();
See Also
Display Functions
DspDirty
Forces CitectSCADA to update an AN. Normally, CitectSCADA updates the animation on
the AN only if the data has changed. This function tells CitectSCADA to update the AN the
next time it animates the AN - even if the data has not changed.
Use this function when you have complex animations that overlap. If two or more anima-
tions overlap, you should use the DspDel() or DspDirty() function on their ANs, and then
display them in the same order (when they need to be updated).
Note: This function is only used for V3.xx and V4.xx animations, and was superseded in
later releases.
Syntax
DspDirty(AN)
AN:
The animation-point number.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspDel
Example
DspDirty(20);
! Forces an update of AN20.
297
Chapter: 25 Display Functions
See Also
Display Functions
DspError
Displays an error message at the prompt AN on the operator’s computer. You can disable
the error message display (of this function) by setting the Cicode execution mode in the
CodeSetMode() function.
Syntax
DspError(String)
String:
The message to be displayed.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
CodeSetMode, Prompt
Example
DspError("Error found");
! Displays "Error found" at the prompt AN.
See Also
Display Functions
DspFile
Defines the screen attributes for displaying a text file. This function defines a "window"
where the file will be displayed. You should call this function before any file-to-screen
function.
You must define sequential ANs for each line of text in the display. The file is displayed
starting at the specified AN, then the next (highest) AN, and so on. You should not use pro-
portionally-spaced fonts, because the columns of text might not be aligned.
You would normally call this function as the entry function for a graphics page. Use the
DspFileSetName() function to specify the file to be displayed. This function is a low level
animation function - it controls exactly how the file is to display. If you just want to display
a file, use the PageFile() function.
Syntax
DspFile(AN, hFont, Height, Width)
AN:
298
Chapter: 25 Display Functions
The AN where the file display window will be positioned. When this is set to -2,
the window will be created in the Citect Kernel. However, the hFont argument is
ignored.
hFont:
The handle for the font that is used to display the file, returned from the Dsp-
Font() or DspFontHnd() function. The font handle identifies the table where all
data on the associated font is stored.
Height:
The maximum number of lines to display on one page of the file display window.
Width:
The width of the file display window, in characters.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
PageFile, DspFileGetInfo, DspFileGetName, DspFileScroll, DspFileSetName, DspFont,
DspFontHnd
Example
DspFile(20,0,20,80);
/* Defines the attributes of a screen display to start at AN20,
using the default font, with a window size of 20 lines x 80
columns. */
See Also
Display Functions
DspFileGetInfo
Gets the attributes of a file-to-screen display (used for displaying text files).
Syntax
DspFileGetInfo(AN, Type)
AN:
The AN where the file display window will be located. This AN must be the same
as the AN specified with the DspFile() function.
Type:
The type of data required:
0 - The width of the file display window, in characters.
1 - The maximum number of lines that can display in one page of the file display
window.
2 - The file-to-screen row offset number.
3 - The file-to-screen column offset number.
4 - The number of lines in the displayed file.
299
Chapter: 25 Display Functions
Return Value
The attributes of the "window" as an integer. If an incorrect AN is specified, an error is re-
turned.
Related Functions
DspFile, DspFileGetName, DspFileScroll, DspFileSetName
Example
! Display the page number of the file display.
PageNumber=IntToStr(DspFileGetInfo(20,2)/DspFileGetInfo(20,1)+1);
DspText(12,0,"Page No "+PageNumber);
See Also
Display Functions
DspFileGetName
Gets the name of the file being displayed in the display "window". You can use this func-
tion to display the file name on the screen.
Syntax
DspFileGetName(AN)
AN:
The animation-point number.
Return Value
The name of the file (as a string). If an incorrect AN is specified, an error is returned.
Related Functions
DspFile, DspFileGetInfo, DspFileScroll, DspFileSetName
Example
DspText(11,0,DspFileGetName(20));
! Displays the name of the file displayed at AN20.
See Also
Display Functions
DspFileScroll
Scrolls a file (displayed in the display "window") by a number of characters.
Syntax
DspFileScroll(AN, Direction, Characters)
AN:
300
Chapter: 25 Display Functions
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspFile, DspFileGetInfo, DspFileSetName, DspFileGetName
Example
Page Keyboard
Key Sequence PgUp
Command DspFileScroll(20,3,10)
Comment Scroll up 10 lines
See Also
Display Functions
DspFileSetName
Sets the name of the file to display in the display "window". You should call the DspFile()
function first (as the entry function for a graphics page) to define the attributes of the dis-
play. You can then use the DspFileSetName() function (as a keyboard command) to display
a user-specified file. When you call this function, the specified file name is read from disk
and displayed on the screen.
Syntax
DspFileSetName(AN, sName)
AN:
The animation-point number.
sName:
The name of the file to display.
Return Value
0 (zero) if successful, otherwise an error is returned.
301
Chapter: 25 Display Functions
Related Functions
DspFile, DspFileGetInfo, DspFileGetName, DspFileScroll
Example
Pages
Page Name FilePage
Entry Command DspFile(20,0,20,80)
Comment Defines a file to screen display to commence at AN20
Page Keyboard
Key Sequence ######## Enter
Command DspFileSetName(20, Arg1)
Comment Displays a specified file on the page
DspFile(20,0,20,80);
/* Defines the file-to-screen display to commence at AN20 using
the default font, with a window size of 20 lines x 80 columns. */
DspFileSetName(20,"C:\AUTOEXEC.BAT");
! Displays file C:\AUTOEXEC.BAT.
See Also
Display Functions
DspFont
Creates a font and returns a font handle. If the requested font already exists, its font handle
is returned. You can use this font handle in the functions that display text, buttons, and text
files.
If the exact font size does not exist, the closest font size is used.
Note: This function is only used for V3.xx and V4.xx animations, and was superseded in
later releases.
Syntax
DspFont(FontType, PixelSize, ForeOnColour, BackOnColour [, ForeOffColour] [, BackOffColour]
)
FontType:
The font type, for example, "Helv".
PixelSize:
The font size, as a positive number for pixels, or a negative number for points.
ForeOnColour:
The foreground color used for the text. If implementing flashing color, this is the
initial color that will be used. Select a color from the list of Predefined Color
Names and Codes or create an RGB-based color using the function MakeCitect-
Colour.
BackOnColour:
302
Chapter: 25 Display Functions
The color used for the background of text. If implementing flashing color, this is
the initial color that will be used. Select a color from the list of Predefined Color
Names and Codes or create an RGB-based color using the function MakeCitect-
Colour.
ForeOffColour:
An optional argument only required if implementing flashing color for the font
foreground. It represents the secondary color used. Select a color from the list of
Predefined Color Names and Codes or create an RGB-based color using the func-
tion MakeCitectColour.
BackOffColour:
An optional argument only required if implementing flashing color for the font
background. It represents the secondary color used. Select a color from the list of
Predefined Color Names and Codes or create an RGB-based color using the func-
tion MakeCitectColour.
Return Value
The font handle as an integer. If the font cannot be created, -1 is returned. The font handle
identifies the table where all data on the associated font is stored.
Related Functions
DspFontHnd, DspText, DspButton, DspButtonFn, DspFile
Example
Font=DspFont("Helv",-12,"White","Red");
DspText(20,Font,"Text in Helv Font");
/* Displays "Text in Helv Font" in 12-point Helvetica font in
white on red at AN20. */
Font=DspFont("Helv",24,"White","Red","White");
DspText(20,Font,"Text in Helv Font");
/* Displays "Text in Helv Font" in 24 pixel Helvetica font in
flashing black and white on red at AN20. */
See Also
Display Functions
DspFontHnd
Gets the font handle of a font that is defined in the Fonts database. You can use this font
handle in the functions that display text, buttons, and text files.
Note: This function is only used for V3.xx and V4.xx animations, and was superseded in
later releases.
Syntax
DspFontHnd(Name)
Name:
The font name in the fonts database.
303
Chapter: 25 Display Functions
Return Value
The font handle as an integer. If the font cannot be found, -1 is returned. The font handle
identifies the table where all data on the associated font is stored.
Related Functions
DspFont, DspText, DspButton, DspButtonFn, DspFile
Example
Fonts
Font Name BigFont
Font Type Helv
Pixel Size 24
Foreground Color Blue
Background Color -1
Comment Defines a font
hBigFont=DspFontHnd("BigFont");
DspText(20,hBigFont,"Text in Big Font");
/* Displays "Text in Big Font" in 24-point Helvetica font in blue
on an unchanged background at AN20. */
See Also
Display Functions
DspFullScreen
Disables or enables the full screen mode of the currently active window. This function does
not resize the window when it is called; it merely sets the mode flag. The next time the win-
dow is displayed, its size (on screen) changes to reflect the setting of the flag. This function
overrides the [Animator]FullScreen parameter setting.
If [Page]DynamicSizing is turned on, a page in full screen state takes up the entire display
area (assuming this does not affect its aspect ratio), and it cannot be resized. Also, a full
screen page will display without a title bar unless Title Bar is checked in Page Properties
(or was checked when the page was created). Resizing pages can result in degraded picture
quality. If this is unacceptable, you should re-design the page using the desired resolution.
If [Page]DynamicSizing is turned off, full screen will have the same limitations as it had in
versions of CitectSCADA prior to V5.10. In other words, for a page to be displayed in full
screen, the size of the page must be the same size as the display (or bigger). If the page is
smaller than the display, the title bar will still display even if full screen mode is enabled.
Check the size of the graphic pages in CtDraw Tools|Page Attributes Dialog to verify that
it is the same as the display resolution. For example 640x480 for VGA, 800x600 for SVGA
and 1024x768 for XGA.
Syntax
DspFullScreen(Mode)
Mode:
304
Chapter: 25 Display Functions
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
WinMode
Example
/*Minimize the Window, Enable full screen mode and then maximize
the window.*/
WinMode(6);
DspFullScreen(1);
WinMode(3);
See Also
Display Functions
DspGetAnBottom
Gets the bottom extent of the object at the specified AN.
Syntax
DspGetAnBottom(AN)
AN:
The animation-point number.
Return Value
The y coordinate of the bottom extent of the object at the AN. If no object exists at the AN,
-1 is returned.
Related Functions
DspGetAnBottom, DspGetAnWidth, DspGetAnHeight, DspGetAnLeft, DspGetAnRight,
DspGetAnTop, DspGetAnNext, DspGetAnExtent
Example
nBottom = DspGetAnBottom(30);
See Also
Display Functions
DspGetAnCur
305
Chapter: 25 Display Functions
Gets the number of the current graphics AN. You should only call this function from the
database, by using one of the Page forms (for example, the Page Number, Page String, and
Page Trend forms). This function is useful for writing general functions and macros that ap-
ply to graphics pages.
You cannot call this function from the Button or Keyboard forms.
Syntax
DspGetAnCur()
Return Value
The AN associated with the current record in the associated Page database. If this function
is called outside the page animation system then -1 will be returned.
Example
Numbers
AN 20
Expression MyFunc(PV_10)
Comment Display the value of PV_10 at AN20
See Also
Display Functions
DspGetAnExtent
Gets the extent of the object (the enclosing boundary) at the specified AN.
Syntax
DspGetAnExtent(AN, Top, Left, Bottom, Right)
AN:
The AN at which the object is positioned.
Top:
A buffer that contains the top-most extent of the object.
Left:
A buffer that contains the left-most extent of the object.
Bottom:
306
Chapter: 25 Display Functions
Return Value
0 (zero) if successful, otherwise an error is returned. The Top, Left, Bottom, and Right argu-
ments contain the extents of the object, in pixels.
Related Functions
DspGetAnWidth, DspGetAnHeight, DspGetAnLeft, DspGetAnRight, DspGetAnBottom,
DspGetAnTop
Example
// Get extents at AN 25.
DspGetAnExtent(25, Top, Left, Bottom, Right);
See Also
Display Functions
DspGetAnFirst
Gets the first AN on the current page, based on the order in which the ANs were stored by
Graphics Builder.
Syntax
DspGetAnFirst()
Return Value
The value for the first AN, otherwise an error is returned.
Related Functions
DspGetAnNext
See Also
Display Functions
DspGetAnFromPoint
Gets the AN of the object at a specified set of screen coordinates. If the X and Y coordinates
given are within the extents of an object, then the AN number of the object will be returned.
For example, if there is a button at coordinates (300, 140), and it is 100 wide, 50 high, this
function would return the AN if it uses X between 300 & 400 and Y between 140 and 190,
such as DspGetAnFromPoint(325,180).
307
Chapter: 25 Display Functions
Hint: If you are using groups and the specified coordinates point to an object that is part of
a group, the AN of the object is returned, not the AN of the group.
Syntax
DspGetAnFromPoint(X, Y [, PrevAN] )
X:
The x coordinate of the screen point.
Y:
The y coordinate of the screen point.
PrevAN:
Retrieves the previous AN (in z-order) in situations where a number of objects
overlap at the specified point. The default of 0 (zero) specifies no previous AN. A
non-zero value should only ever be passed if it is the result of a previous call to
DspGetAnFromPoint.
Return Value
The AN or 0 (zero) if no object exists at the point.
Example
DspGetMouse(X,Y);
// GetMouse position
AN = DspGetAnFromPoint(X,Y);
// Gets AN if mouse is over the object
Prompt("AN of object ="+AN:###);
!Displays the object’s AN at the prompt line
If several objects overlap each other at the specified point, the PrevAN argument can be
used to produce a list of the associated ANs. This is achieved by using PrevAN to pass the
previous result into another call of the function until a zero return is given.
INT nAn;
nAn = DspGetAnFromPoint(100,100)
WHILE nAn <> 0 DO
//Do Something
nAn = DspGetAnFromPoint(100,100,nAn);
END
See Also
Display Functions
308
Chapter: 25 Display Functions
DspGetAnHeight
Gets the height of the object at a specified AN.
Syntax
DspGetAnHeight(AN)
AN:
The animation-point number.
Return Value
The height of the object (in pixels). If no object exists at the AN, -1 is returned.
Related Functions
DspGetAnWidth, DspGetAnLeft, DspGetAnRight, DspGetAnBottom, DspGetAnTop
Example
nHeight = DspGetAnHeight(30);
See Also
Display Functions
DspGetAnLeft
Gets the left extent of the object at the specified AN.
Syntax
DspGetAnLeft(AN)
AN:
The animation-point number.
Return Value
The x coordinate of the left extent of the object at the AN. If no object exists at the AN, -1 is
returned.
Related Functions
DspGetAnWidth, DspGetAnHeight, DspGetAnRight, DspGetAnBottom, DspGetAnTop,
DspGetAnExtent
Example
nLeft = DspGetAnLeft(30);
See Also
Display Functions
309
Chapter: 25 Display Functions
DspGetAnNext
Returns the AN that follows the specified AN, based on the order in which the ANs were
stored on a page by Graphics Builder.
Syntax
DspGetAnNext(AN)
AN:
The animation-point number.
Return Value
The value for the next AN. If -1 is returned, it means the specified AN is invalid or it is the
last AN on the page.
Related Functions
DspGetAnFirst
See Also
Display Functions
DspGetAnRight
Gets the right extent of the object at the specified AN.
Syntax
DspGetAnRight(AN)
AN:
The animation-point number.
Return Value
The x coordinate of the right extent of the object at the AN. If no object exists at the AN, -1
is returned.
Related Functions
DspGetAnWidth, DspGetAnHeight, DspGetAnLeft, DspGetAnBottom, DspGetAnTop,
DspGetAnExtent
Example
nRight = DspGetAnRight(30);
See Also
Display Functions
DspGetAnTop
Gets the top extent of the object at the specified AN.
310
Chapter: 25 Display Functions
Syntax
DspGetAnTop(AN)
AN:
The animation-point number.
Return Value
The y coordinate of the top extent of the object at the AN. If no object exists at the AN, -1 is
returned.
Related Functions
DspGetAnWidth, DspGetAnHeight, DspGetAnLeft, DspGetAnRight, DspGetAnBottom,
DspGetAnExtent
Example
nTop = DspGetAnTop(30);
See Also
Display Functions
DspGetAnWidth
Gets the width of the object at a specified AN.
Syntax
DspGetAnWidth(AN)
AN:
The animation-point number.
Return Value
The width of the object (in pixels). If no object exists at the AN, -1 is returned.
Related Functions
DspGetAnHeight, DspGetAnLeft, DspGetAnRight, DspGetAnBottom, DspGetAnTop,
DspGetAnExtent
Example
nWidth = DspGetAnWidth(30);
See Also
Display Functions
DspGetEnv
Gets a page environment variable.
311
Chapter: 25 Display Functions
Syntax
DspGetEnv(sName)
sName:
The name of the variable (set using the page environment dialog)
Return Value
The value of the variable (as a string).
Example
FUNCTION
PageGroup()
PageDisplay(DspGetEnv("GroupMenu"));
END
See Also
Display Functions
DspGetMouse
Gets the x and y coordinates of the mouse position, relative to the top left corner of the win-
dow.
Syntax
DspGetMouse(X, Y)
X:
The variables used to store the x pixel coordinate of the mouse position, returned
from this function.
Y:
The variables used to store the y pixel coordinate of the mouse position, returned
from this function.
Return Value
0 (zero) if successful, otherwise an error is returned. The X and Y variables are set to the
mouse position.
Related Functions
KeyGetCursor, DspAnGetPos, DspGetMouseOver, DspGetNearestAn
Example
! If the mouse cursor is at x,y pixel coordinate 43,20;
DspGetMouse(X,Y);
! Sets X to 43 and Y to 20.
See Also
Display Functions
312
Chapter: 25 Display Functions
DspGetMouseOver
Determines if the mouse is within the boundaries of a given AN.
Syntax
DspGetMouseOver(AN)
AN
The AN of the animation you wish to check, or -1 for the current AN. Defaults to
-1.
Return Value
1 if within the specified AN, 0 if not.
Related Functions
KeyGetCursor, DspAnGetPos, DspGetMouse, DspGetNearestAn
See Also
Display Functions
DspGetNearestAn
Gets the AN nearest to a specified x,y pixel location.
If using groups and the nearest object to the specified coordinates is part of a group, the AN
of the object is returned, not the AN of the group.
Syntax
DspGetNearestAn(X, Y)
X:
The x coordinate (in pixels).
Y:
The y coordinate (in pixels).
Return Value
The animation point number (AN). A value of -1 is returned if no AN is found.
Related Functions
DspGetMouse, DspAnGetPos, DspGetAnFromPoint
Example
DspGetMouse(X,Y);
! Gets mouse position.
AN=DspGetNearestAn(X,Y);
! Gets AN nearest to the mouse.
Prompt("Mouse At AN"+AN:###);
! Displays AN nearest to the mouse.
313
Chapter: 25 Display Functions
See Also
Display Functions
DspGetParentAn
Gets the parent animation number (if any), for the specified animation number. AN anima-
tion point will have a parent animation point if it corresponds to an object in a group.
Syntax
DspGetParentAn(AN)
AN:
The animation-point number.
Return Value
The parent animation point number (AN). If no parent animation exists or an invalid ani-
mation number is passed, 0 (zero) is returned.
Related Functions
DspGetAnCur
Example
// Get the parent animation for object 89 (part of a symbol set)
AN = DspGetParentAn(89);
See Also
Display Functions
DspGetSlider
Gets the current position (value) of a slider at an AN. You can call this function in the slider
event to find the new position of the slider.
Note: This function is only used for V3.xx and V4.xx animations, and was superseded in
later releases.
Syntax
DspGetSlider(AN)
AN:
The animation-point number.
Return Value
The value of the slider from 0 to 32000. If no animation exists at the AN, -1 is returned.
Related Functions
DspSetSlider
314
Chapter: 25 Display Functions
Example
// Get the position of the slider at AN 30
nPos = DspGetSlider(30);
See Also
Display Functions
DspGetTip
Gets the tool tip text associated with an AN.
Syntax
DspGetTip(AN, Mode)
AN:
The AN from which to get the tool tip text. If no object is configured at the AN,
the function will return an empty string.
Mode:
0 - Tool tips from all animation records configured at the AN. Tips are concate-
nated with a newline character between each string. (This mode is only used for
V3.xx and V4.xx animations, and has been subsequently superseded.)
1 - The tool tip from the object configured at the AN.
Return Value
The tool tip text (as a string). If no user tip is available, an empty string is returned.
Related Functions
DspSetTip, DspTipMode
Example
!Display the tool tip text on AN19
DspText(19, 0, DspGetTip(KeyGetCursor(), 1));
See Also
Display Functions
DspGrayButton
Grays and disables a button. If the button is a symbol, the symbol is overwritten with a gray
mask. (When a button is grayed, it cannot be selected.) If the Disabled field in the Buttons
database is blank, the button is enabled unless you use this function. If the Disabled field
in the Buttons database contains an expression, this function will not override the expres-
sion.
Note: This function is only used for V3.xx and V4.xx animations, and was superseded in
later releases.
315
Chapter: 25 Display Functions
Syntax
DspGrayButton(AN, nMode)
AN:
The AN where the button is located.
nMode:
The mode of the operation:
0 - Ungray the button.
1 - (GRAY_SUNK) Recess the text or symbol (the text or symbol on the button is
recessed and shadowed).
2 - (GRAY_PART) This mode is now obsolete - it now has the same effect as
GRAY_ALL.
3 - (GRAY_ALL) - Mask the entire button (a gray mask displays over the face of
the button).
Return Value
0 (zero) if successful, otherwise, -1 (if no AN is found).
Related Functions
DspButton, DspButtonFn, DspIsButtonGray
Example
! Disable button at AN21
DspGrayButton(21, GRAY_SUNK);
See Also
Display Functions
DspInfo
Extracts individual pieces of object information from an AN. Each AN can have multiple
expressions associated with it, and each expression can have multiple variables associated
with it. You use an index to refer to each individual expressions or variables. Typically, you
would query the number of expressions, then the number of variables in a given expres-
sion, then the details of a given variable tag.
Note: Before calling this function you must first use DspInfoNew() to create a handle to
the information block from which you want to extract information.
Syntax
DspInfo(hInfo, Type, Index)
hInfo:
The object information block handle, as returned by DspInfoNew(). This handle
identifies the table (or block) where all object data is stored.
Type:
The type of data to extract:
316
Chapter: 25 Display Functions
Return Value
The object information (as a string). A blank string is returned if you specify a non-existent
expression or variable.
Related Functions
DspInfoNew, DspInfoField, DspInfoDestroy, TagSubscribe, SubscriptionAddCallback,
SubscriptionGetAttribute
Example
INT hInfo;
INT iEngineeringValue;
INT iNumberOfExpressions;
INT iNumberOfTags;
INT iExpressionIndex;
INT iTagIndex;
STRING sObjectType;
STRING sExpressionText;
317
Chapter: 25 Display Functions
STRING sExpressionResult;
STRING sExpressionContext;
STRING sTagName;
hInfo = DspInfoNew(AN);
IF (hInfo > -1) THEN
sObjectType = DspInfo(hInfo, 0, 0);
iNumberOfExpressions = StrToInt(DspInfo(hInfo, 7, 0));
FOR iExpressionIndex = 0 TO iExpressionIndex < iNumberOfExpressions DO
sExpressionText = DspInfo(hInfo, 1, iExpressionIndex);
sExpressionResult = DspInfo(hInfo, 2, iExpressionIndex);
sExpressionContext = DspInfo(hInfo, 6, iExpressionIndex);
iNumberOfTags = StrToInt(DspInfo(hInfo, 8, iExpressionIndex));
FOR iTagIndex = 0 TO iTagIndex < iNumberOfTags DO
sTagName = DspInfo(hInfo, 3, iTagIndex);
iEngineeringValue = StrToInt(DspInfo(hInfo, 5, iTagIndex));
..
END
..
END
END
See Also
Display Functions
DspInfoDestroy
Destroys an object information block created by DspInfoNew(). You should destroy an ob-
ject information block when you no longer need it, to free CitectSCADA resources.
When the page (with which the object is associated) is closed, CitectSCADA automatically
destroys the object information block.
Syntax
DspInfoDestroy(hInfo)
hInfo:
The object information block handle, as returned by DspInfoNew(). This handle
identifies the table (or block) where all object data is stored.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspInfo, DspInfoNew, DspInfoField, DspInfoValid
Example
hInfo=DspInfoNew(20);
! Do animation operation
DspInfoDestroy(hInfo);
318
Chapter: 25 Display Functions
See Also
Display Functions
DspInfoField
Obtains static and real-time data from a variable tag. You get static data from the Variable
Tags database. The additional field "Eng_Value", returns dynamic real-time data for the
variable tag. To get this real-time data, you must first call the DspInfoNew() function to get
the information block handle hInfo.
Getting the raw value of a variable tag using DspInfoField is no longer supported. To get
the raw value of a tag, use the TagSubscribe function, specifying a value of “Raw” for the
sScaleMode parameter. When using TagSubscribe, you can either call SubscriptionGetAt-
tribute to obtain the value whenever required or register callback cicode function to run
when the value changes. See TagSubscribe for more details.
Syntax
DspInfoField(hInfo, sTag, sField [, ClusterName] )
hInfo:
The object information block handle, as returned by DspInfoNew(). This handle
identifies the table (or block) where all data on the object is stored. Set this handle
to 0 (zero) if you do not require real-time data.
sTag:
The name of the variable tag. The name of the tag can be prefixed by the name of
the cluster that is "ClusterName.Tag". This argument does not support arrays. If
array syntax is used, the information will be retrieved for only the tag name.
sField:
The name of the field from which to extract the data:
Cluster - Name of the cluster in which the Tag resides
Comment - Variable tag comment
Eng_Full - Engineering Full Scale
Eng_Zero - Engineering Zero Scale
Eng_Units - Engineering Units
Eng_Value - Scaled engineering value - Dynamic
Field - Description
FullName - Full name of the tag in the form cluster.tagname.
Name - Variable Tag Name
Type - Data Type
Unit - I/O Device Name
ClusterName:
Specifies the name of the cluster in which the Tag resides. This is optional if you
have one cluster or are resolving the tag via the current cluster context. The argu-
ment is enclosed in quotation marks "".
Return Value
The data (as a string).
319
Chapter: 25 Display Functions
Related Functions
DspInfo, DspInfoNew, DspInfoDestroy, SubscriptionGetAttribute, SubscriptionAddCall-
back, TagSubscribe
Example
! Get the I/O device that Variable Tag "PV123" belongs to.
IODev=DspInfoField(0,"PV123","Unit");
! Get the real-time engineering value of a tag.
hInfo=DspInfoNew(20);
sTag=DspInfo(hInfo,3,0);
EngValue=DspInfoField(hInfo,sTag,"Eng_Value");
See Also
Display Functions
DspInfoNew
Creates an object information block. Use this function with the associated low-level anima-
tion information functions to get and process object information on an AN.
Note: When you have finished with the object information block, you must destroy it with
the DspInfoDestroy() function. There are limited number of info 383 blocks that can be al-
located, if they are not freed properly DspInfoNew will return -1.
If you need simple animation help, use the InfoForm() or the InfoFormAn() functions.
Syntax
DspInfoNew(AN)
AN:
The AN for which object information is provided.
Return Value
The object information block handle. If no object data is available, then -1 is returned.
Related Functions
DspInfo, DspInfoField, DspInfoDestroy, InfoForm, InfoFormAn
Example
/*This example creates a form, with the title "Tag Info" and a
size of 25 x 5 characters. It creates an information block for the
AN closest to the mouse cursor and then extracts the name, I/O
device, and engineering value for the first tag in the object
expression.*/
INT hInfo;
STRING sTag;
hInfo=DspInfoNew(DspGetNearestAN());
IF hInfo>-1 THEN
FormNew("Tag Info",25,5,2);
sTag=DspInfo(hInfo,3,0);
FormPrompt(0,0,sTag);
FormPrompt(0,16,DspInfoField(hInfo,sTag,"Unit"));
320
Chapter: 25 Display Functions
FormPrompt(0,32,DspInfoField(hInfo,sTag,"Eng_Value"));
FormRead(0);
DspInfoDestroy(hInfo);
END
See Also
Display Functions
DspInfoValid
Checks if an object information block handle is valid. An object information block handle
becomes invalid after it is destroyed, or if the user closes the page it is associated with. Use
this function if background Cicode is using the object information block, and the operator
closes the page.
Syntax
DspInfoValid(hInfo)
hInfo:
The object information block handle, as returned by DspInfoNew(). This handle
identifies the table (or block) where all object data is stored.
Return Value
1 if the information block handle is valid, otherwise 0 (zero).
Related Functions
DspInfoNew, DspInfoField, DspInfoDestroy
Example
IF DspInfoValid(hInfo) THEN
EngValue=DspInfoField(hInfo,sTag,"Eng_Value");
END
See Also
Display Functions
DspIsButtonGray
Gets the current status of a button.
Note: This function is only used for V3.xx and V4.xx animations, and has been superseded.
Syntax
DspIsButtonGray(AN)
AN:
The AN for which object information is provided.
321
Chapter: 25 Display Functions
Return Value
The current mode of the button:
0 - The button is active (not grayed).
1 - (SUNK_GRAY) The button is inactive (the text or symbol on the button is recessed).
2 - (PART_GRAY) This mode is now obsolete. The button will be inactive even if
part_gray is returned.
3 - (ALL_GRAY) The button is inactive (the entire button is masked).
Related Functions
DspButton, DspButtonFn, DspGrayButton
Example
! Check the status of the button at AN21
status = DspIsButtonGray(21);
See Also
Display Functions
DspKernel
Displays the Kernel window. You should restrict the use of this function because once you
are in the Kernel, you can execute any Cicode function with no privilege restrictions. You
therefore have total control of CitectSCADA (and subsequently your plant and equip-
ment). Please be aware that you can also open the Kernel by setting the Citect [De-
bug]Menu parameter to 1 and, when your system is running, selecting Kernel from the
control-menu box.
Note: You should be experienced with CitectSCADA and Cicode before attempting to use
the Kernel as these facilities are powerful, and if used incorrectly, can corrupt your system.
Note: You should only use the Kernel for diagnostics and debugging purposes, and not for
normal CitectSCADA operation.
You should restrict access to the Kernel, because once you are in the Kernel, you can exe-
cute any Cicode function with no privilege restrictions. You therefore have total control of
CitectSCADA (and subsequently your plant and equipment).
Syntax
DspKernel(iMode)
iMode:
The display mode of Kernel:
1 - Display the Kernel. If the Kernel is already displayed and iMode=1, the key-
board focus is changed to the Kernel.
0 - Hide the Kernel
Return Value
0 (zero) if successful, otherwise an error is returned.
322
Chapter: 25 Display Functions
Related Functions
KerCmd, TraceMsg
Example
DspKernel(1);
!Display the Citect Kernel window
See Also
Display Functions
DspMarkerMove
Moves a trend or chart marker to a specified position.
Syntax
DspMarkerMove(AN, hMarker, Offset)
AN:
The AN where the trend or chart is positioned.
hMarker:
The marker handle, as returned from the DspMarkerNew() function. The marker
handle identifies the table where all data on the associated marker is stored.
Offset:
The offset by which to move the marker. Vertical markers have an offset from 0
(zero) to the maximum number of samples in the trend. Horizontal markers have
a offset of 0 (zero) to 32000.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspMarkerNew, OnEvent
Example
See DspMarkerNew
See Also
Display Functions
DspMarkerNew
Creates a new trend marker. A trend marker is used to show cursor values or limits on a
trend. You can use up to 10 markers on a single trend or chart.
If you add markers to a trend or chart that CitectSCADA is animating, you must repaint
them using the trend paint event (OnEvent(Window,22)). (Otherwise CitectSCADA will de-
lete any markers displayed when the trend is updated.)
323
Chapter: 25 Display Functions
Syntax
DspMarkerNew(AN, Mode, Color)
AN:
The animation-point number.
Mode:
The mode of the marker:
0 - A vertical marker
1 - A horizontal marker
Color:
The color of the marker (flashing color not supported). Select a color from the list
of Predefined Color Names and Codes or create an RGB color using the function
MakeCitectColour.
Return Value
The marker handle, or -1 if the function is unsuccessful. The marker handle identifies the
table where all data on the associated marker is stored.
Related Functions
DspMarkerMove, OnEvent
Example
INT offset; ! offset of marker
INT hMarker; ! marker handle
hMarker = DspMarkerNew(40, 0, WHITE);
! create a new marker, vertical WHITE
offset = 100;
DspMarkerMove(40, hMarker, offset);
! Moves marker to offset 100
OnEvent(22, MyTrendPaint);
! set trend paint event, must stop event when change pages
! this function is called when CitectSCADA updates the trend
INT
FUNCTION
MyTrendPaint()
DspMarkerMove(40, hMarker, offset);
RETURN 0;
END
See Also
Display Functions
DspMCI
Controls a multimedia device. The Media Control Interface (MCI) is a high-level command
interface to multimedia devices and resource files. MCI provides applications with device-
independent capabilities for controlling audio and visual peripherals (for example, for
playing multimedia devices and recording multimedia resource files).
324
Chapter: 25 Display Functions
Using this function, you can control multimedia devices by using simple commands like
open, play, and close. MCI commands are a generic interface to multimedia devices. You
can control any supported multimedia device, including audio playback and recording.
For a full overview of MCI, see the Windows Multimedia Programmer’s Guide.
Syntax
DspMCI(sCommand)
sCommand:
The MCI command. See the Microsoft Windows Multimedia Programmer’s
Guide for details.
Return Value
A string message with the status of the MCI command.
Related Functions
DspPlaySound
Example
DspMCI("open cdaudio")
DspMCI("set cdaudio time format tmsf")
DspMCI("play cdaudio from 6 to 7")
DspMCI("close cdaudio")
/*Plays track 6 of an audio CD*/
DspMCI("open c:\mmdata\purplefi.wav type waveaudio alias finch")
DspMCI("set finch time format samples")
DspMCI("play finch from 1 to 10000")
DspMCI("close finch")
/*Plays the first 10,000 samples of a waveform audio file*/
See Also
Display Functions
DspPlaySound
Plays a waveform (sound). Wave form sound files *.WAV are provided with Windows and
by third-party developers, or you can record them yourself to play long (and complex)
sound sequences.
This function searches the [Sounds] section of the WIN.INI file for an entry with the speci-
fied name, and plays the associated waveform. If the name does not match an entry in the
WIN.INI file, a waveform filename is assumed. The function will then search the following
directories for the waveform file (directories are listed in search order):
The current directory
The Windows directory
The Windows system directory
The directories listed in the PATH environment variable
The list of directories mapped in the network.
325
Chapter: 25 Display Functions
If the file is not in one of the aforementioned directories, you must include the full path to
the sound file. If the file doesn’t exist in one of the above directories or at a location speci-
fied with a full path, the sound will not be played.
Syntax
DspPlaySound(sSoundname, nMode)
sSoundname:
The waveform to be played. Predefined sounds (in the WIN.INI file) are:
SystemAsterisk
SystemExclamation
SystemQuestion
SystemDefault
SystemHand
SystemExit
SystemStart
nMode:
Not used. Must be 0 (zero).
Return Value
TRUE if successful, otherwise FALSE (if an error is detected).
Related Functions
Beep
Example
DspPlaySound("C:\WINNT\MEDIA\Notify.wav",0);
DspPlaySound("SystemStart",0);
See Also
Display Functions
DspPopupMenu
Creates a popup menu consisting of a number of menu items. Multiple calls to this function
enable you to add new items and create sub menus, building a system of linked, Windows-
style menus.
Menu items can be displayed as checked and/or disabled. You can also specify a bitmap to
display as a menu icon.
This function is first called to build the menu’s items and links, and then called again to dis-
play it on the screen. In this final call, you have the option to specify the coordinates at
which the menu will display, or let it default to the current cursor position.
Syntax
DspPopupMenu(iMenuNumber, sMenuItems [, XPos] [, YPos] )
iMenuNumber:
326
Chapter: 25 Display Functions
An integer representing the menu you are adding items to. The first menu created
is Menu 0. If left unspecified, this parameter defaults to -1, causing the menu to
be displayed on the screen.
Multiple function calls with the same iMenuNumber allow you to build up en-
tries in a particular menu. For example, the following four function calls with iM-
enuNumber = 1 build up 8 entries in Menu 1:
DspPopupMenu(1, "Selection A>2, Selection B>3");
DspPopupMenu(1, "Selection C>2, Selection D");
DspPopupMenu(1, "Selection E>2, Selection F>3");
DspPopupMenu(1, "Selection G>2, Selection H");
sMenuItems:
A comma-separated string defining the items in each menu. The default value for
this parameter is an empty string, which will get passed to the function in the call
to display the menu.
The (!), (~), and (,) symbols control display options for menu items.
For example, !Item1 disables Item1; ~Item2 checks Item2; and ,Item3 inserts a sep-
arator above Item3. To insert a link from a menu item to a sub menu, use the (>)
symbol. For example, : Item4>1 means Item4 links to menu 1.
To insert a bitmap to the left of a menu item as its icon, use the following notation:
[Icon]Item5 Inserts the bitmap Icon.BMP to the left of Item5. [Icon] must be
placed before the Item name, but after any disable (!) or check (~) symbols you
may wish to specify.
Bitmap files used for menu icons must be saved in the project directory so that
they can be found by CitectSCADA.
XPos:
The x-coordinate at which the menu will be displayed. This parameter is option-
al. If it is left unspecified, the menu will display at the cursor’s current position.
YPos:
The y-coordinate at which the menu will be displayed. This parameter is option-
al. If it is left unspecified, the menu will display at the cursor’s current position.
Return Value
The selected menu item as an integer. This comprises the menu number (return value div
100), and the position of the item in the menu (return value mod 100). For example, a return
value of 201 indicates that the first item in Menu 2 was selected, and a return value of 3 in-
dicates that the third item in Menu 0 was selected.
Note: Links to sub menus are not counted as menu items. For example, if your menu con-
sists of 10 links and one unlinked item, the function will return only when the unlinked
item is selected.
Example1
!Example 1 illustrates one menu with three menu items.
FUNCTION BuildPopupMenus()
INT iSelection;
DspPopupMenu(0, "Item 1,!Item 2,~Item 3");
iSelection = DspPopupMenu(-1, "", 150, 300);
! The above builds a menu with three items:
! ’Item 1’ will be shown as normal, ’Item 2’ will be shown as disabled,
! and ’Item 3’ will be shown as checked.
! The menu will be displayed at position (150, 300).
327
Chapter: 25 Display Functions
END
Example 2
!Example 2 illustrates the creation of two menus which are linked.
FUNCTION BuildLinkedPopupMenus()
INT iSelection;
DspPopupMenu(0, "Item A,Item B>1,Item C");
DspPopupMenu(1, "Item B1,,[Trend]Item B2,,Item B3");
iSelection = DspPopupMenu();
! The above will build two menus - Menu 0 and Menu 1
! Item B on Menu 0 links to Menu 1.
! ’Item B2’ will be shown with Trend.BMP at its left.
! The menu will be displayed at the cursor’s position.
! If ’Item A’ is selected, iSelection will equal 1
! If ’Item C’ is selected, iSelection will equal 2
! If ’Item B1’ is selected, iSelection will equal 101
! If ’Item B2’ is selected, iSelection will equal 102
! If ’Item B3’ is selected, iSelection will equal 103
END
See Also
Display Functions
DspRichText
Creates a Rich Text object of the given dimensions at the animation point AN. This object
can then be used to display an RTF file (like an RTF report) called using the DspRichText-
Load function.
Syntax
DspRichText(AN, iHeight, iWidth, iMode)
AN:
The AN at which the rich text object will display when the DspRichText com-
mand is run.
iHeight:
The height of the rich text object in pixels. The height is established by measuring
down from the animation point.
iWidth:
The width of the rich text object in pixels. The width is established by measuring
across to the right from the animation point.
iMode:
The display mode for the rich text object. The mode can be any combination of:
0 - Disabled - should be used if the rich text object is to be used for display pur-
poses only.
1 - Enabled - allows you to select and copy the contents of the RTF object (for in-
stance an RTF report), but you will not be able to make changes.
328
Chapter: 25 Display Functions
2 - Read/Write - allows you to edit the contents of the RTF object. Remember,
however, that the object must be enabled before it can be edited. If it has
already been enabled, you can just enter Mode 2 as your argument. If it is
not already enabled, you will need to enable it. By combining Mode 1 and
Mode 2 in your argument (3), you can enable the object, and make it read/
write at the same time.
Because the content of the rich text object is just a copy of the original file, changes
will not affect the actual file, until saved using the DspRichTextSave function.
Return Value
0 if successful, otherwise an error is returned.
Related Functions
DspRichTextLoad, PageRichTextFile
Example
//This will produce a rich text object at animation point 57,
which is 200 pixels high, and 200 pixels wide. This object will be
for display purposes only (that is read only)//
DspRichText(57,200,200,0);
See Also
Display Functions
DspRichTextEdit
Enables editing of the contents of the rich text object at AN if nEdit = TRUE, and disables
editing if nEdit = FALSE.
Syntax
DspRichTextEdit(AN, bEdit)
AN:
The reference AN for the rich text object.
bEdit:
The value of this argument determines whether you will be able to edit the con-
tents of the rich text object at AN. Enter TRUE to enable editing, or enter FALSE
to make the contents read-only.
Changes made to the contents of the object will not be saved until the DspRich-
TextSave function is used.
Return Value
0 if successful, otherwise an error is returned.
Related Functions
PageRichTextFile, DspRichTextEnable, DspRichTextSave
329
Chapter: 25 Display Functions
Example
// Enables editing of the rich text object at AN 25 - if one
exists. Otherwise an error will be returned to iResult //
iResult = DspRichTextEdit(25,TRUE);
See Also
Display Functions
DspRichTextEnable
Enables the rich text object at AN if nEnable = TRUE, and disables the object if nEnable =
FALSE. When the object is disabled, its contents cannot be selected or copied etc.
Syntax
DspRichTextEnable(AN, bEnable)
AN:
The reference AN for the rich text object.
bEnable:
The value of this argument determines whether the rich text object at AN will be
enabled or disabled. Enter TRUE to enable the object (that is you can select and
copy the contents of the RTF object, but you can’t make changes). Enter FALSE to
disable the object (that is make it display only).
Return Value
0 if successful, otherwise an error is returned.
Related Functions
DspRichTextEdit
Example
// This line disables the rich text object at AN 25 - if one
exists. Otherwise an error will be returned to iResult //
iResult = DspRichTextEnable(25,FALSE);
See Also
Display Functions
DspRichTextGetInfo
Retrieves size information about the rich text object at animation point AN.
Syntax
DspRichTextGetInfo(AN, iType)
AN:
The reference AN for the rich text object.
330
Chapter: 25 Display Functions
iType:
The following size information (in pixels) can be returned about the specified rich
text object:
0 - Height
1 - Width
Return Value
The requested information as a string (units = pixels).
Related Functions
PageRichTextFile
Example
! Gets the height of the rich text object at AN 25 - if one exists.
iHeight = DspRichTextGetInfo(25,0);
! Gets the width of the rich text object at AN 423.
iWidth = DspRichTextGetInfo(423,1);
See Also
Display Functions
DspRichTextLoad
Loads a copy of the file Filename into the rich text object) at animation point AN. (The rich
text object may have been created using either the DspRichTextLoad function or the PageR-
ichTextFile function.)
Syntax
DspRichTextLoad(AN, sFilename)
AN:
The animation point at which a copy of the rich text file (for example, an RTF re-
port) will display. This AN must match that of a rich text object (created using ei-
ther the DspRichText function, or the PageRichTextFile function), or the copy of
the file will not be loaded into anything, and will not display.
sFilename:
The name of the file to be copied and loaded into the rich text object at the speci-
fied animation point. The filename must be entered in quotation marks "".
The maximum file size that can be loaded is 512kb.
If you are loading a copy of an RTF report, the report must already have been run
and saved to a file. Remember that the filename for the saved report comes from
the File Name field in the Devices form. The location of the saved file must also
be included as part of the filename. For example, if the filename in the Devices
form listed [Data];RepDev.rtf, then you would need to enter "[Data]\repdev.rtf"
as your argument. Alternatively, you can manually enter the path, for example,
"c:\MyApplication\data\repdev.rtf".
331
Chapter: 25 Display Functions
If you are keeping a number of history files for the report, instead of using the ex-
tension rtf, you must change it to reflect the number of the desired history file, for
example, 001.
Return Value
0 if successful, otherwise an error is returned.
Related Functions
DspRichText, PageRichTextFile
Example
// This will look in the [Data] path (as specified in the
Citect.ini file), and load a copy of the file DayRep.rtf into the
rich text object at animation point 57. //
DspRichTextLoad(57,"[Data]\DayRep.rtf");
// This will look in the [Data] path (as specified in the
Citect.ini file), and load a copy of the history file DayRep.003
into the rich text object at animation point 908. //
DspRichTextLoad(908, "[Data]\DayRep.003");
// This will load a copy of the history file
f:\MyApplication\data\DayRep.006, into the rich text object at animation
point 908. //
DspRichTextLoad(908, "f:\MyApplication\data\DayRep.006");
See Also
Display Functions
DspRichTextPgScroll
Scrolls the contents of the rich text object displayed at AN, by one page length in the direc-
tion given in direction.
Syntax
DspRichTextPgScroll(AN, iDirection)
AN:
The reference AN for the rich text object.
iDirection:
The direction in which you want to scroll each time this function is run. You can
choose from the following:
1 - Left
2 - Right
3 - Up
4 - Down
8 - Scroll to top
16 - Scroll to bottom
332
Chapter: 25 Display Functions
Return Value
0 if successful, otherwise an error is returned.
Related Functions
PageRichTextFile, DspRichTextEdit, DspRichTextScroll
Example
// This line scrolls the contents of the rich text object at AN 25
down one page. Otherwise an error will be returned to iResult //
iResult = DspRichTextPgScroll(25,4);
// This line scrolls the contents of the rich text object at AN 423
right one page. Otherwise an error will be returned to iResult //
iResult = DspRichTextPgScroll(423,2);
See Also
Display Functions
DspRichTextPrint
Prints the contents of the rich text object at animation point AN, to the port PortName.
Syntax
DspRichTextPrint(AN, sPortName)
AN:
The reference AN for the rich text object.
sPortName:
The name of the printer port to which the contents of the rich text object will be
printed. This name must be enclosed within quotation marks "". For example
"LPT1", to print to the local printer, or "\\Pserver\canon1" using UNC to print to
a network printer.
Return Value
0 if successful, otherwise an error is returned.
Related Functions
DspRichText, FileRichTextPrint
Example
! This lines prints
DspRichTextPrint(25,"LPT1:");
See Also
Display Functions
DspRichTextSave
333
Chapter: 25 Display Functions
Saves the contents of the rich text object at animation point AN, to the file Filename.
Syntax
DspRichTextSave(AN, sFilename)
AN:
The reference AN for the rich text object.
sFilename:
The name under which the contents of the rich text object will be saved. This
name must be enclosed within quotation marks "", and must include the destina-
tion path. For example "[Data]\saved.rtf".
Return Value
0 if successful, otherwise an error is returned.
Related Functions
DspRichText, PageRichTextFile, DspRichTextLoad, DspRichTextEdit
Example
// These lines show two different ways of saving the contents of
the rich text object (at AN 25) to file DayRep.rtf//
DspRichTextSave(25,"[Data]\DayRep.rtf");
DspRichTextSave(25,"c:\MyApplication\data\DayRep.rtf");
See Also
Display Functions
DspRichTextScroll
Scrolls the contents of the rich text object displayed at AN, in the direction given in direction,
by the number of lines/units given in amount. Remember that the height of a line varies ac-
cording to the font used, therefore if you need to scroll absolute distances, it might be ad-
visable to use the DspRichTextPgScroll function.
Syntax
DspRichTextScroll(AN, iDirection, iAmount)
AN:
The reference AN for the rich text object.
iDirection:
The direction in which you want to scroll each time this function is run. You can
choose from the following:
1 - Left
2 - Right
3 - Up
4 - Down
8 - Scroll to top
334
Chapter: 25 Display Functions
16 - Scroll to bottom
iAmount:
The amount by which you would like to scroll each time this function is run. En-
ter the number of lines (for a vertical direction) or units (for a horizontal direc-
tion) by which you would like to scroll.
Return Value
0 if successful, otherwise an error is returned.
Related Functions
PageRichTextFile, DspRichTextEdit, DspRichTextPgScroll
Example
DspRichTextScroll(25,4,8);
DspRichTextScroll(423,2,1);
See Also
Display Functions
DspRubEnd
Ends the rubber band selection, and returns the coordinates of the rubber band selection.
The meaning of the cx and cy values depend on the nMode you specify in the DspRubStart()
function.
Syntax
DspRubEnd(x, y, cx, cy)
x,y:
The x and y coordinates of the start position.
cx,cy:
The x and y coordinates of the end position.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspRubStart, DspRubMove, DspRubSetClip
Example
See DspRubStart
See Also
Display Functions
DspRubMove
335
Chapter: 25 Display Functions
Moves the rubber band selection to the new position. You must first have defined a rubber
band selection using the DspRubStart() and DspRubEnd() functions.
This function will erase the existing rubber band and then redraw it in the new position.
You would normally move the rubber band by mouse input, but you can get input from
the keyboard or any other Cicode to control the rubber band.
Syntax
DspRubMove(x, y)
x,y:
The x and y coordinates of the current position.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspRubStart, DspRubEnd, DspRubSetClip
Example
See DspRubStart
See Also
Display Functions
DspRubSetClip
Sets the clipping region for the rubber band display. If you enable the clipping region, the
rubber band will not move outside of the clip region. This allows you to restrict the rubber
band to within some constrained region. (For example, to prevent an operator from drag-
ging the rubber band outside of the trend display when zooming the trend.)
You must call this function (to enable the clipping region) before you can start the rubber
band selection (with the DspRubStart() function).
Syntax
DspRubSetClip(x1, y1, x2, y2)
x1,y1,x2,y2:
The x and y coordinates of the clipping region.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspRubStart, DspRubEnd, DspRubMove
Example
// Set the clipping region to a rectangle starting at 100, 100 to
200, 300
DspRubSetClip(100, 100, 200, 300);
336
Chapter: 25 Display Functions
See Also
Display Functions
DspRubStart
Starts the rubber band selection. Call this function when the left mouse button is pressed -
the rubber band is displayed at the starting position. Call the DspRubEnd() function to end
the selection, when the mouse button is released. The DspRubMove() function moves the
selection to the new position.
This function is used by the trend templates for the trend zoom function. Use the rubber
band functions whenever you want the operator to select a region on the screen or display
a dynamic rectangle on the screen.
You can only display one rubber band per page. If you display a second rubber band, the
first rubber band is erased. To move a rubber band with the mouse, use the OnEvent() func-
tion to get notification of the mouse movement, and then the DspRubMove() function. Be-
cause these are generic rubber-band display functions, you can get input from the
keyboard, Cicode variables, the I/O device, and the mouse.
Syntax
DspRubStart(x, y, nMode)
x,y:
The x and y coordinates of the current position.
nMode:
The mode of the rubber banding operation:
0 - cx,cy as absolute pixel positions
1 - cx,cy in pixels relative to x,y
2 - (x,y) the distance from top left to (cx,cy)
4 - enable the rubber band selection using the clipping region defined by DspRub-
SetClip().
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspRubEnd, DspRubMove, DspRubSetClip, OnEvent
Example
See also the ZOOM.CI file in the Include project for details.
INT xRub,yRub,cxRub,cyRub;
/* Call this function on left mouse button down. */
FUNCTION
StartSelection()
INT x,y;
337
Chapter: 25 Display Functions
See Also
Display Functions
DspSetSlider
Sets the current position of a slider at the specified AN. You can use this function to move
a slider, and adjust the value of the variable associated with the slider.
Note: This function is only used for V3.xx and V4.xx animations, and was superseded in
later releases.
Syntax
DspSetSlider(AN, nPos)
AN:
The animation-point number.
nPos:
The position of the slider from 0 to 32000 where 0 is the zero position of the slider
and 32000 if full position of the slider.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspGetSlider
Example
// Set the position of the slider at AN 30 to 1/2 scale
DspSetSlider(30, 16000);
338
Chapter: 25 Display Functions
See Also
Display Functions
DspSetTip
Sets tool tip text associated with an AN. Any existing text associated with the AN will be
replaced with the new text.
Syntax
DspSetTip(AN, sText)
AN:
The animation-point number.
sText:
The tool tip text to set for the AN.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspGetTip, DspTipMode
Example
!Set a tool tip for AN19
DspSetTip(19, "Start Slurry Pump");
See Also
Display Functions
DspSetTooltipFont
Sets the font for tool tip text.
The parameter [Animator]TooltipFont also specifies the tool tip font. The parameter is
checked at startup, and if it is set, the font is set accordingly. You can then use DspSetTool-
tipFont() to override the parameter until the next time you start CitectSCADA.
Syntax
DspSetTooltipFont(sName [, nPointSize] [, sAttribs] )
sName:
The name of the Windows font to be used, enclosed by quotation marks " ". A val-
ue for this parameter is required, however specifying an empty string "" will set
the tooltip font to the default of MS Sans Serif.
nPointSize:
The size of the font in points. If you do not specify a value, the point size defaults
to 12.
sAttribs:
339
Chapter: 25 Display Functions
A string specifying the format of the font. Use one or all of the following, enclosed
by quotation marks " ":
B to specify Bold
I to specify Italics
U to specify Underline
If you don’t specify a value for this parameter, it will default to an empty string
and no formatting will be applied.
Return Value
No return value.
Related Functions
DspGetTip, DspTipMode
Example
!Set the tool tip font to Bold, Italic, Times New Roman, with a
point size of 12
DspSetTooltipFont("Times New Roman", 12, "BI");
See Also
Display Functions
DspStatus
Determines whether the object at the specified AN will be grayed (hatch pattern) in the
event communication attempts are unsuccessful.
Syntax
DspStatus(AN, nMode)
AN:
The animation-point number.
nMode:
0 - Normal display when communication attempts are unsuccessful
1 - Gray the object (with a hatch pattern) when communication attempts are un-
successful
Return Value
0 (zero) if successful, otherwise an error is returned.
Example
DspStatus(67, 1)
// Disable the animation at AN 67
See Also
Display Functions
340
Chapter: 25 Display Functions
DspStr
Displays a string at a specified AN.
Note: This function is only used for V3.xx and V4.xx animations, and was superseded in
later releases.
Syntax
DspStr(AN, sFont, sText)
AN:
The AN where the text will be displayed.
sFont:
The name of the font that is used to display the text. The Font Name must be de-
fined in the Fonts database. If the font is not found, the default font is used.
sText:
The text to display.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspText
Example
DspStr(25,"RedFont","Display this text");
/* Displays "Display this text" using "RedFont" at AN25. "RedFont"
must be defined in the Fonts database. */
See Also
Display Functions
DspSym
Note: This function is only used for V3.xx and V4.xx animations. In later releases this func-
tion is redundant. The same functionality can be achieved using objects.
Displays a symbol at a specified AN. If the symbol number is 0, any existing symbol (at the
AN) is erased.
Syntax
DspSym(AN, Symbol [, Mode] )
AN:
The AN where the symbol will be displayed.
Symbol:
The name of the symbol to display in the format <[LibName.]SymName>. If you
do not specify the library name, a symbol from the Global library will display (if
it exists).
341
Chapter: 25 Display Functions
Mode:
Not used. The mode is always set to 1, which means do not erase the existing
symbol, just draw the new symbol.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspDel
Example
! Display the centrifuge symbol (from the pumps library) at AN25.
DspSym(25,"Pumps.Centrifuge");
! Display the centrifuge symbol (from the global library) at AN26.
DspSym(26,"Centrifuge");
See Also
Display Functions
DspSymAnm
Animates a series of symbols at an AN. Sym1 displays first, then Sym2, Sym3 . . . Sym8 and
then Sym1 displays again, etc. When the next symbol in the sequence is displayed, the cur-
rent symbol is not erased, but is overwritten to provide a smoother animation. The symbols
should all be the same size.
The frequency of changing the symbols is determined by the [Page]AnmDelay parameter.
You only need to call this function once to keep the animation going. To stop the animation
call the DspDel() function, or call this function again with different symbols (to change the
animation).
Note: This function is only used for V3.xx and V4.xx animations. In later releases this func-
tion is redundant. The same functionality can be achieved using objects.
Syntax
DspSymAnm(AN, Sym1 [, Sym2 ... Sym8] [, iDisplayMode] [, sSym9] )
AN:
The AN where the animation will occur.
Sym1:
The name of the first symbol to animate in the format <[LibName.]SymName>. If
you do not specify the library name, a symbol from the Global library will display
(if it exists). Sym1 must be specified.
Sym2..Sym8:
The names of the symbols to animate in frames 2 to 8 in the format <[Lib-
Name.]SymName>. If you do not specify the library name, a symbol from the
Global library will display (if it exists).
iDisplayMode:
342
Chapter: 25 Display Functions
Not used. Always set to -1, which means Soft animation. The background screen
(a rectangular region beneath the symbol) is restored with the original image.
Any objects that are within the rectangular region are destroyed when the back-
ground is restored. Use this mode when each animation symbol is a different size.
Sym9:
Not all symbols have to be specified. If for example, only two symbols are to dis-
play, specify Sym1 and Sym2.
Return Value
0 (zero) if successful, otherwise an error is returned.
Related Functions
DspSym
Example
DspSymAnm(25,"Pumps.Centrifuge","Pumps.Floatation");
! Alternately displays the centrifuge symbol and the flotation symbol(from the pumps
library) at AN25.
See Also
Display Functions
DspSymAnmEx
Animates a series of symbols at an AN. Sym1 displays first, then Sym2, Sym3 . . . Sym9 and
then Sym1 displays again, etc. When the next symbol in the sequence is displayed, the cur-
rent symbol is not erased, but is overwritten to provide a smoother animation. The symbols
should all be the same size.
The frequency of changing the symbols is determined by the [Page]AnmDelay parameter.
You only need to call this function once to keep the animation going. To stop the animation
call this function again with a different Mode.
Note: This function is only used for V3.xx and V4.xx animations. In later releases this func-
tion is redundant. The same functionality can be achieved using objects.
Syntax
DspSymAnmEx(AN, Mode, Sym1 [, Sym2 ... Sym9] )
AN:
The AN where the animation will occur.
Mode:
Not used. Always set to -1, which means Soft anim