[This local archive copy is from the official and canonical URL, http://www.w3.org/1999/05/XFA/xfa-formcalc-19990614; please refer to the canonical source document if possible.]


XFA-FormCalc
Version 1.0

Latest version:
http://www.w3.org/1999/05/XFA/xfa-formcalc.html
This version:
http://www.w3.org/1999/05/XFA/xfa-formcalc-19990614
Editor:
Gavin F. McKenzie (JetForm) <gavin.mckenzie@jetform.com>
Author:
Mike Tardif (JetForm) <mike.tardif@jetform.com>
Contributors:
Richard Devitt (JetForm) <richard.devitt@jetform.com>
Rob McDougall (JetForm) <rob.mcdougall@jetform.com>
Gavin McKenzie (JetForm) <gavin.mckenzie@jetform.com>
Andy Miller (JetForm) <andy.miller@jetform.com>
Andy Neilson (JetForm) <andy.neilson@jetform.com>

 © Copyright 1999, JetForm Corporation. All rights reserved.

Status of this document

This document is a Submission to W3C from JetForm Corporation.

Abstract

This document, as part of a family of specifications referred to as the XML Forms Architecture, describes an XML based language, XFA-Template, for modelling electronic form templates. XFA provides for the specific needs of electronic forms and the applications that use them. XFA addresses the needs of organizations to securely capture, present, move, process, output and print information associated with electronic forms. This document specifically describes a simple scripting language optimized for creating e-form centric logic and calculations.

Table of Contents


Language Overview

FormCalc is a simple scripting language whose roots lie in electronic form software from JetForm, and common spreadsheet software. It is largely an expression-based language with few control flow statements. It is also a type-less language, where values of type string or type number are promotable to strings, numbers or booleans to suit the context.

FormCalc is tailored to the skills of the non-programmer who is comfortable with spreadsheet-class application software. This user can, with the addition of a few FormCalc expressions, validate user input and/or unburden the form user from the spreadsheet like calculations.

To that aim, the language provides a large set of built-in functions to perform arithmetic, scientific, and financial tasks. Locale-sensitive date and time functions are provided, as are string manipulation functions.

To better illustrate the capabilities of the FormCalc language, we present a simple purchase order application, and focus on those spreadsheet like calculations and validations typically required of such forms.

Diagram of a simple purchase order.

Down-pointing call-outs indicate all the field names on this form. In the tabular area of the form are four fields called Item, four fields called Quantity, four fields called UnitPrice, and four fields called Amount. We will focus on these shortly.

Green up-pointing call-outs indicate fields with embedded calculations, and the red up-pointing call-outs indicate fields with embedded validations.

A subset of the XML used to defined this purchase order form might be as follows:

<XFA>
  <Template Name="FormCalc Example">
    <Subform>
      <Area Name="Leader" ...> ... </Area>
      <Area Name="Table">
        <Field Name="Item"> ... </Field>
        <Field Name="Quantity">
          <Valid>Within($, 0, 19)</Valid>
        </Field>
        <Field Name="UnitPrice"> ... </Field>
        <Field Name="Amount">
          <Calc>Quantity * UnitPrice</Calc>
        </Field>
        <Field Name="Item"> ... </Field>
        <Field Name="Quantity">
          <Valid>Within($, 0, 19)</Valid>
        </Field>
        <Field Name="UnitPrice"> ... </Field>
        <Field Name="Amount">
          <Calc>Quantity * UnitPrice</Calc>
        </Field>
        <Field Name="Item"> ... </Field>
        <Field Name="Quantity">
          <Valid>Within($, 0, 19)</Valid>
        </Field>
        <Field Name="UnitPrice"> ... </Field>
        <Field Name="Amount">
          <Calc>Quantity * UnitPrice</Calc>
        </Field>
        <Field Name="Item"> ... </Field>
        <Field Name="Quantity">
          <Valid>Within($, 0, 19)</Valid>
        </Field>
        <Field Name="UnitPrice"> ... </Field>
        <Field Name="Amount">
          <Calc>Quantity * UnitPrice</Calc>
        </Field>
      </Area>
      <Area Name="Summary" ...>
        <Field Name="ShipDate">
          <Calc>Num2Date(Date() + 2, DateFmt())</Calc>
        </Field>
        <Field Name="Total">
          <Calc>Str(Sum(Amount[*], 10, 2))</Calc>
        </Field>
      </Area>
    </Subform>
  </Template>
</XFA>
Focusing our attention on the contents of the <Calc> and <Valid> elements, we see text like
       Within($, 0, 19)
       Quantity * UnitPrice
and
       Num2Date(Date() + 2, DateFmt())
all of which are real-world examples of FormCalculations.

The first of these ensures that the entered field value is within the range of 0 to 19. The second computes the product of two fields, while the third simply displays a date that is two days hence from the current date. Some of these expressions are continually being re-executed as the user interacts with the form and enters new data.

On each of the four Quantity fields is the validation:
       Within($, 0, 19)
This is used to limit the user's input to between 0 and 19 items. Any other value entered in these fields will cause a validation error, requiring to user to modify his input. Here the symbol $ is an identifier that references the value of the field to which this FormCalculation is bound; in this case, the Quantity field.

On each of the four Amount fields is the calculation:
       Quantity * UnitPrice
which multiplies the value of the Quantity field by the value of the UnitPrice field on that row, and stores the resulting product in the Amount field. Whenever the user changes any of the quantity fields, this calculation is re-executed and the new value is displayed in the corresponding Amount field.

Below the column of Amounts is the Total field. It contains the calculation:
       Str(Sum(Amount[*], 10, 2))
This sums all four occurences of the field Amount, and formats the resulting number to two decimal places in a string, 10 characters wide. Whenever any of the amount fields change, this calculation is re-executed and a new value is displayed in the Total field.

Finally, the field named ShipDate also contains a calculation, specifically, a date calculation
       Num2Date(Date() + 2, DateFmt())
This calculation gets the value of the current date (in days), adds 2 days to it and then formats this date value into a locale-sensitive date string. Were that user to be in the United States, in the year 2000, and on the ides of March, the result that would be displayed in the ShipDate field, is:
       Mar 17, 2000
A user in Germany, on that same day, would see the value
       17.03.1999
displayed in the same field. The latter is an illustration of the built-in internationalization capabilities of FormCalc's date and time functions.

Admitedly, this is a very simple application. A real-world purchase order form would be significantly more complex, with perhaps several dozen calculations and validations. Hopefully that this example will suffice to introduce some of the capabilites of the FormCalc language.

We will now proceed to formalize the definition of this language. More complex language examples will be presented throughout.

Grammar

The FormCalc language is defined in terms of a context-free grammar. This is a specification of the lexical and syntactic structure of FormCalc calculations.

A context-free grammar is defined as a number of productions. Each production has an abstract symbol called a non-terminal as its left-hand side, and a sequence of one or more non-terminal and terminal symbols as its right-hand side. The grammar specifies the set of possible sequences of terminal symbols that can result from repeatedly replacing any non-terminal in the sequence with a right-hand side of a production in which the non-terminal is the left-hand side.

Notational Conventions

The following convention in notation or metasymbols is used to describe the grammar of FormCalc:

The non-terminal symbols of the grammar are always in normal print, or are often sub scripted by a integer, as in LogicalAndExpression[25] or Identifier[14]. The terminal symbols of the grammar are always enclosed in single quotes, as in '=' and 'then', or enclosed in square brackets, as in [0-9].

 

Lexical Grammar

This section describes the lexical grammar of the FormCalc language. This grammar has as its terminal symbols the characters of the Unicode character set. It defines a set of productions, starting from the non-terminal symbol Input1, to describe how sequences of Unicode characters are translated into a sequence of input elements.

Input elements other than white space and comment form the terminal symbols for the syntactic grammar of FormCalc, and are called tokens. These tokens are the literals, identifiers, keywords, separators and operators of the FormCalc language.

[1] Input ::= WhiteSpace | LineTerminator | Comment | Token

The source text for a FormCalc calculation is a sequence of characters using the Unicode character encoding. These Unicode characters are scanned from left to right, repeating taking the longest possible sequence of characters as the next input element.

[2] Character ::=  #x9 | #xB | #xC | [#x20-#xD7FF] | [#xE000-#xFFFD]

Note: not all FormCalc hosting environments recognize these characters, e.g., XML does not allow the vertical tab (#xB) and form feed (#xC) characters as input.

White Space

White space characters are used to separate tokens from each other and improve readability but are otherwise insignificant.

[3] WhiteSpace ::=  #x9 | #xB | #xC | #x20

Line Terminators

Line terminators, like white spaces are used to separate tokens and improve readability but are otherwise insignificant.

[4] LineTerminator ::=  #xA | #xD

Comments

Comments are used to improve readability but are otherwise insignificant.

A comment is introduced with a semi-colon (;) character and continues until a Line Terminator is encountered.

[5] Comment ::= ';' ( Character - LineTerminator )*

String Literals

A string literal is a sequence of Unicode characters enclosed within double quote characters, e.g., "the cat jumped over the fence." The string literal "" defines an empty sequence of text characters called the empty string.

To embed a double quote within a string literal, specify two double quote characters, as in "He said ""She said.""". Moreover within string literals, any Unicode character may be expressed as a Unicode escape sequence of 6 characters consisting of \u followed by four hexadecimal digits, e.g.,

	"\u0047\u006f \u0066\u0069\u0073\u0068\u0021"

To embed a control character with a string literal, specify its Unicode escape sequence, e.g., specify \u000d for a carriage return, and \u000a for a newline character.

[6] HexDigit ::= [0-9] | [a-f] | [A-F]
[7] EscapedCharacter ::= '"' '"'
                       | '\' 'u' HexDigit HexDigit HexDigit HexDigit
[8] StringLiteral ::= '"' ( Character - '"' | EscapedCharacter )* '"'                   

Number Literals

A number literal is a sequence of mostly digits consisting of an integral part, a decimal point, a fractional part, an e (or E) and an optionally signed exponent part. Either the integral part or the fractional part may be missing, but not both. In the fractional part, either the decimal point or the e and exponent part may be missing, but not both. Examples of number literals include 12, 1.2345, .12, 1e-2, and 1.2E+3.

All number literals are internally converted to IEEE754 64-bit binary values. However, IEEE754 values can only represent a finite quantity of numbers. Specifically, but not limited to, number literals having more than 16 significant digits in the non-exponent part will be the rounded to the nearest representable IEEE754 64-bit value using a round-to-nearest mechanism. This means that a number literal like
         123456789.012345678
will be rounded to the (nearest) value
         123456789.01234567
and a number literal like
         99999999999999999
will be rounded to the (nearest) value
         100000000000000000
This behaviour is conformant to the IEEE754 standard.

IEEE754 64-bit values also support representations like NaN (not a number), +Inf (positive infinity), and -Inf (negative infinity). However for simplicity, FormCalc does not support these; any intermediate expression that evaluates to NaN, +Inf, or -Inf results in an error exception which is propagated in the remainder of the expression.

[9] Integer ::= [0-9]+
[10] Exponent ::= [Ee] [+-]? Integer
[11] NumberLiteral ::= Integer '.' [0-9]* Exponent?
                     | '.' Integer Exponent?
                     | Integer Exponent?

Literals

[12] Literal ::= StringLiteral | NumberLiteral

Keywords

Keywords in FormCalc are reserved words and are case insensitive. Of these, the 'if', 'then', 'else', 'endif' keywords delimit the components of an IfExpression39. The remaining keywords are keyword operators.

These keywords may not be used as identifiers:

[13] Keyword ::= 'if' | 'then' | 'else' | 'endif'
               | 'or' | 'and' | 'not' | 'eq' | 'ne'
               | 'le' | 'ge' | 'lt' | 'gt'

Identifiers

An identifier is a sequence of characters of unlimited length but always beginning with an alphabetic character, or an underscore (_) character, or a dollar sign ($) character.

FormCalc identifiers are case sensitive, i.e., identifiers whose characters only differ in case, are considered distinct. Case sensitivity is mandated by FormCalc's hosting environments.

[14] Identifier ::= ( AlphabeticCharacter | _ | $ )
                        ( AlphaNumericCharacter | _ | $ )*
An alphabetic character is any Unicode character classified as a letter. An alphanumeric character is any Unicode character classified as either a letter, or a digit.

Operators

FormCalc defines a number of operators; they include unary operators, multiplicative operators, additive operators, relational operators, equality operators, logical operators, and the assignment operator.

FormCalc operators are symbols common to most other scripting languages:

[15] Operator ::= '=' | '|' | '&' | '==' | '<>' | '<='
                | '>=' | '<' | '>' | '+' | '-' | '*' | '/'

Several of the FormCalc operators have an equivalent mnemonic operator keyword, e.g., RelationalOperator34. These keyword operators are useful whenever FormCalc expressions are embedded in HTML and XML source text, where symbols <, >, and & have predefined meanings and must be escaped.

Tokens

[16] Separator ::= '(' | ')' | '[' | ']' | ',' | '.'
[17] Token ::= Literal | Keyword | Identifier | Operator | Separator

Syntactic Grammar

The syntactic grammar for FormCalc has the tokens defined in the preceding lexical grammar as its terminal symbols, and defines the set of productions, starting from the non-terminal symbol FormCalculation20, to describe how sequences of tokens can form a syntactically valid calculation.

[20] FormCalculation ::= ExpressionList

[21] ExpressionList ::= 
        Expression ( Expression )*

[22] Expression ::= 
        AssignmentExpression |
        IfExpression |  
        SimpleExpression

[23] SimpleExpression ::= 
        LogicalOrOperator

[24] LogicalOrExpression ::= 
        LogicalAndExpression 
        ( LogicalOrOperator LogicalAndExpression )*

[25] LogicalAndExpression ::= 
        EqualityExpression 
        ( LogicalAndOperator EqualityExpression )*

[26] EqualityExpression ::= 
        RelationalExpression 
        ( LogicalAndOperator RelationalExpression )*

[27] RelationalExpression ::= 
        AdditiveExpression 
        ( RelationalOperator AdditiveExpression )*

[28] AdditiveExpression ::= 
        MultiplicativeExpression 
        ( AdditiveOperator MultiplicativeExpression )*

[29] MultiplicativeExpression ::= 
        UnaryExpression 
        ( MultiplicativeOperator UnaryExpression )*

[30] UnaryExpression ::= 
        UnaryOperator UnaryExpression |  
        PrimaryExpression

[31] LogicalOrOperator ::= '|' | 'or'

[32] LogicalAndOperator ::= '&' | 'and'

[33] EqualityOperator ::= '==' | '<>' | 'eq' | 'ne'

[34] RelationalOperator ::= '<=' | '>=' | '<' | '>'
                          | 'le' | 'ge' | 'lt' | 'gt'

[35] AdditiveOperator ::= '+' | '-'

[36] MultiplicativeOperator ::= '*' | '/'

[37] UnaryOperator ::= '-' | 'not'

[38] PrimaryExpression ::= 
        Literal | AccessorReference | BuiltinFunction | '(' SimpleExpression ')'

[39] IfExpression ::= 
        'if' '(' SimpleExpression ')' 'then' 
            ExpressionList
      [ 'else'
            ExpressionList ]
        'endif'

[40] AssignmentExpression ::= 
        AccessorReference '=' SimpleExpression

[41] AccessorReference ::=
        ContainerReference ('.' ContainerReference )* ('.' PropertyReference )?

[42] ContainerReference ::=
        Identifier |
        Identifier '[' [+-]? Integer ']' |
        Identifier '[' '*' ']'

[43] PropertyReference ::= Identifier

[44] BuiltinFunction ::= Identifier '(' [ ArgumentList ] ')'

[45] ArgumentList ::= SimpleExpression (',' SimpleExpression )*

Expressions

Expressions Lists

A FormCalculation[20] is just a list of expressions. Under nominal circumstances, each Expression[22] evaluates to a value, and the value of an ExpressionsList[21] is the value of last expression in the list. For example, if the FormCalculation[20]

	5 + abs(JF02)
	"Hello World"
	10 * 3 + 5 * 4
is associated with object JF01, then after the evaluation of this FormCalculation[20], the value of object JF01 would be 50.

Simple Expressions

The grammar presented above defining a SimpleExpression[23] is common to conventional languages. Operator precedence rules behave as expected, so, e.g.,

	10 * 3 + 5 * 4
is equivalent to
	(10 * 3) + (5 * 4)
and evaluates to 50. Similarly
	0 and 1 or 2 > 1
is equivalent to
	(0 and 1) or (2 > 1)
and evaluates to 1. Enumerating all the FormCalc operators in order, from high precedence to lowest precedence yields:
	=
	(unary) -  not
	*  /   
	+  -
	<  <=  >  >=  lt  le  gt  ge
	==  <>  eq  ne
	&  and
	|  or

When performing numeric operations involving non numeric operands, the non numeric operands are first promoted to numbers; if the non numeric operand can be fully converted to a numeric value then that is its value; otherwise its value is zero (0). When promoting null-valued operands to numbers, their value is always zero. As examples, the expression

	(5 - "abc") * 3
evaluates to 15, i.e., (5 - 0) * 3 = 15, whereas
	"100" / 10e1
evaluates to 1, and
	5 + null() + 3
evaluates to 8.

When performing boolean operations on non boolean operands, the non boolean operands are first promoted to booleans; if the non boolean operand can be fully converted to a non zero value then its value is true (1); otherwise its value is false (0). When promoting null-valued operands to booleans, their value is always false. As examples, the expression

	"abc" | 2
evaluates to 1, i.e., false | true = true, whereas
	if ("abc") then
		10
	else
		20
	endif
evaluates to 20.

When performing string operations on non string operands, the non string operands are first promoted to strings by using their value as a string. When promoting null-valued operands to strings, their value is always the empty string. As examples, the expression

	concat("The total is ", 2, " dollars and ", 57, " cents.")
evaluates to "The total is 2 dollars and 57 cents."

All the intermediate results of numeric expressions are evaluated as double precision IEEE754 64 bit values. The final result is displayed with up to 11 fractional digits of precision. Should an intermediate expression yield an NaN, +Inf or -Inf, FormCalc will generate an error exception and propagate that error for the remainder of that expression, and the expression's value will always be zero, e.g.,

	3 / 0 + 1

Handling of error exceptions returned from the evaluation of FormCalc expressions is application defined.

Logical Or Expressions

A LogicalOrExpression24 returns the result of a logical disjunction of its operands, or null if both operands are null. If not both null, the operands are promoted to numeric values, and a numeric operation is performed.

The LogicalOrOperators '|' and 'or', both represent the same logical-or operator. The logical-or operator returns the boolean result true, represented by the numeric value 1, whenever either operand is not 0 and returns the boolean result false, represented by the numeric value 0, otherwise.

Logical And Expressions

A LogicalAndExpression25 returns the result of a logical conjunction of its operands, or null if both operands are null. If not both null, the operands are promoted to numeric values, and a numeric operation is performed.

The LogicalAndOperators '&' and 'and', both represent the same logical-and operator. The logical-and operator returns the boolean result true, represented by the numeric value 1, whenever both operand are not 0 and returns the boolean result false, represented by the numeric value 0, otherwise.

Equality Expressions

An EqualityExpression26 returns the result of an equality comparison of its operands.

If either operand is null, then a null comparison is performed. Null valued operands compare identically whenever both operands are null, and compare differently whenever one operand is not null.

If both operands are string valued, then a locale-sensitive string comparison is performed on the operands. Otherwise, if not both null, the operands are promoted to numeric values, and a numeric comparison is performed.

The EqualityOperators '==' and 'eq', both denote the equality operator. The equality operator returns the boolean result true, represented by the numeric value 1, whenever both operands compare identically and returns the boolean result false, represented by the numeric value 0, otherwise.

The EqualityOperators '<>' and 'ne', both denote the inequality operator. The inequality operator returns the boolean result true, represented by the numeric value 1, whenever both operands compare differently and returns the boolean result false, represented by the numeric value 0, otherwise.

Relational Expressions

A RelationalExpression27 returns the result of a relational comparison of its operands.

If either operand is null valued, then a null comparison is performed. Null valued operands compare identically whenever both operands are null and the relational operator is less-than-or-equal or greater-than-or-equal, and compare differently otherwise.

If both operands are string valued, then a locale-sensitive string comparison is performed on the operands. Otherwise, if not both null, the operands are promoted to numeric values, and a numeric comparison is performed.

The RelationalOperators '<' and 'lt', both denote the same less-than operator. The less-than-or-equal relational operator returns the boolean result true, represented by the numeric value 1, whenever the first operand is less than the second operand, and returns the boolean result false, represented by the numeric value 0, otherwise.

The RelationalOperators '<=' and 'le', both denote the less-than-or-equal operator. The less-than-or-equal relational operator returns the boolean result true, represented by the numeric value 1, whenever the first operand is less than or equal to the second operand, and returns the boolean result false, represented by the numeric value 0, otherwise.

The RelationalOperators '>' and 'gt', both denote the same greater-than operator. The greater-than relational operator returns the boolean result true, represented by the numeric value 1, whenever the first operand is greater than the second operand, and returns the boolean result false, represented by the numeric value 0, otherwise.

The RelationalOperators '>=' and 'ge', both denote the greater-than-or-equal operator. The greater-than-or-equal relational operator returns the boolean result true, represented by the numeric value 1, whenever the first operand is greater than or equal to the second operand, and returns the boolean result false, represented by the numeric value 0, otherwise.

Additive Expressions

An AdditiveExpression28 returns the result of an addition (or subtraction) of its operands, or null if both operands are null. If not both null, the operands are promoted to numeric values, and a numeric operation is performed.

The AdditiveOperator '+', is the addition operator; it returns the sum of its operands.

The AdditiveOperator '-', is the subtraction operator; it returns the difference of its operands.

Multiplicative Expressions

A MultiplicativeExpression29 returns the result of a multiplication (or division) of its operands, or null if both operands are null. If not both null, the operands are promoted to numeric values, and a numeric operation is performed.

The MultiplicativeOperator '*', is the multiplication operator; it returns the product of its operands.

The MultiplicativeOperator '/', is the division operator; it returns the quotient of its operands.

Unary Expressions

A UnaryExpression30 returns the negation of its operand.

The UnaryOperator '-' denotes the arithmetic negation operator; it returns the arithmetic negation of its operand, or null if its operand is null. If its operand is not null, it is promoted to a numeric value, and the negation operation is performed.

The UnaryOperator 'not' denotes the logical negation operator. it returns the logical negation of its operand. Its operand is promoted to a boolean value, and the logical operation is performed.

The logical negation operation returns the boolean result true, represented by the numeric value 1, whenever its operand is 0, and returns the boolean result false, represented by the numeric value 0, otherwise.

Note: the arithmetic negation of a null operand yields the result null, whereas the logical negation of a null operand yields the boolean result true. This is justified by the common sense statement: If null means nothing then "not nothing" should be something.

Primary Expressions

A PrimaryExpression38 is the building block of all simple expressions. It consists of Literals12, AccessorReferences41, BuiltinFunctions44, and parenthesised SimpleExpressions39.

If Expressions

An IfExpression39 is a conditional expression, which will either evaluate and return the value of the ExpressionList21 in its then-part or evaluate and return the value of the ExpressionList21 in its else-part depending upon the value of the SimpleExpression39 in the if-part.

In either circumstance, only one of the expression lists is ever evaluated.

The value of the SimpleExpression39 in the if-part is promoted to a boolean value and a logical boolean operation is performed. If this boolean operation evaluates to true (1), the value of the ExpressionList21 in the then-part is returned. Otherwise, the value of the ExpressionList21 in the else-part is returned; if there is no else-clause, the value 0 is returned.

Assignment Expressions

An AssignmentExpression40 sets the property identified by the AccessorReference41 to the value of the SimpleExpression39.

The value of an AssignmentExpression is the value of the SimpleExpression.


Accessor References

FormCalc provides access to object properties and values. An AccessorReference41 is the syntactic element through which object values and properties are assigned, when used on the left-hand side of an AssignmentExpression40, or retrieved, when used in a SimpleExpression39, as in:

	Invoice.VAT = Invoice.subtotal * (8 / 100)
Accessor references may consist of a fully qualified hierarchy of objects optionally followed by a property reference, as in:
	Invoice.Border.Edge[1].Color = "255,9,9"
An hierarchy of objects presupposes an architectural model, but that description is outside the scope of this document.

Because there can be multiple instances of referenced objects with the same name on a form, each instance gets assigned an occurrence number, starting from one. To refer to a specific instance of an object which bears the same ambiguous name as other objects, it is required that the name by qualified by an occurrence number corresponding to the desired ordinal instance of the object.

Aside from a reference to the absolute occurrence of a object, there also exists the need to refer to the relative occurrence of a object, and to all occurrences of a object. To that end, FormCalc uses the notation:

By convention, Identifier[+0], Identifier[-0], and Identifier[0] all refer to the identified object whose occurence number is the same as the referencing object.

For a definition of referencing object and object scoping rules, you are referred to Scripting Object Model Specification for a thorough description of these.

This specification recommends that the processing application forbids from including a dollar sign ($) character in the names of objects and properties, so that this character can be successfully reserved for special application-defined names.


Builtin Functions

FormCalc supports a large set of built-in functions to do arithmetic, scientific, financial, logic, date, time, and string operations.

The names of the FormCalc functions are case insensitive, but are not reserved. This means that calculations on forms with objects whose names coincide with the names of built-in functions do not conflict; any object or built-in function can be equally referenced. Case insensitivity of built-in function names is mandated by FormCalc's historical legacy.

All built-in functions take an ArgumentList45. The number and type of arguments varies with each function. Some, like Pi() take no arguments. Others, like Num2Date() take 1, 2 or 3 arguments, the first argument being a number, with the remaining arguments being strings. Many functions accept a variable number of arguments. Leading arguments are mandatory, and trailing arguments are often optional. This maintains the complexity of most functions at a low level. Increased functionality is provided to those users who need it by requiring them to supply the additional arguments.

All arguments in an ArgumentList45 are evaluated in order, leading arguments first. If the number of mandatory arguments passed to a function is less than the number required, the function generates an error exception.

Expressions can often evaluate to a set of values, so it is not always possible to determine the exact number of arguments passed to a function at time of compilation. For example, consider the following FormCalculation

	Max(JF01[*])
If there are no occurrences of object JF01, then the function Max() will generate an error exception. If there is a single occurrence of object JF01, then the function Max() will return the value of that object occurrence. If there are multiple occurrences of object JF01, then the function Max() will return the maximum value of all those object occurrences.

Note: for all occurrences of a given object to be are included in a calculation, the object must be specified using the [*]-style reference, e.g., Sum(JF01[*]) will sum all occurrences of object JF01. Specifying Sum(JF01) will only sum a single occurrence of object JF01.

In many built-in functions, the description of the formal arguments stipulates that it must be a single value, but it may be that the passed argument evaluates to a set of values. In such circumstances, the function will generate an error exception. For example, the following FormCalculation

	Sqrt(JF01[*])
will always generate an error exception, irrespectively of the number of occurrences of object JF01.

Many functions require numeric arguments. If any of the passed arguments are non-numeric, they are promoted to numbers. Some function arguments only require integral values; in such cases, the passed arguments are always promoted to integers by truncating the fractional part.

Arithmetic Functions

Abs()

This function returns the absolute value of a given number.

Definition

Abs(n1)

Parameters

n1
is the number to evaluate.

Returns

The absolute value or null if its parameter is null.

Examples

    Abs(1.03)

returns 1.03.

    Abs(-1.03)

returns 1.03.

    Abs(0)

returns 0.


Avg()

This function returns the average of the non-null elements of a given set of numbers.

Definition

Avg(n1 [, n2...])

Parameters

n1
is the first number in the set.
n2, ...
are optional additional numbers in the set.

Returns

The average of its non-null parameters, or null if its parameter are all null.

Examples

    Avg(JF01, JF02, JF03, JF04)

returns 9 if JF01 has a value of 8, JF02 has value 10, and JF03 and JF04 are null.

    Avg(JF01[*])

returns 9 if JF01 has two occurrences with values of 8 and 10, and returns null if all occurrences of JF01 are null.


Ceil()

This function returns the whole number greater than or equal to a given number.

Definition

Ceil(n1)

Parameters

n1
is the number to evaluate.

Returns

The ceiling or null if its parameter is null.

Examples

    Ceil(1.9)

returns 2.

    Ceil(-1.9)

returns -1.

    Ceil(A)

is 100 if the value A is 99.999


Count()

This function returns the count of the non-null elements of a given set of numbers.

Definition

Count(n1 [, n2...])

Parameters

n1
is the first argument to count.
n2, ...
are optional additional arguments in the set.

Returns

The count.

Examples

    Count(5, "ABCD", "", null())

returns 3.

    Count(JF01[*])

returns the number of occurrences of JF01 that are non-null, and returns 0 if all of occurrences of JF01 are null.


Floor()

This function returns the largest whole number that is less than or equal to a given value.

Definition

Floor(n1)

Parameters

n1
is the number to evaluate.

Returns

The floor or null if its parameter is null.

Examples

    Floor(6.5)

returns 6.

    Floor(7.0)

returns 7.

    Floor(JF01)

returns 99 if the value of JF01 is 99.999.


Max()

This function returns the maximum value of the non-null elements of a given set of numbers.

Definition

Max(n1 [, n2...])

Parameters

n1
is the first number in the set.
n2, ...
are optional additional numbers in the set.

Returns

The maximum of its non-null parameters, or null if all its parameters are null.

Examples

    Max(JF01[*], 100)

returns the maximum value of all occurrences of the object JF01 or 100, whichever is greater.

    Max(7, 10, null(), -4, 6)

returns 10.

    Max(null())

returns null.


Min()

This function returns the minimum value of the non-null elements of a given set of numbers.

Definition

Min(n1 [, n2...])

Parameters

n1
is the first number in the set.
n2, ...
are optional additional numbers in the set.

Returns

The minimum of its non-null parameters, or null if all its parameters are null.

Examples

    Min(7, 10, null(), -4, 6)

returns -4.

    Min(JF01[*], 100)

returns the minimum value of all occurrences of the object JF01 or 100, whichever is less.

    Min(null())

returns null.


Mod()

This function returns the modulus of one number divided by another.

Definition

Mod(n1, n2)

Parameters

n1
is the dividend number.
n2
is the divisor number.

Returns

The modulus or null if any of its parameter are null.

The modulus is the remainder of the implied division of the dividend and the divisor. The sign of the remainder always equals the sign of the dividend.

For integral operands, this is simple enough. For floating point operands, the floating point remainder r of mod(n1, n2) is defined as r = n1 - (n2 * q) where q is an integer whose sign is negative when n1 / n2 is negative, and positive when n1 / n2 is positive, and whose magnitude is the largest integer less than the quotient n1 / n2.

If the divisor is zero, the function generates an error exception.

Examples

    Mod(64, 2)

returns 0.

    Mod(-13, 3)

returns -1.

    Mod(13, -3)

returns 1.

    Mod(-13.6, 2.2)

returns -0.4.


Round()

This function returns a number rounded to a given number of decimal places.

Definition

Round(n1 [, n2])

Parameters

n1
is the number to be evaluated.
n2
is the number of decimal places.
If n2 is omitted, 0 is used as the default.
If n2 is greater than 12, 12 is used as the maximal precision.

Returns

The rounded value or null if any of its parameters are null.

Examples

    Round(33.2345, 3)

returns 33.235.

    Round(20/3, 2)

returns 6.67.

    Round(-1.3)

returns -1.

    Round(JF01, 2)

returns 2.33 if the value of the object JF01 is 2.3333


Sum()

This function returns the sum of the non-null elements of a given set of numbers.

Definition

Sum(n1 [, n2...])

Parameters

n1
is the first number to sum.
n2, ...
are optional additional numbers in the set.

Returns

The sum of its non-null parameters, or null if all of its parameters are null.

Examples

    Sum(1, 2, 3, 4)

returns 10.

    Sum(JF01[*])

returns the sum of all occurrences of the object JF01.

    Sum(JF01[2], JF01[3])

returns the sum of two occurrences of the object JF01.


Scientific Functions

 

Acos()

This function returns the arc cosine value of a given number.

Definition

Acos(n1)

Parameters

n1
is the number to evaluate.

Returns

The arc cosine value in radians or null if its parameter is null.

If n1 is outside the range -1 to 1, the function generates an error exception.

Examples

    Acos(1)

returns 0.

    Acos(-1)

returns 3.14159265359.


Asin()

This function returns the arc sine value of a given number.

Definition

Asin(n1)

Parameters

n1
is the number to evaluate.

Returns

The arc sine value in radians or null if its parameter is null.

If n1 is outside the range -1 to 1, the function generates an error exception.

Examples

    4 * Asin(1 / Sqrt(2))

returns 3.14159265359.


Atan()

This function returns the arc tangent value of a given number.

Definition

Atan(n1)

Parameters

n1
is the number to evaluate.

Returns

The arc tangent value in radians or null if its parameter is null.

Examples

    4 * Atan(1)

returns 3.14159265359.


Atan2()

This function returns the arc tangent value of the quotient of two given numbers. The signs of the given numbers are used to calculate the quadrant of the result.

Definition

Atan2(n1, n2)

Parameters

n1
is the dividend number.
n2
is the divisor number.

Returns

The arc tangent value in radians of n1 / n2, or null if its parameters are null.

Examples

    Atan2(0, -2.33)

returns 3.14159265359.


Cos()

This function returns the cosine value of a given number.

Definition

Cos(n1)

Parameters

n1
is the number in radians to evaluate.

Returns

The cosine value or null if its parameter is null.

Examples

    Cos(0)

returns 1.


Deg2Rad()

This function returns the radian value of a given number.

Definition

Deg2Rad(n1)

Parameters

n1
is the number in degrees to convert.

Returns

The radian value or null if its parameter is null.

Examples

    Deg2Rad(180)

returns 3.14159265359.


Exp()

This function returns the value of e raised to the power of a given number.

Definition

Exp(n1)

Parameters

n1
is the number to raise e by.

Returns

e raised to a power or null if its parameter is null.

Examples

    Exp(1)

returns 2.71828182846.

    Exp(-1)

returns 0.36787944117.


Log()

This function returns the natural logarithm value a given number.

Definition

Log()

Parameters

n1
is the number to evaluate.

Returns

The natural logarithm or null if its parameter is null.

If n1 is non-positive, the function generates an error exception.

Examples

    Log(Exp(1))

returns 1.


Pi()

This function returns the value of pi which is 3.14159265359.

Definition

Pi()

Returns

pi.

Examples

    Pi() * (RADIUS * RADIUS)

returns the area of a circle given by the value of the object RADIUS.


Pow()

This function returns the value of a given number raised to the power of another.

Definition

Pow(n1, n2)

Parameters

n1
is the number to be raised.
n2
is the number to raise n1 by.
If n1 is negative, then n1 is raised to the integral power of n2.

Returns

The value raised to the power or null if any of its parameters are null.

If n2 is 0, the function returns 1.

Examples

    Pow(3, 2)

returns 9.

    Pow(-12.0, 2.2)

returns 144.


Rad2Deg()

This function returns the degree value of a given number.

Definition

Deg2Rad(n1)

Parameters

n1
is the number in radians to convert.

Returns

The degree value or null if its parameter is null.

Examples

    Rad2Deg(Pi() / 4)

returns 45.


Sin()

This function returns the sine value of a given number.

Definition

Sin(n1)

Parameters

n1
is the number in radians to evaluate.

Returns

The sine value or null if its parameter is null.

Examples

    Sin(Pi() / 2)

returns 1.


Sqrt()

This function returns the square root of a given number.

Definition

Sqrt(n1)

Parameters

n1
is the number to be evaluated.

Returns

The square root or null if its parameter is null.

If n1 is negative, the function generates an error exception.

Examples

    Sqrt(4)

returns 2.

    Sqrt(100)

returns 10.


Tan()

This function returns the tangent value of a given number.

Definition

Tan(n1)

Parameters

n1
is the number in radians to evaluate.

Returns

The tangent value or null if its parameter is null.

Examples

    Tan(Pi() / 4)

returns 1.


Date And Time Functions

A number of built-in date and time functions are provided, to allow the form designer to:

To properly parse and format a date, we need to know what format it is in, and what locale it comes from. As we all know, dates are represented differently, even within the same country. So we need to define the concepts of locale and date format more precisely.

Locales

FormCalc is locale sensitive; see the section "Locale" in the XFA-Template specification for more information.

Date Formats

The format of dates is governed by an ISO standards body whereby each nation gets to specify the form of its default, short, medium, long, and full date formats. Specifically, the locale is responsible for identifying the format of dates that conform to the standards of that nation.

Short date formats tend to be purely numeric, e.g.,
         10/2/70.
Medium date formats specify use of abbreviated month names, e.g.,
         10-Feb-70,
and long date formats specify use of full month names, e.g.,
         February 10, 1970.
Full date formats tend to include the weekday name, as in:
         Thursday, February 10, 1970.
The default format tends to coincide with the medium date format.

Specifically, in the default en_US locale, the default date format is
         MMM D, YYYY.

Properly internationalized applications then, will always query the locale for a date format. The form designer has the option of choosing from either the default, short, medium, long or full formats, and will never present to the user a hand-crafted date format. Except for the need of a common format for data interchange, use of hand-crafted date formats are best avoided.

For a specification of how to construct date formats, refer to the section "Date Pictures" within the XFA-Template specification for more information.

Examples of date formats include:

Date formats are used to both format and parse date strings, using the built-in functions Num2Date() and Date2Num(). All formatting and parsing is strict; when formatting, all literals and punctuations are included, and when parsing, all literals and punctuations must be matched exactly. If the date format is meaningless, no formatting nor parsing is attempted.

Localized Date Formats

Properly internationalized e-forms need to prompt the user for a date in a particular format, e.g., if the caption on a date entry field reads:
         YY/MM/DD,
then that is a compelling hint to the user that a date needs to be entered in the
         "YY/MM/DD"
format. That is, to an English user. But to a user from the city of Chicoutimi, that caption may be unrecognizable; the user may more likely be able to understand the caption:
         aa-nn-jj.
The above string is an example of a localized date format -- it's the localized French Canadian date format equivalent to the
         "YY/MM/DD"
date format.

As another example, the full date format for the German-speaking part of Switzerland is
         "EEEE, D. MMMM YYYY".
The equivalent localized date format is
         "EEEE, t. MMMM uuuu",
which is hopefully more meaningful to these users than it is to us, and that
         "EEEE, D. MMMM YYYY"
is to them.

The built-in functions Num2Date() and Date2Num() do not understand localized date formats; they only understand the date formats defined above. Use of these localized date formats is for UI presentation only.

Time Formats

In much the same way that date formats are governed by an ISO standards body, so are time formats. Again, each nation gets to specify the form of its default, short, medium, long, and full time formats. The locale is responsible for identifying the format of times that conform to the standards of that nation.

The default time format tends to coincide with the medium time format. Specifically, in the default en_US locale, the default time format is h:MM:SS A.

Just as with a date format, a time format is a shorthand specification to format a time. It consists of punctuations, literals, and pattern symbols, e.g., "HH:MM:SS" is a time format.

For a specification of how to construct time formats, refer to the section "Time Pictures" within the XFA-Template specification for more information.

Examples of time formats include:

Any time format containing incorrectly specified pattern symbols, e.g., HHH are invalid. When parsing, time formats with multiple instances of the same pattern symbols, e.g., HH:MM:HH are invalid, as are time formats with conflicting pattern symbols, e.g., h:HH:MM:SS. Time formats with adjacent one letter pattern symbols, e.g., HMS, are inherently ambiguous and should be avoided.

Date and Time Values

To do basic arithmetic on dates and times, we introduce the concept of date values and time values. Both of these are of numeric type, but their actual numeric value is implementation defined and thus meaningless in any context other than a date or time function. In other words, a FormCalculation obtains a date value from a date function, performs some arithmetic on that date value, and only passes that value to another date function. These same rules apply to time values.

Both date values and time values have an associated origin or epoch -- a moment in time when things began. Any date value prior to its epoch is invalid, as is, any time value prior to its epoch.

The unit of value for all date function is the number of days since the epoch. The unit of value for all time functions is the number of milliseconds since the epoch.

The reference implementation defines the epoch for all date functions such that day 1 is Jan 1, 1900, and defines the epoch for all time functions such that millisecond 1 is is midnight, 00:00:00, GMT. This means negative time values may be returned to users in timezones east of Greenwich Mean Time.

The return values provided as examples in the following functions are based on this implementation; a number followed by an * indicates implementation-specific date and time values. Actual values may vary.


Date()

This function returns the current system date as the number of days since the epoch.

Definition

Date()

Returns

The number of days for the current date.

Examples

    Date()

returns 35733* on Oct 31 1998.


Date2Num()

This function returns the number of days since the epoch, given a date string.

Definition

Date2Num(d1[, f1[, k1]])

Parameters

d1
is a date string in the format given by f1, governed by the locale given by k1.
f1
is a date format string .
If f1 is omitted, the default date format is used.
k1
is a locale identifier string conforming to the locale naming standards defined above.
If k1 is omitted, the ambient locale is used.

Returns

The days since the epoch or null if any of its parameters are null.

If the given date is not in the format given, or the format is invalid, or the locale is invalid, the function returns 0.

Sufficient information must be provided to determine a unique day since the epoch: if any of the day of the year and year of the era are missing, or any of the day of the month, month of the year and year of the era are missing, the function returns 0.

Examples

    Date2Num("Mar 15, 1996")

returns 35138*.

    Date2Num("1/1/1900", "D/M/YYYY")

returns 1*.

    Date2Num("03/15/96", "MM/DD/YY")

returns 35138*.

    Date2Num("Aug 1,1996", "MMM D,YYYY")

returns 35277*.

    Date2Num("31-ago-96", "DD-MMM-YY", "es_ES")

returns 35307*.

    Date2Num("1/3/00", "D/M/YY") - Date2Num("1/2/00", "D/M/YY")

returns 29, year 2000 being a leap year!

See Also


Num2Date()

This function returns a date string, given a number of days since the epoch.

Definition

Num2Date(n1 [,f1 [, k1]])

Parameters

n1
is the number of days.
f1
is a date format string .
If f1 is omitted, the default date format is used.
k1
is a locale identifier string conforming to the locale naming standards defined above.
If k1 is omitted, the ambient locale is used.

Returns

The date string or null if any of its parameters are null.

The formatted date is in the format given in f1, governed by the locale given in k1.

If the given date is invalid, the function returns an empty string.

Examples

    Num2Date(1, "DD/MM/YYYY")

returns "01/01/1900".

    Num2Date(35139, "DD-MMM-YYYY", "de_CH")

returns "16-Mrz-1996".

    Num2Date(Date2Num("31-ago-98", "DD-MMM-YY", "es_ES") - 31, "D' de 'MMMM' de 'YYYY", "pt_BR")

returns "31 de Julho de 1998".

See Also


DateFmt()

This function returns a date format string, given a date format style.

Definition

DateFmt([n1[, k1]]])

Parameters

n1
is an integer identifying the date format style:
- if the value is 0, the locale specific default-style date format is requested.
- if the value is 1, the locale specific short-style date format is requested.
- if the value is 2, the locale specific medium-style date format is requested.
- if the value is 3, the locale specific long-style date format is requested.
- if the value is 4, the locale specific full-style for date format is requested.
If n1 is omitted, the default style value 0 is used.
k1
is a locale identifier string conforming to the locale naming standards defined above.
If k1 is omitted, the default locale is used.

Returns

The date format or null if any of its parameters are null.

If the given format style is invalid, the function returns default-style date format.

Examples

    DateFmt()

returns "MMM D, YYYY". This is the default date format .

    DateFmt(1)

returns "M/D/YY".

    DateFmt(2, "fr_CA")

returns "YY-MM-DD".

    DateFmt(3, "de_DE")

returns "D. MMMM YYYY".

    DateFmt(4, "es_ES")

returns "EEEE D' de 'MMMM' de 'YYYY".

See Also


LocalDateFmt()

This function returns a localized date format string, given a date format style.

Definition

LocalDateFmt([n1[, k1]]])

Parameters

n1
is an integer identifying the date format style:
- if the value is 0, the locale specific default-style localized date format is requested.
- if the value is 1, the locale specific short-style localized date format is requested.
- if the value is 2, the locale specific medium-style localized date format is requested.
- if the value is 3, the locale specific long-style localized date format is requested.
- if the value is 4, the locale specific full-style localized date format is requested.
If n1 is omitted, the default style value 0 is used.
k1
is a locale identifier string conforming to the locale naming standards defined above.
If k1 is omitted, the ambient locale is used.

Returns

The localized date format or null if any of its parameters are null.

If the given format style is invalid, the function returns default-style localized date format.

The date format strings returned by this function are not usable in the functions Date2Num() and Num2Date().

Examples

    LocalDateFmt(1, "de_DE")

returns "tt.MM.uu".

    LocalDateFmt(2, "fr_CA")

returns "j nnn aa".

    LocalDateFmt(3, "de_DE")

returns "t. MMMM uuuu".

    LocalDateFmt(4, "es_ES")

returns "EEEE t' de 'MMMM' de 'uuuu".

See Also


Time()

This function returns the current system time as the number of milliseconds since the epoch.

Definition

Time()

Returns

The number of milliseconds for the current time.

Examples

    Time()

returns 61200001* at precisely noon to a user in Boston.


Time2Num()

This function returns the number of milliseconds since the epoch, given a time string.

Definition

Time2Num(d1[, f1[, k1]])

Parameters

d1
is a time string in the format given by f1, governed by the locale given by k1.
f1
is a time format string, as defined above.
If f1 is omitted, the default time format is used.
k1
is a locale identifier string conforming to the locale naming standards defined above.
If k1 is omitted, the ambient locale is used.

Returns

The milliseconds from the epoch or null if any of its parameters are null.

If the time string does not include a timezone, the current timezone is used.

The locale is used to parse any timezone names.

If the given time is not in the format given, or the format is invalid, or the locale is invalid, the function returns 0.

Sufficient information must be provided to determine a second since the epoch: if any of the hour of the meridiem, minute of the hour, second of the minute, and meridiem are missing, or any of the hour of the day, minute of the hour, and second of the minute are missing, the function returns 0.

Examples

    Time2Num("00:00:00 GMT", "HH:MM:SS Z")

returns 1*.

    Time2Num("1:13:13 PM")

returns 76393001* to a user in California.

    (Time2Num("13:13:13", "HH:MM:SS") - Time2Num("13:13:13 GMT", "HH:MM:SS Z")) / (60 * 60 * 1000) 

returns 8 to a user in Vancouver and returns 5 to a user in Ottawa.

    Time2Num("1.13.13 PM GMT+01:00", "h.MM.SS A Z", "it_IT")

returns 43993001*.

See Also


Num2GMTime()

This function returns a GMT time string, given a number of milliseconds from the epoch.

Definition

Num2GMTime(n1 [,f1 [, k1]])

Parameters

n1
is the number of milliseconds.
f1
is a time format string, as defined above.
If f1 is omitted, the default time format is used.
k1
is a locale identifier string conforming to the locale naming standards defined above.
If k1 is omitted, the ambient locale is used.

Returns

The GMT time string or null if any of its parameters are null.

The formatted time is in the format given in f1, governed by the locale given in k1.

The locale is used to format any timezone names.

If the given time is invalid, the function returns an empty string.

Examples

    Num2GMTime(1, "HH:MM:SS")

returns "00:00:00".

    Num2GMTime(65593001, "HH:MM:SS Z")

returns "18:13:13 GMT".

    Num2GMTime(43993001, TimeFmt(4, "de_CH"), "de_CH")

returns "12.13 Uhr GMT".

See Also


Num2Time()

This function returns a time string, given a number of milliseconds from the epoch.

Definition

Num2Time(n1 [,f1 [, k1]])

Parameters

n1
is the number of milliseconds.
f1
is a time format string, as defined above.
If f1 is omitted, the default time format is used.
k1
is a locale identifier string conforming to the locale naming standards defined above.
If k1 is omitted, the ambient locale is used.

Returns

The time string or null if any of its parameters are null.

The formatted time is in the format given in f1, governed by the locale given in k1.

The locale is used to format any timezone names.

If the given time is invalid, the function returns an empty string.

Examples

    Num2Time(1, "HH:MM:SS")

returns "00:00:00" in Greenwich, England and "09:00:00" in Tokyo.

    Num2Time(65593001, "HH:MM:SS Z")

returns "13:13:13 EST" in Boston.

    Num2Time(65593001, "HH:MM:SS Z", "de_CH")

returns "13:13:13 GMT-05:00" to a German Swiss user in Boston.

    Num2Time(43993001, TimeFmt(4, "de_CH"), "de_CH")

returns "13.13 Uhr GMT+01:00" to a user in Zurich.

    Num2Time(43993001, "HH:MM:SSzz")

returns "13:13+01:00" to that same user in Zurich.

See Also


TimeFmt()

This function returns a time format given a time format style.

Definition

TimeFmt([n1[, k1]]])

Parameters

n1
is an integer identifying the time format style:
- if the value is 0, the locale specific default-style time format is requested.
- if the value is 1, the locale specific short-style time format is requested.
- if the value is 2, the locale specific medium-style time format is requested.
- if the value is 3, the locale specific long-style time format is requested.
- if the value is 4, the locale specific full-style time format is requested.
If n1 is omitted, the default style value 0 is used.
k1
is a locale identifier string conforming to the locale naming standards defined above.
If k1 is omitted, the ambient locale is used.

Returns

The time format or null if any of its parameters are null.

If the given format style is invalid, the function returns default-style time format.

Examples

    TimeFmt()

returns "h:MM:SS A".

    TimeFmt(1)

returns "h:MM A".

    TimeFmt(2, "fr_CA")

returns "HH:MM:SS".

    TimeFmt(4, "de_DE")

returns "H.MM' Uhr 'Z".

See Also


LocalTimeFmt()

This function returns a localized time format string, given a time format style.

Definition

LocalTimeFmt([n1[, k1]]])

Parameters

n1
is an integer identifying the time format style:
- if the value is 0, the locale specific default-style localized time format is requested.
- if the value is 1, the locale specific short-style localized time format is requested.
- if the value is 2, the locale specific medium-style localized time format is requested.
- if the value is 3, the locale specific long-style localized time format is requested.
- if the value is 4, the locale specific full-style localized time format is requested.
If n1 is omitted, the default style value 0 is used.
k1
is a locale identifier string conforming to the locale naming standards defined above.
If k1 is omitted, the ambient locale is used.

Returns

The localized time format or null if any of its parameters are null.

If the given format style is invalid, the function returns default-style localized time format.

The time format strings returned by this function are not usable in the functions Time2Num() and Num2Time().

Examples

    LocalTimeFmt(1, "de_DE")

returns "HH:mm".

    LocalTimeFmt(2, "fr_CA")

returns "HH:mm:ss".

    LocalTimeFmt(3, "de_DE")

returns "HH:mm:ss z".

    LocalTimeFmt(4, "es_ES")

returns "HH'H'mm'' z".

See Also


IsoDate2Num()

This function returns the number of days since the epoch, given an [ISO-8601] date string.

Definition

IsoDate2Num(d1)

Parameters

d1
is a date string in one of the following two formats:
YYYY[MM[DD]]
YYYY[-MM[-DD]]
or, is an ISO-8601 date-time string -- the concatenation of an ISO-8601 date string with an ISO-8601 time string, separated by the character T, as in:
1997-07-16T20:20:20

Returns

The days from the epoch or null if its parameter is null.

If the given date is not in one of the accepted formats, the function returns 0.

Examples

    IsoDate2Num("1900")

returns 1.

    IsoDate2Num("1900-01")

returns 1.

    IsoDate2Num("1900-01-01")

returns 1.

    IsoDate2Num("19960315T20:20:20")

returns 35138.

    IsoDate2Num("2000-03-01") - IsoDate2Num("20000201")

returns 29.

See Also


IsoTime2Num()

This function returns the number of milliseconds since the epoch, given an [ISO-8601] time string.

Definition

IsoTime2Num(d1)

Parameters

d1
is a time string in one of the following formats:
HH[MM[SS[.FFF][z]]]
HH[MM[SS[.FFF][+HH[MM]]]]
HH[MM[SS[.FFF][-HH[MM]]]]
HH[:MM[:SS[.FFF][z]
HH[:MM[:SS[.FFF][-HH[:MM]]]]
HH[:MM[:SS[.FFF][+HH[:MM]]]]
or, is an ISO-8601 date-time string -- the concatenation of an ISO-8601 date string with an ISO-8601 time string, separated by the character T, as in:
1997-07-16T20:20:20

Returns

The number of milliseconds from the epoch or null if its parameter is null.

If the time string does not include a timezone, the current timezone is used.

If the given time is not in a valid format, the function returns 0.

Examples

    IsoTime2Num("00:00:00Z")

returns 1.

    IsoTime2Num("13")

returns 64800001 to a user in Boston.

    IsoTime2Num("13:13:13")

returns 76393001 to a user in California.

    IsoTime2Num("19111111T131313+01")

returns 43993001.

See Also


Financial Functions

Note: the value of the results in the examples of this section have all been rounded for presentation purposes. A number followed by an * indicates a rounded return value.

Apr()

This function returns the annual percentage rate for a loan.

Definition

Apr(n1, n2, n3)

Parameters

n1
is the principal amount of the loan.
n2
is the payment on the loan.
n3
is the number of periods.

Returns

The annual percentage rate or null if any of its parameters are null.

If any of n1, n2, or n3 are non-positive, the function generates an error exception.

Examples

    Apr(35000, 269.50, 30 * 12)

returns 0.085* (8.5%) which is the annual interest rate on a loan of $35,000 being repaid at $269.50 per month over 30 years.


CTerm()

This function returns the number of periods needed for an investment earning a fixed, but compounded, interest rate to grow to a future value.

Definition

CTerm(n1, n2, n3)

Returns

The number of periods or null if any of its parameters are null.

If any of n1, n2, or n3 are non-positive, the function generates an error exception.

Parameters

n1
is the interest rate per period.
n2
is the future value of the investment.
n3
is the amount of the initial investment.

Examples

    CTerm(.02, 200, 100)

returns 35*, which is the required period for $100 invested at 2% to grow to $200.


FV()

This function returns the future value of periodic constant payments at a constant interest rate.

Definition

FV(n1, n2, n3)

Parameters

n1
is the amount of each equal payment.
n2
is the interest rate per period.
n3
is the total number of periods.

Returns

The future value or null if any of its parameters are null.

If n1 or n3 are non-positive, or if n2 is negative, the function generates an error exception.

If n2 is 0, the function returns the product of n1 and n3, i.e., the payment amount multiplied by the number of payments.

Examples

    FV(100, .075 / 12, 10 * 12)

returns 17793.03*, which is the amount present after paying $100 a month for 10 years in an account bearing an annual interest of 7.5%.

    FV(1000, 0.01, 12)

returns 12682.50*.


IPmt()

This function returns the amount of interest paid on a loan over a period of time.

Definition

IPmt(n1, n2, n3, n4, n5)

Parameters

n1
is the principal amount of the loan.
n2
is the annual interest rate.
n3
is the monthly payment.
n4
is the first month of the computation.
n5
is the number of months to be computed.

Returns

The interest amount or null if any of its parameters are null.

If any of n1, n2, or n3 are non-positive, the function generates an error exception.

If n4 or n5 are negative, the function generates an error exception.

If the payment is less than the monthly interest load, the function returns 0.

Examples

    IPmt(30000, .085, 295.50, 7, 3)

returns 624.88* which is the amount of interest paid starting in July (month 7) for 3 months on a loan of $30,000.00 at an annual interest rate of 8.5% being repaid at a rate of $295.50 per month.


NPV()

This function returns the net present value of an investment based on a discount rate, and a series of periodic future cash flows.

Definition

NPV(n1, n2 [, ...])

Parameters

n1
is the discount rate over one period.
n2, ...
are the cash flow values which must be equally spaced in time and occur at the end of each period.

Returns

The net present value rate or null if any of its parameters are null.

The function uses the order of the values n2, ... to interpret the order of the cash flows. Ensure payments and incomes are specified in the correct sequence.

If n1 is non-positive, the function generates an error exception.

Examples

    NPV(0.15, 100000, 120000, 130000, 140000, 50000)

returns 368075.16* which is the net present value of an investment projected to generate $100,000, $120,000, $130,000, $140,000 and $50,000 over each of the next five years and the rate is 15% per annum.

    NPV(0.10, -10000, 3000, 4200, 6800)

returns 1188.44*.

    NPV(0.08, 8000, 9200, 10000, 12000, 14500)

returns 41922.06*.


Pmt()

This function returns the payment for a loan based on constant payments and a constant interest rate.

Definition

Pmt(n1, n2, n3)

Parameters

n1
is the principal amount of the loan.
n2
is the interest rate per period.
n3
is the number of payment periods.

Returns

The loan payment or null if any of its parameters are null.

If any of n1, n2, or n3 are non-positive, the function generates an error exception.

Examples

    Pmt(30000.00, .085 / 12, 12 * 12)

returns 333.01*, which is the monthly payment for a loan of a $30,000, borrowed at a yearly interest rate of 8.5%, repayable over 12 years (144 months).

    Pmt(10000, .08 / 12, 10)

returns 1037.03*, which is the monthly payment for a loan of a $10,000 loan, borrowed at a yearly interest rate of 8.0%, repayable over 10 months.


PPmt()

This function returns the amount of principal paid on a loan over a period of time.

Definition

PPmt(n1, n2, n3, n4, n5)

Parameters

n1
is the principal amount of the loan.
n2
is the annual interest rate.
n3
is the monthly payment.
n4
is the first month of the computation.
n5
is the number of months to be computed

Returns

The principal paid or null if any of its parameters are null.

If any of n1 , n2 , or n3 are non-positive, the function generates an error exception.

If n4 or n5 are negative, the function generates an error exception.

If payment is less than the monthly interest load, the function generates an error exception.

Examples

    PPmt(30000, .085, 295.50, 7, 3)

returns 261.62*, which is the amount of principal paid starting in July (month 7) for 3 months on a loan of $30,000 at an annual interest rate of 8.5%, being repaid at $295.50 per month. The annual interest rate is used in the function because of the need to calculate a range within the entire year.


PV()

This function returns the present value of an investment of periodic constant payments at a constant interest rate.

Definition

PV(n1, n2, n3)

Parameters

n1
is the amount of each equal payment.
n2
is the interest rate per period.
n3
is the total number of periods.

Returns

The present value or null if any of its parameters are null.

If any of n1 and n3 are non-positive, the function generates an error exception.

Examples

    PV(1000, .08 / 12, 5 * 12)

returns 49318.43* which is the present value of $1000.00 invested at 8% for 5 years.

    PV(500, .08 / 12, 20 * 12)

returns 59777.15*.


Rate()

This function returns the compound interest rate per period required for an investment to grow from present to future value in a given period.

Definition

Rate(n1, n2, n3)

Parameters

n1
is the future value.
n2
is the present value.
n3
is the total number of periods.

Returns

The compound rate or null if any of its parameters are null.

If any of n1, n2 , or n3 are non-positive, the function generates an error exception.

Examples

    Rate(110, 100, 1)

returns 0.10 which is what the rate of interest must be for and investment of $100 to grow to $110 if invested for 1 term.


Term()

This function returns the number of periods needed to reach a given future value from periodic constant payments into an interest bearing account.

Definition

Term(n1, n2, n3)

Parameters

n1
is the payment amount made at the end of each period.
n2
is the interest rate per period.
n3
is the future value.

Returns

The number of periods or null if any of its parameters are null.

If any of n1, n2, or n3 are non-positive, the function generates an error exception.

Examples

    Term(475, .05, 1500)

returns 3* which is the number of periods for an investment of $475, deposited at the end of each period into an account bearing 5% compound interest, to grow to $1500.00.


Logical Functions

Most of these Logical functions return the boolean results true or false, represented by the numeric values of 1 and 0, respectively.

Some of the following built-in function examples make use of the identifier $ to mean a reference to the value of the object to which the FormCalculation is bound.

If()

Returns conditional values based on the value of a given number.

Definition

If(n1, e1 [,e2])

Parameters

n1
is the number to be evaluated.
e1
is teh value returned if n1 evaluates to true.
e2
is the value returned if n1 evaluates to false.

Returns

The conditional value or null if its first parameter is null.

Note that both simple expressions e1 and e2 are always evaluated.

Examples

    If(JF01 > 100, .10, .05)

returns the value .10 if object JF01 is greater than 100, and .05 otherwise.

    If(RESPONSE == "YES" | RESPONSE =="Y", "GO TO SECTION A")

returns "GO TO SECTION A" if the object RESPONSE contains the value "YES" or "Y"; otherwise an empty string is returned.

See also the IfExpression39 which provides for more flexible conditional expressions, particularly when the expressions e1 and e2 need to be lists of expressions.

    If(FF01 <> Null(), "is not null", "is null")

returns "is not null" if object FF01 is not null, and "is null" if object FF01 is null.

See Also


Choose()

This function selects a value from a given set of parameters.

Definition

Choose(n1, s1 [, s2...])

Parameters

n1
is n'th value to select from the set.
s1
is the first value of the set.
s2, ...
are optional additional value of the set.

Returns

The selected argument or null if its first parameter is null.

If n1 is less than 1 or greater than the number of arguments in the set, the function returns an empty string.

Examples

    Choose(3, "Accounting", "Administration", "Personnel", "Purchasing")

returns "Personnel".

    Choose(JF01, "A", "B", "C")

returns B if the value in JF01 is 2.


Oneof()

This logical function returns true if a value is in a given set.

Definition

Oneof(s1, s2 [, s3...])

Parameters

s1
is the value to match.
s2
is the first value in the set.
s3, ...
are optional additional values in the set.

Returns

True (1) if the first parameter is in the set, false (0) if it is not in the set.

Examples

    Oneof($, 4, 13, 24)

returns true (1) if the current object has a value of 4, 13 or 24; otherwise it returns false (0).

    Oneof(JF01, null(), "A", "B", "C")

returns true (1) if the value in the object JF01 is null, "A", "B" or "C"; otherwise it returns false (0).


Within()

This logical function returns true if a value is within a given range.

Definition

Within(s1, s2, s3)

Parameters

s1
is the value to test.
s2
is the lower bound of the range.
s3
is the upper bound of the range.

Returns

True (1) if the first parameter is within range, false (0) if it is not in range, or null if the first parameter is null.

If the first value is numeric then the ordering comparison is numeric.

If the first value is non-numeric then the ordering comparison uses the collating sequence for the current locale.

Examples

    Within("C", "A", "D")

returns true (1).

    Within(1.5, 0, 2)

returns true (1).

    Within(-1, 0, 2)

returns false (0).

    Within ($, 1, 10)

returns true (1) if the value of the current object is between 1 and 10.


Return()

This function stops the evaluation of an expression and returns a given value. It is typically used in the body of an IfExpression39 to alter the flow of expression evaluation.

Definition

Return([v1])

Parameters

v1
a return value; if omitted, the return value defaults to an empty string.

Returns

The return value.

Examples

    If (F1 == F2) Then 
      Return()
    Endif
    F3

will return without ever evaluating F3 whenever F1 equals F2.

    1 + Return(2) 

returns 2, and not 3. The additive expression never gets evaluated.


Miscellaneous Functions

This list of functions may grow over time, for instance to include to retrieve system or application specific properties, but for now, its limited to the following

 

Eval()

This function returns the value of a given expression.

Definition

Eval(e1)

Parameters

e1
is an expression.

Returns

The value of the expression.

If e1 is not a valid expression, the function generates an error exception.

Examples

    Eval("ABC")

returns "ABC".

    Eval("10 * 3 + 5 * 4")

returns 50.

    Eval(FF01)

returns FF02 if the value of FF01 was "FF02".

    Sum(Eval(FF01))

returns 133 if the value of FF01 was "FF02 + 10", and the value of FF02 was 123.


Null()

This function returns the null value.

Definition

Null()

Returns

The null value. The null value really means no value.

Examples

    Concat("ABC", Null(), "DEF")

returns "ABCDEF".

    Null() + 5

returns 5.

    FF01 = Null()

returns null and assigns null to the object FF01.

    FF01 = Null() + 5

returns 5 and assigns the value 5 to the object FF01.


String Functions

FormCalc provides a large number of function to operate on the content of strings, including the ability to:

Many of these functions require a numeric position argument. All strings are indexed starting at character position one; i.e., character position 1 is the first character of the array. The last character position coincides with the length of the string.

Any character position less than one refers to the first character string, and any character position greater than the length of the string refers to the last character of the string.

 

At()

This function locates the starting character position of string s2 within string s1.

Definition

At(s1,s2)

Parameters

s1
is the source string.
s2
is the string to search for.

Returns

The character position of the start of s2 within s1 or null if any of its parameters are null.

If string s2 is not in s1, the function returns 0.

If string s2 is empty, the function returns 1.

Examples

    At("ABC", "AB")

returns 1.

    At("ABCDE", "DE")

returns 4.

    At("WXYZ", "YZ")

returns 3.

    At("123999456", "999")

returns 4.


Concat()

This function returns the string concatenation of a given set of strings.

Definition

Concat(s1 [, s2...])

Parameters

s1
is the first string in the set.
s2,...
are additional strings to append from the set.

Returns

The concatenated string or null if all of its parameters are null.

Examples

    Concat("ABC", "CDE")

returns "ABCCDE".

    Concat("XX", JF01, "-01")

returns "XXABC-01" if the value of JF01 is "ABC".


Left()

This function extracts a number of characters from a given string, starting with the first character on the left.

Definition

Left(s1, n1)

Parameters

s1
is the string to extract from.
n1
is the number of characters to extract.

Returns

The extracted string or null if any of its parameters are null.

If the number of characters to extract is greater than the length of the string, the function returns the whole string.

If the number of characters to extract is 0 or less, the function returns the empty string.

Examples

    Left("ABCD", 2)

returns "AB".

    Left("ABCD", 10)

returns "ABCD".

    Left("XYZ-3031", 3)

returns "XYZ".


Len()

This function returns the length of a given string.

Definition

Len(s1)

Parameters

s1
is the string to be evaluated.

Returns

The length or null if it parameter is null.

Examples

    Len("ABC")

returns 3.

    Len("ABCDEFG")

returns 7.


Lower()

This function returns a string where all given uppercase characters are converted to lowercase.

Definition

Lower(s1[, k1])

Parameters

s1
is the string to be converted.
k1
is a locale identifier string conforming to the locale naming standards.
If k1 is omitted, the ambient locale is used.

Returns

The lowercased string or null if it parameter is null.

In some locales, there are alphabetic characters that do not have an lowercase equivalent.

Examples

    Lower("Abc123X")

returns "abc123x".

    Lower("ÀBÇDÉ")

returns "àbçdé".


Ltrim()

This function returns a string with all leading white space characters removed.

Definition

Ltrim(s1)

Parameters

s1
is the string to be trimmed.

Returns

The trimmed string or null if it parameter is null.

White space characters includes the ASCII space, horizontal tab, line feed, vertical tab, form feed, carriage return, file separator, group separator, record separator, and unit separator characters, as well as, the Unicode space, line, and paragraph separator characters.

Examples

    Ltrim(" ABC")

returns "ABC".

    Ltrim(" XY ABC")

returns "XY ABC".


Replace()

This function replaces all occurrences of one string with another within a given string.

Definition

Replace(s1, s2[, s3])

Parameters

s1
is the source string.
s2
is the string to be replaced.
s3
is the replacement string.
If s3 is omitted or null, the empty string is used.

Returns

The replaced string or null if any of its mandatory parameters are null.

Examples

    Replace("it's a dog's life", "dog", "cat")

returns the string to "it's a cat's life".

    Replace("it's a dog's life", "dog's ")

returns the string to "it's a life".


Right()

This function extracts a number of characters from a given string, beginning with the last character on the right.

Definition

Right(s1, n1)

Parameters

s1
is the string to be extract from.
n1
is the number of characters to extract.

Returns

The extracted string or null if any of its parameters are null.

If the number of characters to extract is greater than the length of the string, the function returns the whole string.

If the number of characters to extract is 0 or less, the function returns the empty string.

Examples

    Right("ABC", 2)

returns "BC".

    Right("ABC", 10)

returns "ABC".

    Right("XYZ-3031", 4)

returns "3031".


Rtrim()

This function returns a string with all trailing white space characters removed.

Definition

Rtrim(s1)

Parameters

s1
is the string to be trimmed.

Returns

The trimmed string or null if any of its parameters are null.

White space characters includes the ASCII space, horizontal tab, line feed, vertical tab, form feed, carriage return, file separator, group separator, record separator, and unit separator characters, as well as, the Unicode space, line, and paragraph separator characters.

Examples

    Rtrim("ABC ")

returns "ABC".

    Rtrim("XYZ ABC ")

returns "XYZ ABC".


Space()

This function returns a string consisting of a given number of blank spaces.

Definition

Space(n1)

Parameters

n1
is the number of spaces to generate.

Returns

The blank string or null if it parameter is null.

Examples

    Concat("Hello ", null(), "world.")

returns "Hello world.".

    Concat(FIRST, Space(1), LAST)

returns "Gerry Pearl" when the value of the object FIRST is Gerry, and the value of the object LAST is Pearl.


Str()

This function converts a number to a character string.

Definition

Str(n1 [, n2 [, n3]])

Parameters

n1
is the number to convert.
n2
is the maximal width of the string; if omitted, a value of 10 is used as the default width.
n3
is the precision -- the number of digits to appear after the decimal point; if omitted, or negative, 0 is used as the default precision.

Returns

The formatted number or null if any of its parameters are null.

The number is formatted to specified width and rounded to the specified precision; the number may have been zero-padded on the left of the decimal to the specified precision.

If the resulting string is longer than the maximal width of the string, as defined by n2, then the function returns a string of '*' (asterisk) characters of the specified width.

Examples

Str(2.456) returns "         2".
Str(4.532, 6, 4) returns "4.5320".
Str(31.2345, 4, 2) returns "****".

Stuff()

This function inserts a string into another string.

Definition

Stuff(s1, n1, n2[, s2])

Parameters

s1
is the source string.
n1
is the character position in string s1 to start stuffing.
If n1 is less than one, the first character position is assumed.
If n1 is greater than then length of s1, the last character position is assumed
n2
is the number of characters to delete from string s1, starting at character position n1.
If n2 is less than or equal to 0, 0 characters are assumed.
s2
is the string to insert into s1.
If s2 is omitted or null, the empty string is used.

Returns

The stuffed string or null if any of its mandatory parameters are null.

Examples

    Stuff("ABCDE", 3, 2, "XYZ")

returns "ABXYZE".

    Stuff("abcde", 4, 1, "wxyz")

returns "abcwxyze".

    Stuff("ABCDE", 2, 0, "XYZ")

returns "AXYZBCDE".

    Stuff("ABCDE", 2, 3)

returns "AE".


Substr()

This function extracts a portion of a given string.

Definition

Substr(s1, n1, n2)

Parameters

s1
is the string to be evaluated.
n1
is the character position in string s1 tostart extracting.
If n1 is less than one, the first character position is assumed.
If n1is greater than then length of s1, the last character position is assumed
n2
is the number of characters to extract.
If n2 is less than or equal to 0, 0 characters are assumed.

Returns

The sub string or null if any of its parameters are null.

If n1 + n2 is greater than the length of s1 then the function returns the sub string starting a position n1 to the end of s1 .

Examples

    Substr("ABCDEFG", 3, 4)

returns "CDEF".

    Substr("abcdefghi", 5, 3)

returns "efg".


Upper()

This function returns a string with all given lowercase characters converted to uppercase.

Definition

Upper(s1[, k1])

Parameters

s1
is the string to convert.
k1
is a locale identifier string conforming to the locale naming standards.
If k1 is omitted, the ambient locale is used.

Returns

The uppercased string or null if it parameter is null.

In some locales, there are alphabetic characters that do not have a lowercase equivalent.

Examples

    Upper("abc")

returns "ABC".

    Upper("àbCdé")

returns "ÀBCDÉ".


WordNum()

This function returns the English text equivalent of a given number.

Definition

WordNum(n1 [, n2 [, k1]])

Parameters

n1
is the number to be converted.
n2
identifies the format option as one of the following:
- if the value is 0, the number is converted into text representing the simple number
- if the value is 1, the number is converted into text representing the monetary value with no fractional digits
- if the value is 0, the number is converted into text representing the monetary value with fractional digits
If n2 is omitted, the default value of 0 will be used.
k1
is a locale identifier string conforming to the locale naming standards defined above.
If k1 is omitted, the default en_US locale is used.

Returns

The English text or null if any of its parameters are null.

By specifying an locale identifier other than the default, it should be possible to have this function return something other than English text. Note however that the language rules used to implement this function are inherently English.

If the integral value of n1 is negative or greater than 922,337,203,685,477,550 the function returns "*" (asterisk) characters to indicate an error condition.

Examples

    WordNum(123.54)

returns "One Hundred Twenty-three".

    WordNum(1011.54, 1)

returns "One Thousand Eleven Dollars".

    WordNum(73.54, 2)

returns "Seventy-three Dollars And Fifty-four Cents".


References

[ISO639]
""Code for the representation of names of languages". The list is available at http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt.
[ISO3166]
"ISO 3166 Code (Countries)". The list is available at ftp://ftp.ripe.net/iso3166-countrycodes.
[ISO8601]
"Data elements and interchange formats -- Information interchange -- Representation of dates and times", ISO 8601:1988. Available at http://www.iso.ch/markete/8601.pdf.