Explore Categories

 

User Defined Functions

TDL functions are action statements defined by an application developer. The developer has a complete control over the sequence in which these actions get executed. A TDL function extends the following benefits to the TDL programmer:

  • To perform a set of actions sequentially with or without any conditional statements.
  • Allows looping and conditional execution of a set of actions.
  • Defining once and executing it repetitively passing different set of parameters.
  • To define variables, manipulate and set values in it.
  • To work on data elements like getting an object context from the calling UI, changing the context, looping the objects of a collection, reading data from source and setting value in the target object, and so on.
  • Creation and manipulations of the existing internal objects.

With the advent of TDL the application developer can write complex business functions with ease and without much platform dependency.

Traditionally, TDL was always a non-procedural, action-driven language. The sequence of execution was not in the hands of the programmer. But, with this development in a ‘Function’ Definition, Conditional evaluation of statements and looping has been made possible. User defined Functions basically can be used for performing complex calculations or executing a set of actions serially. Functions can accept parameter(s) as input, and return a ‘Value’ to the caller.

With this development, the programmers can write business functions with complex computations by themselves, without platform dependency.

 

Function – Building Blocks

In TDL, Function is also a definition. It has two blocks:

  • Definition Block
  • Procedural Block

A glimpse into the function:

[Function : Function Name]

;; Definition Block

;; Parameter Specification

Parameter : Parameter 1 : Datatype

Parameter : Parameter 2 : Data t ype

;; Variable Declarations

Variable : Var 1 : Number

Variable : Var 2 : String

;; Explicit Object Association

Object : ObjName : ObjectType

;;Return Value

Returns : D atatype

;;Definition Block Ends here

;;Procedural Block

Label 1 : Statement 1

Label 2 : Statement 2

|

|

Label n : Statement n

;; Procedural Block Ends here

Definition Block

The definition Block is utilized for the following purposes:

Parameter specification

This implies specifying the list of parameters which are passed by the calling code. The values thus obtained, are referred to in the function with these variable names. The syntax for specifying the same is given below:

Syntax

PARAMETER : <Variable Name> : <Data Type of the Variable>

Where,

< Variable Name > is the name of the Variable which holds the parameter sent by the caller of the Function.

< Data Type of the Variable > is the Data type of the Variable sent by the caller of the Function.

Example

[Function: FactorialOf]

Parameter : InputNumber : Number

The Function ‘$$FactorialOf’ receives number as the parameter from the Caller.

Variable declaration

If a function requires some Variable(s) for intermediate calculation, then those Variable(s) need to be defined. The scope of these Variable(s) will be within the Function, and the Variable(s) lose their value after exit from the function.

Syntax

VARIABLE : <Variable Name> [:<Data Type of the Variable>]

Where,

< Variable Name > is the name of the Variable.

< Data Type of the Variable > is the Data type of the Variable.

Datatype is optional. If datatype is specified, a separate Variable definition is not required (these are considered as in-line variables). If data type is not specified, the interpreter will look for a variable definition, with the name specified.

Example

[Function : FactorialOf]

Parameter : InputNumber : Number

Variable : Counter : Number

Variable : Factorial : Number

The Function $$FactorialOf requires intermediate Variables ‘Counter’ and ‘Factorial’ for calculation within the ‘Function’ Definition.

Static Variable declartion

Static Variable is a Variable, whose value persists between successive calls to a Function.

The scope of the static variable is limited to the Function in which it is declared, and exists for the entire session.

Syntax

STATIC VARIABLE : <Variable Name> [:<Data Type of the Variable>]

Where,

< Variable Name > is the name of the Static Variable

< Data Type of the Variable > is the Data type of the Static Variable.

Data type is optional. If data type is specified, a separate Variable definition is not required (these are considered as in-line variables). If data type is not specified, the interpreter will look for a variable definition with the name specified.

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 .

Return value specification

If a function returns a value to the caller, then its data type is specified by using RETURNS statement.

Syntax

RETURNS : <Data Type of the Return Value>

Where,

<Data Type of the Return Value > is the Data type of the return value of the Function.

Example

[Function : FactorialOf]

Parameter : InputNumber : Numb e r

Returns : Number

Variable : Factorial : Number

The function FactorialOf returns the value of type Number to the caller of the Function

Object specification

Function will inherit the Object context of the caller. This can be overridden by using the attribute Object for Function definition. This now becomes the current object for the function.

Syntax

Object : <ObjType> : <ObjIdValue>

Where,

< ObjType > is the type of the object, and

< ObjIdValue > is the unique identifier of the object.

Example

[Function : Sample Function]

Object : Ledger : “Party”

The function Sample Function will be in the context of the ledger Party .

Procedural Block

This block contains a set of statements. These statements can either be a programming construct or an Action specification. Every statement inside the procedural block has to be uniquely identified by a label specification.

Syntax

LABEL SPEC I FICATION : Programming Construct

Or

LABEL SPEC I FICATION : Action: Action Parameter

Example

[Function : DispStockSummary]

01 : Display : Stock Summary

02 : Display : Stock Category Summary

The Function ‘DispStockSummary’ is having two Actions with Label.

Valid Statements inside a Function

The statements used inside the procedural block of a function can be:

  • A programming construct, as discussed in the previous sections
  • A TDL action

There have been major changes in some actions to work especially with functions. Some new actions have been introduced as well. Let us now discuss the various Actions used inside functions.

Programming Constructs In Function

Conditional Constructs

IF–ENDIF

The ‘IF–ENDIF’ statement is a powerful decision making statement and is used to control the flow of execution of statements. It is basically a two-way decision statement and is used in conjunction

with an expression. Initially, the expression will be evaluated and based on the whether the expression is True or False, it transfers the execution flow to a particular statement.

Figure_13.1_Flow_Chart_for_IF___ENDIF.jpg

Syntax

IF : <Condition Expression>

STATEMENT 1

STATEMENT N

ENDIF

Example:

If the f unction parameter sent to the Function ‘FactorialOf’ is less than zero, then it is multiplied by -1 to find the absolute value.

[Function : FactorialOf]

Parameter : InputNumb e r : Number

Returns : Number

Variable : Counter : Number

Variable : Factorial : Number

1 : SET : Counter : 1

2 : SET : Factorial : 1

3 : IF ##I n putNumber <

4 : SET : Inp u tNumber : ##InputNum b er * -1

5 : END IF

6 : WHILE : ##Counter <= ##InputNumber

7 : SET : Fa c torial : ##Factorial * ##Counter

8 : SET : Counter : ##Counter + 1

9 : END WH I LE

10 : RETURN ##Factorial

DO IF

When an IF-ENDIF statement block contains only one statement, then the same can be written in a single line by using DO-IF statement.

Syntax

DO IF : <Condition Expression> : STATEMENT

Example

Here, IF – END IF statement is rewritten using the DO – IF statement.

[Function : FactorialOf]

Parameter : InputNumber : Num b er

Returns : Number

Variable : Counter : Number

Variable : Factorial : Number

1 : SET : Counter : 1

2 : SET : Factori a l : 1

3 : DO IF : ##InputNumber < : ##InputNumber * -1

4 : WHILE : ##Counter <= ##In p utNumber

5 : SET : Fa c torial : ##Factorial * ##Counter

6 : SET : Co u nter : ##Counter + 1

7 : END WH I LE

8 : RETURN ##Factorial

IF–ELSE–ENDIF

The IF–ELSE–ENDIF statement is an extension of the simple IF-ENDIF statement. If the condition expression is True, then the ‘True’ block’s statement(s) are executed; otherwise, the ‘False’ block’s statement(s) are executed. In either case, either the True block or the False block will be executed, not both.

 

Syntax

IF : <Condition Expression>

STATEMENT 1

STATEMENT N

ELSE

STATEMENT 1

STATEMENT N

ENDIF

Example

Finding the greatest of three numbers

[Function : FindGreatestNumbers]

Parameter : A : Number

Parameter : B : Number

Parameter : C : Number

RETURNS : Number

01 : IF : ##A > ##B

02 : IF : ##A > ##

03 : RETURN : ##A

04 : ELSE

05 : RETURN : ##C

06 : END IF

07 : ELSE

08 : IF : ##B > ##C

09 : RETURN : ##B

10 : ELSE

11 : RETURN : ##C

12 : END IF

13 : END IF

Looping Constructs

WHILE – ENDWHILE

In looping, a sequence of statements is executed until some condition(s) for termination of the loop is satisfied. A typical loop consists of two segments, one known as the body of the loop and the other known as the control statement. The control statement checks the condition and then directs the repeated execution of the statements contained in the body of the loop.

The WHILE – ENDWHILE is an entry-controlled loop statement. The condition expression is evaluated and if the condition is True, then the body of the loop is executed. After the execution of the statements within the body, the condition expression is once again evaluated and if it is True, the body is executed once again. This process of repeated execution of the body continues until the condition expression finally becomes False, and the control is transferred out of the loop.

 

Syntax

WHILE : <Condition Expression>

STATEMENT 1

STATEMENT N

ENDWHILE

Example

[Function : FactorialOf]

Parameter : InputNumber : Number

Returns : Number

Variable : Counter : Number

Variable : Factorial : Numb e r

1 : SET : Counter : 1

2 : SET : Factorial : 1

3 : WHILE : ##Counter <= ##I n putNumber

4 : SET : Factorial : ##Factorial * ##Co u nter

5 : SET : Counter : ##Counter + 1

6 : END WH I LE

7 : RETURN ##Factorial

The Function ‘FactorialOf’ repeats statements 4 and 5, till the given condition is satisfied.

WALK COLLECTION – END WALK

If a Collection has ‘n’ Objects, then WALK COLLECTION – ENDWALK will be repeated for ‘n’ times. Body of the loop is executed for each object in the collection, making it the current context.

Figure_13.4_Flow_Chart_for_WALK_COLLECTION___ENDWALK.jpg

Syntax

WALK COLLE C TION : <Collection Name>

STATEMENT 1

STATEMENT N

ENDWALK

Example

Walking over all the Vouchers and counting the same.

[Collection : Vouchers Coll]

Type : Vouch e r

[Function : CountVouchers]

Returns : Number

Variable : Count : Number

001 : SET : Count :

002 : WALK COLLECTION : Vouch e rs Coll

003 : SET : Count : ##Count + 1

004 : END W ALK

005 : RETU R N : ##Cou n t

Control Constructs

Loops perform a set of operations repeatedly until the condition expression satisfies the given condition or the Collection is exhausted. Sometimes, when executing the loop, it becomes desirable to skip the part of the loop or to exit the loop as a certain condition occurs, or to save the current state and return back to the current state later.

BREAK

When a BREAK statement is encountered inside the loop, the loop is immediately exited and the control is transferred to the statement immediately following the loop. BREAK statement can be used inside WHILE – END WHILE and WALK COLLECION – END WALK. When loops are nested, the Break would only exit from the loop containing it.

Syntax

BREAK

Exam p le:

[Function : PrintNumbers]

Variable : Counter : Number

1 : SET : Counter : 1

2 : WHILE : ##Counter < = 10

3 : LOG : ## Counter

4 : IF : ## Counter > 5

5 : BREAK

6 : END IF

7 : SET : Counter : ##Counter + 1

8 : ENDWHI L E

9 : RETURN

In the Function ‘PrintNumbers’, the loop is running from 1 to 10. But because of BREAK statement, the loop will be terminated as the counter reaches 6.

CONTINUE

In some scenarios, instead of terminating the loop, the loop needs to be continued with next iteration, after skipping any statements in between. For this purpose, CONTINUE statement can be used. CONTINUE statement can be used inside WHILE – END WHILE and WALK COLLECION – END WALK.

Syntax

CONTINUE

Example:

Function to Count the total number of Journal Vouchers

[Collection : Vouchers Coll]

Type : Vou c her

[Function : CountJournal]

Returns : Number

Variable : Count : Number

01 : SET : Count :

02 : WALK C OLLECTION : Vouchers C oll

03 : IF : NOT $$IsJ o urnal:$VoucherTypeN ame

04 : CONTINUE

05 : ENDIF

06 : Count : ##C o unt + 1

07 : END W A LK

08 : RETURN : ##Count

START BLOCK – END BLOCK

START BLOCK –- END BLOCK has been introduced to save the current state and execute some actions within the block and return back to the original state. This is handy in cases where the Object context needs to be temporarily switched for the purpose of executing some actions. Current source and target object contexts are saved and the further statements within the START BLOCK and END BLOCK section get executed. Once the END BLOCK is encountered, the Object context is restored back to the original state.

Syntax

START BLOCK

Block Statements

END BLOCK

Example

10 : WALK C OLLECTION : EDCollDetailsExtract

11 : INSERT CO L LECTION OBJECT : InventoryEntries

12 : SET : QtyVar : $$String : $Qty + ” Nos”

13 : SET : Amt V ar : $$String:$Amt

14 : START BLO C K

15 : SET OBJECT

16 : SET VALUE : ActualQty : $$AsQty :##QtyVar

17 : SET VALUE : BilledQty : $$AsQty :##QtyVar

18 : SET VALUE : Amount : $$AsAmount:# #AmtVar

18A : END BLOCK

19 : SET TARGET : …

20 : SET VALUE : StockItemName : $ I tem

21 : END W A LK

;; For Explanation on Object context, i.e., Source Object and Target Object,

;; Set Target, Set Object, etc., please refer to the Topic ‘Function Execution – Object Context’

In this code snippet, the collection ‘EDCollDetailsExtract’ is being walked over and the values for the Objects within Voucher Entry are being set.

RETURN

This statement is used to return the flow of control to the calling program, with or without returning a value. When RETURN is used, the execution of the function is terminated and the calling program continues from where it had called the function.

Syntax

RETURN : <value expression>

Where,

< value expression > is optional, i.e., it can either return a value or return void.

Example

The Function ‘FactorialOf’ returns factorial of number

[Function : FactorialOf]

Parameter : InputNumber : Nu m ber Returns : Numb e r

Variable : Counter : Number

Variable : Factorial : Numb e r

1 : SET : Counter : 1

2 : SET : Facto r ial : 1

3 : WHILE : ##Counter <= ##I n putNumber

4 : SET : Factorial : ##Factorial * ##C o unter

5 : SET : Counter : ##Counter + 1

6 : ENDWHI L E

7 : RETURN : ##Factorial

Actions used in a TDL Function

Actions for Variable Manipulation

TDL provides various new actions that can be used inside User Defined Functions.

SET

This action is used to assign a value for a variable.

Syntax

SET : <VariableName> : <Value Expression>

Where,

< Variable Name > is the variable for which the value needs to be assigned.

< Value Expression > is the formula evaluating to a value.

Example

[Function : FactorialOf]

Parameter : InputNumber : Number Returns : Number

Variable : Counter : Number

Variable : Factorial : Number

1 : SET : Counter : 1

2 : SET : Factori a l : 1

3 : WHILE : ##Counter <= ##In p utNumber

4 : SET : Factorial : ##Factorial * ## C ounter

5 : SET : Counter : ##Counter + 1

6 : ENDWHI L E

7 : RETURN : ##Factorial

EXCHANGE

This action is used to exchange (swap) the values of two variables. But, values of only the variables of the same Data type can be exchanged.

Syntax

EXCHANGE : <First Variable Name> : <Second Variable Name>

Where,

< First Variable Name > and < Second Variable Name > are the Variables whose values need to be swapped.

Example:

01 : EXCHAN G E : Var1 : Var2

In this statement, both variables are of type ‘Number’ and their values are swapped.

INCREMENT

This action is used to increment the value of variables by any numerical value. INCREMENT is used inside the loop to increment value of control variables.

You can specify multiple variables by separating them with a comma.

Syntax

INCREMENT : <Variable Name> [,<Variable Name>, …] [:<Number Expression>]

Where,

< Variable Name > is the name of the variable whose value needs to be incremented.

< Number Expression > is the numerical value by which the variable needs to be incremented. If no number is given, the variable will be incremented by 1.

Example

[Function: VATVchrColWalk_Inv_GUJ_AnnxError_LoadVAR]

If : ##GUJeVATAnex201BError

Increment : vVATAnxTotalCount, vVATAnxErrorCount, vVATAnx201BTotalCount, vVATAnx201BErrorCount

Else

Increment : vVATAnxTotalCount, vVATAnx201BTotalCount

End If

Note: The keyword Last will only work from release 5.4.8.

DECREMENT

This action is used to decrement the value of variables by any numerical value. DECREMENT is used inside the loop to decrement the value of the control variables.

Syntax

DECREMENT : <Variable Name> [,<Variable Name>, …] [:<Number Expression>]

Where,

< Variable Name > is the name of the variable whose value needs to be decremented by the number specified.

< Number Expression > is the numerical value by which the variable needs to be decremented. If no number is given, the variable will be decremented by 1.

Example

[Function : PrintNumbers]

Variable : Cou n ter : Number

1 : SET : Co u nter : 10

2 : WHILE : ##Counter >

3 : LOG : ##Counter

4 : DECREMENT : Counter

5 : ENDWHI L E

6 : RETURN

In the function ‘PrintNumbers’, the loop is running from 10 to 1.

Action Enhancements and New Actions

The global actions have been enhanced, so that they can be called from the User Defined Functions. Some new actions have also been introduced.

Global Action s- Alter/Execute/Create

These are global actions meant for the purpose of opening a report in the mode specified. The return value of these actions is FALSE, if the user rejects the report, and TRUE, if the user accepts it.

Syntax

Display/Alter/Execute/Create : Report Name

Example

[Function : CreateReport]

01 : Create : Ledger

The Function ‘CreateReport’ opens the Ledger Creation screen.

Global Actions – MENU, DISPLAY

These global actions are used to invoke a menu or a report in Display mode. The return value of these actions is TRUE if Ctrl+Q is used to reject the report (i.e., via Form Reject To Menu action). It returns FALSE when user uses ‘Esc’ to reject the report (i.e., via ‘Form Accept’ action). For menu, this is only applicable if it is the first in the stack.

Syntax

Menu : <Menu name>

Display : <ReportName>

Example

[Function : DispPaySheet]

01 : Menu : Statements of Payroll

02 : Display : Pay Sheet

The Function ‘DispPaySheet’ opens the Pay Sheet and by pressing Escape, it will pop up the ‘Statements of Payroll’ Menu.

MSG BOX

This action is used to Display a message box to the user. It comes back to the original screen on the pressing of a key. This can be used by the programmers to display intermediate values of variables during calculations, thus helping in error diagnosis.

Syntax

MSG BOX : <Title Expression> : <Message Expression> : <GreyBack Flag>

Where,

< Title Expression > is the value that is displayed on the title bar of the message window.

< Message Expression > is the actual message which is displayed in the box. This can be an expression as well, i.e., the variable values can be concatenated and displayed along with the message in the display area of the box.

< GreyBack Flag > indicates if the background window is to be greyed out during message display. It takes two values, i.e., YES/NO

Example

01 : MSGBOX : ”Return Value” : ##Factorial

QUERY BOX

This action is used to Display a confirmation box to the user and ask for a Yes/No response.

Syntax

QUERY BOX : <Message Expression> : <GreyBack Flag> : <EscAsYes>

Where,

< Message Expression > is the message which is displayed inside the box. This can be an expression.

< GreyBack Flag > indicates if the background window is to be greyed out during message display. It takes two values, i.e., YES/NO

< Escape as Yes > is a flag which indicates the response when the user presses the ESC key. This can be specified as YES/NO. A YES value for this flag indicates that the response should be treated as YES on pressing of an ESC key.

LOG

During expression evaluation, intermediated values of the expression can be passed to calculator window and a log file ‘ tdlfunc.log’ insid e the application director y . This is very much helpful for debugging the expression. By default, logging is enabled inside the function .

Syntax

LOG : < Expression>

Where,

< Expression > is the expression whose value needs to be passed to the calculator window.

Example

While finding the factorial of a number , intermediated values are outputted to the ‘Calculator’ win d ow using LOG action

[Function : FactorialOf]

Parameter : InputNumber : Nu m ber

Returns : Number

Variable : Counter : Number Variable : Factorial : Numb e r

1 : SET : Counter : 1

2 : SET : Factor i al : 1

3 : WHILE : ##Counter <= ##I n putNumber

4 : SET : Factori a l : ##Factorial * # # Counter

5 : SET : Counter : ##Counter + 1

5a : LOG : # # Factorial

6 : ENDWHI L E

7 : RETURN : ##Factorial

SET LOG ON

While debugging a Function, sometimes it is required to conditionally Log the values of an expression. If logging is stopped, then logging can be re-started based on the condition Action SET LOG ON. This Action does not require any parameter.

Syntax

SET LOG ON

SET LOG OFF

This Action is used in conjunction with SET LOG ON. Log can be stopped by the Action SET LOG OFF. This Action does not require any parameter.

Syntax

SET LOG OFF

SET FILE LOG ON

This Action is similar to SET LOG ON. SET FILE LOG ON is used to conditionally Log the values of an expression to log file ‘tdlfunc.log’. This Action does not require any parameter.

Syntax

SET FILE LOG ON

SET FILE LOG OFF

This Action is used in conjunction with SET FILE LOG ON . Logging the file ‘tdlfunc.log’ can be stopped by the Action SET LOG OFF. This Action does not require any parameter.

Syntax

SET FILE LOG OFF

Progress Bar Actions

Sometimes, a Function may take some time to complete the task. It is always better to indicate the user whether the task is occurring, how long the task might take and how much work has already been done. One way of indicating the amount of progress is to use an animated image. This can be achieved by using the following Actions:

  • START PROGRESS
  • SHOW PROGRESS
  • END PROGRESS
Action – START PROGRESS

This action sets up the Progress Bar by mentioning the total number of steps involved in the task. In addition to this, the Title, SubTitle and Subject of the Progress Bar can also be given as parameters.

Syntax

START PROGRESS : <Number of steps> :< Title> [:< Sub Title> :< Subject>]

Where,

< Number of steps > denotes the whole task quantified as a number.

< Title >, < Sub Title > and < Subject > Shows the Title, Sub Title and Subject of the Progress Bar, respectively.

Example

START PROGRESS : ##TotalSteps : ”TDS Migration”:@@CmpMailName : ”MigrationgVouchers..”

Action – SHOW PROGRESS

This action shows the current status o f the task to the user .

Syntax

SHOW PROGRESS : <Number of Steps Completed>

Where,

< Number of Steps Completed > is a number which denotes the amount of work completed.

Example:

SHOW PROGRESS : ##Counter

Action – E ND PROGR E SS

When a task is completed, the Progress Bar can be stopped by using the Action END PROGRESS. This Action does not take any parameter.

Syntax

END PROGRESS

Actions – For Object and Context Manipulation

As already seen in previous sections, functions can operate on 3 object contexts, i.e., Requestor, Current Object and Target object context. When a function is invoked, the target object context will be the same as the current object context of the caller, i.e., the target object will be set to the current object.

Here, we will discuss the various actions for manipulation of Object and Context.

Action – NEW OBJECT

This action creates a new object from object specification and sets it as the target object. It takes only Primary Object as the Parameter.

Syntax

NEW OBJECT : <ObjType>:<ObjIdValue>

Where,

< ObjType > is the type of the object to be created, and

< ObjIdValue > is the unique identifier of the object. If this is an existing object in DB, then the further manipulations are performed on that object, else it creates a new object altogether.

Example

01 : NEW OBJECT : Stock Item : ”My Stock Item”

This creates a new object in memory for Stock Item and sets it as the target object. Later, by using other methods of this, the target object can be set and saved to the Tally DB.

Action – INSERT COLLECTION OBJECT

This action inserts the new object of the type specified in the collection and makes it as the current target object. This object is inserted into the collection at the end. This Action takes only Secondary Collection as the parameter.

Syntax

INSERT COLLECTION OBJECT : <CollectionName>

Where,

< CollectionName > is the name of the Secondary Collection.

Example

01 : INSERT COLLECTION OBJECT : Ledger Entries

This insets a new object ‘Ledger Entries’ in memory under Voucher, and sets it as the target object. Later, by using other methods of this, the target object can be set and saved to Tally DB.

Action – SET VALUE

This action sets the value of a method for the target object. The value formula is evaluated with respect to the current object context. This can use the new method formula syntax. Using this, it is possible to access any value from the current object.

Syntax

SET VALUE : <Method Name>[: <Value Formula>]

Where,

< Method Name > is the name of the method, and

< Value Formula > is the value which needs to be set to the method. It is optional. If the second parameter is not specified, it searches for the same method in the context object and the value is set based on it. If the source method name is same as in Target Object, then the Source Object method name is optional.

Example: 1

01 : SET VA L UE : Ledger Name : $LedgerName

OR

01 : SET VA L UE : Ledger Name

These statements set the values of ‘Ledger Entries’ Object from the current Object context.

Example: 2

02 : WALK COL L ECTION : Vouchers of My Objects

03 : NEW OBJECT : Voucher

;; Since the methods Date, VoucherTypeName are same in the source object and target object, they are not specified again as SET VALUE : DATE : $Date.

04 : SET VALUE : D ate

05 : SET VALUE : VoucherTypeName

Example: 3

[Function : Sample Function]

Object : Ledger : “Party 1”

01 : NEW O B JECT : Ledger : “Party 2”

;; absence of Value expression will assume that same method to be copied from source

02 : SET V A LUE : Parent

03 : ACCEPT ALTER

‘Party 1’ is a ledger under the Group ‘North Debtors’ and Party 2 is a Ledger under the Group ‘South Debtors’. After the execution of this function, Party 2 will also come under the Group ‘South Debtors’.

Action – RESET VALUE

This action sets the value of the method using the Value Formula. If Value Formula is not specified, it sets the existing value to null.

Syntax

RESET VALUE : MethodName [: Va l ue Formula]

Where,

< Method Name > is the name of the method, and

< Value Formula > is an optional parameter and if it is used, it will reset the value of the method.

Example

01 : SET VALUE : Ledger Name : $LedgerName

02 : RESET VALUE : Ledger Name : “New Value”

In this code snippet, RESET VALUE resets the value of the method ‘Ledger Name’

Action – CREATE TARGET/ACCEPT CREATE

It accepts the Target Object to the Company Data base, i.e., it saves the target object to the database. This creates a new object in the database if it does not exist, else results in an error.

Syntax

CREATE TARGET / ACCEPT CREATE

Action – SAVE TARGET/ ACCEPT

It accepts the Target Object to the Company Tally DB. If another object exists in the Tally DB with the same identifier, then the object is altered, else a new object is created.

Syntax

SAVE TARGET / ACCEPT

Action – ALTER TARGET/ACCEPT ALTER

It allows altering an exiting object in the Tally Data Base. If the object does not exist, it results in an error.

Syntax

ALTER TARGET / ACCEPT ALTER

Action – SET OBJECT

It sets the current object with the Object Specification. If no object specification is given, the target object will be set as the current object. Only Secondary Object can be used along with this Action.

Syntax

SET OBJECT [:<Object Spec>]

Where,

< Object Spec > is the name of the Secondary Object.

Example:

[Function : Sample Function]

Object : Ledger : “My Test Ledger”

01 : LOG : $Name

02 : SET O B JECT : BillAllocat i ons[1]

03 : LOG : $Name

04 : SET O B JECT : ..

05 : LOG : $Name

Initially, the context object is Ledger, so $Name gives the name of the Ledger. By Using ‘ SET OBJECT ’, the current Object is changed to first Bill allocation. So, the second $Name is giving the Bill name. The Fourth line changes the current Object back to ‘Ledger’ using dotted notation.

Action – SET TARGET

This action sets the target object with the Object Specification . If no object specification is given , then the current object will be set a s the target object .

Syntax

SET TARGET : <Object Spec>

Where,

<Object Spec> is the name of the Object.

Example:

01 : SET TARGET : Group

This sets the ‘Group’ Object as the Target Object. Later, by using other methods of this, the target object can be set and saved to the Tally DB.

Usage of Object manipulation Actions

Duplicating all payment Vouchers

[Function : DuplicatePaymentV o uchers]

;;Process for each Payment Voucher

01 : WALK C OLLECTION : My Vou c hers

;; Create new Voucher Object as Target Object

02 : NEW O B JECT : Voucher

;;For New Object, set methods from the First Object of the Walk Collection, i.e., from the Current Object

03 : SET V A LUE : Date : $Date

04 : SET VALUE : VoucherTypeName : $ VoucherTypeName

05 : S ET VALUE : Narration : $Narrat i on + ” Duplicated”

;; Walk over Ledger Entries of the current Object

05a : WALK COLLE C TION : LedgerEntries

;;Insert Collection Object to the Target Object and make it the present Target Object

06 : INSERT COLL E CTION OBJECT : Ledg e r Entries

;;Set the Values of the Target Object’s Method from Current Objects Methods

07 : SET VALUE : Ledger Name : $Ledg e rName

08 : SET V A LUE : IsDeemedPosi t ive : $IsDeemedPosi t ive

09 : SET VALUE : Amount : $Amount

;;Set the Voucher Object as Target, (which is 1 level up in the hierarchy) as Voucher is already having

;;Object specification

10 : SET TARGET : ..

11 : END W A LK

;;Save the Duplicated Voucher to the DB.

12 : CREATE TARGET

13 : ENDWA L K

14 : RETU R N

Calling a Function

A Function can be invoked in two ways:

  • 1. By using a “CALL” action – This is mainly used when the function does not return a value. It only performs a certain functionality.
  • 2. By Using the prefix $$ with the function name within a value expression – This is used when a return value is expected from the function execution. This value is used in the value expression of the calling program.

Using the Action ‘CALL’

Action ‘CALL’ can be used to call a function. It can be invoked from a Key, Menu Item or a Button.

Syntax

CALL : <Function Name> [: <Parameter List>]

Where,

< Function Name > is the name of a user defined function.

< Parameter List > is the list of parameters accepted by the function.

Example

Calling the Function as a procedure with CALL action

[#Menu : G ateway of Tally]

Button : Call Function

[Button : Call Function]

Key : A l t + F9

Title : “ C all Function”

Call : D i spStaturoryRpts

Using the Symbol Prefix ‘$$’

A Function can be called and executed by prefixing it with the symbol ‘$$’. This can be used inside a value expression or as a value for the ‘Set As’ attribute of the field. The value returned from the function is used.

Syntax

$$FunctionName : <Parameter List>

Where,

<Function Name> is the name of a us e r defined function.

<Parameter List> is the list of parameters accept e d by the function.

Note :

♦ During Tally Startup, Tally executes a function with the name “TallyMAIN”.

♦ Internal functions always override if both exist in the same name.

Example

Calling t he User Defined Function at Field using $$

[Field : Call Function]

Use : Number Field

Set as : $$FactorialOf:#InputFld

Call an action at line level

To call an action at a line level, associate a key with the line which calls the appropriate action.

Example: 1

You can select or deselect a line using the action Toggle Selection.

[Line: TSPL Ledger Line]

Key : Toggle Selection

[Key: Toggle Selection]

Key : Space

Action : Toggle Selection

In the above example, when space bar is pressed on the line TSPLLedgerLine , it calls the action Toggle selection .

Example: 2

To call a function on selecting a line. Along with selecting a line, call a function.

[Line: TSPL Ledger Line]

Key : TSPLSelectFunc

[Key: TSPLSelectFunc]

Key : Space

Actionlist : TSPL Toggle Selection, TSPLFunc

[Key: TSPL Toggle Selection]

Key : Space

Action : Toggle Selection

[Key: TSPLFunc]

Key : Space

Action : Call : TSPLFunc

[Function: TSPLFunc]

000: Set : SVSelectedLines: $$NumItems:NumSelectedLines

005: Log: ##SVSelectedLines

[System: Variables]

Variable: SVSelectedLines: Number

[Collection: NumSelectedLines]

Datasource: Report : Selected

;; In Release 6.0 and later, use the action ActionEx instead of ActionList

[Key: TSPLSelectFunc]

Key : Space

Action Ex: Toggle: Toggle Selection

Action Ex: Func: Call: TSPLFunc

In the above example, when space bar is pressed on the line, it executes the action Toggle Selection and then the function TSPLFunc to set the variables to the number of selected lines.

Example: Convert Numbers to Roman Numerals

You can convert the Arabic numerals (1, 2, 3, and so on) to Roman numerals by writing a user defined function as shown below. For example, if the input is 1, then the user defined function returns I, which is a Roman numeral. The following code snippet is to convert any number between 1 and 50 to the corresponding Roman numeral.

[Function: ConvertNumber]

;; This code snippet converts only the numbers between 1 and 50 to the corresponding Roman numeral. You need to add appropriate validations to exclude values below 1 and above 50.

Parameter : InputValue : Number

Variable : VarReturnVal : String: “”

01 : While :##InputValue = 50

05 : Set:VarReturnVal:##VarReturnVal+”L”

10 : Set:InputValue:##InputValue-50

15 : End While

20 : While :##InputValue >= 40

25 : Set :VarReturnVal:##VarReturnVal+”XL”

30 : Set:InputValue:##InputValue-40

35 : End While

40 : While:##InputValue >= 10

45 : Set:VarReturnVal: ##VarReturnVal+”X”

50 : Set:InputValue:##InputValue-10

55 : End While

60 : While:##InputValue >= 9

65 : Set:VarReturnVal:##VarReturnVal +”IX”

70 : Set:InputValue:##InputValue-9

75 : End While

80 : While:##InputValue >= 5

85 : Set:VarReturnVal:##VarReturnVal+”V”

90 : Set:InputValue:##InputValue-5

95 : End While

100: While:##InputValue >= 4

105: Set:VarReturnVal:##VarReturnVal+”IV”

110: Set:InputValue:##InputValue-4

115: End While

120: While:##InputValue >= 1

125: Set:VarReturnVal:##VarReturnVal+”I”

130: Set:InputValue:##InputValue-1;

135: End While

140: Return: ##VarReturnValFunction

Execution – Object Context

We all are aware that in TDL, any function, method or formula gets evaluated in the current object context. All the platform defined functions will be executed with the current object and requestor context.

With the introduction of User Defined Functions, another type of context is introduced. This is known as the target context.

Target Object Context

Target Context mainly refers to the object context which can be set inside the function, which allows the function to perform manipulation operations for that object, i.e., alteration and creation. The object context of the caller and target object context can be different. It will now be possible to obtain the values from the caller object context and alter the values of the target object with those values.

The User has the option to override the context within the function later or use the same context being passed. He can change the current and target object at any point and also switch target and current object to each other.

$$TgtObject is used to evaluate the value of an expression in the context of the target object.

Parameter Evaluation Context

It is important to note that the parameter values which are passed to the functions are always evaluated in the context of the caller. Parameter specification within the functions is just to determine the data type, order and number of parameters. These are basically the place-holders for values passed from caller object context. The target object context or context switch within the function does not affect the initial values of the parameters. Later, within the function, these values can be altered just like ordinary variables.

Return Value Evaluation

We have already discussed above that function can return a value. This can be specified by the function by indicating the data type of the value it returns, no specification assumed as a void function (a function which does not return a value). Each statement (Actions discussed in the next section) used can return a value. This depends on the individual action. Some actions may not return a value. The data type of the return value is also predefined by the action. Return value of the last action executed can be extracted using an internal function ‘$$LastResult’. Any error messages generated from the system can be obtained with $$LastError. This can only be used to determine the result of the intermediate statements used within the function. The final value which is to be returned from the function has to be explicitly given using the RETURN construct discussed in the previous section.

 

Enhancements in Tally.ERP 9 Releases

Release 1.52

Looping Constructs ‘For Collection’ and ‘For Token’ introduced

Two new looping constructs – For Collection and For Token have been introduced in user-defined functions.

Looping Construct – FOR COLLECTION

When WALK COLLECTION is used inside a function, the object of collection is set as the current object in the context of iteration, i.e., the loop is executed for each object in the collection, making it as the current context.

The newly introduced FOR COLLECTION provides a context-free walk, as the current object is not set as the current object context while looping. It loops on the collection for the specific value and returns the value in the iterator variable. The value of the iterator variable can be referred to by the actions inside the For Collection loop.

Syntax

FOR COLLECTION : <IteratorVar> : <CollExprn> [:<Value Exprn : <Rev Flag>]

Where,

<Iterator Var> is the name of the variable which is used for the iteration. This variable is created implicitly.

<Coll Exprn> can be any expression which evaluates to a collection name.

<Value Exprn> can be any expression, whose value is returned in the iterator variable. If the value expression is not specified, the name of the object is returned.

<Rev Flag> can be any expression which evaluates to a logical value. If it is True, then the collection objects are traversed in reverse order. This parameter is optional. The Default value is False.

Example

[Function : Test Function]

       |

       |

30 : FOR COLLECTION : i : Group : $ClosingBalance > 1000

40 : LOG : ##i

50 : END FOR

The value Yes is logged in the file ‘TDLFunc.log’ if the closing balance is greater than 1000, else No .

Looping Construct – FOR TOKEN

The looping construct FOR TOKEN is used to walk a String expression separated by a delimiter character. It loops on a String expression and returns one value at a time. The value is returned in the iterator variable.

Syntax

FOR TOKEN : <IteratorVar> : <SrcStringExprn> [:<DelimiterChar>]

Where,

<IteratorVarName> is the name of the variable used for iteration. The variable is created implicitly.

<Src String Exprn> can be any string expression separated by a <delimiter Char>.

<Delimiter Char> can be any expression which evaluates to a character used for separating the string expression. It is optional. The default separator char is ‘:’.

Example

[Function : Test Function]

       |

       |

01 : FOR TOKEN : TokenVar : “Tally : Shopper : Tally Developer” : “:”

02 : LOG : ##TokenVar

03 : END FOR

This code snippet will give the output as shown below:

Tally

Shopper

Tally Developer

 

Release 1.6

The user-defined function can use a newly introduce looping construct which iterates for the given range of values, and the action New Object has been enhanced to accept a logical value.

New Looping Construct – FOR RANGE

As explained earlier, TDL allows different looping constructs for varied usage. The existing loop constructs allow us to loop on the objects in the collection or on the tokenized string or condition-based looping of a set of the statement.

There are scenarios where the looping is to be performed for a range of values. For this, a new loop FOR RANGE has been introduced. The newly introduced loop construct allows to loop on a range of numbers or date. This loop can be used to repeat a loop for the given range of specified values. The range can either be incremental or decremental. The FOR RANGE loop can be used to get the Period Collection-like functionality.

Syntax

FOR RANGE : <Iterator Var>: <Data type>: <StartRangeExpr>: <EndRangeExpr>[:<Increment Expr>[:<DateRangeKeyword>]]

Where,

<Iterator Var Name> is the name of the variable used for the iteration. This variable is created implicitly.

<Data Type> can be Number or Date only.

<StartRangeExpr> is an expression which evaluates to number or date values. It refers to the starting value of the range.

<EndRangeExpr> is an expression which evaluates to number or date values. It refers to the end value of the range.

<Increment Expr> is an expression which evaluates to a number by which the <StartRange- Expr>value is incremented. It is optional, and the default value is 1.

<DateRangeKeyword> is optional, and only applicable if the data type is Date. The values can be any one of ‘Day’, ‘Week’, ‘Month’ and ‘Year’.

Example

             |

01 : FOR RANGE : IteratorVar : Number : 2 : 10 : 2

02 : LIST ADD : EvenNo : ##IteratorVar

03 : END FOR

             |

The values 2,4,6,8,10 are added in the List variable ‘EvenNo’, as the range of value is 2 to 10, and the value is incremented by 2 with each iteration.

Example

The following code snippet is used to calculate the number of weeks elapsed between System date and Current Date set in Tally.

      |

09 : FOR RANGE : IteratorVar : Date : ##SVCurrentDate : $$MachineDate : 1 : “Week”

10 : LOG : ##IteratorVar

20 : INCREMENT : Cnt

30 : END FOR

50 : LOG : “No of weeks Back Dated : ” + $$String:##Cnt

60 : RETURN : ##Cnt

      |

Assume that the range for this is from 15 – Mar – 2009 to 30 – Mar – 2009. The values 15-Mar-2009, 22-Mar-2009 and 29-Mar-2009 are logged, as the increment is done by a ‘Week’. So, there are three iterations of the loop. The number of weeks is logged using the counter.

Example

                    |

09 : FOR RANGE : IteratorVar : Date : ##SVFromDate:##SVToDate : 1 : “Month”

10 : LOG : $$MonthEnd:##IteratorVar

20 : END FOR

                    |

Assume that the range for this is from 1-Jan-2009 to 5-Mar-2009. The values 31-Jan-2009, 28- Feb-2009 and 31 -Mar -2009 are logged.

New Function – $$LoopIndex

The TDL programming community is now aware of the enhancements that have been introduced in TDL language and are efficiently implementing the same in the programs.

A vast area of possible extensions is unlocked by the User Defined Functions in TDL. User Defined functions gave sequential control in the hands of the TDL programmers. Many actions and looping constructs have been introduced in User Defined Functions in TDL. During the sequential execution, the loops are used to iterate through a set of values. TDL allows nested loops as well.

There are scenarios where the loop counter is required for some evaluation. Presently, a variable is defined and then at the end of the loop, its value is incremented. This variable can be used for some calculations if required. To avoid this inline declaration of variable which is solely used as a counter, a new function $$Loop Index has been introduced.

The function $$LoopIndex gives the count of how many times the current loop is executed. In case of nested loops, the additional parameter <outer loop index number>can be used in the inner loop to get the current iteration count of the outer loop.

Syntax

$$LoopIndex [:<Outer Loop Index Expr>]

Where,

<Outer Loop Index Expr> can be any expression which evaluates to a number. It is optional, and the outer loop index number in the nested loop hierarchy from the innermost loop to the outermost loop. For the current loop, the value is 0 by default, for the parent loop 1, and so on.

Consider following example:

[Function : LoopIndex Test]

    |

    |

05 : WALK COLLECTION : ………

   |

WHILE : …….

   |

   |

FOR : ……….

SET : Var: $$LoopIndex

LOG : ##Var

   |

END FOR

SET : Var1: $$LoopIndex:1

   |

END WHILE

   |

   |

END WALK

The variable Var will hold the count of number of times the FOR loop is executed, while the variable Var1 will have the count of ‘WALK Collection’ loop execution.

Enhanced Action – NEW OBJECT

The action ‘ New Object ’ takes two parameters Object Type and Object Identifier. The syntax is:

Syntax

NEW OBJECT : <Object Type>: [:<Object Identifier>]

Where,

<Object Type> is the type of the object to be created,

<Object Identifier> is the unique identifier of the object. This parameter is optional. In case this is not specified, it creates a blank object of the specified type.

The actions Save Target/Alter Target/Create Target is used along with New Object for specific usage. There are three scenarios to consider for this:

  • In case a Blank Object is created using ‘New Object’ without specifying the Object Identifier, the actions ‘Save Target’ and ‘Create Target’ will work, while ‘Alter Target’ would fail.
  • In case an existing object is brought into context by specifying Object Identifier with ‘New Object’, the actions ‘Save Target’ and ‘Alter Target’ will work, while ‘Create Target’ would fail.

Note: Save Target’ saves the current Object, whether it is a blank new Object, or an existing Object for Alteration.

  • When an Object Identifier is specified with ‘New Object’ and the object does not exist in the database, the Action ‘Save Target’ fails, as ‘New Object’ does not create a blank object.

In order to overcome the scenario (3), the Action ‘New Object’ has been enhanced to accept an additional parameter ‘Force Create Flag’ along with the Object Identifier. This forces the creation of an empty blank object, in case the Object with Identifier does not exist in the database.

Syntax

NEW OBJECT : <Object Type>: [:<Object Identifier>[:<Forced Create Flag>]]

Where,

<Object Type> is the type of the object to be created,

<Object Identifier> is the unique identifier of the object.

<Forced Create Flag> is an Optional Flag and is required only if <Object Identifier>is specified. If the Flag is set to TRUE, then if the object identified by <Object Identifier>exists, the object is altered; otherwise, a new empty object of the specified type is created.

Example

         |

01: NEW OBJECT : Group : ##EGroupName : TRUE

02: SET VALUE : Name : ##NGroupName

03: SAVE TARGET

         |

If the ledger identified by ‘##EGroupName’ exists in Tally database, then the objects are altered by the action SAVE TARGET; else, a new object is created as the Forced flag is set to ‘YES’.

 

Release 2.0

TDL Procedural Enhancements

With every Release, the TDL Procedural Capabilities are getting strengthened at a commendable pace. The latest along this path is the File Input/Output Capability.

Watch the below video to know about the Procedural Capabilities.

TDL Procedural File Input/Output Capabilities

As we are aware, any High level programming language will support Reading and Writing From/ To multiple hardware devices. It will have predefined constructs in the form of functions to Read from and Write to a File as well. This file can reside on the hard disk or on a network, which can be accessed via various protocols HTTP or FTP.

This capability introduced in TDL will now pave the way for supporting import/export operations from the Tally DataBase in the most amazing way. It will now be possible to export almost every piece of information in any Data Format which we can think of. The Text and Excel Formats are supported, which allow data storage in SDF-Fixed Width, CSV-comma separated, etc., sufficing the generic data analysis requirements of any business.

The TDL artefacts used for supporting various Read/Write operations are Actions and Functions. These are made to work only inside the TDL Procedural Block. ‘Write’ operations are mostly handled using Actions, and all the file Access and Read operations are performed using Functions. These give tremendous control in the hands of the programmer for performing the data manipulations To/From the file. And that too, on a file present on a network accessible using the protocols FTP and HTTP. Since these artefacts operate on characters and not bytes, the file encoding ASCII/UNICODE does not have any effect on the operations.

File Contexts

The entire procedural Read/Write artefacts basically operate on two file contexts:

  • Source file Context

When a file is opened for Reading purpose, the context available for all the ‘read’ operations is the Source File Context. All the subsequent ‘read’ operations are performed on the Source File Context.

  • Target file Context

When a file is opened for Writing purpose, the context available for all the ‘write’ operations is the Target File Context. All the subsequent Write operations are performed on the Target File Context.

It is important to understand that these contexts are available only inside the procedural block (User Defined Function), where the files are opened for use. The file context concept is different from the concept of Object Context where the Object context is carried over to all its child Objects. File Contexts are only available to the functions, and the subsequent functions are called from within the parent Function. The called function can override the inherited context by opening a new file within its block.

The file context created by opening a file is available only until the execution of the last statement. Once the control is out of the function, the file is automatically closed. However, it is highly recommended as a good programming practice to close a file on exit.

Both the file contexts, i.e., Source and Target file contexts, are available simultaneously. This makes it possible to read from one file and write to another file simultaneously.

File Operations

A programming language supporting File Read/Write typically supports the following operations:

  • Open- This operation identifies the file which needs to be opened for Read/Write purpose.
  • Close- This operation closes the opened file after Read/Write.
  • Read – This is an operation to read the data from an opened File.
  • Write – This is an operation to write the data to an opened File.
  • Seek – This is an operation to access the character position in an already opened file.
  • Truncate – This is an operation which will delete a particular number of characters/entire contents of the file.

General File Operations

As discussed, the entire procedural Read/Write concepts basically operate on two file contexts, i.e., a source file context and a target file context. Source context is used to read the contents from a file which is opened for reading purpose, whereas the target context is used to write the data to a file which is opened for writing purpose. Since both these file contexts are available simultaneously, it is possible to read from one file and write to another file.

Action – OPEN FILE

It is used to open a text/excel file for read/write operations. The file can reside in Hard Disk, in the main memory or on FTP/HTTP site. Also, it is used to open a file for read/write operations.

If no parameters are used, then a memory buffer will be created, which will act as a file. This file will be in both read/wrItemode and will act as both the source and the target context. Based on the mode specified (read/write), the file automatically becomes the source file or the target file, respectively.

Syntax

OPEN FILE [:<File Name> [:<File Format> [:<Open Mode> [:<Encoding>]]]]

Where,

<File Name> can be any expression which evaluates to a regular disk file name like C:\Output.txt, or to an HTTP/FTP site like “ftp://ftp.tallysolutions.com/Output.txt”

<File Format> can be Text or Excel. By default, ‘Text’ mode will be considered, if not specified. Also, during the opening of an existing file, if the mode does not match, the Action will fail.

<Open Mode> can be Read / Write. By default, it is Read. If a file is opened for ‘Read’ purpose, then it must exist. If ‘Write’ mode is specified, and the file exists, it will be opened for updating. If the file does not exist, a new file is created. If the file is opened in ‘Write’ mode, it is possible to read from the file as well.

<Encoding> can be ASCII or Unicode. If not specified, ‘Unicode’ is considered as the default value for ‘Write’ Mode. In ‘Read’ mode, this parameter will be ignored and considered, based on the encoding of the file being read.

Example: 1

10 : OPEN FILE : “Output.txt” : Text : Write : ASCII

A Text File ‘Output.text’ is opened in ‘Write’ mode under the Tally application Folder, and if it already exists, the same will be opened for appending purpose.

Example: 2

10 : OPEN FILE : “http://www.tallysolutions.com/Output.txt” : Text

A Text File ‘Output.text’ is opened in ‘Write’ mode at the HTTP URL specified. If the file already exists, the same will be opened for appending purpose.

Example: 3

10 : OPEN FILE : “C:\Output.xls” : Excel : Read

An Excel File ‘Output.xls’ is opened in ‘Read’ mode under C drive, and if the file does not exist, the Action will fail.

Note: Please refer to the functions like $$MakeFTPName and $$MakeHTTPName for constructing the FTP and HTTP URLs using the various parameters like server name, username, password, etc. Refer to Tally.Developer 9 Function Browser for help on usage.

Actions – CLOSE FILE and CLOSE TARGET FILE

A file which is opened for Read/Write operation needs to be closed, once all the read/write operations are completed. However, if the files are not closed explicitly by the programmer, these are closed by default when the function is returned. But, it is always recommended to close the file after the operations are completed.

Files which are opened in the current function can only be closed by it. If a function inherits the file contexts from the caller function, then it cannot close these files; however, it can open its own instances of the files. In such cases, the caller context files will not be accessible.

Action – CLOSE FILE

This action is used to close an opened source file.

Syntax

CLOSE FILE

Example

10 : OPEN FILE : “Output.xls” : Excel : Read

            |

            |

30 : CLOSE FILE

In this example, the Excel file ‘Output.xls’, which is opened for reading purpose, is closed.

Action – CLOSE TARGET FILE

This action is used to close an opened target file.

Syntax

CLOSE TARGET FILE

Example

10 : OPEN FILE : “Output.txt” : Text : Write

|

|

|

30 : CLOSE TARGET FILE

In this example, the text file ‘Output.txt’, which is opened for writing purpose, is closed.

General Functions – $$TgtFile, $FileSize

Function – $$TgtFile

All the file accessing functions, for both text and excel files, operate on the source file context. The function $$TgtFile can be used to switch to the target file context temporarily. It evaluates the expression passed, in the context of the target file.

Syntax

$$TgtFile:Expression

Example

In this example, the objective is to Read the contents of a cell in Sheet 1 and copy it to a cell in the Sheet 2 of the same file. The function opens the File “ABC.xls” in ‘Write’ mode.

[Function : Sample Func]

Variable : Temp : String

10 : SET : Temp : “”

20 : OPEN FILE : “Output.xls” : Excel : Write

30 : ADD SHEET : “Sheet 1”

40 : WRITE CELL : 1 : 1 : “Item A”

50 : SET : Temp : $$TgtFile:$$FileReadCell:1:1

60 : ADD SHEET : “Sheet 2”

70 : WRITE CELL : 1 : 1 : ##Temp

80 : CLOSE TARGET FILE

In this example, there is no file present in the source file context, as the file is opened in the ‘Write’ mode. In such case, for reading a value from Sheet 1, the expression $$FileReadCell:1:1 will return no value. Prefixing the expression with $$Tgtfile will temporarily change the context to Target File for the evaluation of the expression, and will fetch the value from the cell 1 of Sheet 1, existing in the Target File context.

Function – $$FileSize

This function will return the size of the file, specified in bytes. It takes an optional parameter. If the parameter is not given, then it works on the current context file and returns the size.

Syntax

$$FileSize [:<FileName>]

Where,

<FileName> is an expression, which evaluates to the file name, along with the path.

Example

10 : Log : $$FileSize:“Output.xls”

It gives the size of the Excel file ‘output.xls’, in terms of bytes.

Read/Write Operation on Text Files

Writing to a File

Various Actions have been introduced in order to write to a text file. These Actions operate on the Target File context. The scope of these Actions is within the TDL procedural block (User Defined Functions), where the file is opened and the context is available.

Action – WRITE FILE

This action is used to append a file with the text specified. The ‘write’ operation always starts from the end of the file. This Action always works on the target file context.

Syntax

WRITE FILE : <TextToWrite>

Where,

<TextToWrite> can be any expression evaluating to the data that needs to be written to the file.

Example

10 : OPEN FILE : “Output.txt” : Text : Write

20 : WRITE FILE : “Krishna”

30 : CLOSE TARGET FILE

Here, a txt file ‘Output.txt’ is opened in ‘write’ mode and the content ‘Krishna’ is appended at the end of the file.

Action – WRITE FILE LINE

This action is similar to WRITE FILE, but it also places a new line character (New Line/Carriage Return) after the text. All the subsequent ‘writes’ begin from the next line. This action always works on the target context.

Syntax

WRITE FILE LINE : <TextToWrite>

Where,

<TextToWrite> can be any expression evaluating to the data that needs to be written to the file.

Example

10 : OPEN FILE : “Output.txt” : Text : Write

20 : WRITE FILE LINE : “Line 1”

30 : WRITE FILE LINE : “Line 2”

40 : CLOSE TARGET FILE

Here, a txt file ‘Output.txt’ is opened in ‘Write’ mode, and two more lines are appended at the end of the file.

Action – TRUNCATE FILE

This action removes the contents of the file by setting the file pointer to the beginning of the file and inserting an ‘end of file’ marker. It can be used to erase all characters from an existing file, before writing any new content to it.

Syntax

TRUNCATE FILE

Example

10 : OPEN FILE : “Output.txt” : Text : Write

20 : TRUNCATE FILE

30 : WRITE FILE : “New Value”

40 : CLOSE TARGET FILE

In this example, the entire contents of the existing txt file ‘Output.txt’ are removed and ‘New Value’ is inserted subsequently.

Action – SEEK FILE

This action operates on the Target File Context. It is used to move the file pointer to a location as specified by the number of characters. As we already know that it is possible to Read and Write from the Target File context, all the subsequent Reads and Writes will be starting from this position. By Default, if the file position is not specified, the ‘Read’ pointer will be always be from the beginning of file and the ‘Write’ pointer will be from the end of the file.

Note: It has already been covered how to Read from the Target File context by using the function $$ TgtFile .

Syntax

SEEK FILE : <File Position>

Where,

<File Position> can be any expression, which evaluates to a number which is considered as the number of characters.

Reading a File

Some functions and Actions have been introduced, which can operate on the Source File context to read from the file or access some information from them. The scope of these functions is within the TDL procedural block (User Defined Functions) where the file is opened, and the context is available. It is also possible to read from the Target File Context by using the function $$TgtFile.

Function – $$FileRead

This function is used to read data from a text file. It takes an optional parameter. If the parameter is not specified or has value as 0, it reads one line and ignores the ‘end of line’ character. However, file pointer is positioned after the ‘end of line’ character, so that the next read operation starts on the next line. If the no. of characters is mentioned, it reads that many no. of characters.

Syntax

$$FileRead [:<CharsToRead>]

Where,

<CharsToRead> can be any expression which evaluates to the number of characters to be read.

Example

10 : OPEN FILE : “Output.txt” : Text : Read

20 : LOG : $$FileRead

30 : CLOSE FILE

In this example, the first line of the text file ‘Output.txt’ is being read.

Function – $$FileIsEOF

This function is used to check if the current character being read is the End of file character.

Syntax

$$FileIsEOF

Action – SEEK SOURCE FILE

This action works on a source file context. It sets the current file pointer to the position specified. Zero indicates the beginning of the file and -1 indicates the end of the file. The file position is determined in terms of the characters. All the subsequent reads begin from this position onwards.

Syntax

SEEK SOURCE FILE : <File Position>

Where,

<File Position> can be any expression evaluating to a number, which is the no. of characters.

Example

10 : OPEN FILE : “Output.txt” : Text : Read

20 : SEEK SOURCE FILE : 2

30 : LOG : $$FileRead

40 : CLOSE FILE

In this example, the first line of the file ‘Output.txt’ is read, starting from the 3rd character.

Read/Write Operation on Excel Files

Setting the Active Sheet

For an Excel file, all the Read and Write operations will be performed on the Active Sheet .

Action – SET ACTIVE SHEET

This action is used to change the Active Sheet during Read and Write operations.

Syntax

SET ACTIVE SHEET : <Sheet Name>

Where,

<Sheet Name> is an expression evaluating to a string, which is considered as name of the sheet.

Example

10 : OPEN FILE : “Output.xls” : Excel : Read

20 : SET ACTIVE SHEET : “Sheet 2”

30 : Log : $$FileReadCell:1:1

40 : CLOSE FILE

In this example, an Excel sheet Output.xls is opened in Read mode, ‘Sheet 2’ is made active and the content is read from the first cell.

Writing to a File

Various actions have been introduced in order to write to an excel file. These Actions operate on the Target File context. The scope of these Actions is within the TDL procedural block (User Defined Functions), where the file is opened and the context is available.

Action – ADD SHEET

This action adds a sheet in the current workbook opened for writing. The sheet will always be inserted at the end. If a sheet with the same name already exists, it will be made as active.

Syntax

ADD SHEET : <Sheet Name>

Where,

<Sheet Name> is an expression evaluating to a string, which is considered as name of the sheet.

Example

10 : OPEN FILE : “Output.xls” : Excel : Write

20 : ADD SHEET : “New Sheet”

Here, an existing Excel sheet ‘Output.xls’ is opened in ‘Write’ mode and the new sheet ‘New Sheet’ is inserted at the end of the workbook.

Action – REMOVE SHEET

This action removes the specified sheet from the current workbook. The entire contents of the sheet will be removed. This action will fail if the workbook has only one sheet, or if the specified sheet name does not exist in the workbook.

Syntax

REMOVE SHEET : <Sheet Name>

Where,

<Sheet Name> is an expression evaluating to a string, which is considered as name of the sheet.

Example

10 : OPEN FILE : “Output.xls” : Excel : Write

20 : ADD SHEET : “New Sheet”

30 : REMOVE SHEET : “Sheet1”

In this example, a workbook is created with a sheet named ‘New Sheet’.

Action – RENAME SHEET

This action renames a worksheet.

Syntax

RENAME SHEET : <Old Sheet Name> : <New Sheet Name>

Where,

<Old Sheet Name> and <New Sheet Name> can be any expression, evaluating to a string, which will be considered as the name of the sheet.

Example

01 : OPEN FILE : “Output.xls” : Excel : Write

02 : RENAME SHEET : @@OldSheetName : @@NewSheetName

04 : CLOSE TARGET FILE

In this example, the existing sheet is renamed with a new sheet name.

Action – WRITE CELL

This action writes the specified content at the cell address specified by the row and column number of the currently active sheet.

Syntax

WRITE CELL : <Row No> : <Column No> : <Content To be Written>

Where,

<Row No> and <Column No> can be any expression which evaluates to a number, which can be used to identify the cell

<Content To be Written> can be any expression which evaluates to data, which needs to be filled in the identified cell.

Example

10 : OPEN FILE : “Output.xls” : Excel : Write : ASCII

15 : ADD SHEET : “New Sheet”

20 : WRITE CELL : 1 : 1 : “Krishana”

30 : CLOSE TARGET FILE

It opens an Excel File ‘Output.xls’, adds a new sheet, and in that sheet, the first cell will have the content as ‘Krishna’.

Action – WRITE ROW

This action writes multiple cell values at a specified row in the Active sheet. The no. of values separated by commas are written, starting from initial column no. specified, for the row specified.

Syntax

WRITE ROW : <Row No> : <Initial Column No> : <Comma Separated Values>

Where,

<Row No> and <Initial Column No> can be any expression which evaluates to a number, which can be used to identify the cell.

Comma Separated Values can be expressions separated with comma, which evaluate to data that needs to be filled, starting from the cell mentioned by ‘Row Number’ and ‘Initial Column Number’.

Example

10 : OPEN FILE : “Output.xls” : Excel : Write

20 : ADD SHEET : “New Sheet”

30 : WRITE ROW : 1 : 1 : @@Val1, @@Val2

40 : CLOSE TARGET FILE

Here, cells (1,A) and (1,B) are filled with the values from expressions ‘Val1’ and ‘Val2’.

Action – WRITE COLUMN

This action writes multiple cell values at a specified column in the Active sheet. The no. of values separated by commas are written starting from the initial row no., specified for the column.

Syntax

WRITE COLUMN : <Initial Row No> : <Column No> : <Comma Separated Values>

Where,

<Initial Row No> and <Column No> can be any expression, evaluating to a number, which can be used to identify the cell.

Comma Separated Values can be expressions separated with comma, which evaluate to data that needs to be filled, starting from the cell mentioned by ‘Initial Row Number’ and ‘Column Number’.

Example

10 : OPEN FILE : “Output.xls” : Excel : Write

20 : ADD SHEET : “New Sheet”

30 : WRITE Column : 5 : 5 : @@Val3, @@Val4

40 : CLOSE TARGET FILE

In this example, cells (5, E) and (6,E) are filled with the values from expressions ‘Val3’ and ‘Val4’.

Reading a File

Some functions and actions have been introduced which can operate on the Source File context to read from the file or access some information from them. The scope of these functions is within the TDL procedural block (User Defined Functions), where the file is opened and the context is available. It is also possible to read from the Target File Context by using the function $$TgtFile.

Function – $$FileReadCell

This function returns the content of the cell identified by the mentioned row number and column number of the active sheet.

Syntax

$$FileReadCell : <Row No> : <Column No>

Where,

<Row No> and <Column No> can be any expression which evaluates to a number used to identify the row number and the column number.

Example

10 : OPEN FILE : “Output.xls” : Excel : Read

20 : SET ACTIVE SHEET : “Sheet 1”

20 : Log : $$FileReadCell:1:1

The function $$FileReadCell Logs the contents of the first cell of the excel sheet ‘Sheet 1′.

Function – $$FileGetSheetCount

This function returns the number of sheets in the current workbook.

Syntax

$$FileGetSheetCount

Example

10 : OPEN FILE : “Output.xls” : Excel : Read

20 : Log : $$FileGetSheetCount

The function $$ FileGetSheetCount returns the total number of sheets in the Excel sheet ‘Output.xls’.

Function – $$FileGetActiveSheetName

This function returns the name of the active sheet.

Syntax

$$FileGetActiveSheetName

Example:

10 : OPEN FILE : “Output.xls” : Excel : Read

20 : Log : $$FileGetActiveSheetName

The name of the active sheet is returned after opening the Excel file ‘Output.xls’.

Function – $$FileGetSheetName

This function returns the name of the sheet at a specified index.

Syntax

$$FileGetSheetName : <Sheet Index>

Where,

<Sheet Index> can be any expression which evaluates to a number as the Sheet Index.

Example

10 : OPEN FILE : “Output.xls” : Excel : Read

Log : $$FileGetSheetName:1

The function $$FileGetSheetName gives the name of the sheet at a particular index

Function – $$FileGetSheetIdx

This function returns the Index of the sheet for a specified sheet name.

Syntax

$$FileGetSheetldx : <Sheet Name>

Where,

<Sheet Name> can be any expression which evaluates to the name of the Excel Sheet.

Example

10 : OPEN FILE : “Output.xls” : Excel : Read

20 : Log : $$FileGetSheetIdx:“Ledgers”

The function $$FileGetSheetIdx gives the index number of the sheet name.

Function – $$FileGetColumnName

This function gives the column name in terms of alphabets for the given index.

Syntax

$$FileGetColumnName:Index

Where,

<Index> can be any expression which evaluates to the Index number.

Example

10 : OPEN FILE : “Output.xls” : Excel : Read

20 : Log : $$FileGetColumnName:10

The function $$FileGetColumnName returns the value J .

Function – $$FileGetColumnldx

This function returns the index of the column for a given alphabetical name.

Syntax

$$FileGetColumnldx : <Name>

Where,

<Name> can be any expression which evaluates to the name of the column in alphabets.

Example

10 : OPEN FILE : “Output.xls” : Excel : Read

20 : Log : $$FileGetColumnIdx:AA

The function $$FileGetColumnIdx returns the value as 27.

Use Case – Import from Excel

Scenario

ABC Company Limited, which is into the trading business, is using Tally.ERP 9. It deals with the purchase and sale of computers, printers, etc. The company management wants to import the stock items from the Excel sheet, or a text file into Tally.ERP 9.

Functional Demo

A configuration report is added in Tally.ERP 9 to accept the file location, worksheet name, column details, etc. An option to display the error report can also be specified.

By default, Excel format is selected. But, the user can also select the Import source format as Text and specify the file details. The text separator character should be specified as well, in addition to the column details.

Once the details are entered, a confirmation message is displayed to start the import process.

If the user has selected the option to display the error report after successful import, the report is shown with imported stock items and status as “Imported successfully”, as seen in the figure:

If the user has selected the option to display the Log file, then after the import, the log file is displayed as follows:

The imported items are now available in the Stock Item list as follows:

In case the import is unsuccessful, the error report, with the reason for failure, is displayed as follows:

Solution Development

The import from the excel file is simplified, as the user can specify the import details. The file I/O capabilities are used to develop the solution. The steps followed to achieve the requirement are:

  1. A report is designed to display the configuration report. The value entered by the user is stored in a system variable.

 

Local : Field : Name Field : Modifies : SIC Source : Yes

Local : Field : Name Field : Variable : SIC Source

|

|

Local : Field : Name Field : Modifies : SIC DirPath : Yes

Local : Field : Name Field : Variable : SIC DirPath

[System : Variable]

SIC Source : “Excel”

SIC DirPath : “C:\Tally.ERP9”

  1. On form accept, the function to import the stock item is called.

On : Form Accept : Yes : Form Accept

On : Form Accept : Yes : Call : Smp Import Stock Items

  1. A function “Smp Import Stock Items” is defined.
  2. In this function, first of all, the format of the source file is checked, and then, the action ‘Open File’ is used to open the file in ‘Read’ mode accordingly.

20 : IF : ##SICSource = “Excel”

30 : OPEN FILE : @@TSPLSMPTotFilePath : Excel : READ

40 : ELSE 

50 : OPEN FILE : @@TSPLSMPTotFilePath : Text : READ

60 : ENDIF

  1. The data from the Excel cells are read and added as items in the list variable.

120 : WHILE : NOT $$IsEmpty:($$FileReadCell:##Row:##ItemColumns.ItemName)

130 : LISTADDEX : ItemDetails

140 : SET : ItemDetails[$$LoopIndex].ItemName : $$FileReadCell:##Row:##ItemColumns.ItemName

150 : SET : ItemDetails[$$LoopIndex].ItemGrp: $$FileReadCell:##Row:##ItemColumns.ItemGrp

160 : SET : ItemDetails[$$LoopIndex].ItemUOM: $$FileReadCell:##Row:##ItemColumns.ItemUOM

170 : INCREMENT: Row

180 : END WHILE

  1. If source format is ‘Text’, the text file is read line by line and added as items to the list variable.

210 : WHILE : NOT $$FileIsEOF

220 : SET : TempVar : $$FileRead

230 : IF : NOT $$IsEmpty:##TempVar AND (NOT ##SICIncHeader OR (##SICIncHeader AND $$LoopIndex>1))

240 : LIST ADD EX : ItemDetails

250 : SET : ItemDetails[##Counter].ItemName : $$SICExtractDet:##TempVar:##ItemColumns.ItemName

260 : SET : ItemDetails[##Counter].ItemGrp : $$SICExtractDet:##TempVar:##ItemColumns.ItemGrp

270 : SET : ItemDetails[##Counter].ItemUOM : $$SICExtractDet:##TempVar:##ItemColumns.ItemUOM

280 : INCREMENT : Counter

290 : ENDIF

300 : END WHILE

  1. A collection is populated using the List variable as data source.

[Collection : TSPLSMPImpStockItem]

Data Source : Variable : ItemDetails

[Collection : TSPLSMPImpStockItem Summ]

Source Collection : TSPL SMP Imp Stock Item

By : SICStockItem : $ItemName

By : SICStockGroup : $ItemGrp

By : SICStockUOM : $ItemUOM

Filter : TSPLSMPNonEmptyItem

  1. Now, the Stock Item objects are created. If the item can’t be imported, then the item details are written in the error file or compound variable, based on the format selected for displaying, i.e., ‘Report’ or ‘Log’.

380 : WALK COLLECTION : TSPL SMP Imp StockItem Summ

390 : SET : Last Status : “”

400 : IF : $$IsEmpty:$Name:StockItem:$SICStockItem

410 : NEW OBJECT: Stock Item

420 : SET VALUE : Name : $SICStockItem

430 : IF : NOT $$IsEmpty:$Name:StockGroup:$SICStockGroup

440 : SET VALUE : Parent : $SICStockGroup

450 : ELSE

460 : SET : LastStatus : “Group” + $SICStockGroup + “does not exist”

470 : ENDIF

480 : IF : NOT $$IsEmpty:$Symbol:Unit:$SICStockUOM

490 : SET VALUE : Base Units : $SICStockUOM

500 : ELSE

510 : SET : LastStatus : “Unit” + $SICStockUOM + “does not exist”

520 : ENDIF

530 : IF : $$IsEmpty:##LastStatus

540 : SAVE TARGET

550 : SET : Last Status : “Imported Successfully”

560 : ENDIF

570 : ENDIF

;; Writing Import Status to the LOG File, if LOG File is to be displayed at the end

580 : IF : ##SICOpenLogFile

590 : WRITE FILE LINE : $SICStockItem + ##SICTextSep + ##LastStatus

600 : ENDIF

;; Updating List of Compound Variables is the Status is to be displayed in a Report

610 : IF : ##SICDisplayReport

620 : LIST ADD EX : ItemImportStatus

630 : SET : ItemImportStatus[##Counter].ItemName : $SICStockItem

640 : SET : ItemImportStatus[##Counter].Status : ##LastStatus

650 : INCREMENT : Counter

660 : ENDIF

670 : END WALK

  1. If the format selected is ‘Report’, then the stock item name and the status is updated in a compound variable; whereas, if the format selected is Log file, then the action ‘Write File’ is used to write in the file.

WRITE FILE LINE : $SICStockItem + ##SICTextSep + ##LastStatus

  1. After import, if the user wants to display error report, a function is called to display the same.

690 : IF : ##SICDisplayReport

700 : DISPLAY : TSPL Smp SIC Error Report

710 : ENDIF

  1. After the import, if the user has selected to display the log file, then the log file is displayed.

720 : IF : ##SICOpenLogFile

730 : EXEC COMMAND : @@TSPLSmpErrorFilePath

740 : ENDIF

  1. The Error Report displays the reason of failure, if the Stock Item cannot be imported. In error report, the line is repeated over the collection populated, using list variable as the data source.

Function Parameter Changes – Optional Parameters

Prior to this Release, while invoking a user defined function, it was mandatory to pass values to all the parameters declared within the function. Now, the capability has been introduced to have optional parameters. The function will execute smoothly even if the caller of the function does not pass the values to these optional parameters. However, the caller of the function must pass all the mandatory parameters. Only the rightmost parameters can be optional, i.e., any parameter from the left or middle cannot be optional.

If the Parameter value is supplied by the calling Function, then the same is used, else the default Parameter value provided within the ‘Parameter’ Attribute is used as the Parameter value. For this enhancement, the Function attribute ‘Parameter’ has been modified to accept parameter value.

Syntax

[Function : <Function Name>]

Parameter : <Parameter Name1> : <Data Type>

Parameter : <Parameter Name2> : <Data Type>

Parameter : <Parameter Name3> : <Data Type> [: Parameter Value]

Parameter : <Parameter Name4> : <Data Type> [: Parameter Value]

Where,

<Parameter Name1> and <Parameter Name2> are mandatory parameters for which, values must be passed while calling the function.

<Parameter Name3> and <Parameter Name4> are optional parameters for which, values may or may not be passed while calling the function. If values for these parameters are passed, the parameter value specified within the ‘Parameter’ Attribute is ignored. In absence of these values, the specified parameter value is taken into consideration.

Note: Parameter Value indicates Optional Parameters, and all the Optional Parameters should be the rightmost elements of the function.

Example

[Function : Split VchNo]

;; this Function returns the number part of voucher number from a string. For example, Voucher Number is Pymt/110/2010-11. This Function will return only ‘110’.

Parameter : pVchNo : String

Parameter : pSplitChar : String : “/”

;; usual separator

00 : FOR TOKEN : TokenVar : ##pVchNo : ##pSplitChar

10 : IF : $$LoopIndex = 2

20 : RETURN : ##TokenVar

30 : ENDIF

40 : END FOR

While invoking the function $$SplitVchNo, only the Voucher No is passed. The 2nd Parameter is optional and the default value is “/”. It is passed only if the separator character is other than “/”.

Optional parameters can be very useful where the Parameter values remain constant in most of the cases; and rarely require some change.

Note: A small change has been done in the way function parameters are tokenized. The last parameter passed to the function is not broken up into sub-parts now. This is particularly useful in cases where we require the result of one function to be treated as a parameter to another function. In other words, if a function requires 4 parameters, it tokenizes only till 3 parameters and all the subsequent values are considered as the 4th parameter (last parameter).

 

Release 3.0

Enhancement – Programmable Configuration

Prior to Tally.ERP 9 release 1.52, when multiple reports were printed or mass mailing was being done in a sequence; before each Action, a configuration report was displayed for user input. This would interrupt the flow, thereby requiring a dedicated person to monitor the process, which is time-consuming. This had been addressed in Tally.ERP 9 release 1.6, by providing an optional logical parameter to suppress the repeated display for the configuration screen, before the invocation of global actions ‘Print’, ‘Export’, ‘Upload’ and ‘Email’.

Actions enabled for Programmable Configurations

In order to print, export, upload and email the current report in context, the actions ‘Print Report’, ‘Export Report’, ‘Upload Report’ and ‘Email Report’ are used. Prior to this release, the programmable configuration was not supported for these actions. With the latest enhancement, the display of the configuration screen can be suppressed for these actions also. The syntax of these actions supporting programmable configurations is:

Syntax

<Action Name> [ : <Report Name> [:<Logical Value>]]

Where,

<Action Name> can be any of ‘Print’, ‘Export’, ‘Mail’ and ‘Upload’. The actions ‘Print Report’, ‘Export Report’, ‘Upload Report’ and ‘Email Report’ have also been enabled in the latest release.

<Report Name> is the name of the report or a dot (.). Since ‘Print Report’, ‘Export Report’, ‘Upload Report’ and ‘Email Report’ take the current report in context, and the subsequent parameter is the logical parameter for suppressing the configuration, dot (.) signifies the specification of the current Report Name. This is an optional parameter. However, it is mandatory in case to suppress configuration is to be enabled.

<Logical Value> can be TRUE/FALSE or YES/NO. It is an optional parameter. By default, the value is NO. If set to YES, the configuration screen would not be displayed.

Note: The variables to be set as per the requirement of each Action is done in the same way as discussed in prior releases. Refer to the topic “Programmable Configuration for Actions” in Release 1.6 document for more details.

Example:

To export current report without displaying the configuration screen:

|

|

40: EXPORT REPORT: . : TRUE

|

|

 

Refresh Issues in the context of User Defined Function Evaluation

As we are already aware, the TDL Procedural artefact “Function” is used in two scenarios:

  1. Evaluation – where the function is expected to perform some computation and return the result to the expression within which it is called. The usage is similar to a Predefined function. In evaluation mode, the function is called using a “$$”.

Example:

[Field : My Field]

Set as : $$MyUserFunction : Parameter1 : Parameter2

  1. Execution – where the function is expected to perform certain set of tasks, which changes the state of the application or the data. The usage is similar to a Predefined Action. In execution mode, the function is called using the keyword “Call” and can be invoked from a Key/Button, a Menu item, an Event, or from within another function.

Example:

[Key : My Key]

Action : CALL : MyUserActionFunction : Parameter1 : Parameter2

In case of predefined Functions, whenever a function accesses and manipulates certain UI elements like variable, field, etc., or data elements like method values of objects, a link is established between the element and the calling UI. Each time these get manipulated, the function gets re-evaluated, new values are calculated and the corresponding UI is refreshed with new values.

Let us look at the following example to articulate this better:

[Variable : My Variable]

Type : String

[Field : My Field]

Type : String

Set a s : ##MyVariable

When the report is started, the ‘Set as’ attribute of the field ‘My Field’ is evaluated. During this evaluation, a link between the Field ‘My Field’ and the Variable ‘My Variable’ (which is accessed for its value) is established.

Consider a scenario where, say, a F12:configuration of the report changes the ‘MyVariable’ value. Now, the system would automatically determine that the Field ‘My Field’ was depending on the value of the variable, which has changed now; and hence, RE-EVALUATE the field’s ‘Set As’ attribute to get its new value.

In case of a TDL procedural “Function”, we faced certain issues, where the fields calling the function for some evaluation were not refreshed with new values when the accessed elements got modified elsewhere, and the function did not get re-evaluated. To articulate this better, let’s extend the previous example by using a user defined function.

[Variable : My Variable]

Type : String

[Field : My Field]

Type : String

Set a s : $$MyUserFunction

[Function : My User Function]

Returns : String

01 : RETURN : ##MyVariable

In this case, the system would not establish any relation between the Field and the variable, as it is processed via a function; and hence, when the Value of the variable is changed elsewhere, the Field’s ‘Set As’ will not get re-evaluated automatically to get its new value.

This issue has been resolved in this Release. The related refresh problems which might have been have faced by the users in context of using “Function” in the evaluation scenario, have been resolved. However, in some negligible cases, we may hit with performance issues due to repeated refresh. This mainly happens when the modification of values of UI / data elements like objects, variables, etc., causes the regeneration of linked UI elements. To overcome the same, certain rules have been established and implemented at the platform level itself. In very few cases where one may require a slight change in design of the function, using the new actions and functions may be useful.

Function – $$ExclEvaluate

This function, when prefixed to an expression, helps in evaluating it without establishing the link with the UI elements. There may be a few cases where the programmer would not want the system to establish relationship between the caller and the object being accessed, to refresh the value in subsequent modification. In such cases, prefixing $$ExclEvaluate would indicate the same to the system.

Example

[Variable : My Variable]

Type : String

[Field : My Field]

Type : String

Set a s : $$ExclEvaluate:##MyVariable

OR

Set a s : $$ExclEvaluate:$$MyUserFunction

[Function : My User Function]

Returns : String

01 : LOG : ##MyVariable

02 : RETURN : “Constant String”

Action START SUB … END SUB

In evaluation mode, the dependent regenerations of UI elements are deferred till the function exit. In cases where it is desired to trigger regenerations based on the set of statements as and when they occur, one can enclose the statements within the START SUB – END SUB action block.

To articulate this better, let’s take the previous example, where the Variable is being accessed by a field. The following function, on a button press, changes the value of the Variable two times.

[Function : My User function]

01 : SET : My Variable : “First Value”

02 : SET : My Variable : ##MyVariable + “, Second Value”

In a normal scenario, as both SET actions are modifying the value of the variable, the field (dependent on this variable) would get re-valuated twice. However, the platform has the ability to do it only once during the end of the function by default, when the function is called in EVALUATION mode.

To change this behaviour to refresh the field twice, these two SET actions can be covered inside START SUB – END SUB as follows:

[Function : My User function]

01 : START SUB

02 : SET : My Variable : “First Value”

03 : SET : My Variable : ##MyVARIABLE + “, Second Value”

04 : END SUB

Action – SUB ACTION

The purpose of this action is the same as START SUB – END SUB. The only difference is that this action takes an Action to be executed as a parameter. The former one encloses a set of Actions inside the block.

Following is the alternative of the previous code by using SUB ACTION, rather than using the START SUB – END SUB action block.

[Function : My User function]

01 : SUB ACTION : SET : My Variable : “First Value ”

02 : SUB ACTION : SET : My Variable : ##MyVariable + “, Second Value”

Action START XSUB … END XSUB

In execution mode, the dependent regenerations are handled as and when they occur. In cases where we would like to defer regenerations based on the set of statements, we can enclose the statements within the START XSUB … END XSUB block.

Let’s take the following example to demonstrate this:

[Field : My Field]

Set as : $Value1 + $Value2

;; field value depends on the Value1 and Value2 of the current object

[Function: ModifyCurrentObj]

01 : SET VALUE : Value1 : “Somethi n g else”

02 : SET VALUE : Value2 : “Another value”

This code would normally cause the field to be re-evaluated twice during the function execution. However, enclosing it in an XSUB block would convert it into a single re-evaluation as below:

[Function : ModifyCurrentObj]

01 : START XSUB

02 : SET VALUE : Value1 : “Something else”

03 : SET VALUE : Value2 : “Another value”

04 : END XSUB

Action – XSUB ACTION

The purpose of this action is the same as START XSUB and END XSUB. The only difference is that this action takes an Action to be executed as a parameter. The former one encloses a set of Actions inside the block.

Following is the alternative of the previous code by using XSUB ACTION, rather than using the START XSUB … END XSUB block.

[Function : ModifyCurrentObj]

02 : XSUB ACTION : SET VALUE : Value1 : “Something else”

03 : XSUB ACTION : SET VALUE : Value2 : “Another value”

Release 5.4.8

The actions Increment and Decrement have been enhanced to accept multiple variables.

 

Post a Comment