Variable Framework
Variables in TDL (Tally Definition Language) are entities which can hold values during the execution of a program. The values of these variables are initialized when they are created and can change during the entire execution of program. The Program can change the variable value by specifying expressions which are evaluated to set the values of the variables.
The Concept
Variables are context-free structures which do not require any specific object context for manipulation. They are declared by name and can be operated using the same name. It is also possible to access and operate variables declared at the parent scope.
Variables are lightweight data structures, which are simple to operate and provide the capability of storing multiple values of the same type and different types as well. It is also possible to perform various manipulation operations like insert/update/delete/sort/find. These are mainly used to perform complex computations.
Types of Variables
Variable can hold a single value, or more than one value of same type or different types. It can be declared at various scopes such as Report, Function and System Level. The various types of variables are:
- Simple Variable
- Simple Repeat Variable
- Compound Variable
- List Variable
Now we can look into these variable types in detail.
Simple Variable
Simple variables allow the storage of a single value of the specified data type.
Simple Repeat Variables
The Simple Variable can hold method values of multiple objects of a collection based on an implicit index. This concept is used in Columnar Reports only, where the lines should be repeated vertically and the fields should be repeated horizontally.
Compound Variable
Compound Variables allow us to store the values of different data types. This is achieved by making the variable itself compound, by allowing Variable declaration inside itself. These sub-variables are called member variables of the main variable.
A member variable can be a single instance or a list variable. A member variable can be a compound variable and can have members again, and therefore any hierarchy can be created.
Compound variables help grouping of related information together into one specification. In another terms, we can think about compound variables as an ‘object’.
Following table shows the similarities between an object and a compound variable:
Object |
Compound Variable |
Can have methods |
Can have Simple Variables as members |
Can have repeated methods (simple collections) |
Can have a simple List Variable as member |
Can have collections (compound collections) |
Can have Compound List Variable as its members |
*Cannot have objects under it directly* |
Can have Compound Variables as members |
We can have a comparison between the internal data Object ‘ Voucher ’ and a Compound Variable ‘CLV Emp ’ to understand the similarities between an Object and Compound Variable.
For instance, the Compound Variable ‘CLV Emp’ is defined as follows:
[Variable : CLV Emp]
Variable : Name : String
Variable : Designation : String
Variable : Age : Number
Variable : Salary : Amount
List Variable : Contact Nos : String
List Variable : Relatives
Variable : Contact Address
;; Defining Compound Variable
[Variable : Relatives]
Variable : Name : String
Variable : Age : Number
Variable : Relation : String
Variable : Salary : Amount
;;Defining another compound variable
[Variable : Contact Address]
Variable : Street Name : String
Variable : City Name : String
Object: Voucher |
Compound Variable: CLV Emp |
Object “Voucher” is having methods directly under it such as Date, Voucher Number, Narration, etc. |
Compound Variable “CLV Emp” is having Simple Member Variables such as Name, Age, Salary, etc. |
Voucher is having the repeated method BasicBuyerAddress (Simple Collection) |
CLV Emp is having the Simple List Member Variable ‘Contact Nos’ |
Voucher is having the collection Inventory Entries (Compound Collection). |
CLV Emp is having the Compound List Member Variable ‘Relatives’ |
Voucher object is not having another voucher (primary object) under it directly. |
CLV Emp is having the another Compound Member Variable ‘Contact Address’ |
List Variable
A variable at declaration time can be declared as a single instance or as a list. List variable is a container (data structure) variable and hence it is not defined. Variables can be declared as list.
List Variable can hold one or more variables which can be either a simple or a compound variable. Each of these is called Element Variable. Element Variable holds value as well as key, if specified. The key is optional, and hence without a key also, elements can be added to list variables. The value of key specified for each of the element variables must be unique.
Simple List Variable
Simple Variable can be declared as a list. Simple List Variables can hold multiple values of single data type.
Compound List Variable
Compound Variable can be declared as a list. Compound List Variables can hold multiple values of different data types.
Variable Definition and Its Attributes
Definition – Variable
A Variable definition is similar to any other definition. The behaviour of the variable is specified by the programmer via ‘Variable’ definition.
Syntax
[Variable : <Variable Name>]
Attribute : Value
Where, <Variable Name> is the name of the variable. A meaningful name which determines its purpose can be given as a variable name.
Attributes of a Variable Definition
Let us discuss the attributes of Variable definition in detail.
Attribute – TYPE
This attribute determines the Type of value that will be held by the variable. All the data types supported by TDL such as String, Number, Date, etc., can be used to specify the variable data type. In the absence of this attribute, a variable assumes to be of the Type ‘String’ by default.
Syntax
[Variable : <Variable Name>]
Type : <Data Type>
Example:
[Variable : GroupNameVar]
Type : String
In this example, a variable which holds the data of Type ‘String’ is defined.
Attribute- DEFAULT
The default value of variables can be specified during definition, using DEFAULT attribute. It is the initial value assigned to the variable when it is instantiated / declared. We can also specify the default value during declaration / instantiation. The difference is that the default value specified using this attribute at definition time will be applicable to all instances of the variable declared (at any scope). Default value specified while declaration will apply only to the specific instance.
Declaration and scope will be covered in detail in the subsequent topics. The above explanation will be more clear after that.
Syntax
[Variable : <Variable Name>]
Default : <Default Value>
Example
[Variable : GroupNameVar]
Type : String
Default : $$LocaleString:”SundryDebtors”
In this example, the default value for the variable is set as “Sundry Debtors”.
Attribute – VOLATILE
If the Volatile attribute in Variable definition is set to Yes, then the variable is capable of retaining previous values from the caller scope. The default value of this attribute is Yes, i.e., if the variable by the same name is declared in the called Report/Function and the ‘Volatile’ attribute is set to “Yes”, then in the called Report, it will assume the last value from the caller Report. The default value of the attribute ‘Volatile’ is always YES.
For better understanding, let us elaborate it further. When a variable is declared/instantiated, it assumes a default value. The default value which it assumes is controlled by the following factors:
- If ‘Volatile’ is set to “Yes” for a variable in its definition which is instantiated/declared inside a function/report, and the variable by the same name exists in the parent scope, then it will take its default value from the Parent scope. If no variable by the same name exists in the parent scope, it will take the default value specified within the definition.
- If the default value is specified within the declaration itself, it will assume that value.
If a new report Report2 is initiated, using a volatile variable GroupNameVar, from the current report Report1, the same variable in Report 2 will have the default value as the last value saved in Report 1. Within Report 2, the variable can assume a new value. Once the previous report Report1 is returned back from Report2, the previous value of the variable will be restored. A classic example of this is a drill down Trial Balance.
Syntax
[Variable : <Variable Name>]
Volatile : <Logical Value>
Example
[Variable : GroupNameVar]
Type : String
Volatile : Yes
Volatile Attribute of GroupNameVar Variable is set to Yes, which means that ‘GroupNameVar’ can inherit values from one Report to another.
Variables defined at the function level are Non Volatile by default. They do not inherit the values from the caller scope.
Scope will be discussed in detail in the subsequent topics.
Attribute – PERSISTENT
This attribute decides the retention periodicity of the variable, i.e., till when it will retain the value: i) till application termination, or ii) after application termination as well. Setting the attribute Persistent to Yes, means that the value saved during the last application session will be retained permanently in the system. When the next session of Tally is started, it will take its initial value from the value saved in the previous session, i.e., the latest value of the variable will be retained across the sessions. Please note that Variables declared at the system scope can only be persisted.
A List variable at System scope can also be persisted by specifying the ‘Persistent’ attribute for its element variable (whether it is simple/compound) within the definition. Inline variables even at system scope cannot be persisted. Inline variable declaration will be discussed in further topics.
Syntax
[Variable : <Variable Name>]
Persistent : <Logical Value>
Example:
[Variable : SV Backup Path]
Type : String
Persistent : Yes
The attribute Persistent of the variable SV Backup Path has been set to Yes, which means that it retains the latest path given by the user, even during the subsequent sessions of Tally.
All the Persistent Variable Values are stored in a File Named TallySav.Cfg in the folder path specified for Tally Configuration file in F12 -> Data Configuration. Each time Tally is restarted, these variable values are accessed from this file.
Attribute – REPEAT
The attribute Repeat for a variable is used for its usage in Columnar Reports. It accepts Collection name and optional Method name, as parameters. Multiple values are stored in the variable based on an implicit Index. Method value of each object of the collection will have to be picked up and stored in the variable, based on implicit index. In case the method name is not specified, the variable name is considered as the method name and picked up from the collection.
Syntax
[Variable : <Variable Name>]
Repeat : <Collection Name> [:<Method Name>]
Where,
<Variable Name> is the name of the variable.
<Collection Name> can be any expression which evaluates to a Collection name.
<Method name> is the name of the method whose value needs to be picked up from each object of the collection. If not specified, the variable name is considered as the method name.
Example
[Variable : SVCurrentCompany]
Volatile : Yes
Repeat : ##DSPRepeatCollection
Suppose ‘DSPRepeatCollection’ holds the value “List of Primary Companies”. Method value ‘SVCurrentCompany’ will be gathered from each object of the collection and stored in index 1, index2, and so on.
Repeat attribute will be elaborated further under the topic “Implication of Repeat Variables in Columnar Report”.
Attribute – VARIABLE
The attribute Variable is used to define the member variables (Simple/Compound) for a Compound Variable.
Syntax
[Variable : <Variable Name>]
Variable : <Variable Names> [:<Data Type> [:<Value>]]
Where,
<Variable Names> is the list of Simple or Compound Variables, separated by comma.
<Data Type> is used to specify the data type of Simple Variable. In case of Compound Variable, data type cannot be specified, as it consists of members belonging to various data types. If the data type is not mentioned, the primary variable definition is mandatory.
<Value> is the default/initial value provided for the variable.
Specifying <Data Type> and <Value> is optional. If data type is specified, then it is called inline declaration of variable.
Example
[Variable : CLV Emp]
Variable : Name : String
Variable : Age : Number : 25
Variable : Salary : Amount
Variable : Relatives
In this example, the simple variables Name, Age and Salary and the compound variable ‘Relatives’ are defined as members for the Compound Variable CLV Emp.
Attribute – LIST VARIABLE
The attribute List Variable is used to specify a list of Simple/Compound Variables.
Syntax
[Variable : <Variable Name>]
List Variable : <Variable Names> [:<Data Type> [:<Value>]]
Where,
<Variable Names> is the list of Simple or Compound Variables, separated by comma.
<Data Type> is the data type of Simple Variable. In case of Compound Variable, data type cannot be specified, as it consists of members belonging to various data types.
<Value> denotes the no. of elements in the list. Specifying <Data Type> and <Value> is optional.
Example
[Variable : CLV Emp]
Variable : Name : String
Variable : Age : Number
Variable : Salary: Amount
List Variable : City : String : 3
List Variable : Relatives
[Variable : Relatives]
Variable : Name : String
Variable : Age : Number
Variable : Relation : String
Variable : Salary : Amount
In this example, in addition to simple variables, a simple list variable City and a compound list variable Relatives are defined as members using the attribute List Variable. A separate definition is required for the compound list variable Relatives, as it holds the multiple values of different data types.
Variable Declaration and Scope
Variables can be declared at various scopes. The availability of the variable within the definition under which it is declared is called as the scope. The lifetime of the variable will be within the scope. For example, if the scope of a particular variable is within a function, then the variable will last till the function is executing, and then it is destroyed.
Variables can be declared at System, Report and Function scopes. Let us have a detailed look on the variable scopes.
System Scope Declaration
Variables declared at the system level will start their life when the application starts, and will be alive till the application’s termination. System variables are declared using a special [System: Variable] definition. The variables declared at system scope are accessible everywhere in the system.
Syntax
[System : Variable]
Variable Name : <Initial Type Based Value>
OR
Variable : < Variable Names > :[<Data Type>:[<Value>]]
OR
List Variable : < Variable Names > :[<Data Type>:[<Value>]]
OR
Variable : <Instance Names>:[<Variable Names>]
OR
List Variable : <Instance Names>:[<Variable Names>]
Where,
<Initial Type Based Value> is the initial value specified to the variable.
<Instance Names> is the list of simple / compound / list variables separated by comma (instance variables).
< Variable Name> is the simple or compound variable name
The variables can be declared at the system scope by using the above syntax. The usage of the attributes ‘Variable’ and ‘List Variable’ is same as described above in the variable definition section.
Example
[System : Variable]
BSVerticalFlag : No
The BSVerticalFlag Variable is declared in System Scope. Hence, this variable value being modified in a Report, is retained even after we quit and re-enter the report.
Report Scope Declaration
Variables declared at Report definition are termed as having Report Scope. These variables will exist till the life of the report. The variables declared at Report scope are accessible from the report itself and all the TDL elements which are executed from within this report such as another report, function, etc.
Report variables get their default value from definition specification, or from the declaration specification, or the values are inherited from the owner scope, if the variable is marked as Volatile.
Report allows two special attributes SET and PRINT SET to set/override the values of the variable during the startup of the report in Display / Print mode respectively.
Form definition also has a SET attribute, which overrides the variable’s value during startup creation and subsequent re-creation of the form during any refresh/regeneration. We will study about these value specification attributes in detail under the topic “Manipulating Simple and Compound List Variables”.
Syntax
[Report : <Report Name>]
Variable : <Variable Names>
OR
Variable : <Variable Names> [:<Data Type> [:<Value>]]
OR
List Variable : <Variable Names> [:<Data Type> [:<Value>]]
The variables can be declared at Report scope by using the above. The usage of attributes Variable and List Variable is same as described above in the “Variable definition”.
Example
[#Report : Balance Sheet]
Variable : Explode Flag
Explode Flag Variable is made local to the Report ‘Balance Sheet’ by associating it using the Report attribute ‘Variable’. This variable retains its value as long as we work with this Report. On exiting the Report, the variable is destroyed and the values are lost.
Field Acting as a Variable
The Variable attribute in a Field Definition is used to make the field behave as a variable, with the specified name. The variable need not be defined as it inherits data type from the field itself. Field can act as a simple variable only, since it can hold only simple value.
Syntax
[Field : <Field Name>]
Variable : <Variable Name>
Where,
<Field Name> is the name of the field.
<Variable Name> is the name of the variable.
Example:
[Field : Employee Name]
Variable : EmpNameVar
Function Scope Declaration
Function (User Defined Function) also allows the variables to be declared at its scope. Function variables have lifetime till the end of execution of the function. Function variables can also be declared with default value. Function variables will never inherit the value from the parent context. This means that ‘Volatile’ attribute on function variables has no effect. Functions allow actions to change the values of the variables.
Function allows a special scope called STATIC. A static variable declared in a function is equivalent to a system variable, but can be accessed only within the defined function. Its initial value is set only during the first call to the function, and later it retains the value for further calls. Only simple or compound variables can be declared as static. List variables are not currently supported at Static scope.
Syntax
Variable : <Variable Names>
OR
Variable : <Variable Names> [:<Data Type> [:<Value>]]
OR
List Variable : <Variable Names> [:<Data Type> [:<Value>]]
OR
Static Variable : <Variable Names> [:<Data Type> [:<Value>]]
The variables can be declared at ‘Function’ scope by using the above. The usage of the attributes Variable and List Variable is the same as described above in the “Variable” definition.
Example
[Function : FactorialOf]
Variable : Factorial
The Function FactorialOf requires variable ‘Factorial’ for calculation within the Function.
Example:
[Function : Sample Function]
Static Variable : Sample Static Var : Number
The static variable Sample Static Var retains the value between successive calls to the Function ‘Sample Function’.
Inline Declaration
Variables can also be defined (with limited behaviour) during declaration itself; so a separate definition would not be mandatory. This is called inline variable specification (i.e., during declaration itself, the variables are defined inline).
Only the DATA TYPE and the DEFAULT VALUE can be specified as the behaviour for inline variables. If the DATA TYPE is specified as a variable name (i.e., not an implicit data type key word such as String, Amount, etc.) or is left blank, it is treated as a pre-defined variable.
Persistence: Inline variables even at system scope cannot be persisted.
Declaring Simple Variable Inline
The ‘Variable’ attribute allows declaring Simple Variable inline by specifying the data type. Initial value to the variable can also be specified optionally.
Syntax
Variable : <Variable Names> [:<Data Type> [:<Value>]]
Where,
<Variable Names> is a list of Simple Variables, separated by comma.
<Data Type> is the data type of the Simple Variable.
<Value> is the default/initial value provided for the variables, and this value specification is optional.
Example
[Report : Cust Group Report]
Variable : VarGroupName1, VarGroupName2 : String : “Sundry Debtors”
In this example, the Simple Variables ‘VarGroupName1’ and ‘VarGroupName2’ of type ‘String’ are declared in a report. Hence, the following separate variable definitions are not required, which will help to reduce the coding complexity.
[Variable : VarGroupName1]
Type : String
[Variable : VarGroupName2]
Type : String
Declaring Simple List Variable Inline
List Variable attribute allows declaring Simple List Variable inline by specifying the Data Type. If the default value is specified, it is treated as the count to initialize the list with the specified elements by default.
Syntax
List Variable : <Variable Names> [: <Data Type> [: <Value>]]
Where,
<Variable Names> is a list of Simple Variables, separated by comma.
<Data Type> is the data type of the Simple Variable.
<Value> is treated as the count to initialize the list with the specified elements by default. The number of elements can be specified only for an index-based list.
Example:
[System : Variable]
List Variable : VarGroupName1, VarGroupName2 : String : 10
In this example, the variables VarGroupName1 and VarGroupName2 of ‘String’ data type are declared as inline simple list variables at System level, and each variable will have 10 elements by default.
Declaring Compound List Variable Inline
For Compound List Variables , definition is mandatory. They cannot be declared inline.
Using Modifiers with Variables
Variable allows static modifiers such as Add/Delete/Change and Dynamic modifier ‘Local’.
Static Modification
Add/Delete/change modifiers can be used on variables to change the behaviour.
Example:
[#Variable : SV From Date]
Delete : Default
Locally modifying variables
When different reports require the same Compound Variable, and some modifications are required specific to respective reports, like adding additional members (local to the report); this is possible through the Dynamic Modifier Local.
Example:
In this example, a Compound Variable CLVEMP is defined as shown:
[Variable : CLV Emp]
Variable : Name : String
Variable : Designation : String
Variable : Age : Number
Variable : Salary : Amount
List Variable : Contact Nos : String
List Variable : Relatives
Variable : Contact Address
;; Defining Compound List Variable
[Variable : Relatives]
Variable : Name : String
Variable : Age : Number
Variable : Relation : String
Variable : Salary : Amount
;;Defining another compound variable
[Variable : Contact Address]
Variable : Street Name : String
Variable : City Name : String
In Employee Report1, the variable is declared and no modifications are required locally.
[Report : Employee Report1]
Variable : CLV EMP
In Employee Report2, the same variable is declared but locally one member variable is added and one existing member variable is deleted.
[Report : Employee Report2]
Variable : CLV EMP
Local : Variable : CLV EMP : Add : Variable : Qualification : String
Local : Variable : CLV EMP : Delete : Variable : Age
Also, member variables can be localized within a compound variable. This provides the ability to re-use a compound structure defined earlier and do any local modifications, as required.
Example:
[Variable : CLVEMP]
Variable : Contact Address
Local : Variable : Contact Address : Add : Variable : State : String
List Variable Manipulations
Simple and Compound List variables support various data manipulation operations such as Adding/Deleting/Expanding List elements, Value Specifications, Retrieving values from the list elements, Searching and Sorting, Populating List Variable from a Collection, etc. New Actions and Functions specific to List Variables have been introduced for these manipulations. Before looking into these manipulations, let us understand the concept of Key, Index and Variable Path Specification using Dotted Notation Syntax.
The Concept
Key
List variables can hold multiple values of variable types using a string based Key specification. ‘Key’ is of type String, by default. We can specify a different data type for a key only in scenarios where we require key-based sorting. It is optional to specify key value while adding values to the list variable. The TDL Programmer has to explicitly specify the key value. Key is unique for all elements in the list. If an element is added with duplicate key, the existing element is overwritten. It is advisable to use a key only if we require frequent access to elements of the list based on key.
Index
An element of the list can be accessed via Index. Index of an element is the location/position of the variable from the first element in the current sorting order. Even if we have specified keys for elements of a list, index is generated internally. It is always possible to access each element in the list by specifying the index within square brackets [ ] in the dotted notation syntax. This is explained below. Index can be negative as well. In that case, it is possible to access the elements in the reverse order of entry.
Variable Path Specification Using Dotted Notation Syntax
We know that, method value of any object including its sub-collections to any level can be accessed or modified with dotted notation syntax. The behavior of the symbol prefix $ also used to access the method value of any object, and an action MODIFY OBJECT is used to modify multiple values of any object.
Compound Variables allow us to store values of different data types. A member variable can be a single instance or a list variable. A member variable can be a compound variable and can have members again, and thus, any hierarchy can be created. In short, it is similar to a Data Object. Hence, all the attributes and actions which operate the Variable, have now been enhanced to take extended variable path syntax, i.e., the variable path can be specified using dotted notation syntax. The syntax can be used to fetch any value from any member within the hierarchy. This syntax is applicable wherever we need to specify either the variable identifier or access the value of the variable. In case of value access the operator ## is used. Value access using operator ## has been discussed in detail in the topic Index Based Retrieval using ## Operator.
Syntax
<Element Variable Specification>.<Member Variable Specification>. <Simple Member Value Specification>
Where,
<Element Variable Specification> can be a Compound Variable or Compound List Variable [Index Expression].
<Member Variable Specification> can be a Compound Variable Member or Compound List Member Variable [Index Expression].
<Simple Member Value Specification> refers to the name of the simple member in the specified path.
<Index Expression> is an expression evaluating to a number. Suffixing a variable with index refers to an Element Variable. It can be positive or negative. Negative index denotes reverse access.
Example: 1
Consider the compound variable defined below:-
[Variable : CLV Emp]
Variable : Name : String
Variable : Age : Number
Variable : Salary : Amount
List Variable : Relatives
[Variable : Relatives]
Variable : Name : String
Variable : Age : Number
Variable : Relation : String
Variable : Salary : Amount
The same is declared at System Scope, and hence can be accessed anywhere in the system.
[System : Variable]
List Variable : CLV Emp
Example: 2
Suppose we want to set the value of a simple variable ‘Employee Name’, which is declared at Report Level:
[Report : Employee Report]
Variable : Employee Name : String
SET : Employee Name : ##CLVEMP[1].Name
The variable Employee Name will be set with the value of the member Name of the first element of the Compound List Variable CLVEMP.
Example: 3
In case the age of the first relative of the second employee needs to be displayed, the following statement would be used in the field in a report.
[Field : RelAge]
Set As : ##CLVEMP[2].Relatives[1].age
The value specification attributes and actions, with the enhanced variable path specification, will be discussed in detail in the further topics.
List Variable Manipulations – A Detailed Look
Let us have a detailed look on List Variable manipulations with examples:-
Adding/Deleting/Expanding Elements
Adding Elements to the List Variable
The Action LIST ADD is used on a list variable to add an element to the list variable based on KEY. This is mandatory before we set value into the element. KEY is compulsory in this case. Key is unique for all elements in the list. If an element is added with duplicate key, then the existing element is overwritten.
Syntax
LIST ADD : <List Variable Specification> : <Key Formula> [:<Value Formula> [:<Member Specification>]]
Where,
<List Variable Specification> is the Simple List or Compound List Variable specification.
<Key Formula> can be any expression which evaluates to a unique string value.
<Value Formula> can be any expression which returns a value. It sets the initial value of the element variable, and is optional.
<Member Specification> is required only if the value needs to be added to a specific member of a Compound List Variable. If member specification is not provided, the first member variable is considered for the value.
The actions LIST APPEND and LIST SET are aliases for the action LIST ADD.
To add multiple values dynamically to the List variable, we can use LIST ADD within a looping construct like While, Walk Collection, etc.
Example:
Adding elements to Simple List Variable using LIST ADD
- Adding an element to the Simple List Variable SLV Emp with a Key
LIST ADD : SLV Emp : “E001”
- Adding an element to the Simple List Variable SLV Emp with a Key and a value
LIST ADD : SLV Emp : “E001” : “Kumar”
- Adding an element to the Simple List Variable SLV Emp with a Key and value, and subsequently overriding a value corresponding to a particular key
LIST ADD : SLV Emp : “E001” : “Kumar”
LIST SET : SLV Emp : “E001” : “Keshav”
- The value corresponding to the Key E001 is changed to Keshav
Adding Elements to Compound List Variable using LIST ADD
A Compound Variable CLV Emp is defined, which stores employee details such as Name, Age, Salary, etc., and the details of the Relatives.
[Variable : CLV Emp]
;;simple member variable
Variable : Name : String
;;simple member variable
Variable : Age : Number
;;simple member variable
Variable : Salary : Amount
;;compound list member variable
List Variable : Relatives
;; Compound Variable is defined here
[Variable : Relatives]
Variable : Name : String
Variable : Age : Number
Variable : Relation : String
Variable : Salary : Amount
The same is declared at the System Scope; hence, can be accessed anywhere in the system.
[System: Variable]
List Variable: CLV Emp
- Adding an element to Compound List Variable CLV Emp with a Key.
LIST ADD : CLVEmp : “E001”
- Adding an element to Compound List Variable CLV Emp with a Key and a Value.
LIST ADD : CLVEmp : “E001” : “Kumar”
Since member specification is not provided, the first member variable is considered for value.
- Adding an element to Compound List Variable CLV Emp with a Key and a value with member specification.
LIST ADD : CLVEmp : “E001” : 25 : Age
Since member specification is provided, member variable ‘Age’ is considered.
- Adding an element to the Compound List Member of a Compound List Variable with a Key and value with member specification
LIST ADD : CLVEmp[1].Relatives : “R001” : “Prem” : Name
In this example, we are adding an element to the Compound List Variable Relatives and the member variable Name is considered for the value. ‘Relatives’ is a Compound List Member variable of the Compound List Variable CLVEMP.
The values are hardcoded in the examples for explanation purpose. The above Simple and Compound List Variable examples are used to explain further list variable manipulations.
Action – LIST ADD EX
This action is used on a list variable to add an element to the list variable without KEY.
Syntax
LIST ADD EX : <List Variable Specification> [:<Value Formula> [:<Member Specification>]]
Where,
<List Variable Specification> is the Simple List/Compound List Variable specification.
<Key Formula> can be any expression which evaluates to a unique string value.
<Value Formula> can be any expression which returns a value. It sets the initial value of the element variable, and is optional.
<Member Specification> is required only if the value needs to be added to a specific member of a Compound List Variable. If member specification is not provided, the first member variable is considered for the value.
Action LIST APPENDEX is an alias for the action LIST ADDEX.
Adding elements to Simple List Variable using LIST ADD EX
- Adding an element to Simple List Variable SLV Emp
LIST ADD EX : SLV Emp
- Adding an element to Simple List Variable SLV Emp, with Value
LIST ADD EX : SLV Emp : “Kumar”
Adding elements to Compound List Variable using LIST ADD EX
- Adding an element to Compound List Variable CLV Emp
LIST ADD EX : CLV Emp
- Adding an element to Compound List Variable CLV Emp, with value
LIST ADD EX : CLV Emp : “Kumar”
Here, since member specification is not provided, first member variable is considered for value.
- Adding an element to Compound List Variable CLV Emp, with value and member specification
LIST ADDEX : CLV Emp : 25 : Age
Here, member specification is provided, hence member variable ‘Age’ is considered for the value.
- Adding an element to the Compound List Member variable of a Compound List Variable with value and member specification
LIST ADDEX : CLVEmp[1].Relatives : “Prem” : Name
In this example, we are adding an element to the Compound List Variable “Relatives” and the member variable ‘Name’ is considered for the value. ‘Relatives’ is a Compound List Member variable of the Compound List Variable CLVEMP.
Deleting Elements from the List Variable
Action – LIST DELETE
The Action LIST DELETE is used to delete an element from the list based on Key. The key formula is optional. If not specified, all the elements in the list are deleted.
Syntax
LIST DELETE : <List Variable Specification> [ : <Key Formula>]
Where,
<List Variable Specification> is the Simple List or Compound List Variable specification.
<Key Formula> can be any expression which evaluates to a unique string value . It is optional.
Action LIST REMOVE is an alias for the action LIST DELETE.
Deleting elements from Simple List Variable using LIST DELETE.
- Deleting a single element from a simple List Variable
LIST DELETE : SLV Emp : “E001”
The element identified by key ‘E001’ will be deleted from the Simple List Variable SLV Emp.
- Deleting all elements from a simple List Variable
LIST DELETE : SLV Emp
Since key formula is not specified, all elements from simple list variable SLV EMP will be deleted.
Deleting elements from a Compound List Variable using List Delete.
- Deleting an element from a Compound List Variable
LIST DELETE : CLV Emp : “E001”
The element identified by key E01 will be deleted from the Compound List Variable “CLV Emp”.
- Deleting all elements from a Compound List Variable
LIST DELETE : CLV Emp
Since key formula isn’t specified, all elements from compound list variable CLV Emp are deleted.
This action is used to delete an element from the list based on index. Index formula is optional. If not specified all the elements in the list are deleted. A negative index denotes reverse position.
Syntax
LIST DELETE EX : <List Variable Specification> [:<Index Formula>]
Where,
<List Variable Specification> is the Simple List or Compound List Variable specification.
<Index Formula> can be any expression which evaluates to an index number. It is optional.
Action LIST REMOVE EX is an alias for the action LIST DELETE EX.
Deleting elements from Simple List Variable using LIST DELETE EX
- Deleting a single element from a simple List Variable
LIST DELETE EX : SLVEmp : 2
The element identified by index number ‘ 2 ’ will be deleted from Simple List Variable SLC Emp.
- Deleting all elements from a simple List Variable
LIST DELETE EX : SLVEmp
Since index formula is not specified, all elements from Simple List Variable SLV Emp are deleted.
Deleting elements from a Compound List Variable using LIST DELETE EX
- Deleting an element from a Compound List Variable
LIST DELETE EX : CLVEmp : 10
The element identified by index ‘1 ’ will be deleted from the Compound List Variable CLV Emp.
- Deleting all elements from a Compound List Variable
LIST DELETE EX : CLVEMP
Since index formula isn’t specified, all elements of compound list variable CLV EMP are deleted.
Expanding Elements in the List Variable
Action – LIST EXPAND
The action LIST EXPAND is used to create the specified number of blank elements and insert them into the list. All these elements are created without a key. If key specification is required for each element then either LIST FILL or a loop can be used to add elements individually.
Syntax
LIST EXPAND : <List Variable Specification> : <Count Formula>
Where,
<List Variable Specification> is the Simple List or Compound List variable specification.
<Count Formula> can be any expression which evaluates to a number.
Example:
Expanding Simple List Variable using LIST EXPAND
LIST EXPAND : SLVEMP : 10
Here, count formula is 10. Hence, 10 blank elements are added to Simple List Variable ‘ SLVEMP’.
Expanding Compound List Variable using LIST EXPAND.
LIST EXPAND : CLVEMP : 5
Here, count formula is 5. Thus, 5 blank elements are added to the Compound List Variable ‘CLV EMP’.
LIST EXPAND : CLVEMP[1].Relatives : 10
Here, count formula is 1. Hence, 10 blank elements are added to Compound List Variable ‘Relatives’. ‘Relatives’ is a Compound List Member variable of the Compound List Variable ‘CLVEMP’.
Value Specifications
The value for the Simple/List Variables (Simple & Compound) can be specified using Attributes at Report and Form Level, and using Actions in User Defined Functions.
Value specification at Report level
The attributes SET and PRINTSET are used to specify the variable values at Report level.
Attribute – SET
The Report attribute SET can be used to specify a Variable name and its value, which will be set during the startup of the report.
Syntax
SET : <Variable Specification> : <Value Expression>
Where,
<Variable Specification> is the variable path specification.
<Value Expression> can be any expression, which evaluates to a value for the Variable of the specified data type.
Example:
;; Setting value to a simple Variable
SET : Var : “ABC”
;; Setting value to a simple List Variable element
SET : ListVar[1] : “XYZ”
;; Setting value to Compound List Variable element’s member
SET : CLVEMP[1].Name : “Kumar”
Attribute – PRINT SET
The Report attribute Print Set is similar to the SET attribute but sets the value of the variables to the specified value when the report is started in Print mode.
Syntax
PRINT SET : <Variable Specification> : <Value Expression>
Where,
<Variable Specification> is the variable path specification.
<Value Expression> can be any expression which evaluates to a value for the variable of the specified data type.
Example:
;; Setting value to a simple Variable
PRINTSET : Var : “ABC”
;; Setting value to a simple List Variable element
PRINTSET : ListVar[1] : “XYZ”
;; Setting value to Compound List Variable element’s member
PRINTSET : CLVEMP[1].Name : “Kumar”
Value specification at Form Level
-
Attribute – SET
The Form attribute SET is similar to the Report attribute SET, the difference being that while the report sets the value once in its lifetime, the form SET is executed during every regeneration/ refresh of the report.
Syntax
SET : <Variable Specification> : <Value Expression>
Where,
<Variable Specification> is the variable path specification.
<Value Expression> can be any expression, which evaluates to a value for the Variable of the specified data type.
Example:
;; Setting value to a simple Variable
SET : Var : “ABC”
;; Setting value to a simple List Variable element
SET : ListVar[1] : “XYZ”
;; Setting value to Compound List Variable element’s member
SET : CLVEMP[1].Name : “Kumar”
Value specification at Function level
Actions SET , MULTISET , EXCHANGE, INCREMENT and DECREMENT are used.
-
Action – SET
Values of variables can be set/updated via the SET action. This action is available as a global action, and can be used within a function also. List variables and compound variables cannot have values; they can have only element/member variables inside them, respectively. If SET action is used on compound variables, the value will be set to the FIRST member variable. If the first member variable is again compound, the program would search for the first non-compound leaf member and set the value.
For list variables, the value is treated as the count, and the list is expanded by the number of elements provided in the expression.
Syntax
SET : <Variable Specification> : <Value Expression>
Where,
<Variable Specification> is the variable path specification.
<Value Expression> can be any expression which evaluates to a value for the variable of the specified data type.
Example:
;; Setting value to a simple Variable
SET : Var : “ABC”
;; Setting value to a simple List Variable element
SET : SLVEMP[1] : “XYZ”
;; Setting value to Compound List Variable element’s member
SET : CLVEMP[1].Name: “Kumar”
-
Action – MULTISET
The action MULTI SET is used to set the values of compound member variables in one call. All member specifications are relative to the compound variable specification given.
Syntax
MULTI SET : <CompoundVariable Specification> + : <Member Specification :Value> [, <Member Specification : Value>, …]
Where,
<Compound Variable Specification> is the Compound Variable specification.
<Member Specification : Value> is the list of name-value pairs for setting member values.
Example: 1
MULTISET : CLVEMP[1] : Name : “Vimal”,Age : 26, Salary :($$AsAmount:10000)
All member variables of 1st element of Compound List Variable CLV EMP are set with MULTISET .
Example: 2
MULTISET : CLVEMP[1].Relatives[1] : Name : “Hari”, Age : 20, +
Relation:“Brother”
Here, all member variables for the first element of the Compound List Variable Relatives are set.
Relatives is a Compound List Member variable of the Compound List Variable CLV EMP.
-
Action – EXCHANGE
This action is used to swap the values of two variables, provided both belong to the same data type. This cannot be done for Simple List or Compound List as a whole. However, values of elements of Simple List and Compound List member variables having same data type can be exchanged.
Syntax
EXCHANGE : <First Variable Specification> : <Second Variable Specification>
Where,
<First Variable Specification> is the simple variable specification.
<Second Variable Specification> is the simple variable specification.
Exchanging value of a simple variable with another simple variable.
EXCHANGE : EmpVarOld : EmpVarNew
Both the Variables are of ‘ String’ data type. The value of the variable Emp VarOld is exchanged with that of the variable Emp VarNew on execution of the action.
Exchanging value of an element of Simple List Variable with that of another Simple List Variable.
EXCHANGE : SlvEmpOld[1] : SlvEmpNew[1]
The value of the first element of SLV EmpOld is exchanged with that of the first element of SlvEmpNew. Both the Simple List Variables are of ‘String’ data type
Exchanging value of a simple variable with a member variable of a compound list variable.
EXCHANGE : EMP Salary : CLVEmp[1].Salary
The value of a variable EMP Salary is exchanged with that of the member variable “Salary’ of the Compound List Variable CLV Emp. Both the simple variables are of String data type.
-
Action – INCREMENT
INCREMENT is a special action provided in ‘Function’ scope to increment values of the variable. This is supported only on simple variables of type Number.
Syntax
INCREMENT : <Simple Variable Specifica t ion> [:<NumIncrement Expression>]
Where,
<Simple Variable Specification> is the simple variable specification.
<NumIncrementExpression> is an expression which evaluates to a number. Based on this, the Variable value is incremented. It is optional. If not specified, the variable value is incremented by 1.
Example:
INCREMENT : Counter
;; Incrementing the variable value by 1
INCR : Counter : 2
;; Incrementing the variable value by 2
-
Action – DECREMENT
Decrement is a special action provided in ‘Function’ scope to decrement values of the variable. It is supported only on simple variables of type Number.
Syntax
DECREMENT : <Simple Variable Specification> [:<NumIncrementExpression>]
Where,
<SimpleVar Specifiction> is the simple variable specification.
<NumIncrement Expression> is an expression evaluating to a no., based on which , the Variable value is decremented. It is optional. If not specified, the variable value is decremented by 1.
Note: Action DECR is an alias for the action DECREMENT.
Example:
;; Decrementing the variable value by 1
DECREMENT : Counter
;; Decrementing the variable value by 2
DECR : Counter : 2
Value Modification at Field Level
-
Attribute – MODIFIES
The Field attribute Modifies is used to modify the value of the variable.
Syntax
Modifies : <Variable Specification> [:<Logical Flag>]
Where,
<Variable Specification> is the variable path specification.
<Logical Flag> can be a logical value TRUE / FALSE. TRUE would set the value after the field’s acceptance, while FALSE will set it during the acceptance of the report having the field.
Example:
[Field : EMP Age]
Modifies : EMPAgeVar : Yes
Here, value of the variable EMPAgeVar will be modified with the values stored/keyed in the field EMPAgeafter the field’s acceptance.
Retrieving value from List
It is used to retrieve the value of an element in the list for a given key. If the list is of compound Variables, an optional member specification can be given to extract value of a specific member.
Syntax
$$ListValue : <List Variable Specification> : <Key Formula> [:<Member Specification>]
Where,
<List Variable Specification> is the Simple List or Compound List Variable specification.
<Key Formula> can be any expression which evaluates to a string value.
<Member Specification> is required only if the value needs to be extracted from a specific member of a Compound List Variable.
Example:
Retrieving value from Simple List Variable using $$List Value
$$ListValue:SLVEMP:”E001″
In this example, the function returns the value of the element identified by the key ‘E001’ from the simple list variable ‘SLV Emp’.
$$ListValue:SLVEMP:##KeyVar
In this example, the variable KeyVar holds the key value. The function returns the value of the element identified by the key from the simple list variable SLV Emp.
Retrieving value from Compound List Variable using $$LISTValue
$$ListValue:CLVEmp:##KeyVar:Age
In this example, the variable KeyVar holds the key value. The function returns the identified Compound List Variable elements member Variable value. In this case, the member specification has been specified as ‘Age’.
The Function $$ListValueEx returns the value of an element at the specified index in the list.
Syntax
$$ListValueEx : <List Variable Specification>:<Index Formula> [:<Member Specification>]
Where,
<List Variable Specification> is the Simple or Compound List Variable specification.
<Index Formula> can be any expression which evauates to an index number.
<Member Specification> is required only if the value needs to be extracted from a specific member of a Compound List Variable.
Example:
Retrieving value from Simple List Variable using $$List Value Ex
$$ListValueEx:SLVEmp:##IndexVar
In this example, the variable IndexVar holds the index value. The function returns the value of the elementidentified by the index from the simple list variable SLV Emp.
Retrieving value from Compound List Variable using $$ListValueEx.
$$ListValueEx:CLVEmp:##IndexVar:Age
Here, Variable Key Var holds the index value. The function returns the identified Compound List Variable element’s mem b er variable value. Here, the member specified is ‘Age’.
The operator ## is used to access the value of the variable. It also allows dotted notation syntax to access variables/member variables/element Variables of a list at any level.
When ## is used on a compound variable (without path specification), it returns the value of the first member variable, by default. Similarly, on a list variable, it returns the no. of items in the list.
Syntax
##<Element Variable Specification>.<Member Variable Specification>.<Simple Member Value specification>
Where,
<Element Variable Specification> can be a Compound Variable or Compound List Variable [Index Expression ].
<Member Variable Specification> can be a Compound Variable Member or Compound List Member Variable [Index Expression].
<Simple Member Value Specification> refers to th e name of a simple member in specified path.
<Index Expression> is an expression that evaluates to a no. suffixing a variable with index refers to an element variable. It can be positive or negative. Negative index denotes reverse access.
Example:
Retrieving Value from Simple Li s t Variable using ## Operator
SET : TempVar : ##SLVEMP[3]
Value of element in SLVEMP , identified by the index ‘3’, will be set to t h e Variable ‘ Temp Var’.
Retrieving Value from Compound List Variable using ##Operator
LOG : ##CLVEmp[2].Relatives[1].Name
Here, we are retrieving value of the identified Compound List Variable (Relatives) element ’ s member variable value. ‘Relatives’ is a member variable of the Compound List Variable CLVEMP .
Looping Construct – For In/For Each
The FOR IN loop is used to iterate over the values in the list variable. The number of iterations depends on the number of items in the list variable .
Syntax
FOR IN : <I terator Variable> : <List Variable Name>
.
.
END FOR
Where,
<Iterator Variable> is the name of the variable which hold s the Key value in e very iteration.
<List Variable Name> is the name of the Simple Li s t or Compound List Variable.
This construct will walk only the element s in the list which are having a key . Since the iterator variable is filled with a key for each element , all elements which do not have a key a reignored . This is useful to walk keyed list Variable elements in the current sorting order . If the element does not have a key , then other loop s like WHILE, FOR, etc., can be used and the elements can be op e rated via index.
Example:
Iterating the Simple List Variable Values
FOR IN : KeyVar : SLV Emp
LOG : $$ListValue:SLVEmp:##KeyVar
END FOR
Here, the iterator Variable Key Var holds the Key val u e in every occurrence of the iteration. In every iteration, the value of the element identified by t h e key is logged using the function $$List Value .
Iterating the Compound List Variable Values
FOR IN : KeyVar : CLV Emp
LOG : $$ListValue:CLVEmp:##KeyVar:Age
END FOR
Here, the iterator variable KeyVar holds the Key value in every iteration. In every iteration, the v a lue o f the member “Age” of the element o f CLVEMP iden t ified by the key is logged using the function $$ListValue .
The looping construct FOR EACH is an alias for the looping construct FOR IN.
List Variable Specific Functions
Function – $$ListKey
The function $$ListKey returns the corresponding key for the given index.
Syntax
$$ListKey : <List Variable Specification> : <Index Specification>
Where,
<List Variable Specification> is the Simple List or Compound List Variable specification.
<Index Specification> can be any expression which evaluates to a number.
Example:
Retrieving key from a simple L ist V ariable using $ $ListKey
01 : LOG : $$ListKey:SLVEMP:2
In this example, the function $$ListKey retrieves the Key of the second element of the Simple List Variable ‘SLVEMP’.
Retrieving key from a Compound List Variable using $$ListKey
02 : LOG : $$ListKey:CLVEmp[1].Relatives:1
Here, key of first element of Compound List Variable Relatives is retrieved. ‘Relatives’ i s a member of Compound List Variable ‘CLVEMP’.
Function – $$ListIndex
The function $$ListIndex returns the Corresponding index for the given Key .
Syntax
List$$Index : <List Variable Specification> : <Key Specification>
Where,
<List Variable Specification> is the Simple List or Compound List Variable specification.
<Key Specification>can be any expression which evaluates to a string value.
Example:
Retrieving index from a simple List Variable using $$ListIndex
01 : LOG : $$ListIndex:SLVEMP:E001
Here, index of the element identified by the key value ‘E001’ is retrieved from ‘SLVEMP’.
Retrieving index from a Compound List Variable using $$List Index
02 : LOG : $$ListIndex:CLVEmp:E001
Here, index value of the element identified by the key value ‘ E 001’ is retrieved from ‘C L VEMP’.
Function – $$ListCount
The function $$ListCount retrieves the number o f items in the list.
Syntax
$$ListCount : <List Variable Specification>
Where,
<List Variable Specification> is the Simple List or Compound List Variable specification.
Example:
01 : LOG : $$ListCount:SLVEMP
02 : LOG : $$ListCount:CLVEMP
Function – $$ListFind
It is used to check if a given key exist s in the list or not. I t r e turns a logical flag as a result.
Syntax
$$ListFind : <List Variable Specification> : <Key Formula>
Where,
<List Variable Specification> is the Simple List or Compound List Variable specification.
<Key Formula> can be any expression which evaluates to a string value.
Example:
01 : LOG : $$ListFind:SLVEMP : E001
02 : LOG : $$ListFind:CLVEMP : E001
Function – $$ListValueFind
This function can be used to check if a given value exists in the list . If a given list has more th a n one same value, the index can be used to retrieve the n’th matching value.
Syntax
$$ListValueFind : <List Variable Specification> : <Occurrance Specification> : <Value Formula> [:<Member Specification>]
Where,
<List Variable Specification> is the Simple List or Compound List Variable specification.
<Occurrance Specification> can be any expression which evaluates to a number.
<Value Formula> can be any expression which evaluates to a value.
<Member Specification> can be specified if the list element is compound. It is optional.
Example:
;; Finding value from the Simple List Variable
01 : LOG : $$ListValueFind:SLVEMP:1:RAMESH
;;Finding value from the Compound List Variable with member specification
03 : LOG : $$ListValueFind:CLVEmp:1:PRIYA:Name
The function will return YES if the value exists in the list, else it will return NO.
Populating a List from a Collection
Action – LIST FILL
It is used to fill a list from a collection instead of using the looping construct s . The specified collection is walked and the key formula and value formula is evaluated in the context of each object to create list elements.
Syntax
LIST FILL : <List Variable Specification> : <CollectionName> [:<Key Formula> [:<Value Formula> [:<Member Specification>]]]
Where,
<List Variable Specification> is the Simple List or Compound List Variable specification.
<Collection Name> is the name of the collection from which the values need to be fetched to fill the list Variable.
<Key Formula> can be any expression which evaluates to string value. It is optional.
<Value Formula> c an be any expression which returns a value. The data type of the value must be same as that of the List Variable. Value formula is optional. I f not specified , only KEY is set for each added element.
<Member Specification> can be given if the list contains a compound variable
If both key and value are not specified, blank elements are added to the list.
Example
Populating a simple List Variable from a Collection
LIST FILL : SLV Emp : Employees : $Name : $Name
All the employee names from the collection Employees will b e added to the Simple List Variable , once the action LIST Fill is execute d .
Populating a Compound List Variable from a Collection
LIST FILL : CLV Emp : Employees : $Name : $Name
In this example, all the employee names from the collection Employees will be added to the first member variable , as there is no member specification.
LIST FILL : CLV Emp : Employees : $Name : $Designation: Designation
In this example, Designation s of all the employees from the collection ‘Employees’ will be added to the member variable Designation.
LIST FILL : CLV EMP[1].Relatives:Employees : $Name : $SpouseName : Name
Spouse name of all employees from the collection Employees will be added to member variable ‘Name’ of Compound List Variable ‘Relatives’. ‘Relatives’ is a member Variable of ‘CLVEMP’.
Sorting of List Elements
Initially , when the list variable is create d , it is sorted on the order of insert ion. TDL provides the facility to sort the values in the list variable based either on key or on value. The following actions allow changing the sort order:
- List Key Sort
- List Value Sort
- List Reset Sort
Action – LIST KEY SORT
The action LIST KEY SORT allows the user to sort the elements of the list based on the key .
Keys are by default of type ‘String’; so, the absence of key data type specification will consider key data type as String while sorting. The user can override his by specifying a key data type . Keys are optional for elements . All elements in the list may not have a key . In such cases, comparisons of elements would be done based on the insertion order .
Syntax
LIST KEY SORT : <List Variable Specification> [:<Ascending/DescendingFlag> [:<Key Datatype>]]
Where,
<List Variable Specification> is the Simple List or Compound List Variable specification.
<Ascending/DescendingFlag> can be YES/NO. YES is used to sort the list in ascending order and NO for descending. If the flag is not specified, then the default order is ascending.
<Key Data Type> can be String, Number, etc. It is optional.
The action LIST SORT is an alias for the action LIST KEY SORT .
Example
Sorting Simple List based on Key
LIST KEY SORT : SLVEmp : Yes : String ;;Ascending Order
LIST KEY SORT : SLVEmp : No : String ;;Descending Order
Sorting Compound List based on Key
LIST KEY SORT : CLVEmp : Yes : String ;;Ascending Order
LIST KEY SORT : CLVEmp[1].Relatives : No : String ;;Descending Order
Action – LIST VALUE SORT
The action LIST VALUE SORT allows the user to sort the elements of the list based on value. The data are sorted as per the data type specified for the list variable in case of simple list, and the member specification data type in case of compound list. If a compound list is chosen and member specification is not specified, then the list is sorted by value of the first member variable.
If duplicate values are in the list, the key data type passed is considered to sort by key, and then in absence of key, insertion order is used.
Syntax
LIST VALUE SORT : <List Variable Specification> [:<Ascending/Descending Flag> [:<Key Datatype> [:<Member Specification>]]]
Where,
<List Variable Specification> is the Simple List or Compound List Variable specification.
<Ascending/Descending Flag> can be YES/NO. YES is used to sort the list in ascending order and NO for descending. If the flag is not specified, then the default order is ascending.
<Key Data Type> can be String, Number, etc. It is optional.
<Member Specification> is the member specification in case of compound list. If not specified, the list is sorted by the value of first member variable.
Example
Sorting Simple List based on Value
;;Ascending Order
LIST VALUE SORT : SLVEmp : Yes : String
;;Descending Order
LIST VALUE SORT : SLVEmp : No : String
Sorting Compound List based on Value
;;Ascending Order
LIST VALUE SORT : CLVEmp : Yes : String
;;Descending Order
LIST VALUE SORT : CLVEmp[1].Relatives : No : String
Action – LIST RESET SORT
This action resets the sorting method of the list and brings it back to the insertion order.
Syntax
LIST RESET SORT : <List Variable Specification>
Where,
<List Variable Specification> is the Simple List or Compound List Variable specification.
Example:
LIST RESET SORT : SLVEMP LIST RESET SORT : CLVEMP
Some Common Functions Used
Function – $$IsSysNameVar
This function checks if the variable has a value which is a sysName like ‘Not Applicable’, ‘End of List’, etc. In case of repeated variables, if any one value is a non-sysname, it returns FALSE.
Syntax
$$IsSysNameVar : <Variable Specification>
Where,
<Variable Specification> is the simple variable path specification.
Example
$$IsSysNameVar:EmpVar
Here, $$IsSysNameVar returns YES if variable EmpVar has Sysname as value, else returns NO.
Function – $$IsDefaultVar
This function determines if the content of the variable has a Default or blank as the value. This function is applicable only for Simple variables. In case of simple repeated variable, if any one value is non-default, then this is not a default variable, and the function returns NO.
Syntax
$$IsDefaultVar : <Variable Specification>
Where,
<Variable Specification> is the simple variable path specification.
Example:
[Field : DefaultVar]
Set as : $$IsDefaultVar:SVValuationMethod
$$IsDefaultVar returns YES if value of SVValuationMethod is blank or Default, else returns NO.
Function – $$IsActualsVar
This function checks if the content of t h e variable is blank or sysname or “ACTUALS”.
Syntax
$$IsActualsVar : <Variable Specification>
Where,
<Variable Specification> is the simple variable path specification.
Example:
$$IsActualsVar:SVBudget
YES is returned if the value o f Variable SVBudget is Blank or Sysname or “ACTUALS”, else NO.
Function – $$IsCurrentVar
This function checks if the content of the variable is Blank or Sysname or “ Stock in hand”.
Syntax
$$IsCurrentVar : <Variable Specification>
Where,
<Variable Specification> is the simple variable path specification.
Example
$$IsCurrentVar:DSPOrderCombo
YES is returned if value of DSPOrderCombo is Blank or Sysname or Stock-In-Hand, else NO.
Function – $$ExecVar
This function returns the value of a variable in the parent report chain.
Syntax
$$ExecVar : <Variable Specification>
Where,
<Variable Specification> is the simple variable path specification.
Example:
$$ExecVar:DSPShowMonthly
Function $$ExecVar returns the value of the variable DSPShowMonthly from the parent report.
Function – $$FieldVar
This function returns the value of the field which is acting as a variable with the specified name.
Syntax
$$FieldVar : <Variable Specification>
Where,
<Variable Specification> is the simple variable path specification.
Example
[Collection : GodownChildOfGodownName]
Type : Godown
Child of : $$FieldVar:DSPGodownName
In this example, $$FieldVar is used to fetch the value of the variable DSPGodownName whose value is modified in a field. This value becomes the value for the ChildOf attribute.
Function $$ParentFieldVar
This function gets the field variable value from its parent report.
Syntax
$$ParentFieldVar:<Variable Specification>
Where,
<Variable Specification> is the simple variable path specification
Example:
[Field: ParentFieldVar]
Set as : $$ParentFieldVar:SVStockItem
In the above Example the function returns field variable value from its parent report for the variable SVStockItem
Variable Persistence at ‘Report’ Scope
Variables at Report scope can now be persisted into a user specified file. This is stored in a standard variable format and also allows reloading the report scope variables from the specified file. The actions SAVE VARIABLE and LOAD VARIABLE have been introduced for this purpose.
Action – SAVE VARIABLE
The action SAVE VARIABLE is used to persist the Report Scope Variables in a user specified file.
Syntax
SAVE VARIABLE : <FileName> [:<Variable List>]
Where,
<FileName> is the name of the file in which the report scope variables are persisted. The extension .PVF will be taken by default, if the file extension is not specified.
<Variable List> is the list of comma-separated variables that need to be persisted in the file. Specifying the variable list is optional.
If the Variable List is not specified, all the variables at the ‘Report’ scope, which have ‘Persist’ attribute set to YES, will be persisted in the specified file. We need not declare the variable at System level unless it is required to persist the same in the default configuration file tallycfg.tsf.
Example
Let us assume that the variables EmpNameVar and EmpIDVar are declared at the Report Scope, and the same need to be persisted in a user specified file. We can achieve this using the newly introduced actions SAVE VARIABLE and LOAD VARIABLE . The buttons SAVEVAR and LOADVAR are added at the Form Level for the same.
[Button: SaveVar]
Key : Alt + S
Action : Save Variable : SmpVar.pvf : EmpNameVar, EmpIDVar
The action SAVE VARIABLE will persist the values of the variables EmpNameVar and EmpIDVar in the file SmpVar.pvf
Action – LOAD VARIABLE
The action LOAD VARIABLE is used to reload the report scope variables from the specified file.
Syntax
LOAD VARIABLE : <FileName> [:<Variable List>]
Where,
<FileName> is the name of file in which the Report scope variables are persisted. The extension .PVF will be taken by default, if the file extension is not specified.
<Variable List> is the comma-separated list of variables that need to be loaded from the file. It is optional. In case it is not specified, all the variables saved in the file will be loaded.
Example
In the previous example, we have persisted values of the Report Scope Variables EmpNameVar and EmpIDVar in the file SmpVar.pvf . Now, let us see how to re-load these ‘report’ scope variables from the file.
[Button : LoadVar]
Key : Alt + L
Action : LOAD VARIABLE : SmpVar.pvf : EmpNameVar, EmpIDVar
The action LOAD VARIABLE will load the report scope variables EmpNameVar and EmpIDVar from the file SmpVar.pvf .
Member Variable Specification or Dotted Notation Specification is not allowed for specifying Variable list for both the actions SAVE VARIABLE and LOAD VARIABLE . It has to be a variable name identifier at the current report scope.
Variable Copy
The contents of a variable can now be entirely copied from one instance to another instance.
Action – COPY VARIABLE
The action COPY VARIABLE is used to copy the content from one variable (Source) to another variable (Destination). This action is supported for all types of variables (Simple/Compound/List Variables).
Syntax
COPY VARIABLE : <Destination Variable> : <Source Variable>
Where,
<Destination Variable> is the name of the Simple/Compound/List Variable.
<Source Variable> is the name of the Simple/Compound/List Variable, from which the content has to be copied.
Example: Copying from Simple Variable to Simple Variable
[Function : SimpleVar Copy Function]
VARIABLE : SimpleVar1 : String : “Employee1”
VARIABLE : SimpleVar2 : String
10 : COPY VARIABLE : SimpleVar2 : SimpleVar1
20 : LOG : “Source” + ##SimpleVar1
30 : LOG : “Destination” + ##SimpleVar2
In this example, the variables SimpleVar1 and SimpleVar2 are declared at the Function level. After execution of the action COPY VARIABLE , the content of the variable is copied from SimpleVar1 to SimpleVar2 .
Example: Copying from Compound Variable to Compound Variable
Let us suppose that the following compound variables are defined:
[Variable : Employee1]
Variable : EmpName : String : “Praveen”
Variable : Designation : String : “Manager”
[Variable : Employee2]
Variable : EmpName : String
Variable : Designation : String
In the function below, contents are copied from Compound Variable Employee1 to Employee2:
[Function : Compound Var Copy Function]
VARIABLE : Employee1
VARIABLE : Employee2
10 : COPY VARIABLE : Employee2 : Employee1
20 : LOG : “Source” + ## Employee1.EmpName
30 : LOG : “Source” + ## Employee1.Designation
40 : LOG : “Destination” + ## Employee2.EmpName
50 : LOG : “Destination” + ## Employee2.Designation
The content will be copied from a member variable of a Compound Variable (Source) to another member variable of a compound variable (Destination), based on the member variable names, since more than one member variable may have the same data type.
Example: Copying from List Variable to List Variable
Let us suppose that the following compound variables are defined:-
[Variable : Employee1]
Variable : EmpName : String
Variable : Designation : String
[Variable : Employee2]
Variable : EmpName : String
Variable : Designation : String
In the following function, the compound variables Employee1 and Employee2 are declared as List Variable. We are copying all the elements from the compound list variable Employee1 to the compound list variable Employee2 .
[Function : ListVar Copy Function]
LIST VARIABLE : Employee1, Employee2
10 : LIST FILL : Employee1 : Employees : $Name : $Name
20 : LIST FILL : Employee1 : Employees : $Name : $Designation + :Designation
30 : COPY VARIABLE : Employee2 : Employee1
40 : LOG : “Source Variable – Employee”
50 : FOR IN : KEY VAR : Employee1
60 : LOG : $$LISTVALUE:Employee1:##KEYVAR:EmpName
70 : LOG : $$LISTVALUE:Employee1:##KEYVAR:Designation
80 : END FOR
90 : LOG : “Destination Variable – Employee”
100 : FOR IN : KEY VAR : Employee2
110 : LOG : $$LISTVALUE:Employee2 : ##KEYVAR:EmpName
120 : LOG : $$LISTVALUE:Employee2 : ##KEYVAR:Designation
130 : END FOR
Scope Specification in Variable Dotted Syntax
The Dotted Notation Syntax for Variables (##) to allow specification of scope or relative scope, etc.
Syntax
.. (DOUBLE DOT) denotes owner scope
… (TRIPPLE DOT) denotes owner’s owner scope and so on
(). denotes a system scope
Where,
<Definition Type> is the name of the definition such as Report, Function, etc., in the current execution chain.
<Definition Name Expression> can be any expression which evaluates to a Definition Name. The Definition Name Expression is optional.
(<Definition Type>, <Definition Name Expression>) can be used for absolute scope specification. The element (<Definition Type>, <Definition Name Expression>) has to be in the current execution chain, else one will not be able to refer to the same.
Example
Let us suppose that the Variable TSPLSMPScopeVar is declared at System Scope.
[Variable : TSPLSMPScopeVar]
Type : String
[System : Variable]
TSPLSMPScopeVar : “System Scope”
The function TSPLSMPScopeSpec is called from a Menu. We have declared the variable TSPLSMPScopeVar in the ‘Function’ scope also.
[Function : TSPLSMP ScopeSpec]
VARIABLE : TSPLSMPScopeVar
01 : SET : TSPLSMPScopeVar : “Function Level”
02 : Display : TSPLSMP ScopeSpec
The following report is displayed from the function TSPLSMP ScopeSpec. We have declared the variable TSPLSMPScopeVar in the ‘Report’ Level also.
[Report : TSPLSMP ScopeSpec]
Form : TSPLSMP ScopeSpec
Variable : TSPLSMPScopeVar
Set : TSPLSMPScopeVar : “Report Level”
Following are the field definitions of the report TSPLSMP ScopeSpec. Let us see the variable values at the field level by specifying the scope in Variable Dotted Syntax.
[Field : TSPLSMP ScopeSpecCurrent]
Use : Name Field
Set As : ##TSPLSMPScopeVar
;;Variable value in this field will be “Report Level” (Current Scope)
[Field : TSPLSMP ScopeSpecOwner]
Use : Name Field
Set As : ##..TSPLSMPScopeVar
Border : Thin Left Right
;;Variable value in this field will be “Function Level” (Owner’s Scope)
[Field : TSPLSMP ScopeSpecSystem]
Use : Name Field
Set As : ##().TSPLSMPScopeVar
Border : Thin Left
;;Variable value in this field will be “System Level” (System Scope)
[Field : TSPLSMP ScopeSpecAbsolute]
Use : Name Field
Set as : ##(Function,“TSPLSMP ScopeSpec”).TSPLSMPScopeVar
Border : Thin Left
;;Variable Value in this field will be “Function Level” (Absolute Specification)
Definition Name and Instance Name of Variable can be different now
A variable can be declared in a scope in two ways, i.e., either by specifying the name of the variable (in this case, a separate variable definition is required) or by specifying the name of the variable and a data type (in this case, a separate variable definition is not required; and hence, is called as inline declaration).
Note: In this chapter, we will go through the ‘Report’ Scope variable declaration, syntax and examples. It is applicable for other scopes also.
Let us look into the variable declaration syntax of Report Scope.
Syntax
[Report : <Report Name>]
;;This syntax expects a separate variable definition in the same name
Variable : <Variable Names>
OR
;;Inline declaration
Variable : <Variable Names> [:<Data Type>[:<Value>]]
OR
List Variable : <Variable Names> [:<Data Type>[:<Value>]]
Example
[Report : SMP Report]
Variable : Emp Name
Variable : Emp Relation : String
List Variable : Employee1
List Variable : Employee2 : String : “Prem”
[Variable : Emp Name]
Type : String
[Variable : Employee1]
Variable : EmpName : String
Variable : EmpID : String
Now, the ‘Data Type’ parameter can be pointing to a variable definition; in which case, it will allow one to have a variable which has the instance name and definition name different. This allows flexibility to create two instances of a compound structure in the same scope, with different instance names, without requiring to duplicate the definition. This capability is available at all the scopes where variable declaration is allowed.
Existing Syntax
[Report : <Report Name>]
Variable : <Variable Names>
OR
Variable : <Variable Names> [:<Data Type>[:<Value>]]
OR
List Variable : <Variable Names> [:<Data Type>[:<Value>]]
New Enhanced Syntax
[Report : <Report Name>]
Variable : <Variable Names>
OR
Variable : <Variable Names> [:<Data Type>[:<Value>]]
OR
List Variable : <Variable Names> [:<Data Type>[:<Value>]]
OR
Variable : <Instance Names> : [<Variable Name>]
OR
List Variable : <Instance Names> : [<Variable Name>]
Where,
<Instance Names> is the list of Simple/Compound/List Variables separated by comma (instance variables).
<Variable Name> is the Simple or Compound variable name. A separate variable definition is required. It should not be an inline variable.
Example: 1
Given here is the definition of a Compound Variable “Employee”.
[Variable : Employee]
Variable : EmpName : String
Variable : Designation : String
Now, we can create a variable instance using the definition of another variable. Let us understand this with the help of the following ‘Report’ definition:
[Report : Employee Report]
;;An instance is declared with the name as ‘Prem’ and definition name as ‘Employee’. The variable instance ‘Prem’ will inherit the entire structure of the variable definition ‘Employee’.
Variable : Prem : Employee
;;An instance is declared with the name as ‘Ramesh’ and definition name as ‘Employee’.
Variable : Ramesh : Employee
;;Locally, the instance “Ramesh” is modified to add a member variable.
Local : Variable : Ramesh : Add : Variable : EmpID : String
;; Two instances are declared with the names “Kamal” and “Vimal”, and the definition name as “Employee”
Variable : Kamal, Vimal: Employee
;; A List Variable instance is declared with the name “EmployeeList” and the definition name as “Employee”
List Variable : EmployeeList : Employee
Example: 2
[Report : TSPL SMP Variable Instance]
Variable : Employee : String : “Suresh”
Variable : New Employee : Employee
In this example, we are trying to declare a variable instance New Employee, which is of the type of another variable ‘Employee’. This will NOT work because the variable ‘Employee’ is declared as inline and an explicit Definition does not exist for the same.
Hence, inline variables cannot be used to declare another variable instance.
Persisting Variables at System Scope in a User Specified File
The variables at the Report scope can be persisted in a user specified file using the action SAVE VARIABLE. This can be re-loaded as required using the action LOAD VARIABLE.
The latest enhancements in variable persistence allow the user to persist and re-load the variables at System Scope (in a User Specified File) as well.
Action – SAVE VARIABLE
The action SAVE VARIABLE, which is used to persist the Report Scope Variables in a user specified file, now allows us to persist the System Scope Variables also. Syntax of this action remains the same. The desired behaviour is achieved with changes in variable list specification.
Syntax
SAVE VARIABLE : <FileName> [:<Variable List>]
Where,
<File Name> is the name of the file in which the report scope/ system scope variables are persisted. The extension .PVF will be taken by default, if the file extension is not specified.
<Variable List> is the comma-separated list of variables that need to be saved in the file.
Variable List specification changes
- Now * can also be used to specify the variable list, which means all at ‘current scope’.
- The current scope can either be ‘System’ or ‘Report’.
- Specifying ‘*’ will ignore the ‘Persist’ flag and save all the variables in the scope, irrespective of “Persist: Yes” at the ‘Variable’ definition level.
- If Variable list is not provided, it will persist all the variables which are set as “Persist: Yes” at the Variable definition level.
- Dotted notation syntax is also supported in the variable list specification for scope specification.
However, this cannot be used for SUB levels. It can be used only for accessing parent scope variables.
- Single Dot “.” refers to current scope, Double Dot “ . .” to parent scope, Triple Dot “ . . . ” to grandparent scope, and so on.
- “ (). ” refers to the System Scope.
Action – LOAD VARIABLE
The action LOAD VARIABLE , which is used to load the Report Scope Variables in a user-specified file, now allows us to load the System Scope Variables also. Syntax of this action remains the same. The desired behaviour is achieved with changes in variable list specification.
Syntax
LOAD VARIABLE : <File Name> [:<Variable List>]
Where,
<File Name> is the name of the file in which the report scope/ system scope variables are persisted. Specifying file extension is mandatory while loading variable values.
<Variable List> is the comma-separated list of variables that need to be loaded from the file.
Variable List specification changes:
- While loading, ‘ * ’ is not relevant and will be ignored.
- While loading, ‘Persist’ flag of the variable is ignored. It is assumed that the variable must have a persist flag OR it is saved forcefully and hence to be loaded.
Example:1
There is a requirement to persist values of all system scope variables in a user specified file and load the values from the file whenever required. Refer to the following code snippet:
[#Menu : Gateway of Tally]
Add : Button : SLSystemScopeSave, SLSystemScopeLoad
;;Buttons SLSystemScopeSave & SLSystemScopeLoad are added at the Gateway of Tally Menu to execute the actions SAVEVARIABLE & LOADVARIABLE.
[Button : SLSystemScopeSave]
Key : Alt + F
Action : SAVE VARIABLE : SLSystemScope.pvf : *
Title : “Save Sys Var”
Values of all system scope variables will be persisted in the file SLSystemScope.pvf on execution of the action Save VARIABLE.
[Button : SLSystemScopeLoad]
Key : Alt + L
Action : LOAD VARIABLE : SLSystemScope.pvf
Title : “Load Sys Var”
Values of all system scope variables will be loaded from the file SLSystemScope.pvf on execution of the action LOAD VARIABLE.
Example:2
There is a requirement to persist values of all system scope variables which are set as “Persist : Yes” at variable definition level in a user specified file, and load the values from the file whenever required. Refer to the following code snippet:
[#Menu : Gateway of Tally]
Add : Button : SLSystemScopeSave, SLSystemScopeLoad
Buttons SLSystemScopeSave & SLSystemScopeLoad are added at the Gateway of Tally Menu to execute the actions SAVE VARIABLE & LOAD VARIABLE .
[Button : SLSystem ScopeSave]
Key : Alt + F
Action : SAVE VARIABLE : SLSystemScope.pvf
Title : “Save SysVar”
;; Values of all variables at system scope which are set “Persist : Yes” at variable definition level, will be persisted in the file SLSystem-Scope.pvf on execution of the action SAVE VARIABLE.
[Button : SLSystemScopeLoad]
Key : Alt + L
Action : LOAD VARIABLE : SLSystemScope.pvf
Title : “Load Sys Var”
;;Values of all variables will be loaded from the file SLSystemScope.pvf on execution of the action LOAD VARIABLE.
Example: 3
There is a requirement to persist the system scope variables SVSymbolInSign & SVInMillions in a user specified file, and load the values of these variables from the file whenever required. Refer to the following code snippet:
[#Menu : Gateway of Tally]
Add : Button : SLSystemScopeSave, SLSystemScopeLoad
Buttons SLSystemScopeSave & SLSystemScopeLoad are added at the Gateway of Tally Menu to execute the actions SAVE VARIABLE & LOAD VARIABLE.
[Button : SLSystemScopeSave]
Key : Alt+F
Action : SAVE VARIABLE : SLSystemScope.pvf : SVSymbolInSign, SVInMillions
Title : “Save Sys Var”
Values of the system Scope variables SVSymbol InSign & SVInMillions will be persisted in the file SLSystemScope.pvf on execution of the action Save VARIABLE.
[Button : SLSystemScopeLoad]
Key : Alt + L
Action : LOAD VARIABLE : SLSystemScope.pvf : SVSymbolInSign ,SVInMillions
Title : “Load Sys Var”
Values of the system scope variables SVSymbolInSign & SVInMillions will be loaded from the file SLSystemScope .pvf on execution of the action LOAD VARIABLE.
Example: 4
The following report is displayed in ‘Create’ mode from a menu item.
[Report : Smp SLReport]
Form : Smp SLForm
Variable : SaveLoadVar1, SaveLoadVar2
The variables SaveLoadVar1 & SaveLoadVar2 are declared at Report Scope.
[Form : Smp SLForm]
Parts : Form SubTitle, Smp SLPart
Button : Smp SaveVar, Smp LoadVar
Buttons SmpSaveVar & SmpLoadVar are added at ‘Form’ Level to execute the actions SAVE VARIABLE & LOAD VARIABLE.
Let us look into the following scenarios to persist and load System Scope as well as Report Scope Variable values:
- Persist & Load all Report Scope Variables & a specific System Scope Variable
[Button : Smp SaveVar]
Key : Alt + S
Action : SAVE VARIABLE : SLReportCfg.pvf: *,().SVInMillions
Title : “Save Variable”
;; Values of all variables declared at report scope and the value of system scope variable SVInMillions will be persisted in the file SLReportCfg.pvf on execution of the action SAVE VARIABLE. (The variable SVInMillions is prefixed with (). to denote the same as System Scope Variable).
[Button : Smp LoadVar]
Key : Alt + L
Action : LOAD VARIABLE : SLReportCfg.pvf : *,(). SVInMillions
Title : “Load Variable”
Variable list specification * will be ignored. Values of all report scope variables and the value of system scope variable SVInMillions will be loaded from the file SLReportCfg.pvf on execution of the action LOAD VARIABLE.
- Persist and Load a specific Report Scope variable & a specific Syst e m Scope variable
[Button : Smp SaveVar]
Key : Alt + S
Action : SAVE VARIABLE: SLReportCfg.pvf : SaveLoadVar1 ,().SVInMillions
Title : “Save Variable”
;;Value of Report scope variable SaveLoadVar1 and value of system scope variable SVInMillions will be persisted in the file SLRe-portCfg.pvf on execution of the action SAVE VARIABLE.
[Button : Smp LoadVar]
Key : Alt + L
Action : LOAD VARIABLE : SLReportCfg.pvf : SaveLoadVar1, ().SVInMillions
Title : “Load Variable”
;;Value of Report scope variable SaveLoadVar1 and value of system scope variable SVInMillions will be loaded from the file SLReportCfg.pvf on execution of the action LOAD VARIABLE.
Use Case – Multiple Email Configurations
Scenario
ABC Company Ltd., a manufacturing company, is having the Head Office in Bangalore and branch offices in Delhi, Mumbai, Kolkata and Chennai. The company uses TallyPrime at all the locations.
The Head Office and Branch Offices are using the e-mail capability of Tally extensively to send remainder letters, outstanding statements, etc., to the customers.
The System Administrator at the Head office will be facilitating the Branch office staff for email configurations in Tally. The company is using its own mail server and also another mail server “SIFY”. If there is a change in the mail server, the system admin needs to communicate the information to branch staff, and they will be updating the email configurations in TallyPrime .
Now, the company wants to set the email configurations centrally for all the branches so that the branch staff need not struggle for email configurations, particularly when there is a change in the mail server. This solution provides the facility of saving multiple configurations in multiple file names, and later loading them from the file, based on user selection.
Requirement Statement
Presently in TallyPrime, users need to set email configurations locally & update required details.
Now, the configurations can be created centrally and shared among the locations. Thus, the user need not set email configuration every time. They have to simply load the configuration from the file. This can be achieved using newly introduced actions SAVE VARIABLE & LOAD VARIABLE.
Functional Demo
Before looking into the design logic, we will have a functional demo.
Let us suppose that ABC Company Ltd. is using its own mail server and another mail server Sify in its Head Office and its branch offices.
Saving Email Configurations
Let us suppose that the System Administrator in Head Office wants to save the required email configurations in TallyPrime for HO and Branches
Gateway of Tally> F12: Configure> E-Mailing . The email configuration screen will appear as follows:
The System Admin needs to save the configurations for mail servers abc and Sify. Hence, he has to specify Email server as “User Defined” and enter the required configuration settings as follows:
Now, the System Admin has to press Alt+S, or click on the Button Save Config. The following screen will appear, where he has to enter the configuration file name:
Once the System Admin accepts this screen, the configuration details will be saved in the file “abc.pvf”. Similarly, he has to create the Configuration for the mail server “Sify”. The files will be created in Tally.ERP 9 application folder, as shown in the following screenshot:
The admin can share these two files to the staff in HO and Branch Offices, and they should place the file in the respective Tally.ERP 9 application folders.
Loading Configurations
Gateway of Tally> F12: Configure> E-Mailing . The e-mail configuration screen will be displayed with the previously set configurations.
Now, the user at HO/Branch wants to load the configurations for the email server “abc”. He has to press Alt+L or click on the Button “Load Config”, and enter the file name.
Accept the screen. The Email Configuration Report will display the configuration details loaded from the file “abc”. Accept the configuration screen, and the settings will be applicable to all reports. Suppose the User now wants to mail the report Balance Sheet. He has to select ‘Balance sheet’ and press Alt + M. The following configuration report will appear:
Note that the configuration details are changed as per the selected configuration. Now, the user wants to change the email server as Sify. Go to Gateway of Tally> F12:Configure> E-Mailing . Press Alt + L . Enter the file name as Sify and press Enter . The email configuration screen will have new configurations loaded from the file Sify .
Similarly, we can save/load multiple configurations.
Solution Development
The steps followed to achieve Saving of Multiple Email Configurations are:
Declaring variables at ‘Report’ Level
Variables SVMailServerName, SVMailServer, SVMailFormat, SVMailUseSsl, etc., are declared at ‘Report’ Level. All these variables have the attribute Persistent set as YES at the Definition level.
[#Report : EMail Configuration]
Variable : SVMailServerName, SVMailServer, SVMailFormat, SVMailUseSsl
Variable : SVMailUseSSLOnStdPort, SVMailAuthUserName, SVExportFormat
Saving Configuration
A button is added to the Form, and the action will call a User Defined Function. In a User Defined Function, we are executing a report to accept a File Name from the user. We are persisting all the report scope variables in the specified file through the Action SAVE VARIABLE.
Loading Configurations
A button is added to the Form and on clicking it, the action will call a User Defined Function. In the User Defined Function, we are executing a report to accept the File name from the user. We are reloading the report scope variables from the file through the Action LOAD VARIABLE. Please refer to the following code snippet for Save and Load configurations.
[Function : TSPL Smp SaveLoadVar]
Parameter : IsSaveVar : Logical : Yes
Variable : ConfigNamewithExt : String : Yes
00 : EXECUTE : TSPL Smp SaveLoadConfigName
;; Correcting the file name entered with or without extension by the user
06 : IF : ##SaveLoadConfigName CONTAINS “.Pvf”
10 : SET : ConfigNamewithExt : ##SaveLoadConfigName
20 : ELSE
30 : SET : ConfigNamewithExt : ##SaveLoadConfigName + “.pvf”
40 : ENDIF
;; Saving or Loading the variables based on parameter value
50 : IF : NOT $$IsEmpty : ##SaveLoadConfigName
60 : IF : ##IsSaveVar
70 : SAVE VARIABLE : ##ConfigNamewithExt
80 : ELSE
90 : LOAD VARIABLE : ##ConfigNamewithExt
100 : ENDIF
110 : ENDIF
The corresponding field values need to reflect the values of the variables loaded from the file. This is handled by using the following code:
Local : Field : DSPMailServer : Set as : If #DSPMailServerName Contains $$SysName:UserDefined Then ##SVMailServer +
Else If #DSPMailServerName NOT Contains $$SysName:UserDefined Then $$GetMailServerAddr:#DSPMailServerName +
Else ##SVMailServer
Local : Field : DSPMailServerName : Set As : ##SVMailServerName
Local : Field : DSPMailFormat : Set As : ##SVMailFormat
Local : Field : DSPMailUseSsl : Set As : ##SVMailUseSsl
Local : Field : DSPMailUseSSLOnStdPort : Set As : ##SVMailUseSSLOnStdPort
Local : Field : DSPMailAuthUserName : Set As : ##SVMailAuthUserName
Local : Field : DSPFinalExportFormat : Set As : ##SVExportFormat
Also, if the field values are changed, the Report level variables need to be modified with those values. This is handled using the following code:
Local : Field : DSP MailServerName : Modifies : SVMailServerName : Yes
Local : Field : DSP MailServer : Modifies : SVMailServer : Yes
Local : Field : DSP MailFormat : Modifies : SVMailFormat : Yes
Local : Field : DSP MailUseSsl : Modifies : SVMailUseSsl : Yes
Local : Field : DSP MailUseSSLOnStdPort : Modifies : SVMailUseSSLOnStdPort : Yes
Local : Field : DSP MailAuthUserName : Modifies : SVMailAuthUserName : Yes
Local : Field : DSP FinalExportFormat : Modifies : SVExportFormat : Yes
On accepting the Form email configuration, we are calling a User Defined Function to set the System Variable values. Thus, the changed configuration details will be available for all the reports. Please refer to the following Code Snippet:
[Function: TSPL Smp Update System Variables]
10 : SET : ().SVMailServerName : ##SVMailServerName
20 : SET : ().SVMailServer : ##SVMailServer
30 : SET : ().SVMailFormat : ##SVMailFormat
40 : SET : ().SVMailUseSsl : ##SVMailUseSsl
50 : SET : ().SVMailUseSSLOnStdPort : ##SVMailUseSSLOnStdPort
60 : SET : ().SVMailAuthUserName : ##SVMailAuthUserName
70 : SET : ().SVExportFormat : ##SVExportFormat