Explore Categories

 

Objects and Collections

Release 6.4.1 enhancement – Export Header

In the previous lesson, the usage of Variables, Buttons and Keys were explained. In this lesson, the concept of ‘Objects’ and ‘Collections’ will be discussed in detail. Let us try to understand what an object is in general, its importance and usage in TDL.

Objects

Any information that is stored in a computer is referred to as Data. Database is a collection of information organized in such a way that a computer program can quickly select desired data. A database can be considered as an electronic filing system. To access information from a database, a Database Management System (DBMS) is used. DBMS allows to enter, organize, and select data in a database.

The organization of data in a database is referred to as the ‘Database Structure’. The widely used database structures are hierarchical, relational, network and object-oriented.

In the hierarchical structure the data is arranged in a tree-like structure. This structure uses the parent–child relationships to store repeating information. A parent can have multiple children, but a child can have only one parent. The child in turn can have multiple children. Information related to one entity is referred to as an object. A database is a group of interrelated objects.

An object is a self-contained entity that consists of both data, and procedures to manipulate the data. It is defined as an independent entity, based on its properties and behaviour/functionality. Objects are stored in a data base.

A relationship can be created between the objects. As discussed, the hierarchical structure has a parent-child relationship. For example, child objects can inherit characteristics from parent objects. Likewise, a child object can not exist without a parent object.

After discussing the object concept in general, let us examine the Tally object structure in the following section.

Tally Object Structure

The Tally data base is hierarchical in nature, in which the objects are stored in a tree-like structure. Each node in the tree can be a tree in itself. An object in Tally is composed of methods and collections. Method is used to retrieve data from the database. A collection is a group of objects. Each object in the collection can further have methods and collections. The structure is as shown below:

Figure_6.1_Tally_Object_Structure.jpg

Everything in TDL is an Object. As mentioned in the earlier chapters, Report, Menu, Company, Ledger, etc., all are objects in TDL. The properties of objects in TDL are called Attributes. For example, the attributes Object, Title, Form are all properties that define the Report object.

An object can have Methods and Collections, as mentioned earlier. For example, the Object ‘Ledger’ contains the Methods Name, Parent, etc., and the collections Address and BillwiseDetails.

As shown in the image the Objects available at Level 1 are referred to as Primary objects and objects which are at Level 2-n are referred to as Secondary objects.

Two different types of objects are available in TDL. The following section describes the classification of objects in TDL.

Tally Objects Types

Objects in TDL are classified into two types, based on the their usage and behaviour, as follows:

  • Interface Objects
  • Data Objects

 

Interface objects define the user interface while Data objects store the value in the Tally Primary or Secondary database. Any data manipulation operation on the data object is performed through Interface objects only. Figure 6.2 shows the classification of objects in TDL.

Figure_6.2_Classification_of_objects.jpg

Interface Objects

Objects used for designing the User Interface are referred to as Interface objects. Report, Form, Menu, etc., are interface objects. Interface objects like Report and Menu are independent items and can exist on their own. The objects Form, Part, Line, Field can’t exist independently. They must follow the containment hierarchy as mentioned in the section Basic TDL Structure.

Example

[Field : Sa m ple Fld]

Width : 22

[Line : Sam p le Ln]

Field : Name Field

TDL allows a re-usage of all the objects. There are two ways to obtain some more properties that are required in an object:

  • The existing object can either be used in new objects or in lieu of defining a new object.
  • The existing object can be modified to add new properties.

The interface objects can be shared by other interface objects. For example, a single field can be used in multiple lines. The following examples describe the discussed scenarios:

Example : 1

[Field : Sample Fld]

Width : 22

Set As : “TDL Demo”

[#Field : Sample Fld]

Style : Normal Bold

The field Sample Fld will have both the properties. The width of the field is 22 and text is displayed using the style Normal Bold.

Example : 2

[Field : Sa m ple Fld]

Width : 22

Set As : “TDL Demo”

[Field : Sa m ple Fld1]

Use : Sample Fld

Style: Normal Bo l d

The field Sample Fld1 will have both the properties. The width of the field is 22 and the text is displayed using the style Normal Bold.

Example : 3

[Line: TitleA]

Field : Name Field

[Line: TitleB]

Field : Name Field

The field Name Field is used in both the lines TitleA and TitleB .

A set of available attributes of interface objects are predefined by the platform. A new attribute can not be created for an interface object. Interface objects are always associated with a Data Object and essentially add, retrieve or manipulate the information in Data Objects.

Data Objects

Data is actually stored in the Data Objects. These objects are classified into two types viz., Internal objects and User defined objects/TDL objects.

Internal Objects

Internal objects are provided by the platform. They are stored in the Tally Database. Multiple instances of internal objects can exist. In Tally.ERP 9, internal objects are of several types. Examples of internal objects are Company, Group, Ledger, Stock, Stock Item, Voucher Type, Cost Centre, Cost Category Budget, Bill and Unit of Measure.

User Defined Objects/TDL Objects

All the Objects which are defined by the user in TDL are referred to as User Defined Objects or TDL objects. User defined objects are further classified as Static Objects or Dynamic Objects.

Static TDL Objects cannot be stored in Tally Database. The data for the Static object is hard coded in the program and can be used for display purpose only.

Dynamic TDL Objects can be created from the data available in any of the following external data sources:

  • XML Files from remote HTTP server
  • DLL files
  • From any type of database through ODBC

In TDL, the data from all these external data sources is available in a collection.

Example of Internal Objects and TDL Objects

Static TDL Objects/External Objects

As discussed earlier, a user can create Static TDL Objects for which the data is hard coded. Consider the following examples of Employee Details.

Employee Details

objects_and_collections00059.png

In TDL, two objects have to be created such that EmpNo, Name, Date and Designation become the attributes of the object. The code snippet to create these objects is as shown:

[Object : Emp1]

EmpNo : E001

Name : “Krishna”

Date : Aug 01 Designation : Manager

[Object : Emp 2]

EmpNo : E002

Name : “Radha”

Date : Aug 01

Designation : “Asst. Manager”

Internal Objects

Consider the data for a ledger object which has multiple bill details associated with it.

Ledger Details

objects_and_collections00061.png

This hierarchical structure shows that the ledger Krishna is created under the group Sundry Creditors. It further contains multiple bill details. The Ledger Name is Krishna, the parent group is Sundry Creditors and the closing amount is 3000. The two bills Bill 1 for the amount 1000 and Bill 2, for the amount 2000, are associated with the ledger Krishna.

Note: Please refer to Appendix for the detailed structure of Internal Objects and Methods.

Object Context

Each Interface object exists in the context of a Data Object. An Interface object either retrieves information from the Data Object or stores information into the Data Object. The association of the Interface object with a Data Object can be done at the Report, Part, Line and Field level. All the methods of the associated Data Object are available in the Interface object, which is said to be in the ‘Context’ of the associated Data Object.

The data is always retrieved from the database in context of the current object. All the data manipulation operations are performed on the object in context only.

Any expression such as Formulae, Methods and so on which are evaluated in the Interface object, will be in the ‘Context’ of the Data Object.

To understand the concept of object context, consider the following example:

When the Interface object ‘Report’ is associated to the Data Object ‘Ledger’, then all the methods and collection of the Ledger object can be referenced in the associated report. The Method

$Name, when used in the field, will display the name of the Ledger object associated at the Report level. If no object is associated at the Report level, then no data will be displayed in the field, since there is no object in the context.

Collections

A Collection is termed as a group of objects. It refers to a collection of zero or more objects. The objects in the collection can be obtained either from the Tally database, or from external data sources, e.g., XML file.

In default TDL, many collections are defined which are referred to as Internal Collections. The collections created by a user are called user defined collections. Object in a collection follow the Tally object structure, i.e., each object of the collection can contain Methods, Collections, and so on.

A collection can be a collection of objects or a collection of collections. Figure 6.3 shows the collection of objects.

Figure_6.3_Collection_of_objects.jpg

The collection of collections is referred to as a Union of collection. This capability will be discussed in detail in the section Collection capabilities. In TDL, the collections are of two types: Simple collection and Compound collections.

Types of Collection

Collections can have multiple Methods and Collection. They are classified as Simple Collection and Compound Collection based on the constituents of the collection.

Figure_6.4_Classification_of_collections.jpg

Simple Collections

Simple collections contain only a single method which is repeatable. Simple Collections cannot have sub-collections. The Name and Address are examples of Simple Collections.

Compound Collections

The collections which have sub-collections and multiple methods are called Compound Collection. Any Internal or External Collections of Primary or Secondary or user-defined objects is an example of a Compound Collection. In both Simple and Compound Collections, the index can be used to fetch user-defined or internal methods of the Object. The Index can be either First or Last.

After describing the classification of a Collection, the following topic describes the various data sources of a Collection.

Sources of Collection

Collection , the data processing artefact of TDL, provides extensive capabilities to gather data not only from Tally database, but also from external sources using ODBC, DLLs and HTTP.

Based on the source of data, the collections are referred to as External collection, ODBC collection, HTTP XML collection and Aggregate/summary collection.

The Collection of Internal Objects

In cases where a collection contains objects from Tally database, it is referred to as an Internal Collection. In the collection of internal objects, the attributes used are Type, Child Of, Belongs To.

External Collection

The collection of static TDL objects are referred to as an External Collection. The attribute used to create an external collection is Object .

ODBC Collection

The Data Objects populated in the collection are from an external database using ODBC. The attributes used are ODBC, SQL, SQL Objects, SQL Parms and SQL Values.

HTTP XML Collection

The Objects of this collection are obtained from the XML file using HTTP. The file can be made available either on the local machine or on the remote server. The attributes used in creating an XML collections are ‘Remote URL’, ‘Remote Request’, ‘XML Object Path’ and ‘XML Object’.

DLL Collection

A collection can be populated with objects obtained by executing a DLL file. The DLL’s can be written using an external application to extend the existing functionality of Tally. This allows the users to extend the kernel capability by adding their own functions.

External Plug-Ins are written as DLL’s and can be of two types:

  • C++ DLL’s
  • ActiveX DLL’s

In order to create the Collection that calls an external PlugIn the following attributes are used. Values can be passed to the DLL’s as parameters.

Syntax

[Collection : My DLL Collection]

Plug-In               : <path to dll>.<pInput param>

ActiveX Plug-In : <Project Name>.<Class Name>.<pInput param>

The value returned by executing the DLL will be available as objects in the collection.

Creating a Collection

TDL provides a set of attributes to create a collection and populate it with objects obtained from various data sources. The set of attributes used in the collection is based on the data source as mentioned in the section Sources of Collections. This section describes the attributes used in the creation of an internal and external collection. Creating collections from various data sources will be explained later.

Collection of Internal Objects

To create a collection of internal objects, the attribute ‘Type’ is used. It accepts object type name as the value. The collection definition for creating an internal collection has the following syntax.

Syntax

[Collection : <Collection Name>]

Type : <Object Type>

Where,

< Collection Name > is a user-defined name for the collection.

< Object Type > is the name of any of the internal objects, For example, Group, StockItem, Voucher, etc.

Attribute – Type

This attribute is used to define a collection of a particular Type or Subtype. This attribute can take values of the default TDL objects as well as the user-defined fields (UDF).

Syntax

Type : <ObjectType> [: <ParentType>]

Where,

< Object Type > is the name of the object type or its sub-type.

< Parent Type > is optional and is required if the subtype is to be specified.

Example

[Collection : My Collection]

Type : Ledger

The collection My Collection consists of a collection of Ledgers which is an Internal object.

External Collection

To create a collection of Static TDL objects the attribute used is Object. The collection definition for creating external collection has the following syntax:

Syntax

[Collection : <Collection Name>]

Object : <Object Name>, <Object Name>, ……., <Object Name>

Where,

< Collection Name > is the user-defined name for the collection.

< Object Name > are the names of user-defined objects.

Attribute – Object

The attribute Object is used to create a collection of user-defined objects. A collection can have multiple collections/objects in it.

Syntax

Object : <List of Objects>

Where,

< List of Objects > is a comma-separated list of objects.

Here, the objects are defined using the Object definition, as shown in the following example.

Example

[Collection : Emp]

Object : Emp1, Emp2

[Object : Emp1]

   EmpName : ” Ram Kumar”

   Age     : “25”

[Object : Emp2]

EmpName : ” Krishna Yadav”

Age     : “30”

The Objects of Collection ‘Emp’ has the Methods ‘EmpName’ and ‘Age’.

In TDL, methods are used to retrieve data from Objects and Collections. The following section explains the Usage and Types of methods.

Object Association

Object Association is the process of linking an Interface Object with one or more Data Objects. Each Interface Object must be in the context of a Data Object. A TDL programmer can associate an Interface Object with any Data Object. If an Interface object is not explicitly associated with any Data Object, then Anonymous Object is associated with it. Anonymous Object is a Primary data Object provided by the platform. It has no methods, sub-collections, or parameters.

Object Association can be done at the following levels:

  • Report Level Association
  • Part Level Association
  • Line Level Association
  • Field Level Association

Once an Object is associated at the Top-level, the child level Interface Objects inherit it, unless it is explicitly overridden. If there is no explicit association of the Data Object at the Report level, it is associated with the Anonymous Object.

Report Level Object association

A Report is normally associated with a data object, which it gets from the previous Report and if not, will be associated with the anonymous object. From Release 3.0 onwards, the syntax for the association has been enhanced to override the default association as well. The Report attribute ‘Object’ has been enhanced to take an additional optional value as ‘Object Identifier Formula’.

Syntax

Object : <ObjectType> [: <ObjectIdentifierFormula>]

Where,

< ObjectType > is a Type of Primary Object.

< ObjectIdentifierFormula > is an optional value and refers to any formula which evaluates the name of Primary Object.

Example 1: Without the Object Identifier

[#Form : Sales Color]

Delete : Print

Add : Print : New Sales Format

[Report : New Sales Format]

Object : Voucher

Default Sales Color Form is modified to have a new print format ‘New Sales Format’. This Report gets the voucher object from the previous Report.

Example 2: With the Object Identifier

[Report: Sample Report]

Object : Ledger : “Cash”

The Ledger ‘Cash’ is associated to the Report ‘Sample Report’. Now components of a ‘Sample Report’ by default, inherit this ledger object association.

Part Level Object Association

Part inherits the Object from the Report/Part/Line, by default. This can be overridden in two ways.

Using the ‘Object’ attribute specification in the Part definition

The syntax of an Object attribute at the part level is as follows:

Syntax

Object : <SupplierCollection> : <SeekTypeKeyword> [: <SeekCondition>]

Where,

< SupplierCollection > is the name of the Collection of Secondary Objects.

< SeekTypeKeyword > can be First or Last, which denotes the position index.

< SeekCondition > is an optional value, and is a filter condition to the Supplier collection.

Example: Part in the Context of Voucher Object

[Part : Sample Part]

Line : Sample Line

Object : InventoryEntries:First:@@StkNameFilter

Scroll : Vertical

[System : Formula]

StkNameFilter : $StockItemName = “Tally Developer”

The first inventory entry having stock item “Tally Developer” is associated with Part ‘Sample Part’.Only sub-objects can be associated at part level for which the primary object is associated at the Report level. To overcome this limitation a new attribute ‘Object Ex’ is introduced at part level in release 3.0.

Using ‘Object Ex’ attribute specification in Part definition

The attribute ‘Object Ex’ provides the ease of using enhanced method formula syntax, while specifying the object association. Now even the Primary Object can be associated with a Part, which was not possible with the Object attribute of ‘Part’ Definition.

Syntax

Object Ex : <Method Formula Syntax>

Where,

< Method formula syntax > is, <Absolute Specification>.[<Sub Object Specification>]

<Absolute Specification> is (<Object Type>, <Object Identifier Formula>). If only Absolute Spec. is given, then it should end with dot (‘.’).

<Sub Object Specification> is CollectionName[Index,<Condition>]

Example : 1

[Part: Sample Part]

Object Ex : (Ledger,”Customer”)

The Ledger object “Customer 1” is associated with the Part ‘Sample Part’. Since only the absolute specification used, the Object specification ends with ‘.’

Example : 2

[Part : Sample Part]

Object Ex : (Ledger,”Customer”) . BillAllocations[1, @ @Condition1]

[System : Formula]

Condition1 : $Name = “Bills 2”

The Secondary Object ‘Bill Allocation’ is associated with the Part ‘Sample Part’.

The Data Object associated to some other Interface Object can also be associated to a Part. This aspect will be elaborated in the section ‘Object Access via UI Object’ of the Enhancement training. The enhanced method formula syntax is discussed in detail under the section ‘Accessing Methods’.

Line Level Object Association

An object can be associated with a Line by Part attribute ‘Repeat’. Now, the Part attribute ‘Repeat’ is enhanced to support the following.

  • Extraction of collection from any Data object.
  • Extraction of collection from UI Object associated Data object. This aspect will be elaborated in the section “Object Access via UI Object”.

 

Attribute – Repeat

Syntax

Repeat : <Line Name> : <Coll Name> : [<Supplier Coll> : <SeekTypeKeyword> : <SeekCondition>]

Where,

< Coll Name > is the name of the Collection. If the Collection is present in one level down of the object hierarchy, then Supplier Collection needs to be mentioned.

< SupplierCollection > is the name of the Collection of secondary Objects.

< SeekTypeKeyword > can either be First or Last which denotes the position index.

< SeekCondition > is an optional value and is a filter condition to the supplier collection.

Example: Part in the context of Voucher Object

[Part : Sample Part]

Line : Sample Line

Repeat : Sample Line: Bill Allocations: Ledger Entries: First: @@LedFormula

[System : Formula]

LedFormula : $LedgerName = “Customer”

The Line ‘Sample Line’ is repeated over Bill Allocations of first Object ‘Ledger entries’, which satisfies the given condition.

Alternate ‘Repeat’ Syntax

Instead of specifying the <Coll Name>:[<Supplier Coll>:<SeekTypeKeyword>: <SeekCondition>], the new method formula syntax can be used as follows:

Syntax

Repeat : <Line Name> : <MethodFormulaSyntax>

Where,

< MethodFormulaSyntax > is <Absolute Spec>.<SubObjectSpec>

<Absolute Spec> is (<Object Type>, <Object Identifier Formula>)

<Sub Object Spec> is CollectionName[Index,<Condition>]

Example

[Part : Sample Part]

Line : Sample Line

Repeat : Sample Line : (Ledger, “Customer”).BillAllocations

The Line ‘Sample Line’ is repeated over Bill Allocations of Object Ledger for Customer ledger.

Field Level Object Association

By default, it is inherited from the Parent line or Field (if the field is inside a field). This cannot be overridden. However, Field also allows Object Specification syntax. This association, if specified, acts as the ‘Secondary Context Object’ for the Field. During any formula evaluation, if the formula/method fails in the context of the Primary Object, the Secondary Object is tried then.

Methods

Each piece of information stored in the data object can be retrieved using a method. A method either performs some operation on the object, or retrieves a value from it. To retrieve the value from database, the storage name is prefixed with $ symbol. TDL provides pre-defined methods and allows the user to create methods as well. Methods are classified as Internal or External.

Types of Methods

Internal Methods

The methods which are defined by the platform are called Internal Methods. For example, the methods Name, Address, and Parent are the internal Methods of Object ‘Ledger’.

User-Defined/External Methods

A user can change the behaviour or perform an action on the internal object by defining new Methods. Methods defined by the user are referred to as External/User-defined methods. For example., a method ‘DiffBal’ can be created for an Object ‘Ledger’, which gives the difference of the total debit amount and total credit amount.

Accessing Methods

Methods of an object can be accessed in TDL in three different ways, based on the object context.

Accessing data from the current Object

In case you are already in the object context, use the Method name prefixed with $ directly.

Syntax

$<MethodName>

Where,

< Method Name > is the name of the Method of the object in context.

Example

$CompanyName

Accessing by Reference

In cases where the user is not in the object context or is in a different object context then the following syntax may be used:

Syntax

$<Method Name> : <Object Name>:<formula>

Where,

< Method Name > is the name of the Method, which belongs to the Object.

< Object Name > is the name of the Object.

< Formula > is the value, based on which, the Method value is retrieved.

Example

$Name : Ledger : ##SVLedgerName

Accessing by using the Index

In cases where the user is not in the object context, or in a different object context, the following syntax may be used:

Syntax

$<Method Name> : < Collection Name> : <Seek Type>

Where,

< Method Name > is the name of the Method which belongs to the Collection.

< Collection Name > is the name of the Collection.

< Seek Type > is the searching direction. It can either be First or Last.

Example

$LedgerName : LedgerEntries:First

Directly Accessing Data from Any Object

The Method formula syntax allows direct access to any object Method, including its sub-collections to any level, with a dotted notation framework. The values from any object anywhere can be accessed, without making the object as the current object. This syntax is introduced to support access out of the scope of the Primary Object and to access the Subobject at any level using (.) dotted notation, with index and condition support.

Syntax

$<PrimaryObjectSpec>.<SubObjectPathSpec>.MethodName

Where,

< Primary Object Spec > can be (<Primary Object Type Keyword>, <Primary Object Identifier Formula>)

< SubObjectPathSpec > is given as the Collection Name [<Index Formula>, [<Condition>]]

< MethodName > refers to the name of the Method in the specified path.

< Index Formula > should return a number, which acts as a position specifier in the Collection of Objects matching the given <condition>

Example: Assuming that the Voucher is the current object

  • To get the Ledger Name of the first Ledger Entry from the current Voucher:

Set As : $LedgerEntries[1].LedgerName

  • To get the amount of the first Ledger Entry on the Ledger Sales from the current voucher (Sales Invoice):

Set As : $LedgerEntries[1,@@LedgerCondition].Amount

LedgerCondition : $LedgerName = “Sales”

  • To get the first Bill Name of the first Ledger entry on the Party Ledger from the current voucher (Sales Invoice):

Set As : $LedgerEntries[1,@@LedgerCondition].BillAllocaions[1].Name

LedgerCondition : $LedgerName = @@InvPartyName

  • To get the Opening Balance of the first Bill for the Party Ledger Acme Corp:

Set As : $(Ledger,@@PartyLedger).BillAllocations[1].OpeningBalance

PartyLedger : “Acme Corp”

The Primary Object specification is optional. If it is not specified, the current object will be considered as the Primary Object. A Sub-Collection specification is optional. If not specified, Methods from the current or specified primary object will be made available. The Index specifies the position of the Sub-Object to be picked up from the Sub-Collection. This Condition is ‘Filter’ which is checked on the objects of the specified Sub-Collection .

< Primary Object Identifier Formula >, < Index Formula > and Condition can be a value or formula.

The Index Formula can be any formula evaluating to a number. The Positive Number indicates a forward search while a negative number indicates a backward search. This can also be a keyword First or Last, which is equivalent to specifying 1 or – 1 respectively.

In cases where both the Index and Condition are specified, the index is applicable on the Object(s) which satisfies the condition so that one gets the nth Object which clears the condition. Let’s say for example, if the Index specified is 2 and Condition is Name = ‘Sales’, then the second object which matches the name ‘Sales’, will be picked up.

The Primary Object Path Specification can either be Relative or Absolute. A Relative Path is referred to by using empty parenthesis () or a dotted path to refer to the Parent object relatively. A SINGLE DOT denotes the current object, DOUBLE DOT the Parent Object, TRIPLE DOT the Grand Parent Object, and so on, within an Internal Object. The Absolute Path refers to the path in which the Primary Object is explicitly specified.

To access the Methods of Primary Object using a Relative Path, the following syntax is used.

Syntax

$().<MethodName> or $..<MethodName> or $…<MethodName>

Example

With regard to the context of LedgerEntries Object within Voucher Object, the following have to be written to access the Date from its Parent Object which is the Voucher Object.

$..Date

To access the Methods of Primary Object using the Absolute Path:

Example

$(Ledger, “Cash”).OpeningBalance

Collection Capabilities

Having understood the concept of Objects, Collection, Methods and Object association, let us now concentrate on understanding the concept of Collection as a Data Processing Artefact in TDL.

In previous sections, we saw that a Collection can contain objects from Tally Database or populate objects from external data sources as well. In further sections, we will discuss the capabilities of collection from the data processing perspective. Let’s segregate the capabilities into:

  • Basic Capabilities
    • Union
    • Filtering
    • Sorting
    • Searching
  • Advanced Capabilities
    • Extraction
    • Aggregation
    • Usage As Tables
    • Integration Capabilities using HTTP XML Collection
    • Dynamic Object Support
    • Collection Capabilities for Remoting

We will be covering the Basic capabilities in detail with all the relevant attributes and functions for achieving the same. Some portions of Advanced capabilities that were available prior to TallyPrime will be covered here. 

Basic Capabilities

Union

‘Union’ refers to the creation of a Collection by combining multiple Collections. The total number of objects in the resultant Collection will be the sum of objects in all the Collections. The following figure shows a Collection of sub-collections, which can further be unions of collections, and so on.

Figure_6.5_Collection_of_Sub-collection_(2).jpg

This example shows that Collection C1 contains Collection C2 and Collection C3. Likewise, Collection C2 further contains Collection C4 and Collection C5. The attribute Collection is used to create a Union as follows:

Attribute – Collection

The attribute ‘Collection’ is used to specify a Collection under the main Collection. All the objects belonging to the Sub collections are available in the resultant Collection.

Syntax

Collection : <List of Collections>

Where,

<List of Collections> is a comma-separated list of collections. The Collections that are used can be of different types.

Example

[Collection : Groupandledger]

Collections : Group, Ledger

Here, the collections ‘Group’ and ‘Ledger’ are used, under the main collection GroupandLedger.

Filtering

If it is required to retrieve only a specific set of objects from a Collection, then the collection needs to be filtered. Filtering is applied to the Collection, based on a condition. All the objects which satisfy the given condition are retrieved and are available in the Collection.

Filtering Attributes

The attributes used for applying a filter are ChildOf , BelongsTo and Filter .

Attribute – Child Of

The ChildOf attribute helps to control the display of the contents of a collection. It retrieves only those objects whose direct parent is the string specified as the parameter of this attribute.

Syntax

ChildOf : <String Formula>

Example

[Collection : My Collection]

Type : Ledger

ChildOf : “Sundry Debtors”

It will return all the ledgers grouped directly under the group ‘Sundry Debtors’. The following definition code will return all the ledgers under the group blank. By default, Tally returns the ledger ‘Profit and Loss’.

ChildOf : “”

Attribute – BelongsTo

The attribute ‘Belongs To’ is used along with the ‘Child Of’ attribute. This attribute determines whether to retrieve the first level of objects under the value specified in ‘ChildOf’ or include all the objects upto the lowermost level. ‘Belongs To’ takes a logical value.

Syntax

BelongsTo : <Logical Value>

Where,

< Logical Value > can be either YES or NO .

Example

Consider the previous example of accounts. The following code is an extension of that code.’

[Collection : My Collection]

Type     : Ledger

ChildOf  : “Sundry Debtors”

BelongsTo : Yes

This code will retrieve all the objects directly under the group ‘Sundry Debtors’, as well as all the objects which are under the subgroups of ‘Sundry Debtors’.

Attribute – Filter

The attribute ‘Filter’ is used to specify the condition for filtering the objects. The ‘Filter’ attribute takes a system formula. The condition is specified in the formula. If more than one filter has to be specified, they can be separated by a comma.

Syntax

Filter : <FilterName>

Where,

< Filter Name > is the name of the Global formula.

Example

[Collection : LtdDebtors]

Type : Ledgers

ChildOf : “Sundry Debtors”

Filter : NameFilter

[System : Formula]

NameFilter : $Name contains “Ltd” OR $Name contains “Limited”

The filter Namefilter is used to fetch only those objects, whose name contains the string “Ltd” or “Limited”.

Filtering Functions

Function – $$FilterAmtTotal

It is used to get the sum of values returned by the specified filter expression when applied to all the Objects in the Collection that satisfy the expression. The value returned is of type Amount.

Syntax

$$FilterAmtTotal:<CollectionName>:<FilterExpression>:<ValueExpression>

Where,

< CollectionName > is the name of a Collection,

< FilterExpression > is a System Formula.

< FilterExpression > is evaluated for each Object. The resultant Objects that clear the filter are selected for further processing.

< ValueExpression > is any valid expression, which is to be evaluated on each Object of the Collection.

Example

$$FilterAmtTotal:AllLedgerEntries:CashBankEntries:$Amount

[System : Formula]

CashBankEntries : $$IsCashLedger:$LedgerName AND $$IsDr:$Amount

The filter in the example checks whether the ledger is a Cash Ledger and the amount is of the type ‘Debit’. $$IsCashLedger is a logical Function, which checks whether the argument passed is a Cash Ledger or not. This statement can be evaluated only in the context of a Voucher Object.

Function – $$FilterQtyTotal

It is similar to $$FilterAmtTotal, except that the Value Expression should evaluate to type Quantity.

Syntax

$$FilterQtyTotal:<CollectionName>:<FilterExpression>:<ValueExpression>

Where,

< CollectionName > is the name of Collection

< FilterExpression > is a System Formula.The Filter Expression is evaluated for each object, and the resultant Objects that clear the filter are selected for further processing.

< ValueExpression > is any valid expression, which is to be evaluated on each Object of the Collection.

Function – $$FilterCount

The function $$FilterCount is used to get the total number of Objects in a Collection after the filters are applied.

Syntax

$$FilterCount : <CollectionName> : <FilterExpression>

Where,

< CollectionName > is the name of a Collection.

< FilterExpression > is a System Formula.

Example

$$FilterCount:AllLedgerEntries:HasBankEntry > 0

[System : Formula]

HasBankEntry :($$IsDr:$Amount!=$IsDeemedPositive:VoucherType:$VoucherTypeName)+

AND($$IsLedOfGrp:$LedgerName:$$GroupBank OR $$IsLedOfGrp:$LedgerName:$$GroupBankOD)

It confirms whether the voucher has any Ledger under the Group Bank or BankOD.

Note : The function $$FilterCount will not work at the menu level.

$$IsLedOfGrp accepts two parameters and returns TRUE if parameter 1 is a ledger of a Group mentioned in parameter 2. GroupBankOD and GroupBank are functions that return the name of the reserved groups Bank OD and Bank.

Function – $$FilterValue

This function is used to get the value of a specific expression, based on the position specified in the set of objects filtered by the expression.

Syntax

$$FilterValue : <ValueExpression> : <CollectionName> : <PositionSpecifier> : <FilterExpression>

Where,

< CollectionName > is the name of the Collection.

< FilterExpression > is the filter applied to get a set of filtered Objects.

< PositionSpecifier > denotes the position.

< ValueExpression > is any valid expression to be evaluated on each Object of the Collection.

Example

$$FilterValue:$LedgerName:LedgerEntries:First:IsPartyLedger

This example filters all the objects within LedgerEntries to satisfy the filter condition IsPartyLedger and returns the first value of the requested method LedgerName that satisfies the condition.

Some other Functions Used

Function – $$GroupSundryDebtors

It returns the name of the group ‘Sundry Debtor’, even if the user renames it.

Syntax

$$GroupSundryDebtors

Example

[Collection : Sample Coll]

Type     : Ledgers

Child Of : $$GroupSundryDebtors

This will populate the collection Sample Coll with all objects under the Group ‘Sundry Debtors’. In case the user has renamed the group “Sundry Debtors” as “My Sundry Debtors”, the following code snippet won’t have any objects in the collection.

[Collection : Sample Coll1]

Type     : Ledgers

Child Of : “Sundry Debtors”

But in this case, $$GroupSundryDebtors will populate the collection with all the objects that are under the Group ‘Sundry Debtor’ even if the user renames the group.

Function – $$GroupSundryCreditors

It returns the name of the group ‘Sundry Creditors’, even if the user renames it.

Syntax

$$GroupSundryCreditors

Example

[Collection : Sample Coll]

Type     : Ledgers

Child Of : $$GroupSundryCreditors

This will populate the collection Sample Coll with all objects under the Group ‘Sundry Creditors’. In case the user has renamed the group “Sundry Debtor” as “My Sundry Debtors”, the following code snippet won’t have any objects in the collection.

[Collection : Sample Coll1]

Type     : Ledgers

Child Of : “Sundry Creditors”

But in this case, $$GroupSundryCreditor will populate the collection with all the objects that are under the Group “Sundry Creditors”, even if the user renames the group.

Sorting

Sorting refers to the arrangement of objects in a specific order within the collection. The ordering is done on the basis of a specific method and the sort order can either be ascending or descending. The attribute Sort is used for this purpose.

Attribute – Sort

A collection can be sorted by specifying the sort sequence using the ‘Sort’ attribute. The collection can be sorted by a combination of fields in ascending as well as in descending order.

Syntax

Sort : < Sort Name> : <List of Methods>

Where,

< List Of Methods > is a comma separated list of methods. Sorting is done based on values of methods. The default sort order is ascending. Prefix Methods name with ‘-’, for descending order.

Example

[Collection : My Collection]

Collections : MyLedger

Sort : Default : $ClosingBalance, $Name

Searching

Collection capabilities have been enhanced to enable the indexing of objects based on a particular method. Whenever a collection is indexed on a particular method, it allows instant access to the corresponding values without the need for a complete scan.

Attribute – Search Key

Syntax

Search Key : < Combination of Method name/s>

This implies that a unique key is created for every object which can be used to instantly access the corresponding objects and its values. The function which is used to retrieve the values from a collection based on the key specified is $$CollectionFieldByKey .

Function – $$CollectionFieldByKey

Syntax

$$CollectionFieldByKey : <Method Name> : <Key Formula> : <Collection Name>

Where,

< Method Name > is the name of the method.

< Key Formula > is a formula that can be mapped to the methods defined in the search key exactly in the same order.

Example

[Collection: My Ledgers]

Type : Ledger

Search Key : $Name

[Field : My Closing Bal Field]

Set as : $$CollectionFieldByKey:$ClosingBalance:@MySearchKey:My Ledgers

MySearchKey : #LedName

Here, a search key is defined on $ name for collection MyLedgers . In the Field, value $Closing Balance is retrieved based on ledger name. In this case, retrieval is faster than ordinary retrieval.

This capability is quite useful in the case of matrix reports, i.e., when two or more dimensions need to be represented as rows and columns. In such a case, defining the search key on a method combination, and using $$ CollectionFieldByKey for value retrieval improves performance. 

Note : The function $$CollectionFieldByKey will not work at menu level

Advanced Capabilities

Extraction and Chaining

The Collection capabilities have been enhanced to extract information from the collection using other collections, including its sub-objects, with the choice of method (s), filter(s) and sort-order. Specific attributes have been added at the collection level to achieve the same.

Prior to Tally.ERP 9 or TallyPrime, extraction was possible using specific function $$CollectionField.

Function – $$CollectionField

This is used to get the value of a specified expression as applied on the nth Object of a Collection.

Syntax

$$CollectionField:<ValueExpression>:<PositionNumber>:<CollectionName>

Where,

< CollectionName > is the name of a collection.

< ValueExpression > is any valid expression to be evaluated on the element at position < PositionNumber > in the collection.

Example

$$CollectionField:$Amount:1:AllLedgerEntries

It returns the first value of the Method Amount from AllLedgerEntries Object.

This function affects the performance of the report in terms of time taken to display the report. 

Note: The function $$CollectionField will not work at menu level

Grouping & Aggregation

A major technological advancement in this release of Tally.ERP 9 is “Data Roll up in TDL Collection – GROUP BY”, which is a part of the TDL language capabilities. This is a milestone achievement over the past 10 years. This will now facilitate the creation of large summary tables of aggregations in a single shot, using the new attributes of the Collection description. This allows us to Walk down the object hierarchies and gather values to summarizes them in one scan. Overall, it reduces the TDL code complexity, resource requirement and increases performance drastically in case of reports generated using this new capability.

The attributes used for extraction, chaining, and aggregation and grouping are Walk, By, Fetch, Compute, AggrCompute. 

Prior to Tally.ERP 9, the totals were generated using the Total and aggregation functions like CollAmtTotal or FilterAmtTotal on collections. These have certain advantages and disadvantages. While they provide excellent granularity and control, each call is largely an independent activity to gather the data set and then aggregate it. This significantly affects the performance of the reports.

Let us now discuss the various functions which are available for summarization and aggregation.

Function – $$CollAmtTotal

This function is used to get the sum of values of Type Amount returned by a specified expression when applied to all Objects in a given Collection. The return value is of type Amount.

Syntax

$$CollAmtTotal : <CollectionName> : <ValueExpression>

Where,

< CollectionName > is the name of a Collection.

< ValueExpression > is any valid TDL expression to be evaluated on each Object of Collection.

Example

$$CollAmtTotal:LedgerEntries:$Amount

It gets the sum of values in the Method Amount after it is applied on each Object in the Collection LedgerEntries . This statement will hold good only when one is in the context of Voucher Object.

Function – $$CollQtyTotal

This function is used to get the sum of values of Type Quantity returned by the specified expression when applied to all Objects in a given Collection. The value returned is of Type Quantity.

Syntax

$$CollQtyTotal : <CollectionName> : <ValueExpression>

Where,

< CollectionName > is the name of a Collection

< ValueExpression > is any valid TDL expression to be evaluated on each Object of Collection.

Example

$$CollQtyTotal:InventoryEntries:$BilledQty

Each Inventory entry in the current Voucher Object is picked up and the Method BilledQty is evaluated on it. The resultant quantity is summed up to get the result.

Function – $$CollNumTotal

This function is used to get the sum of values of Type Number returned by the specified expression, when applied to all Objects in a given Collection. The value returned is of the Type Number .

Syntax

$$CollNumTotal : <CollectionName> : <ValueExpression>

Where,

< CollectionName > is the name of a Collection.

< ValueExpression > is any valid expression to be evaluated on each Object of the Collection.

Example

$$CollNumTotal:InventoryEntries:$Height

Each Inventory entry in the current Voucher Object is picked up and the Method Height evaluated on it. The resultant height is summed up to get the result. Here, Height is an external Method of Object Inventory Entry in a Voucher.

Usage as Tables

TDL allows to display the values obtained from the collection as a pop-up table. Earlier, the values of voucher and the ODBC data couldn’t be displayed as a collection. Now, all limitations pertaining to usage of Collections as Tables have been completely eliminated. Any collection which can be created in TDL, can be displayed as a table now. Collection with aggregation and XML Collections can also be used as Tables.

Integration Capabilities using HTTP XML Collection

The Collection capability has been enhanced to gather live data from HTTP/web-service delivering XML. The entire XML is automatically now converted to TDL objects and is available natively in TDL reports as $ based methods. Reports can be shown live from an HTTP server. The attributes in collection for gathering XML based data from a remote server over HTTP are RemoteURL, RemoteRequest, XMLObjectPath, and XMLObject.

Dynamic Object Support

When a collection is used for editing (alter/create), objects are dynamically added to the collection when a new line is repeated over the same. The type of object which is added depends on the specification in the TYPE attribute. In case the TYPE attribute is not specified, it defaults to adding a standard empty object.

However, the following holds true for a COLLECTION keeping in mind the latest enhancements:

  • It can be made up of multiple types of objects (say Ledgers and Groups).
  • It can have TDL defined objects which are retrieved from XML file. They are specified using XML Object.
  • It can have aggregated objects.

Depending solely on the TYPE attribute to make a decision, the object type is a constraint with respect to the above facts. This is now being removed with the introduction of a new attribute which will independently govern the type of object to be added to the collection on-the-fly. The following is now supported in a collection.

NEWOBJECT : type-of-object : condition

Collection Capabilities for Remoting

Enabling access to your organizational data ‘any-time, any-where’, and yet being truly usable, is what Tally.ERP 9 delivers. With remote access through Tally.NET Server, it will be possible for any authorized user to access Tally.ERP 9 from anywhere.

Major Enhancements have taken place at the collection level to achieve remoting capabilities. The attributes Fetch, Compute and AggrCompute provided at the Collection level, and FetchObject and FetchCollection at the Report level significantly help in above functionality.

Collection Attribute – Export Header

When you integrate TallyPrime with a third-party application, the communication can happen in a connected or non-connected environment where TallyPrime can act as a client or server or both.

In a connected environment, when communication happens over a network, TallyPrime can send GET or POST request to third-party applications and gather responses using collection capabilities. A GET request is always without a request body while a POST request has a request body. In both the cases, the request can have HTTP headers as required by the third-party and the HTTP standards.

To support this requirement collection is enhanced with a new attribute, Export Header, to specify the HTTP headers when you send requests to HTTP servers.

Syntax

[Collection: <Collection Name>]

Export Header : <String Expression>

Where,

<Collection Name> – the name of the collection where the data is populated.

<String Expression> – a valid expression that evaluates to a string.

 

GET Requests with Headers

A GET request sent to a server can have HTTP headers. It will not have any request body.

To send a GET request to a server with HTTP headers, specify the server URL in the collection attribute, Remote URL or the data source HTTP JSON or HTTP XML and the headers with the attribute Export Header. The choice of the attribute for URL specification depends on the format of data exchange.

Syntax

[Collection: <Collection Name>]

Export Header: <String Expression>

Remote URL: <Target URL>

OR

Data Source: HTTP JSON : <Target URL> [: <Encoding>]

OR

Data SourceHTTP XML : <Target URL> [: <Encoding>]

Where,

<Collection Name> – the name of the collection where the data is populated.

<Target URL> – the URL to which the request is to be sent.

<Encoding> – can be ASCII, UNICODE, UNICODE8, UTF8, or UTF16. It is applicable for the data source types File XML, HTTP XML, File JSON, HTTP JSON. The default value is UTF16.

 

POST Requests with Headers

A POST request is sent to a server with request body and HTTP headers, where the headers are optional.

To send a POST request to a server with HTTP headers, specify the server URL in the collection attribute, Remote URL or the data source HTTP JSON or HTTP XML, and the headers with the collection and report attribute Export Header. To construct the request body use the attribute Request Report. When you specify the headers in both collection and the request report (using Export Header ), both the headers will be considered. The choice of the attribute for URL specification depends on the format of data exchange.

[Collection: <Collection Name>]

Export Header: <String Expression>

Remote Request : <Request Report> [: <Encoding>]

Remote URL: <Target URL>

OR

Data Source: HTTP JSON : <Target URL> [: <Encoding>]

OR

Data Source: HTTP XML : <Target URL> [: <Encoding>]

When you use the attribute Export Header you can observe the following:

  • When multiple collections are used, like summary collection or union collection, specify the attribute Export Header in the collection where the attribute Data source is mentioned.
  • In the case of POST request, the headers specified at collection and report levels will be part of the request sent. The order of adding headers in the request is first from the collection and then from the report.
  • The attributeExport Headeris applicable only when an HTTP source is specified using the attribute Remote URL or data sources like HTTP JSON or HTTP XML.

 

Example

Case 1 :Send a GET request with HTTP headers and receive the response

The HTTP header ” Accept:application/json ” is sent to the server, in order to receive the response in JSON format. Data source type HTTP JSON is used to exchange the data in JSON format.

[Collection: TSPL Get Employees JSON]

Export Header : “Accept:application/json”

Data Source: HTTP JSON: “http://localhost/ExportHeader/getempdetails.php” :UTF8

 

Request Sent

Response Received

Accept: application/json

{

“employees”:

{“employee”: [

{

“Name”: “John Smith”

},

{

“Name”: “Jessica Jones”

}

]

}

}

 

Case 2: Send a POST request with HTTP headers and receive the response

In the request, Accept:application/xml , Emp Id as HTTP header, and Leave Type as body are sent to the server to receive the response in XML format for the selected employee and the leave type. Data source type HTTP XML is used to exchange data in the XML format.

 

[Collection: TSPLLeaveSummaryXML]

Data Source : HTTP XML: ” http://localhost/ExportHeader/getleavedetails.php”

Export Header : “Accept:application/xml”

Export Header : “EmpId:5989”

RemoteRequest : TSPL Leave Request: UTF8

XML Object Path: “LeaveInfo:1:Envelope:LeaveDetails:1”

The request report, TSPL Leave Request is used to construct the request body.

Request Sent

Response Received

Accept: application/xml

EmpId : 5989

<Request>

<LeaveType>

Earned Leave

</LeaveType>

</Request>

<Envelope>

<LeaveDetails>

<Employee> Vamsi </Employee>

<EmpId>5989</EmpId>

<Gender>Female</Gender>

<LeaveInfo>

<Type>Earned Leave</Type>

<Entitled>24</Entitled>

<Availed>10</Availed>

</LeaveInfo>

</LeaveDetails>

</Envelope>

 

Collection Enhancements in Tally.ERP 9 Releases

Release 1.5

TDL supports the hierarchical database structure. While designing any report, the objects are first populated in the collection, before being displayed. TDL also supports the concept of aggregate/summary collection, for creating summarized reports. In the aggregate collection, during the evaluation, the following three sets of objects are available:

  • Source Objects          : Objects of the collection specified in the Source Collection attribute.
  • Current Objects        : Objects of the collection till which the Walk is mentioned.
  • Aggregate Objects    : Objects obtained after performing the Grouping and Aggregation.

There are scenarios where some calculation is to be evaluated based on the source object or the current object value, and the filtration is done based on the value evaluated with respect to final objects before populating the collection. In these cases, to evaluate value based on the changing object context is tiresome, and sometimes impossible as well.

The newly introduced concept of collection-level variables provides Object-Context Free processing. The values of these in-line variables are evaluated before populating the collection. The values of these variables can be accessed from anywhere while evaluating the current collection objects. The sequence of evaluation of the collection attributes is changed to support the attributes ‘Compute Var’, ‘Source Var’ and ‘Filter Var’. The variables defined using attributes ‘Source Var’ and ‘Compute Var’ can be referred to  By, Aggr Compute and Compute attributes of collection. The variable defined by Filter Var can be referred at Filter attribute of the collection.

Collection Attributes – Source Var, Compute Var, Filter Var

Attribute – Source Var

The attribute Source Var evaluates the value of the variable based on the source object.

Syntax

Source Var : <Variable Name> : <Data Type> : <Formula>

Where,

<Variable Name> is the name of the variable.

<Data Type> is the data type of the variable.

<Formula> can be any expression formula, which evaluates to a value of ‘Variable’ data type.

Example

Source Var : Log Var : Logical : No

The value of the variable LogVar is set to No.

Attribute – Compute Var

The attribute Compute Var evaluates the value of the variable based on the sub-object of the source object.

Syntax

Compute Var : <Variable Name> : <Data Type> : <Formula>

Where,

<Variable Name> is the name of the variable.

<Data Type> is the data type of the variable.

<Formula> can be any expression formula which evaluates to a value of ‘Variable’ data type.

Example

Compute Var : IName:String : if ##LogVar then $StockItemName else ##LogVar

Attribute – Filter Var

The attribute Filter Var evaluates the value of the variable based on the objects available in the collection, after the evaluation of attributes Fetch and Compute.

Syntax

Filter Var : <Variable Name> : <Data Type> : <Formula>

Where,

<Variable Name> is the name of the variable.

<Data Type> is the data type of the variable.

<Formula> can be any expression formula which evaluates to a value of the ‘Variable’ data type.

Example

Filter Var : Fin Obj Var : Logical : $$Number:$BilledQty > 100

Sequence of Evaluation of Collection Attributes

The collection attributes are evaluated as per the following sequence, before populating the collection:

  1. Source Collection
  2. Source Var
  3. Walk
  4. Compute Var
  5. By
  6. Aggr Compute
  7. Compute
  8. Filter Var
  9. Filter

With the introduction of these attributes, the calls to the functions $$Owner, $$ReqObject, $$FilterValue, $$FilterAmtTotal can be reduced.

Usage of the Collection attributes – Source Var, Compute Var, Filter Var

In this section, the use cases where the collection attributes can be used, are explained.

Usage of ‘Compute Var’ in Simple Collection

When Compute Var is used in a simple collection, then before populating the objects in the collection, Compute var is evaluated. Consider the following Collection Definition:

[Collection : Test ComVar]

Type : Group

Compute Var : CmpVarColl : String : $Name

Compute : MyAmt : $$CollamtTotal:TestComVarSub:$OpeningBalance

[Collection : Test ComVar Sub]

Type : Ledger

Child Of : ##CmpVarColl

Fetch : Name, OpeningBalance

The sequence of evaluation is as follows:

  1. The ‘Type‘ attribute is evaluated, and the objects of the specified type are identified.
  2. Compute Var is evaluated and the name of the first object, i.e., the Group name is set as a value of the variable ‘CmpVarColl’.
  3. For this selected group, the method MyAmt is evaluated. This gives the total amount of all the ledgers belonging to the group in the variable ‘CmpVarColl’.
  4. Steps 2 and 3 are repeated for each group in the collection ‘Test ComVar’.
  5. After computing the value of the method MyAmt for each group, the collection is populated with the objects.

The variable ‘CmpVarColl’ can also be referred at By, Aggr Compute and Filter attributes of the collection.

Usage of Source Var, Compute Var and Filter Var in Aggregate collection

When these collection attributes are used along with other attributes, the sequence of evaluation is as mentioned earlier. Let us try to understand this with the following ‘Collection’ definition:

[Collection : CFBK Voucher]

Type : Voucher

Filter : IsSalesVT

Compute Var : Src Var : Logical : $$IsSales:$VoucherTypeName

[Collection : Smp Stock Item]

Source Collection : CFBK Voucher

Source Var : Str Var: String : $VoucherNumber “/” $VoucherTypeName

Walk : Inventory Entries

Compute Var : IName: String : if ##StrVar CONTAINS “12” then $StockItemName +

                              else $StockItemName + “-” $$String:##StrVar

By : IName: ##IName

Aggr Compute : BilledQty: SUM: $BilledQty

Filter Var : Fin Obj Var : Logical : $$Number:$BilledQty > 100

Filter : Final Filter

[System : Formula]

IsSalesVT : ##SrcVar

Final Filter : ##FinObjVar

The evaluation process is as follows:

  1. Value of the variable SrcVar is evaluated, and referred in the Filter attribute of the collection ‘CFBK Voucher’.
  2. In the collection ‘Smp Stock Item’, the value of the variable Str Var is evaluated on the first object of source collection ‘CFBK Voucher’.
  3. Then, ‘Walk’ is performed and the Inventory Entry objects are collected.
  4. The value of the variable IName is evaluated. If Source Variable ‘Src Var‘ contains “12”, then the variable IName stores only the StockItemName method, else it stores Stock Item Name + value of the variable Str Var.
  5. The grouping is done on the resultant value of IName variable.
  6. The value of the method $BilledQty is computed.
  7. The variable Fin Obj Var retains a logical value if the method $BilledQty is greater than 100.
  8. Based on the value of Fin Obj Var, filtering is done.
  9. Finally, the collection is populated with the filtered objects.

Release 1.52

Collection Enhancements – Attribute ‘Data Source’ Enhanced

The TDL programmers are aware that data from various data sources can be gathered in a collection. Till the release 1.5, the data sources were Tally database, XML, HTTP, ODBC and DLL. After the multi-line selection capability was introduced, a report or a function could be launched from the current report based on the specified scope. The different scopes that could be specified were Selected lines, Current line, Unselected lines, etc.

Now, the objects can also be gathered from the report or parent report using the Type parameter for the Collection attribute Data Source. This new capability allows the access of specific objects of a report from anywhere; like Functions, Subsequent report or the Current report itself. The Data Source attribute of the collection has been enhanced to support these two data sources, in addition to the existing data sources. The collection can be created directly from the specified data source and can be displayed in a report.

Syntax

Data Source : <Type> : <Identity> [:<Encoding>]

Where,

< Type> specifies the type of da t a source, e. g ., File XML, HTTP XML, Report, Parent Report.

<Identity> can be the file path or the scope keywords. If the type is File XML or HTTPXML,<identity> is the data source file path. If the type is Report or Parent Report then the scope keywords ‘Selected Lines’, ‘UnSelected Lines’, ‘Current Line’, ‘All Lines’, ‘Line’ and ‘Sorting Methods’ are used as the identity.

<Encoding> can be ASCII or UNICODE. It is Optional. The default value is UNICODE. If the da t a source type is Report or Parent report, the encoding format is ignored.

Existing Data Source Types

Example: XML file as data source

[Collection : My XML Coll]

Data Source : File XML : “C:MyFile.xml”

In this code snippet, the type of file is ‘File XML’, as the data source is XML file. The encoding is Unicode by default, as it is not specified.

Example: HTTP as data source

[Collection : My XML Coll]

Data Source : HTTP XML : “http:localhostMyFile.xml” : ASCII

In this code snippet, the type of file is ‘HTTP XML’, as the data source is obtained through HTTP. The encoding of the file ‘MyFile.XML’ is ASCII. While specifying the URL, now the https site can be given in Collection attributes Remote URL and Data Source.

Data Source Types Introduced

Example: Report as data source

[Collection : My Report Coll]

Data Source : Report : Selected Lines

The selected objects from the current report in which the collection is accessed is the data source for the collection ‘MY Report Coll’.

Example: Parent Report as data source

[Collection : My Parent RepColl2]

Data Source : Parent Report : UnSelected Lines

The objects associated with all the unselected lines from the parent report are gathered for the collection ‘My Parent RepColl2’. The objects of the report with the given scope can be accessed from the report and functions which are called from the report.

Enhancements in User Defined Functions

In this release, ‘Dynamic action support’ has been provided for simple actions inside a function and the looping construct Walk Collection has been enhanced. New looping constructs FOR COLLECTION and FOR TOKEN have been introduced as well.

There are scenarios when the collection name is to be obtained from an expression while performing a Walk. WALK COLLECTION has been enhanced to provide this functionality. FOR COLLECTION loop has been introduced to walk the collection for a specific value. FOR TOKEN loop walks on the tokens within a string separated by a specified character.

Attribute ‘Walk Collection’ Enhanced

The Walk Collection attribute has been enhanced to accept Collection Name as an expression and an additional logical parameter. For example, now the collection name can be passed as a parameter to the function while executing it.

Syntax

Walk Collection : <Expression> [:<Rev Flag>]

Where,

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

<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]

Parameter : parmcoll

        |

        |

05 : WALK COLLECTION : ##parmColl : Yes

The collection name is passed as a parameter to the function ‘Test function’ and is walked in reverse order.

The code snippet to call the function ‘Test function’ from a key is as follows:

[Key : DC Call Function]

Key : Enter

Action : CALL : Test Function : ##CollName

The collection name is passed through the variable ‘CollName’.

Dynamic Actions

Prior to Release 1.52, the dynamic action capability was available for global actions. It was possible to specify the Action Keyword and Action parameters as expressions. This allowed the programmer to execute actions based on dynamic evaluation of parameters. The ‘Action’ keyword can as well be evaluated dynamically.

The dynamic action capability is now introduced for simple actions inside a function. Expressions can be used to evaluate the name of the Action as well as Action parameters. The new action with Action keyword has been introduced to achieve this.

Syntax

Action : <Expression> : <Action Parameters>

Where,

<Expression> is any expression evaluating to a simple action name like LOG, DISPLAY, etc.

<Action Parameters> are parameters required by the action passed through an expression.

Example

[Function : ObjFunc]

      |

      |

02 : ACTION : LOG : “$” + ##pObjMethod

Inside a function, a global action can be called using dynamic action capability. In this case, the expression specified in the dynamic action is evaluated in the context of the function, and then the global action is executed.

The context of function elements like Variables, Objects, etc., can be used while calling a global action dynamically. For example, the variable name or methods of an object can be passed as a parameter while executing the dynamic action.

Example

[Function : Dynamic Action Within Function]

Variable : DA Logical : Logical

       |

       |

40 : SET : DA Logical : Yes

50 : ACTION : Display : if ##DALogical then “Trial Balance” else “Balance Sheet”

In function ‘Dynamic Action Within Function’, first, the expression is evaluated and then based on the value, the report ‘Trial Balance’ is displayed.

 

‘https’ URL support in Tally

Https client capability has been enhanced in Tally to exchange data with other applications securely. Https sites can be used for ftp upload, post request and receiving the data in collection. Now, data can be uploaded to https site, or request to the https site can be sent, using the action HTTP Post. The URL for the https site can be specified while gathering data in a collection.

Example: Upload

In the upload configuration screen, the URL for the https site can be given as shown:

Figure_1._Upload_Configuration_Screen_(1.52).jpg

Example: Action HTTP Post

[Button : PostButton]

Key : Ctrl+K

Action : HTTP Post : @@MyURL : ASCII : HTTP Post ReqRep :HTTP Post Response Report1 : HTTP Post Response Report

[System : Formula]

MyURL : “https//www.testserver.co.in/CXMLResponse as per tally.php”

Example: In collection

[Collection : https Coll]

Remote URL : “https//www.testserver.co.in/TestXML.xml”

 

Release 1.6

In Collection definition, attributes Keep Source and Collection have been enhanced. The collection attribute ‘Keep Source’ has been enhanced to accept a new value, i.e., Keep Source: (). to make the data available at Primary Object, which can be a Menu, Report or Function.

The Collection definition can now use a new capability to loop one collection for each object of another collection. This functionality has been introduced by enhancing the ‘Collection’ attribute.

‘Collection’ Attribute Value – Keep Source: ().

Attribute ‘Keep Source’ accepts various values used to specify the In memory source retention of the collection. Specifications like ., ..,Yes , No, etc., were used earlier for this. The source collection was retained along with data object associated with the User Interface object in the current User Interface object hierarchy, as per specification. The newly introduced specification “().” is used to keep the source collection with the parent UI object, which is either Report or Function.

The dotted notation depends on the interface object hierarchy. If there are recursive explodes in a report, then it is difficult to use the dotted notation when the data is to be kept at Report or Function level. The new value Keep Source : (). has been introduced to overcome this issue.

Keep Source : (). signifies that the data of collection has to be kept available at the primary level, which can be Menu or Report or Function. So, now ‘Keep Source’ attribute accepts the following values:

  • Keep Source: NO –The source collection data is not kept in memory.
  • Keep Source: YES – The source collection data is kept in the object associated with the current interface object.
  • Keep Source: (). – The source collection data is kept in the data object associated with the primary owner interface object, i.e., Menu or Function or Report.
  • Keep Source: …. – Each dot in the notation is used to traverse upward in the owner chain by the number of dots specified, till a primary interface object is found.

In scenarios where the data is to be kept at the Primary interface object, the application developer can directly use Keep Source : (). without worrying about the interface object hierarchy.

Example

|

[Part : TB Report KeepSrc Part]

Lines : TB Report KeepSrc Title, TB Report KeepSrc Details

Bottom Lines : TB Report KeepSrc Total

Repeat : TB Report KeepSrc Details:TB Report KeepSrc GroupsPri

The line repeats on collection ‘TB Report KeepSrc GroupsPri’, which displays all the groups belonging to Primary group. The line then explodes to display the subgroups.

[Line : TB Report KeepSrc Details]

Explode : TB Report KeepSrc Group Explosion : $$KeyExplode

In the part ‘TB Report KeepSrc Group Explosion’, if the object is Group, then once again the line explodes to display the sub-groups or the ledgers belonging to the current subgroup.

[Part : TB Report KeepSrc Group Explosion]

Lines : TB Report KeepSrc Details Explosion

Repeat : TB Report KeepSrc Details Explosion:TB Report KeepSrc SubGrp

Scroll : Vertical

[Line : TB Report KeepSrc Details Explosion]

Explode : TB Report KeepSrc Group Explosion : $$KeyExplode

Explode : TB Report KeepSrc Ledger Explosion : $$KeyExplode

Indent : If $$IsGroup Then 2*$$ExplodeLevel Else 3 * $$ExplodeLevel

Local : Field : Default : Delete: Border

The part ‘TB Report KeepSrc Group Explosion’ is exploded recursively. So, it Is useful to keep the data at the primary interface object level.

The collections ‘TB Report KeepSrc GroupsPri’ and ‘TB Report KeepSrc SubGrp’ both use the same source collection ‘TB Report KeepSrcGroups’. The collections are defined as follows:

[Collection : TB Report KeepSrcGroups]

Type : Group

Fetch : Name, Parent, Closing Balance

[Collection : TB Report KeepSrc GroupsPri]

Source Collection : TB Report KeepSrc Groups

Filter : PrimaryGrp

By : Name: $Name

Compute : Parent: $Parent

Keep Source : ().

[Collection : TB Report KeepSrc SubGrp]

Source Collection : TB Report KeepSrc Groups

Filter : SubGrp

By : Name : $Name

Compute : Parent : $Parent

Keep Source : ().

[Collection : TB Report KeepSrc Ledgers]

Type : Ledger

Child Of : #MyGroupName1

Filter : Zero Filter

Fetch : Name ,Parent, Closing Balance

[System : Formula]

Zero Filter : $ClosingBalance>0 AND NOT $$IsLedgerProfit

PrimaryGrp : $$IsSysNameEqual:Primary:$Parent

SubGrp : $Parent = #MyGroupName1

Attribute ‘Collection’ change – Loop Collection

The data processing artefact of TDL, i.e., ‘Collection’, provides extensive capabilities to gather data from various data sources. The TDL application developers are aware that the source can be a report, parent report, collection/s and external data sources like Excel, XML, and so on.

It is possible to gather data from multiple collections in one collection. Till this enhancement, the collection didn’t directly support the capability to gather data dynamically from multiple collections based on the object context of another collection. The functionality was achieved using ‘Filter’ and ‘Child Of’ attributes of the ‘Collection’ definition. Programming using these was tedious and time-consuming and increased the code complexity as well, impacted the performance. The new enhancement has simplified the TDL code development.

The ‘Collection’ attribute of ‘Collection’ definition has been enhanced to repeat and combine the same collection based on the number and context of objects in another collection. The present syntax of ‘Collection’ attribute allows us to combine and collate the data from all the collections specified as a comma-separated list, provided the number, order and data type of methods are the same in each of the collection specified in the list.

Existing Syntax

The existing syntax of ‘Collection’ attribute is as below:

Syntax

[Collection : <Collection Name>]

Collection : <List of Data Collection>

Where,

<Collection Name> is the name of the collection.

<List of Data Collection> is the comma-separated list of data collections.

Example

[Collection : GroupLedColl]

Collection : TestGroups, TestLedgers

In this example, the Collection ‘GroupLedColl’ will contain the union of objects from both the collections ‘TestGroups’ and ‘TestLedgers’.

The Collection attribute has been enhanced to dynamically gather the data collections in the context of each object of another collection. It now accepts two additional optional parameters.

New Enhanced Syntax

The new enhanced syntax of the ‘Collection’ attribute is as given below:

Syntax

[Collection : <Collection Name>]

Collection : <List of Data Collection>[:<Loop Coll Name>[:+<Condition for Loop Coll]]

Where,

<Collection Name> is the name of the collection.

<List of Data Collection> is the comma-separated list of data collections.

<Loop Coll Name> is the name of the loop collection, and is optional.

<Condition for Loop Coll> is optional. The condition is evaluated on each object of the Loop Collection.

The attribute ‘Collection’ has been now enhanced to repeat a collection over objects of another collection. Optionally, a condition can be specified. This condition applies to the collection on which looping is desired. The collection on which the repetition is done is referred to as Loop Collection. The collection names in the list of collections are referred to as Data Collections. The data is populated in the resultant collection from the list of data collections.

Each data collection is gathered once for each object in the loop collection. If there are n objects in the loop collection, the data collections are gathered n times in the context of each object in the loop collection. In the resultant collection, the objects are delivered as TDL Objects. This makes it mandatory to fetch the required methods in the Data Collection.

Example

[Collection : VchOfMultipleLedgers]

Collection : VchOfLedger : LedgerListColl : ($Parent starting with “Sundry”)

[Collection : VchOfLedger]

Type : Vouchers : Ledger

Child of : $Name

Fetch : VoucherNumber, Date, Amount

[Collection : LedgerListColl]

 Type : Ledger

The collection VchofLedger is the data collection. It is mandatory to fetch the required methods ‘Voucher Number’, ‘Data’ and ‘Amount’, in order for them to be available in the resultant collection.

It can be observed that the method $name of loop collection LedgerListColl is used in ChildOf attribute directly. This is because while the evaluation of ‘ChildOf’ attribute, the loop collection object context is available. If we are referring to the methods of the loop collection directly in the attributes SOURCE VAR, COMPUTE VAR, COMPUTE, AGGR COMPUTE, FILTER and FILTER

VAR, we cannot do so. This is because while evaluating these attributes, the loop collection object context is not available. In order to make these methods available in the Data collection, the following function has been introduced.

New Function

Function – $$LoopCollObj

The function $$LoopCollObj has been introduced to refer to any method of the Loop Collection objects in the Data Collection. The Data Collection can use this function for the evaluation of expressions.

Syntax

$$LoopCollObj : <Method name from Loop Coll Obj>

Where,

<Method name from Loop Coll Obj> is name of method from the object of the loop collection.

Example

A collection is created to gather all the vouchers of all the loaded companies as follows:

[Collection : Vouchers of Multiple Companies]

Collection : VchCollection : Company Collection

Sort : Default : $Date, $LedgerName

Objects in collection ‘Vouchers of Multiple Companies’ are sorted based on date and ledger name

[Collection : VchCollection]

Type : Voucher

Fetch : Date, Vouchernumber, VoucherTypeName, Amount, MasterID , LedgerName

Compute : OwnerCompany : $$LoopCollObj:$Name

Let us examine the Data Collection definition “VchCollection”. When the attribute ‘Compute’ is evaluated, the Loop collection object context is not available here. So, to refer to the Company Name, the function $$LoopCollObj is mandatory.

[Collection : Company Collection]

Type : Company

Fetch : Name

Use Case

Scenario : A Stock Summary Report for Group Company.

The consolidated stock summary report of all the members of a group company. The member companies of the group company can have different Unit of Measures and Currency.

Solution : The report displays stock item name, unit of measurement and combined closing balance of all members of the group company, assuming that the base currency is same. At part level, the line is repeated on the aggregate/summary collection GrpCmpSSRepeatColl as follows:

[Part : GrpCmpSSPart]

Line : GrpCmpSSLineTitle, GrpCmpSSLineDetails

Repeat : GrpCmpSSLineDetails : GrpCmpSSRepeatColl

Scroll : Vertical

Common Border : Yes

The summary collection is defined as follows:

[Collection : GrpCmpSSRepeatColl]

Source Collection : GrpCmpSSLoopCollection By : StkName : $Name

By : UOM : $BaseUnits

Aggr Compute : ClBal : SUM : $ClosingBalance Sort : Default : $StkName, $UOM

Since the member companies may have different UOM, the grouping is done on the same. If the UOMs are same then the ‘ClosingBalance’ is aggregated, else the Items are displayed as separate line items with respective UOMs.

Note: We cannot perform aggregation directly on the resultant collection (which is created using data and loop collection). If required to do so, the same has to be used as a source collection for the aggregate/summary collection.

The source collection ‘GrpCmpSSLoopCollection’ is defined as follows:

[Collection : GrpCmpSSLoopCollection]

Collection : StkColl : GrpCmpColl

The data collection ‘StkColl’ is gathered for each object of the loop collection ‘GrpCmpColl’. The collections are defined as follows:

;; Data Collection

[Collection : StkC o ll]

Type : Stock Item

Fetch : Name, BaseUnits, ClosingBalance

;;Loop Collection

[Collection : GrpCmpColl]

Type : Member List : Company

Child Of : ##SVCurrentCompany

Assume that currently a group company Grp ABC is loaded with three member companies A, B and C. The Stock Items details in each company are shown in the following table:

Company Name

Stock Item

Unit of Measure

C losing Balance

Company A

Item 1

Nos

500

Item 2

Kg

500

Item 3

Nos

500

Company B

Item 1

Nos

400

Item 3

Nos

800

Company C

Item 1

Nos

300

Item 2

Nos

700

Item 3

Nos

500

The following table demonstrates the objects in each collection:

Objects in collection GrpCmpColl

Objects in collection Stk­Coll

Objects in collection GrpCmpSSLoopCollection

Objects in collection GrpCmpSSRepeat­Coll

3 – A, B, C

All stock items of First member company i.e. A

All stock items of all member companies

Sum of Closing balance is evaluated by grouping Stock Item name and Unit Of Measure

 

Item 1 – 500

Item 2 – 500

Item 3 – 500

Item 1 – 500

Item 2 – 500

Item 3 – 500

Item 1 – 400

Item 3 – 800

Item 1 – 300

Item 2 – 700

Item 3 – 500

Item 1 – 1200 Nos Item 2 – 500 Kg

Item 2 – 700 Nos

Item 3 – 1800 Nos

Multi-Column behaviour with Multi-Company data

Various reports can be generated in Tally.ERP 9 relevant to the user’s business requirement. All the reports are generated in the context of SVCurrentCompany, SVFromDate and SVToDate. In the multi-column report, the collection is gathered for each column of the report. The code complexity has been reduced with the introduction of Loop Collection in TDL language.

When the Data collections are gathered in the context of Company as Loop collection; in the resultant collection, the object context is forcefully changed to current/owner/loaded company and the report is displayed.

Consider the following example to understand the Loop Collection behaviour of multi-column report for multiple companies. Assume that there are three companies A, B and C. Company A has ledgers L1 and L2, B has ledgers L3 and L4, while C has ledgers L5 and L6. The currently loaded company is A and the loop collection “My Company” has objects as A, B and C.

The collection is constructed as follows:

[Collection : LedCmpColl]

Collection : MyLed : My Company

[Collection : My Led]

Type : Ledger

Fetch : $Name, $ClosingBalance

[Collection : MyCompany]

Type : Company

When the multi-column report is displayed for the first time, all the ledgers are associated with the current company A forcefully, and their closing balance is displayed in the column as follows:

Ledger Name

A ClosingBalance

L1

100

L2

200

L3

300

L4

400

L5

500

L6

600

When an additional column is added for company B, the report is displayed as follows:

Ledger Name

A ClosingBalance

B ClosingBalance

L1

100

 

L2

200

 

L3

 

300

L4

 

400

L5

   

L6

   

For this column, the collection is gathered with the current company B in context.

As a result, the closing balances of ledgers belonging to companies A and B are available and are displayed in their respective company columns. As the company C context is not available, the closing balances of ledgers L5 and L6 are not displayed at all.

When the column for company C is added, the closing balances of ledgers L1, L2, L3, L4, L5 and L6 are displayed in the respective company columns as follows:

Ledger Name

A ClosingBalance

B ClosingBalance

C ClosingBalance

L1

100

   

L2

200

   

L3

 

300

 

L4

 

400

 

L5

   

500

L6

   

600

Points for consideration during usage

The collection attribute ‘Search Key’ can be specified only in the Summary Collection and not in the Data/Loop/Source Collection

The Summary Collection using source collection created using loop collection concept can only be referred from elsewhere using the function $$CollectionFieldByKey. The other functions like $$CollectionField, $$CollAmtTotal are at present not supported.

If the companies have different currencies and aggregation is done, then the resultant val- ues for the masters would not be displayed.

In case the stock items of the companies have different units of measures, and aggregation is done on them, the stock item name having different UOM would not be displayed at all in the list.

Changes pertaining to Parameter Collection

The internal collection “Parameter Collection” was used earlier in TDL at two places:

When objects in the specified scope needed to be referred from a Report or Child Report.

XML Data response, after triggering the action HTTP Post, which is used either in Success/ Error Report displayed for the user.

As the ‘Data Source’ attribute of the Collection has been enhanced to populate it using the objects in the specified scope from a current or Parent Report, the concept of Parameter Collection in this respect does not carry relevance any more. We need to use Data Source capability, instead of Parameter Collection in codes to be written in future.

For the existing TDLs which are already using Parameter Collection, a collection has been introduced in Default TDL, which uses Data Source with scope as selected. The TDLs which are using Parameter Collection for different scopes need to make desired changes in the code.

In the context of HTTP Post, the usage remains as it is.

 

Release 1.61

Narrowing Table Search

The current search capability on a Table allows the user to highlight a particular set of items based on the search text entered in the field. The string is searched from the beginning of the item names in the list and applies to first column only.

In a scenario where there are a large number of items in the list/table, the user can’t remember the starting characters of the item names. He may remember only a part of the item name which he requires to search. Even after the relevant items are explored and highlighted, all the items are displayed, which is not needed.

The latest enhancement in TDL allows the user to search a text from any part of the item name which appears in the list. The table keeps on narrowing down and displaying only those items which fulfil the search criteria. It is also possible now to specify whether the search criteria should apply to the first column or all columns of the table.

Field Attribute – Table Search

A new field attribute called ‘Table Search’ has been introduced to achieve the above capability.

Syntax

[Field : <Field name>]

Table Search : <Enable reducing table search> : <Apply search to all columns>

Where,

<Enable reducing table search> is a logical value (YES/NO), to specify whether we want to enable the reducing of search or not.

<Apply search to all columns> is a logical value (YES/NO), to specify whether the search criteria should apply to all columns of the table or not.

Note: We can also use expressions in attribute values which evaluate to logical values.

Function – $$TableNumItems

A new function $$TableNumItems is introduced, which returns the number of items in the list/table.

Example:

[Collection : RTS Ledger]

Type : Ledger

Format : $Name

Format : $Parent

Format : $ClosingBalance

[Field : Reducing Table Search GT 100]

Use : Name Field

Table : RTSLedger

Show Table : Always

Table Search : $$TableNumItems > 100 : Yes

In this example, the field ‘Reducing Table Search GT 100’ is displaying the table ‘RTS Ledger’, which has three columns’ Name’,’ Parent’, and ‘Closing Balance’. The attribute ‘Table Search’ evaluates the first value to YES, only when the number of items in the table exceeds 100, i.e., reducing search is enabled if the specified condition is satisfied. The second attribute value is set to YES, i.e., the search criteria will apply to all columns in the table.

Functionality Achieved

Using the above capability, it has been possible to deliver the functionality of applying the above search technique to all the tables available in the default product. This will, of course, depends on the configuration settings selected by the user.

Use Cases

  1. Company search based on the Company ID.
  2. Ledger search based on parent Group name available in other columns in a table.
  3. While selecting the Stock item Name in a voucher, the user can now narrow the search, based on the UOM and make his selection of item based on the closing balance available for that UOM.

Using External Plug-Ins as a Datasource for Collections

A Dynamic Link Library takes the idea of an ordinary library one step further. The idea with Astatic library is for a set of functions to be collected together so that a number of different programs could use them. This means that the programmers only have to write code to do a particular task once, and then, they can use the same function in lots of other programs that do similar things.

A Dynamic Link Library is similar to a program, but instead of being run by the user to do one thing, it has a lot of functions “exported”, so that other programs can call them. There are several advantages of this. First, since there is only one copy of the DLL on any computer used by all the applications that need the library code, each application can be smaller, thus saving disk space. Also, if there is a bug in the DLL, a new DLL can be created and the bug will be fixed in all the programs that use the DLL just by replacing the old DLL file. DLLs can also be loaded dynamically by the program itself, allowing the program to install extra functions without being recompiled.

What is DLL?

A Dynamic Link Library (DLL) is a library that can be called from any other executable code, i.e., either from an application or from another DLL. It can be shared by several applications running under Windows. A DLL can contain any number of routines and variables.

Dynamic Link Library has the following advantages:

  • Saves memory and reduces swapping: Many processes can use a single DLL simultaneously, sharing a single copy of the DLL in memory. In contrast, Windows must load a copy of the library code into memory for each application that is built with a static link library.
  • Saves disk space: Many applications can share a single copy of the DLL on disk. In contrast, each application built with Astatic link library has the library code linked into its executable image as a separate copy.
  • Upgrades to the DLL are easier: When the functions in a DLL change, the applications that use them do not need to be recompiled or re-linked, as long as the function arguments and return values do not change. In contrast, statically linked object code requires that the application be relinked when the functions change.

A potential disadvantage of using DLLs is that the application is not self-contained; it depends on the existence of a separate DLL module.

Differences between Applications and DLLs

Even though DLLs and applications are both executable program modules, they differ in several ways. To the end user, the most obvious difference is that DLLs are not programs that can be directly executed. From the system’s point of view, there are two fundamental differences between applications and DLLs:

  • An application can have multiple instances of itself running in the system simultaneously, whereas a DLL can have only one instance.
  • An application can own things such as a stack, Global memory, File handles, and a message queue, but a DLL cannot.

Types of DLL

When a DLL is loaded in an application, there are two methods of linking, i.e., Load-time Dynamic Linking and Run-time Dynamic Linking. Static Linking happens during program development time, whereas dynamic linking happens at run time.

  • Load time Dynamic Linking /Static Linking

In Load-time Dynamic Linking, an application makes explicit calls to exported DLL functions like local functions. To use load-time dynamic linking, a header(.h) file and an import library (.lib) file are provided while compiling and linking the application. Thus, the linker will provide the system with the information required to load the DLL and resolve the exported DLL function locations at load time.

  • Run-time Dynamic Linking /Dynamic Linking

Dynamic linking implies the process that Windows uses to link a function call of one module to the actual function in DLL. In Run-time Dynamic Linking, an application calls either the function LoadLibrary or the function LoadLibraryEx to load the DLL at run time. After the DLL is successfully loaded, the function GetProcAddress can be used to obtain the address of the exported DLL function that has to be called. In the case of run-time dynamic linking, an import library file is not required.

Please note that Tally does not support Static Linking; only Dynamic Linking is possible.

DLL Approach in Tally

As discussed before, Dynamic Link Library (DLL) is a file that can contain many functions. We can compare it with the library functions provided with many programming languages like C, C++. In Tally, there is provision to access the external functions by uploading the DLLs. In general, the DLLs can be generated using VC++, VB, .Net framework, etc., and can be invoked from TDL. Hence, using TDL, the functions of DLL can be invoked to perform the necessary operations.

Why it is required in Tally?

In Tally, all functions are not required for all the customers. Only generalized features are included to keep the functionality of Tally simple. But, for some customers, basic Tally may not cater to the need. For that, we may need to extend the functionality of Tally by writing programs in TDL. TDL is designed to handle the functions in-built in Tally. For the functions that are not available in Tally, we use DLL, wherein we can include many functions and use it in Tally by calling those functions.

How to use DLL in Tally?

Loading the DLL’s

  1. Copy the DLL file to Tally folder, say C:\Tally.ERP9.

DLL points to the external functions that are to be loaded during the startup of the Tally application. Tally loads DLLs from the source to the memory, and DLL functions are available with Tally for usage.

OR

  1. Register the DLL file using a setup program or Command prompt.

In TDL, DLL can be invoked by using CallDLLFunction and DLLCollection.

Note: The CallDLLFunction is a platform function which was already available earlier, and is NOT a part of Collection Enhancements. It has been discussed here as additional information. DLL Collection is an enhancement in this Release, which has been emphasized in the subsequent sections.

Function – $$CallDLLFunction

The internal Function $$CallDLLFunction can be used to call an external DLL containing multiple Functions

Example

If a DLL “TestDll” contains two functions FuncA and FuncB, where

  • FuncA takes one parameter of ‘String’ Data Type and returns a string
  • FuncB takes a parameter of ‘String’ Data Type and Executes the Function. It only returns the status of the function execution (boolean value)

The syntax of invoking the DLL from TDL will be as follows:

Syntax

[Field : <Field Name>]

Set As : $$CallDLLFunction: <DLLName>:<FunctionName> : <Param 1> : <Param 2> ….

Where,

<DLLName> is the name of the DLL.

<Function Name> is the name of the Function.

<Param1> and <Param2>…. are the Parameters for the function.

The value returned from the function will be available in the field.

To call FuncA

[Field : Field2]

Use : NameField

;; Assuming Field1 is of Type ‘String’

Set As : $$CallDllFunction:TestDll:FuncA:#Field1

To call FuncB

[Key : Key1]

Key : Ctrl+A

Action : Set : VarStatus : $$CallDllFunction:TestDll:FuncB:#Field1

This key can be associated with a Form or a Menu. The function FuncB in TestDll can be used to return the status of the execution, i.e., Success/Failure (1/0). This value can be obtained in a variable in TDL and used to display the appropriate message to the user.

$$CallDllFunction can be used to call any function which returns single values. If the function returns an array of values, then it is advisable to use $$DLLCollection.

Let us have an overview of the usage of DLL Collection.

DLL Collection, its Attributes and Usage

Tally now provides a TDL interface to obtain data sets in Collection from external Plug-Ins. These Plug-Ins are written as DLL’s which can be used to fetch external data (i.e., from the Internet, external Database, etc.). These DLL’s should return a valid XML which can be easily mapped into TDL Collection. In other words, TDL developer can provide a simple string value and/or XML to the

DLL function. The DLL gives XML data as an output. Collection takes this data and converts it into objects and object methods, which can be accessed in TDL like other objects.

DLL collection will be very useful in the following scenarios:

  1. To display stock quotes from the internet
  2. To get data from different formats like CSV, HTML
  3. External device interfaces
  4. RFID Barcode scanner
  5. Petrol Pump device interface
  6. Footfall count
  7. External application interfaces
  8. GAS distributor application
  9. To get attendance details in Pay Roll through swipe

In DLL collection, support is being provided for Plug-Ins and ActiveX-Plug-Ins.

  • Plug-Ins: DLLs created using C++ or VC++. These DLLs need not be registered separately.
  • ActiveX Plug-Ins: DLLs created by using VB6, VB.Net, C#.Net, etc. These DLLs have to be registered. The registration process has been explained in detail later.

At present, the ‘Collection’ definition allows working with a C++ DLL, VB DLL, .Net DLL, etc., which has a function defined by the name TDLCollection (The function has to be created by this name ONLY). This function delivers an XML which is available as objects in the Collection.

Attributes of DLL Collection

The attributes of DLL Collection can be categorized as follows:

  • For specifying the source
    • Datasource
  • For sending inputs to DLL
    • Input Parameter
    • Input XML
  • For validating/formatting the data received from DLL
    • Break On
    • XSLT
  • For selective conversion of XML
    • XML Object
    • XML Object Path

Attribute – Datasource

The attribute Datasource is used to set the source of the collection. By using this attribute, the actual DLL is invoked to TDL for further process.

Syntax

[Collection : <Collection Name>]

Datasource : <Type> : <Identity> [:<Encoding>]

Where,

<Type> specifies the type of Datasource, i.e., File XML, HTTP XML, Report, Parent Report, Variable, PlugIn XML, AxPlugIn XML.

<Identity> can be the file path/source of DLL.

<Encoding> can be ASCII or UNICODE. It’s applicable only for File XML and HTTP XML.

For Plug-in DLL

Syntax

Datasource : PlugIn XML : <Path to dll>

Where,

<Type> is ‘PlugIn XML’.

<Identity> identifies the source of DLL, i.e., the path of DLL.

Example

Datasource : PlugIn XML : mydll.dll

For ActiveX DLL

Syntax

Datasource : AxPlugin XML : <Project Name>.<Class Name>

Where,

<Type> is “AxPlugin XML”.

<Identity> identifies the source of DLL, i.e., <Project Name>.<Class Name>

Example

Datasource : AxPlugin XML : DLLEg1.MyClass

For C#.Net, which has the concept of namespaces, the source identifier is “Namespace.ClassName”

Syntax

Datasource : AxPlugin XML : <namespace>.<classname>

Example

Datasource : AxPlugin XML : testcsharpdll.Class1

Attribute – Input Parameter

The attribute Input Parameter is used to pass a single string value to the DLL function.

Syntax

Input Parameter : <Expression>

Where,

<Expression> returns a string value, which is used to pass to the DLL function.

Example

Input Parameter : Test string

In this example, ‘Test String’ is the string value, which is used to pass to the specified DLL.

Attribute – Input XML

The attribute Input XML is used to pass the XML format data to the DLL function.

Syntax

Input XML : <Post Request Report Name>, <Pre-Request Report Name>

Where,

<Post Request Report Name> is the name of the TDL report. It is responsible for generating XML data, which is passed to the DLL function as input.

<Pre-Request Report Name> is optional. It is used to get any input from the end-user.

Example

Input XML : DLLRequestReport

Attribute – Break On

The attribute Break On is used to validate the XML data received from the DLL function. If the XML data contains the string specified in this attribute which is referred to an error string, then the validation fails and the collection will not be constructed.

Syntax

Break On : <String Expression1>, <String Expression 2> …..

Where,

<String Expression 1>, <String Expression 2>… gives the string values which act as error string to validate the XML data.

Example

Break On : My Error String

If XML data received from DLL function contains “My Error String”, then the collection will not be constructed, just as in XML collection.

Attribute – XSLT

The attribute XSLT is used to transform the XML document received from DLL function to another XML document. It will be applied before constructing the collection. This attribute is same like in XML collection.

Syntax

XSLT : <XSLT Filename>

Where,

<XSLT File name> is the name of the XSLT file name.

Example

XSLT : “C:\Myfile.xslt”

Attribute – XML Object

The attribute XML Object is used to represent the structure of DLL collection object to which the obtained data is mapped. It is an optional attribute and it is same as in XML collection.

Syntax

XML Object : <Object Name>

Attribute – XML Object Path

The attribute XML Object Path is used to set the starting XML node from where the object construction starts. If only a specific data fragment is required, it can be obtained using the collection attribute ‘XML Object Path’. This attribute is same like in XML collection.

Syntax

XML Object Path : <StartNode> : <StartNodePosition> : <Path to start node>

Where,

<StartNode> gives the name of the starting XML Node.

<StartNodePosition> gives the position of the starting XML Node.

<Path to Start Node> gives the path of the starting XML Node.

<P ath to start node> can be extended as follows:

<root node> : <child node> : <start position> : <child node> : <start position>:….

Example

XML Object Path : MyNode : 1 : Root

Note:

In DLL collection, all the attributes except Datasource are optional.

All error messages related to DLL collection are stored in dllcollection.log file.

Usage of DLL Collection attributes

The following examples demonstrate the usage of DLL collection attributes:

Example: Datasource – AxPlugIn Xml

XML data received from the ActiveXDLL “testdll.class1” is to be displayed in a Report. For this, a DLL XML collection is constructed and only a fragment of XML data is to be populated in the collection. Consider the following input XML fragment:

<EmpCollection>

<Emp>

<Name>Emp1 </Name>

<EmpId>101 </EmpId>

<Designation>Manager </Designation>

</Emp>

<Emp>

<Name>Emp2 </Name>

<EmpId>102 </EmpId>

<Designation>Senior Manager </Designation>

</Emp>

</EmpCollection>

Note: The same XML has been used to explain all further examples.

The TDL code snippet for generating the report is as follows:

[Part : DLLColl Part]

Lines : DLL CollLine1, DLLCollLine2

Repeat : DLL Coll Line2 : My DLL Collection

Scroll : Vertical

[Line : DLL Coll Line1]

Fields : DLL Coll Field1

[Field : DLL Coll Field1]

Set As : “Retrive fragment EMP List from XML data”

[Line : DLLColl Line2]

Fields : SLNo, EmpName, EmpID, Emp Desig

[Field : SLNo]

Use : Name Field

Set As : $$Line

[Field : Emp Name]

Use : Name Field

Set As : $Name

[Field : Emp ID]

Use : Name Field

Set As : $EmpId

[Field : Emp Desig]

Use    : Name Field

Set As : $Designation

[Collection : My DLL Collection]

Datasource : AxPlugin XML : testdll.class1

XML Object Path : Emp : 1 : EmpCollection

In this example, the attribute Datasource is used to set the source of DLL, i.e., the class name from the DLL “testdll.class1”. The attribute XMLObjectPath retrieves the XML fragment starting from the first <EMP> tag under the XML tag <EmpCollection> from the specified DLL. The XML data thus fetched from the DLL is then displayed in a Report. Here, Emp is the name of the starting XML Node, 1 is the position of the starting XML Node and EmpCollection is the path of the starting XML node

Note: In this case, DLL has to be registered. The registration process is explained in detail in the section “Implementation and Deployment of DLL”.

Example: Data source – PlugIn XML

In the previous example , ActiveX Plugin DLL was used. Now , instead of ‘ ActiveX Plugin’ DLL , the data source is simple PlugIn DLL. The source keyword PluginXML is used in the attribute Datasource . In this case, only the DLL name must be specified.

The collection definition is as follows:

[Collection : My DLL Collection]

Datasource : PluginXML : testdll.dll

XML Object Path : Emp : 1 : Emp Collection

Note: The only difference from the previous example is that, here the DLL registration is not required. What’s just required is to Copy the DLL to Tally.ERP 9 folder and execute the program.

Example: Attribute – Input XML

There are scenarios where the DLL expects some input as in XML fragment before sending the required XML output. The DLL XML collection attribute InputXML allows sending the Input XML to the source DLL in XML format. As explained earlier, the attribute InputXML accepts two parameters, i.e., PostReqReport and PreReqReport.

The collection is defined as follows:

[Collection : Input XMLCollection]

Datasource : AxPluginXML : TestDLL.Class1

XML Object Path : Emp : 1 : EmpCollection

Input XML : PostReqRep , PreReqRep

In this example, the report ‘PreReqRep’ accepts the user input and the report ‘PostReqRep’ generates the input XML, which is sent to the DLL. The response received from the DLL is populated in the collection InputXMLCollection .

The reports ‘PostReqRep’ and ‘PreReqRep’ are defined as follows:

[Report : PostReqRep]

Form : PostReqReport

Export : Yes

[Form : PostReqReport]

|

|

[Line : Post ReqReport]

Fields : Short Name Field , PostReqReport Name, Name Field, +

PostReqRepID, Simple Field, PostReqRepDesig

Local : Field : Short Name Field : Set As : “Name : ”

Local : Field : Name Field : Set As : “Emp ID : ”

Local : Field : Simple Field : Set As : “Designation : ”

[Field : Post ReqReportName]

Set As : ##PreReqNameVar

XMLTag : “ Name”

|

|

;; Pre Request Report accepting User Inputs

[Report : PreReqRep]

Form : Pre ReqReport

|

|

[Part : PreReqReport ]

Lines : PreReqReport Name, PreReqReportID, PreReqReportDesig

[Line : PreReqReport Name]

Fields : Short Name Field, PreReqReport Name

Local : Field : Short Name Field : Info : “Enter Employee Name:”

[Field : Pre ReqReport Name]

Use : Name Field

Set As : “ Enter your Name”

Width : 50

Modifies : DLLPreReqNameVar

|

|

[System : Variable]

DLLPreReqNameVar : “”

Example: Attribute – InputParameter

In scenarios where only one value is to be sent as an input to the source DLL, the attribute Input Parameter can be used as follows:

[Collection : InpParameterColl]

Datasource : AxPlugin XML : TestDLL.Class1 XML Object Path : result

Input Parameter : ##InputParameterVar

The value of the variable InputParameterVar is sent as an input to the DLL “TestDLL.Class1”. The response received is available in the collection InpParameterColl .

Example: Attribute – BreakOn

The following code snippet validates the XML received from the DLL “tesdll.class1”.

[Collection : DLL XML GetCollObjPath]

Datasource : AxPlugin XML : testdll.class1

XML Object Path : Emp : 1 : EmpCollection

Breakon : Manager

Break On attribute is used to check whether the error string “Manager” exists in the output xml. If the error string exists, the XML is considered as an invalid XML and an empty collection is created. Otherwise, the XML is considered as valid and the collection is populated from the received XML fragment.

Signature of function ‘TDL Collection’ in the DLL

The DLL created using any programming language, when called from Tally, must contain a main function named as TDL Collection. The signature of this function is specific to each programming language.

The detailed signature of the function TDL Collection in different languages is as follows:

For VC++ DLL

Consider the following example for VC++ DLL to generate an XML fragment for Employee details. This DLL accepts the input from the TDL, and returns an XML file as output from DLL. Using this XML fragment, it constructs a collection.

extern “C” H RESULT declspec(dll export)

TDLCollection (const wchar_t * pInputParam,

const wchar_t * pInputXML,

wchar_t ** pXMLCollection,

long * pCollection Size)

{

*pCollection Size = 1024;

if ( (*pXMLCollection = (wchar_t *)

( CoTaskMemAlloc (*pCollectionSize * sizeof (wchar_t))))== NULL)

{

return – 1 ;

}

wcscpy (*pXMLCollection, L “<EmpCollection>

<Emp>

<Name>Emp1</Name>

<EmpId>101</EmpId>

<Designation>Manager</Designation>

</Emp>

<Emp>

<Name>Emp2</Name>

<EmpId>102</EmpId>

<Designation>Senior Manager</Designation>

</Emp>

</EmpCollection> “

);

In this example, there are different inputs given as parameters to the function TDLCollection.

  • pInputParam : It is an input value to the DLL and is a string value of collection attribute “Input Parameter”. The TDL passes an input parameter to the DLL.
  • pInputXML : It is an input to DLL and XML data constructed using collection attribute “Input Xml”

Output values from TDLCollection function:

pXMLCollection : O/P buffer containing resultant data, based on which, collection is constructed.

pCollectionSize : Number of wide characters, including the terminating NULL character.

For VB 6 DLL

Consider the following example for displaying the values in XML format using VB6. Here also, two parameters are being passed to the TDL Collection.

Public Function TDLCollection(pInputParam As String,pInputXML As String) As String TDLCollection = “<Root>

<Name> Amazing </Name>

<Name> Brilliant</Name>

</Root>”

End Function

In this example, two attributes are being given as parameters to the function TDLCollection.

  • pInputParam : Simple string value to the function, as specified in ‘Collection’ definition, using the attribute “Input Parameter”.
  • pInputXML : Input value in XML format, as specified in the ‘Collection’ definition, using the attribute “Input XML”.

The function must return an output String value in XML format.

For C#.Net DLL

Consider the following example for .Net DLL to convert the input string’s case to upper case. Here, TDLCollection is passed two parameters.

public string TDLCollection (string pInputParam, string pInputXml)

{

string resultxml; // to contain xml to be sent back to Tally

if (!String.IsNullOrEmpty(pInputXml))

{

resultxml = pInputXml.ToUpper();

}

else

{

resultxml = null;

}

return resultxml;

}

In this example, XML data is being passed to the function TDLCollection. All the data present in various tags are converted to upper case.

The Input XML will be as follows:

<Root>

<Name>

<fname>fname 1</fname>

<lname>lname 1</lname>

</Name>

<Name>

<fname>fname 2</fname>

<lname>lname 2</lname>

</Name>

</Root>

The output XML will be as follows:

<Root>

<Name>

<fname>FNAME 1</fname>

<lname>LNAME 1</lname>

</Name>

<Name>

<fname>FNAME 2</fname>

<lname>LNAME 2</lname>

</Name>

</Root>

Inputs to the TDLCollection function:

  • pInputParam: It is an input value to the DLL and is a string value of collection attribute “Input Parameter”. The TDL passes an input parameter to the DLL.
  • pInputXML: It is an input value to the DLL and the XML data constructed using collection attribute “Input Xml”.

For VB.Net DLL

In VB.Net, the signature for the function TDL Collection is as follows:

Public Function TDLCollection (ByVal pInputParam As String, ByVal pInputXML As String) As String

Inputs to the TDLCollection function:

  • pInputParam : It is an input value to the DLL and is a string value of collection attribute “ Input Parameter ”. The TDL passes an input parameter to the DLL.
  • pInputXML : This is an input value to the DLL and the XML data constructed using collection attribute “ Input Xml ”.

Implementation and Deployment of DLL

Once the DLL is ready for deployment, the following should be ensured for implementation of the same:

  • The dependency for the particular DLL needs to be checked, based on the environment in which it is developed. The necessary environment needs to be installed for the same.
  • The DLL needs to be registered in the system where it is to be deployed. This can be done in two ways:
    • Registering the DLL manually.
    • Running the setup program which is created for deployment.

Dependencies with respect to DLLs created using various Environments

  • Created using .NET framework : For DLLs created using VB .NET, C# .NET, etc., we require Microsoft .Net Framework. For example, if the DLL is created using Visual Studio 2005, then Microsoft .Net Framework 2.0 or above should be installed on the system.
  • Created using Visual Basic 6.0 : For DLLs created using VB 6, we require service pack 6 to be installed on the system.

References

.Net Framework can be downloaded and installed from the following link: HTTP://download.microsoft.com/download/6/0/f/60fc5854-3cb8-4892-b6db-bd4f42510f28/dotnet-fx35.exe

Service Pack 6 for Visual Basic 6.0 can be downloaded from the following links: HTTP://www.microsoft.com/downloads/details.aspx?FamilyId=9EF9BF70-DFE1-42A1-A4C8- 39718C7E381D&displaylang=en

Multi part – HTTP://www.microsoft.com/downloads/details.aspx?familyid=83BF08E6-012D-4DB2- 8109-20C8D7D5C1FC&displaylang=en

How to register DLLs?

After downloading the necessary environment, the DLL needs to be registered before it is used and called by the Tally program. As already discussed, there are two ways in which a DLL can be registered.

Let’s discuss the two ways of Registering a DLL (Manual & Set-Up) one by one:

Manual Registration

For VB6 DLLs

  • Copy the DLL file to the specific folder say C:\Tally.ERP9
  • Open Command Prompt and change the current directory to the folder where DLL is copied, i.e., C:\Tally.ERP9
  • Type the command RegSvr32 <DLL Name>
  • After the command is entered in command prompt, a message box is displayed as shown:

Figure_1._Registering_DLL_using_command_prompt_(1.8).jpg

Now you can use the DLL for calling from Tally.

For .NET DLLs

To register .Net DLL, the RegAsm command needs to be used, instead of RegSvr32 .

Note: Manual registration does not automatically take care of missing dependencies. So, it is always advisable to use Set Up Programs for Registration.

Registering DLLs by using Setup Program

To register using this method, double click on the setup program and proceed with the installation. This automatically registers the required DLL into the selected folder.

Creating a set Up Program

The creation of Set Up program varies from one language to another. Please refer to any learning material for Set Up creation specific to your Development Environment. As an example and common usage, we will just discuss creating Set Up using VB 6. The steps for deployment of VB6 DLLs using Package and Deployment Wizard are as follows:

  1. Open the VB project where you want to create a setup program.
  2. Select Package and Deployment wizard from Add-In menu.
  3. If the option isn’t there, choose Add-In Manager and double click Package and Deployment wizard.
  4. Proceed with the Wizard options.

For more details, please refer to the following links:

HTTP://www.configure-all.com/deployment.php

HTTP://www.developerfusion.com/article/27/package-deployment-wizard/2/

Dynamic Table Support – using ‘Unique’ Attribute

The Unique attribute of Collection definition is used to control the display of unique values in the table for a specified method, based on values selected from the table previously in a field. The display of values is changed dynamically based on the field value.

Existing syntax

The existing syntax of the attribute Unique is:

Syntax

Unique : <Table Object Method> [,<Field Object Method>]

Where,

<Table Object Method> is a method whose value is uniquely displayed in the table.

<Field Object Method> is the storage/method, which is associated with the field which is used to control the display of Table values dynamically. If a particular table object method value from the Table is selected in the field, then that value is removed from the table based on the value of <Field Object Method>. This parameter is optional.

Example

[Part : StkBat]

Repeat : GrpLedLn : StkItemColl

[Line : GrpLedNm]

Field : StkIt, StkBatNm

[Field : StkIt]

Use : Name Field

Storage : ItemName

[Field : Stk BatNm]

Use : Name Field

Table : BatList

Storage : BtName

Show Table : Always

Dynamic : Yes

[Collection : BatList]

Title   : “List of Batches”

Type    : Batch

Format  : $BatchName,20

Child of: #StkIt

Unique  : $BatchName, $BtName

[Collection : StkItemColl]

Type  : StockItem

Fetch : Name

[System : UDF]

BtName  : String : 2010

ItemName: String : 2010

The table “Bat List” is used to display batch names in a Table attached to the field “StkBatNm” . The storage associated with the field is “BtName”. Once the Batch name is selected in the field “StkBatNm” , in the next line, the table will be populated with batches which are not selected previously in the field.

Even if some stock items belong to more than one batch, the table won’t display the common batches, since it may have been already selected in the field for a different stock item. To provide this flexibility for controlling the uniqueness of data, the attribute ‘Unique’ has been enhanced.

New Enhanced Syntax

The new enhanced syntax is:

Syntax

Unique : <Table Object Method> [,<Field Object Method>[,<Extended method>]]

Where,

<Table Object Method> is a method whose value is uniquely displayed in the table.

<Field Object Method> is the storage/method, which is associated with the field which is used to control the display of Table values dynamically. If a particular table object method value from the Table is selected in the field, then that value is removed from the table based on the value of <Field Object Method>. This parameter is mandatory if <Extended method> is specified, else it is optional.

<Extended Method> is a storage/method, whose value specifies whether the previous value of the field object method should be used to control unique values display in the table. If the current value of the value of <Extended Method> is same as that of previous values, then <Field Object Method> value is considered while populating unique values in the table. Otherwise, the <Field Object Method> value is ignored to set the unique values in the table. This parameter is optional.

The collection and definition is modified as follows, so that while populating unique values of Batch names in the table, StockItem name is also considered apart from the value of the field storage/method “BtName”, i.e., if the same stock item is selected in the field which has been selected previously, then the field storage/method value “BtName” is considered for controlling display of Batches, else it is ignored.

Example

[Collection : BatList]

Title    : “List of Batches”

Type     : Batch

Format   : $BatchName,20

Child of : #StkIt

Unique   : $BatchName, $BtName, $ItemName

Here, the method $Itemname used in the ‘Unique’ attribute is the storage defined in the field ‘StkIt’.

Use Case:

Consider the following Scenario:

Stock Item

Batch Name

Item 1

Batch A

 

Batch B

 

Batch C

Item 2

Batch A

 

Batch C

Item 3

Batch A

 

Batch B

 

Batch C

There are two fields in the line, one of which displays stock item name and the other displays batches. The selected batch is stored in a UDF, say BtName.

Following table displays the values in each field and unique values in tables based on selection:

Line No

Value in Field 1

Values in Table

Selected Value in Field 2

1

Item 1

Batch A

Batch B

Batch C

Primary Batch

Batch A

2

Item 2

Batch A

Batch C

Primary Batch

Batch C

3

Item 3

Batch B

Batch C

Primary Batch

Batch B

Using Variable as a Datasource for Collections

Collection attribute Datasource has been enhanced to support ‘Variable’ as a Datasource. Now, variable element(s) can be gathered as objects in the collection and the respective simple member variables are available as methods. Member list variables will be treated as sub-collections.

Syntax

Datasource : <Type> : <Identity> [:<Encoding>]

Where,

<Type> is the type of Datasource, i.e., File XML, HTTP XML, Report, Parent Report, V ariable .

<Identity> can be file path/scope keywords/variable specification, based on type of Datasource.

<Encoding> can be ASCII or UNICODE. It ’s applicable for the types File XML & HTTP XML.

Note: Please refer to the topic “Using Variable as a Datasource for Collections” under Variable Framework for more clarity, with examples.

Evaluating expressions by Changing the Object Context with $$ReqOwner Introduced

In a programming language, an expression is a combination of values, variables, operators and functions that are evaluated according to the rules of their precedence and association. Similarly, expressions in TDL can be a combination of Method/Variable/Field/Constant Values, and Function/Formula evaluation results.

Example: For TDL Expression

$Name + ##VarTest + $$MachineDate + @@FormABC + 90 + #FieldXYZ

Where,

Name is a Method, VarTest is a Variable, MachineDate is a Function, FormABC is a system Formula, 90 is a constant value, and FieldXYZ is a Field.

Methods, Variables and Fields are Leaf components in an expression as other components like Formulae or Functions finally evaluate into either one of these, or result into constants.

A TDL Expression always gets evaluated in the context of an Interface (Requestor) and Data Object. Whenever a report is constructed, an Interface object hierarchy is created, i.e., Report contains a Form, Form contains a Part, and so on. Every Interface Object is associated with a Data Object. In the absence of explicit data object association, an implicit anonymous object gets associated. A method value is evaluated in context of the data object, while Variable and Field values are evaluated in context of Interface object. There may be cases where we would require evaluating these in a context different from the implicit context (Interface and Data). TDL provides many functions which provide the facility to change the Data or Interface Object Context. A change in Data Object context does not change the current Interface (Requestor) Object context and a change in Interface Object Context does not change the current Data Object Context.

We can categorize these functions into mainly two categories:

  • Data Object Context Switching Functions
  • Interface Object Context Switching Functions

Data Object Context Switching Functions

The Tally database is hierarchical in nature, in which the objects are stored in a tree-like structure. Each node in the tree can be a tree in itself. An object in Tally is composed of methods and collections. The method is used to retrieve data from the database. A collection is a group of objects. Each object in the collection can further have methods and collections. The Internal Object hierarchy is predefined in Tally and cannot be altered. These can only be persisted in Tally Database.

Every Interface Object exists in the context of a Data Object which is associated with it. As discussed above, an expression (specifically method value) gets evaluated in the context of the Data Object associated with the Requestor (Interface Object). By using the functions as given ahead, we can change the Data Object Context for expression evaluation.

Note: Switching the Data Object Context does not imply a change in the current Requestor (Interface Object)

In all the subsequent examples, we will be using the ‘Voucher’ Data Object hierarchy to demonstrate the various scenarios for Context Change. Hierarchy of the ‘Voucher’ Object is as shown in the following figure.

Figure_2._Data_Object_Hierarchy_of_Voucher_(1.8).jpg

Function – $$Owner

The function $$Owner evaluates the given expression in the context of the parent data object in the Data Object hierarchy chain, i.e., it will change the Data Object context to the parent of the current Data Object in context. For example, if the current object context is Batch Allocations, then to access the value from Inventory Entries, which is its parent data object, the $$Owner function can be used.

Syntax

$$Owner : <Expression>

Example: 1

In this example, let us assume that the “Bill Allocations Amount” field (Requestor) exists in context of Bill Allocations Data Object. In order to evaluate the method “Amount” from Ledger Entries Object Context, we need to use the function $$Owner.

[Field : Bill Allocations Amount]

Set As : $$Owner:$Amount

In this field, method Amount from parent object LedgerEntries is set by using $$Owner function.

Example: 2

Similarly, let’s assume that the current data object context for the field “ Bill Allocations Remarks ” is Bill Allocations , and we need to evaluate the method Narration from Voucher Object.

[Field : Bill Allocations Remarks]

Set As : $$Owner:$$Owner:$Narration

In this field, Narration from object Voucher, which is 2 levels above in hierarchy, is set using $$Owner twice. In other words, we are requesting for method Narration from the owner of owner. Alternatively, in these examples, we can use the dotted method formula syntax.

[Field : Bill Allocations Amount]

Set As : $..Amount

[Field : Bill Allocations Remarks]

Set As : $…Narration

In these examples, .. denotes the parent and … denotes the Grand Parent.

Function – $$BaseOwner

Function $$BaseOwner evaluates the given expression in the context of the base/primary data object in the Data Object hierarchy chain available with the ‘Report’ Object (in memory).

Note: Since the entire Data Object hierarchy is cached with the Object associated at the Report, the function $$BaseOwner changes the Data Object context to the Object associated at the Report.

For example, if the current data object context is Batch Allocations, then to access the method value from Voucher, $$BaseOwner function can be used.

Syntax

$$BaseOwner : <Expression>

Example

As per the Voucher hierarchy, let’s assume that our current data object context for the field “Bill Allocations Remarks” is Bill Allocations. In order to access the value of Method Narration from Voucher Object, which is the base/primary object in the object hierarchy chain, we can use the function $$BaseOwner.

[Field : Bill Allocations Remarks]

Set As : $$BaseOwner:$Narration

In this field, the Method Narration from the base Object Voucher is set, using $$BaseOwner. Alternatively, in the above example, we can use the dotted method syntax.

[Field : Bill Allocations Remarks]

Set As : $().Narration

In this example, (). navigates to the Primary/Base Data Object

Function – $$PrevObj

Function $$PrevObj evaluates the given expression in the context of the previous data object of the collection, which contains the current data object in context.

Syntax

$$PrevObj : <Expression>

Example:

Assume that a line is being repeated over a collection of Outstanding Bills, which is sorted based on PartyName. After every Party Info, a Total Line is needed to print subtotal for current Party.

[Line : Outstanding Bills]

Option : Partywise Totals : $$PrevObj:$PartyName!= $PartyName

[!Line : Partywise Totals]

Add : Lines : At Beginning : Party SubTotal Line

In this example, an optional line will be included only if the method PartyName of the previous object is not equal to that of the current object.

Function – $$NextObj

Function $$NextObj evaluates the given expression in the context of the next data object of the collection, which contains the current data object in context.

Syntax

$$NextObj : <Expression>

Example:

Assume that a line is being repeated over a collection of Outstanding Bills, which is sorted based on PartyName. After every party Info, a Total Line is needed to print the subtotal for current Party.

[Line : Outstanding Bills]

Explode : Partywise Totals : $$NextObj:$PartyName!= $PartyName

In this example, a part is exploded, provided the method PartyName of the next object is different from that of the current object. This will enable explosion for each party only once, and thereby, we can easily achieve the subtotal line as desired.

Function – $$FirstObj

Function $$ FirstObj evaluates the given expression in the context of the first data object of the collection, which contains the current data object in context.

Syntax

$$FirstObj : <Expression>

Example

Assume that a line is being repeated over the ledger collection, wherein a field, we require the first object’s name to be set.

[Field : First Name]

Set As : $$FirstObj:$Name

In this example , a Field First Name is set as the Name Method of the first object in the Collection.

Function – $$LastObj

Function $$ LastObj evaluates the given expression in the context of the last data object of the collection, which contains the current data object in context.

Syntax

$$LastObj : <Expression>

Example

Assume that a line is being repeated over the ledger collection, where in a field, we require the last object’s name to be set.

[Field : Last Name]

Set As : $$LastObj:$Name

In this example , a Field Last Name is set as Name Method of the last object in the Collection.

Function – $$TgtObject

As we already know, apart from Interface (Requestor) and current Data Object Context, there is one more context available with reference to User Defined Functions and Aggregate Collections, i.e, the Target Object Context. In case of functions, the object being manipulated is the Target Object. In case of aggregate Collection, the object being populated in the resultant collection is the Target Object.

There are scenarios where the expression needs to be evaluated in the context of the Target object. In such cases, the function $$ TgtObject can be used. Using $$TgtObject, values can be fetched from the target object without setting the target object as the current context object.

Syntax

$$TGTObject : <Expression>

Example: 1

Consider writing a Function to import a Voucher from Excel, wherein the Source Object is the Collection gathered out of Objects in an Excel Worksheet, the Target Object being the Voucher and its sub objects. While setting value to Inventory Entries sub-object, the Target Object is changed to Inventory Entries and the Source Object continues to be Excel Objects. In order to set values to the methods Quantity and Rate, Stock Item context is required since Unit Information is available for Item. Hence, $$TGTObject Function is prefixed to the Expression @ BillQty and @ BillRate , in order to evaluate these Methods in the context of the Target Object, which is the ‘Inventory Entries’ Object.

[Function : Import Voucher]

Local Formula : BillQty : $$AsQty:$ExcelBilledQty

Local Formula : BillRate : $$AsRate:$ExcelItemRate

90 : INSERT COLLECTION OBJECT : Inventory Entries

100 : SET VALUE : BilledQty : $$TgtObject:@BillQty

110 : SET VALUE : Rate : $$TgtObject:@BillRate

120 : SET TARGET ..

130 : SAVE TARGET

Example:2

Consider another example where, while populating Asummary collection of Sales Vouchers, we need to track the maximum sales amount for each Item with the date on which the maximum sales was triggered.

[Collection : Src Voucher]

Type : Vouchers : VoucherType

ChildOf : $$VchTypeSales

[Collection : Summ Voucher]

Source Collection : Src Voucher

Walk : Inventory Entries

By : ItemName : $StockItemName

;; The following returns the Date and Amount for an Item, on which Maximum sales has happened

Aggr Compute : MaxDate : SUM : IF $$IsEmpty:$$TgtObject:$MaxItemAmt OR $$TgtObject:$MaxItemAmt <$Amount THEN $Date ELSE $$TgtObject:$MaxDate

;; MaxItemAmt is a method in the Target Object. Hence, the function $$TgtObject is used to evaluate the Method

;; MaxItemAmt in Target Object Context

Aggr Compute : MaxItemAmt : MAX : $Amount

In this example, while populating the Summary Collection, Method MaxItemAmt is being computed for Maximum Amount. Subsequently, Date is also computed by validating if the current object’s Amount is greater than the previous computed Amount. Since Maximum Amount so far is computed and accumulated in the Target Object being populated, we need to access it using the function $$TGTObject. Hence, $$TgtObject:$MaxItemAmt evaluates the Method MaxItemAmt in the context of the computed Target Object MaxItemAmt.

Function – $$LoopCollObj

As we are aware, it is now possible to gather Data Collection in context of each object of another collection, which is referred to as a Loop Collection. To access the methods of Loop Collection Objects from within the Data Collection, $$LoopCollObj is used, with which the expression is evaluated in the context of the Loop Collection Objects.

Syntax

$$LoopCollObj : <Expression>

Example:

To see a consolidated list of vouchers across all the loaded companies.

[Collection : Company Collection]

Type  : Company

Fetch : Name

[Collection : Vouchers of Multiple Companies]

Collection : MultiCmpDB VchCollection : Company Collection

Sort       : Default : $Date, $LedgerName

[Collection : MultiCmpDB VchCollection]

Type    : Voucher

Fetch   : Date, Vouchernumber, VoucherTypeName, Amount, MasterID, LedgerName

Compute : Owner Company : $$LoopCollObj:$Name

In this example, the function $$ LoopCollObj changes the context to Loop Collection Objects, which is the Company Collection and hence, returns the company name.

Function – $$ReportObject

The function $$ReportObject evaluates the given expression in the context of the Data Object associated with the Report Interface Object.

One of the important Use Cases of $$ReportObject is its usage in purview of in-memory Collection gathering. Whenever a collection is gathered, it is retained in memory with the Data Object of the current Interface (Requestor) Object. If the same collection is being used in expressions again and again, then it is beneficial from the performance point of view to attach it to the ‘Report’ Object and evaluate it in the context of ‘Report’ Object n number of times. This eliminates the need to re- gather the collection every time in context of other Data Objects.

Syntax

$$ReportObject : <Expression>

Example: 1

From Bill Allocations Data Object context, Voucher No. of Report Object Voucher is required.

[Field : Bill No]

Set As : $$ReportObject:$VoucherNumber

Example: 2

In a Report, Sales of each Item against the corresponding Parties is required.

[Collection : CFBK Voucher]

Type : Voucher

Filter : IsSalesVT

[Collection : CFBK Summ Voucher]

Source Collection : CFBK Voucher

Walk : Inventory Entries

By : PName : $PartyLedgerName

By : IName : $StockItemName

Aggr Compute : BilledQty : SUM : $BilledQty

Search Key : $PName + $IName

[Field : CFBK Rep Party]

Use : Qty Primary Field

Set as : $$ReportObject:$$CollectionFieldByKey:$BilledQty:@MyFormula:CFBKSummVoucher

MyFormula : ##PName + #CFBKRepName

Here, the function $$ReportObject, during its first execution, retains the collection within the Voucher Object (which is the Data Object associated with the ‘Report’ Object). During subsequent calls, method values are fetched from the Objects available in the ‘Report’ Data Object, instead the entire Collection being regathered again. This helps in improving the performance drastically.

Function – $$ReqObject

This function evaluates the given expression in context of the Data Object associated with the Interface (Requestor) Object. There may be scenarios where during expression evaluation, Data Object context changes automatically and all the methods referred to are evaluated in context of the changed Data Object. The Data Object associated with the Interface (Requestor) Object is lost. Specifically in those cases, where we need to evaluate methods in context of the data object associated with the Interface (Requestor) Object, we will use the function $$ ReqObject .

Syntax

$$ReqObject : <Expression>

Example:

A Report is required to display Ledgerwise Sales Totals

[Field : Fld LedSalesTotal]

Set As : $LedgerSalesTotal

[#Collection : Ledger]

Compute : LedgerSalesTotal : $$FilterAmtTotal:LedVouchrs:MyParty:$Amount

[Collection : Led Vouchers]

Type : Voucher

Filter : OnlySales

[System : Formula]

My Party : $PartyLedgerName = $$ReqObject : $Name

Only Sales : $$IsSales:$VoucherTypeName

In this example, a new method LedgerSalesTotal is added in the Ledger Object to compute the Sales Total from all the Vouchers filtered for the current Party Ledger Object. The Interface Object (Requestor) for this method is the field “FldLedSalesTotal”. In the Formula My Party, current Ledger Name must be checked with the Party Ledger Name of the Voucher Object, which is the current Data Object context. The Data Object associated with the Requestor is Ledger Object. So, in order to evaluate the method $name from the Interface (Requestor) Object’s Data Object context, the function $$ Reqobject must be used.

Function – $$ObjectOf

As we are already aware, there is the capability to identify a Part and Line Interface Object using a unique Access Name. A Form/Report can be identified from any level using the Definition Type. The function $$ObjectOf is used to evaluate the expression in context of the Data Object associated with the Interface Object identified by the Access Name.

The Interface Object being referred to, should be assigned a unique AccessName via Access Name attribute.

Syntax

$$ObjectOf : <DefinitionType> : <AccessNameFormula> : <Evaluation Formula>

Example

[Part : Cust Object Association]

Lines : Cust Object Association

;; Object associated at Part

Object Ex : (Ledger, “Customer”).

;; Access Name specified so that this part can be accessible

Access Name : “CustLedger”

;; In some other fields across parts, we can access the methods of the Ledger Object associated with the part “CustObjectAssocia- tion”, using the function $$ObjectOf

[Field : Ledger Parent]

Set as : $$ObjectOf:Part:”CustLedger”:$Parent

The Part “ Cust Object Association ” is associated with the Ledger Object “Customer”. It is identified by the Access Name “CustLedger”. The Field Ledger Parent from a different Part accesses the method $Parent from the Ledger object ‘Customer’, as it is the Object associated with the part Cust Object Association, identified by Access Name “CustLedger”.

Function – $$Table

It evaluates the expression in the context of ‘Table’ object, which is selected in the given Field.

Syntax

$$Table : <Field Name> : <expression>

Example

[Field : Vehicle Number]

Table : List of Vehicles

Show Table : Always

[Field : Vehicle Type]

Set as : $$Table:VehicleNumber:$VehType

[Field : Vehicle YOP]

Set as : $$Table:VehicleNumber:$VehYOP

[Collection : List of Vehicles]

Type    : Veh AggUDF : Company

ChildOf : ##SVCurrentCompany

Format : $VehNo, 20

Format : $VehType, 40

Format : $VehYOP, 4

Fetch : VehNo, VehType, VehYOP

;; For Remote Client End

In this code, the table is displayed in the field “Vehicle Number”. In the other fields ‘Vehicle Type’ and ‘Vehicle YOP’, $$Table is used to evaluate the methods $VehType and $VehYOP in context of the Data Object selected in the field “Vehicle Number”.

Function – $$TableObj

$$TableObj is similar to the function $$Table. The expression is evaluated in context of the Data Object selected in the Table in the field specified. The difference of this function from the function $$Table is that, in case no object is selected in the Table, or expression evaluation fails, $$Table returns a blank string. In such a case, $$TableObj returns a logical value (FALSE) as the result.

Syntax

$$TableObj : <Field Name> : <expression>

Example:

A field needs to be skipped based on the selection of the table in a field.

[!Field : VBOrdDueDRNote]

Skip : $$TableObj:VCHBATCHOrder:$$IsOrder

In this example, if the Object selected in the Field VchBatchOrder is an Object Order, then the current field needs to be skipped.

Interface Object Context switching functions

Objects used for designing the User Interface are referred to as Interface objects. Interface objects like Report and Menu are independent items and can exist on their own. The objects Form, Part, Line and Field can’t exist independently. A Report can have more than one Form, Part, Line and Field definitions but at least one has to be there. The hierarchy is as follows:

  • Report uses a Form
  • Form uses a Part
  • Part uses a Line
  • Line uses a Field
  • A Field is where the contents are displayed or entered

Figure_3._Interface_Object_Hierarchy_(1.8).jpg

We can take an example of the Simple Customized Invoice Report (as given in the diagram) in order to understand the containment hierarchy of Interface Objects.

A set of available attributes of interface objects has been predefined by the platform. A new attribute cannot be created for an interface object. Interface objects are always associated with a Data Object and essentially add, retrieve or manipulate the information in Data Objects.

At run time, when a report is constructed after the evaluation of all of the above, a complete hierarchy of Interface Objects is created. As we have already discussed, an expression is evaluated in the context of the current Interface Object, which is referred to as the Requestor, and the Data Object associated to it. We will now discuss the switching functions which will change the Interface Object Context for expression evaluation.

Note: Switching the Interface (Requestor) Object Context does not imply a change in the current Data Object context.

Function – $$AsReqObj

The function $$AsReqObj is used to save the Interface (Requestor) context to the current object, for the evaluation of the expression. All the future references have done using $$ReqObject will point to the saved Interface Object context. The actual requestor is overridden using the function $$AsReqObject .

Syntax

$$AsReqObj : <Expression>

Example

Here, a Table of Company Vehicles is displayed in a Field “Select Vehicle”, which exists in the context of the Voucher Object. The table is filtered on the basis of Unused Vehicles.

[Field : Select Vehicle]

;; In Voucher Entry

Table : CMP Vehicles

Storage : VCHVehicle

[Collection : CMP Vehicles]

Type    : Company Vehicles : Company

Childof : ##SVCurrentCompany

Format  : $VehicleNumber, 20

Format  : $VBrand, 10

Title   : “Company Vehicles”

Filter  : Unused Veh

[System : Formula]

Unused Veh : $$AsReqObj:$$FilterCount:PrevSalesVchs:UsedVehicle = 0

Used Vehicle : $$ReqObject:$VehicleNumber=$VCHVehicle

Only Sales : $$IsSales:$VoucherTypeName

[Collection : PrevSalesVchs]

Type : Voucher

Filter : Only Sales

In this example :

  • Field Select Vehicle is the Interface (requestor) object, associated with the data object Voucher.
  • Table/Collection of Company Vehicles is displayed in the Field.
  • Table is filtered for Unused vehicles.
  • This collection contains the list of Vehicle Numbers which need to be compared with the ones used in the previous sales vouchers. Since Requestor is the Field with the data object ‘Voucher’, Function $$ReqObject will get evaluated in the context of ‘Voucher’ Object, which is not expected. Hence to make the current collection, i.e., CMP Vehicles, as requestor object for future reference, Function $$AsReqObj is used.
  • In the Function $$FilterCount, when the object context changes to the list of sales vouchers, the Function $$ReqObject evaluates the parameter $VehicleNumber in the context of the requestor Collection CMP Vehicles set earlier using $$AsReqObj, and compares the same with the Voucher UDF VchVehicle stored in the respective vouchers.

Function – $$ReqOwner

The Function $$ReqOwner evaluates the given expression in the context of the Interface (Requestor) object’s Owner in the current Interface object hierarchy. For instance, Report is an owner requestor for Form, Form is an owner requestor for Part, and so on. From the Line, when the function $$ReqOwner is used, the expression gets evaluated in the context of the Part containing the current line.

Syntax

$$ReqOwner : <Expression>

Example

[#Menu : Gateway of Tally]

Add : Key Item : ReqOwner Sample : W : Alter : ICCF ReqOwner

[Report : ICCF ReqOwner]

Form : ICCF ReqOwner

Variable : VarReqOwner : String : “Keshava”

[Form : ICCF ReqOwner]

Parts : ICCF ReqOwner

[Part : ICCF ReqOwner]

Lines : ICCF ReqOwner

[Line : ICCF ReqOwner]

Fields : ICCF ReqOwner

[Field : ICCF ReqOwner]

Set As : $$FuncToReturnReqOwner

Set Always : Yes

[Function : FuncToReturnReqOwner]

Variable : VarReqOwner : String : “Madhava”

Variable : Temp : String : $$ReqOwner:##VarReqOwner

01 : MSGBOX : ##VarReqOwner : ##Temp

10 : RETURN : $$ReqOwner:##VarReqOwner

In this example, the Variable VarReqOwner is declared & initialized in a Report as well as in a function. From the Field, the function $$ReqOwnerFunc is referred to perform some computation and return the result. Since $$ReqOwner is used in the Function and Field is the Requestor Owner for Function, the Field walks back the Interface (Requestor) Object hierarchy to fetch the Variable value. Hence, the Variable value Keshava of the nearest Interface Object, i.e., of the Report is returned.

Function – $$AccessObj

As we are already aware, there is the capability to identify a Part and Line Interface Object using a unique Access Name. The function $$AccessObj changes the Interface Object context to the one identified by the Access name to evaluate the expression

The Interface Object being referred to should be assigned a unique Access Name via Access Name attribute.

Syntax

$$AccessObj : <DefinitionType> : <AccessNameFormula> : <Evaluation Formula>

Example

[Line : ABC]

Access Name : “AccABC”

[Field : XYZ]

Set As : $$AccessObj:Line:“AccABC”:##VarABC

In this example, the function $$AccessObj changes the Interface Object context from the field “XYZ” to the line “ABC”, which is identified by the Access Name “AccABC”. The variable value is evaluated in context of the line “ABC”.

Function – $$ExplodeOwner

The function $$ExplodeOwner changes the Interface (Requestor) Object to the Line owning the current exploded Part, and evaluates the given expression, i.e ., Field and Variable Values, in the context of Interface Object.

Syntax

$$ExplodeOwner : <Expression>

Example

[Line : Smp InvEntries]

Fields : Name Field

Local : Field : Name Field : Set As : $StockItemName

Explode : Smp Expl Part

[Part : Smp Expl Part]

Lines : Smp Batch Allocations

Repeat : Smp Batch Allocations : Batch Allocations

Scroll : Vertical

[Line : Smp Batch Allocations]

Fields : Name Field

Local : Field : Name Field : Set As : $$ExplodeOwner:#NameField

In this example, the field NameField is being evaluated in the context of the Line Smp InvEntries, which owns the current exploded part Smp Expl Part.

Function – $$PrevLine

When the line is repeating, we may require evaluating an expression in the context of the previous line. For example, we might require to fetch the field values stored in the previous line for expression in the current line. The function $$PrevLine is used to change the Requestor to the Previous Line for expression evaluation.

Syntax

$$PrevLine : <Expression>

Note: The function $$PrevLine not only changes the Interface (Requestor) Object context, but also changes the Data Object context to the Object associated with the Requestor.

Example

[Line : PrevParticulars]

Explode : PrevParticulars ExpPart : $$PrevLine:#PartyParticulars!=#PartyParticulars

In this example, in case of repeated lines, where subtotals are required to be displayed or printed for the same party, we can explode a subtotal line after comparing the previous line’s and the current line’s Ledgers. If the field values are not the same, then the subtotal line is exploded.

 

Repeat Line with Optional Collection

We are aware that the ‘Repeat’ Attribute of a Part is used to Repeat a line over a Collection.

Existing Syntax

Syntax

[Part : <Pa r t Name>]

Repeat : <Line Name> : <Co l lection>

Where,

<Part Name> is the name of the part.

<Line Name> is the name of the line to be repeated.

<Collection> is the name of the collection on which the line is repeated. This was mandatory prior to this release. In this case, the same line will be repeated for each object of the collection. Each line will be associated with an Object of the collection. Report created in Create/Alter/ Display mode will either store method values into the object or fetch method values from the Object. Any expression evaluation within this line will happen with an object in context.

With the introduction of List Variable (Simple/Compound), there will be a requirement to store values into the Variable by accepting user inputs and also to display or use it for expression evaluation. Since Variables are Context free structures there is no need to associate element variables with the line. For this purpose the ‘Repeat’ Attribute of the part has been enhanced to have the collection as Optional. Now, it is possible to Repeat a Line with or without a Collection. In cases where the collection is not specified, the number of lines to be repeated is unknown. Hence, specifying the SET attribute is mandatory. In case of Edit, SET can be optional if ‘Break On’ is specified.

New Enhanced Syntax

Syntax

[Part : <Part Name>]

Repeat : <Line Name> [: <Collection>]

Where,

<Part Name> is the name of the part.

<Line Name> is the name of the line to be repeated.

<Colle c tion> is the name of the collection o n which the line is repeat e d. It is n o w OPTIONAL.

Storing Values into List Variables

With this enhancement, values can be added to List Variable (Simple/Compound) dynamically by accepting user inputs by repeating a line without a Collection. Multiple lines can be added dynamically or a fixed number of lines can be added as per user requirement, while repeating the line.

Example

To accept the values from a user to the Simple List Variables SLVEMP, a report is opened in ‘Create’ Mode. Let us look into the ‘Part’ Definition:

[Part : SLV List Values]

Lines : SLV List Title, SLV List Values

Repeat : SLV List Values

BreakOn: $$IsEmpty:#SLVAlias

Scroll : Vertical

Here, the line is repeated without a collection and it will break if the field value ‘SLV Alias’ is empty. Let us look into the Field Definitions:

[Line : SLV List Values]

Fields : SLV Alias, SLV Name

[Field : SLV Alias]

Use : Name Field

[Field : SLV Name]

Use : Name Field

Delete : Key

Add : Key : SLV List Key

Inactive: $$IsEmpty:#SLVAlias

[Key: SLV List Key]

Key : Enter

Action List : Field Accept, SLV List Add

[Key : SLV List Add]

Key : Enter

Action : LIST ADD : SLVEMP : #SLVAlias : #SLVName

Values are added to the List Variable “SLVEMP” using the Action “LIST ADD”. Similarly, user inputs can be added / altered dynamically to the Compound List Variable also.

Retrieving Values from List V ariables

In the previous example, we had stored values into a simple List Variable “SLVEMP”. Let us suppose that the values need to be retrieved from a simple List Variable SLVEMP and displayed in a report.

This report “SLV List Values with Key Display” is opened in ‘Display’ mode. Let us look into the code snippet of the Part definition:

[Part : SLVList ValuesDisplay]

Lines : SLV List DisplayTitle, SLV List DisplayValues

Repeat : SLV List DisplayValues

Set : $$ListCount:SLVEmp

Scroll : Vertical

CommonBorder : Yes

In Part level, the number of lines is fixed using the Attribute ‘SET’, based on the number of elements in the Simple List Variable “SLVEmp”.

[Line : SLV List DisplayValues]

Fields : SLV Alias, SLV Name

[Field : SLV Alias]

Use : Name Field

Set as : $$ListKey:SLVEMP:$$Line

[Field : SLV Name]

Use : Name Field

Set as : $$ListValue:SLVEMP:#SLVAlias

Key and Value from the Simple List Variable “SLVEMP” are retrieved using the functions $$ListKey and $$ListValue at the field level. Similarl y , the values can be retrieved from a Compound List Variable also.

Variables in Collection

The inline variables can be declared at the Collection using the Attributes Source Var, Compute Var and Filter Var. In case of Simple Collection, during the evaluation, only current objects are available. Whereas in case of Aggregate/Summary collection, during the evaluation, the following three sets of objects are available:

Source Objects : Objects of the collection specified in the ‘Source Collection’ attribute.

Current Objects : Objects of the last collection specified in the Walk path.

Aggregate Objects : Objects obtained after performing the grouping and aggregation.

There are scenarios where some calculation is to be evaluated based on the source object or the current object value and the filtration is done based on the value evaluated with respect to the final objects before populating the collection. In these cases, to evaluate the value based on the changing object context is tiresome, and sometimes impossible as well.

The collection level variables provide Object-Context Free processing. The values of these inline variables are evaluated before populating the collection.

The sequence of evaluation of collection attributes has been changed to support attributes ComputeVar, Source Var and Filter Var. The variables defined using the attributes Source Var and ComputeVar can be referred to in the collection attributes By, Aggr Compute and Compute. The variable defined by ‘Filter Var’ can be referred to in the collection attribute ‘Filter’. The value of these variables can be accessed from anywhere, while evaluating the current collection objects.

Attributes SOURCE VAR, COMPUTE VAR and FILTER VAR

Attribute – Source Var

The attribute ‘Source Var’ evaluates the value of the variable based on the source object.

Syntax

Source Var : <Variable Name> : <Data Type> : <Formula>

Where,

<Variable Name> is the name of the variable.

<Data Type> is the data type of the variable.

<Formula> can be any expression, which evaluates to a value of ‘Variable’ data type.

Example

Source Var : Log Var: Logical : No

The value of the variable ‘LogVar’ is set to NO.

Attribute – Compute Var

The attribute ‘Compute Var’ evaluates the value of the variable based on the current objects.

Syntax

Compute Var : <Variable Name> : <Data Type> : <Formula>

Where,

<Variable Name> is the name of the variable.

<Data Type> is the data type of the variable.

<Formula> can be any expression which evaluates to a value of ‘Variable’ data type.

Example

Compute Var : IName : String : if ##LogVar then $StockItemName else ##LogVar

Attribute – Filter Var

The attribute ‘Filter Var’ evaluates the value of the variable based on the objects available in the collection after the evaluation of the attributes ‘Fetch’ and ‘Compute’.

Syntax

Filter Var : <Variable Name> : <Data Type> : <Formula>

Where,

<Variable Name> is the name of the variable.

<Data Type> is the data type of the variable.

<Formula> can be any expression which evaluates to a value of ‘Variable’ data type.

Example

Filter Var : Fin Obj Var : Logical : $$Number:$BilledQty> 100

Using V aria b l e as a Datasource for Collections

Collection attribute ‘Datasource’ has been enhanced to support ‘Variable’ as a Datasource. Now, variable element(s) can be gathered as objects in collection and their respective simple member variables will be available as methods. Member List Variables will be treated as sub-collections.

Syntax

Datasource : <Type> : <Identity> [:<Encoding>]

Where,

<Type> is the type of Datasource, i.e., File XML, HTTP XML, Report, Parent Report, Variable.

<Identity> can be file path/ scope keywords/ variable specification, based on type of Datasource.

<Encoding> can be ASCII or UNICODE. It is applicable for data types File XML and HTTP XML.

Example:

Simple List Variable as Datasource

[Collection : LV List Collection]

Datasource : Variable : SLVEmp

The elements of the Simple List Variable ‘SLVEmp’ will be available as objects in the collection ‘LV List Collection’. Let us suppose that a Line is repeated over the collection ‘LV List Collection’. The value can be retrieved in the field level as shown below:

[Field : SLVEmp Field]

Use : Name Field

Set as : $SLVEmp

Compound List Variable as Datasource

[Collection : CV List Collection]

Datasource : Variable : CLVEmp

The elements of the Compound List Variable CLVEmp will be available as objects in the collection CV List Collection. It is used as Asource Collection in the following Summary Collection:

[Collection : CV List SummaryCollection1]

Source Collection : CV List Collection

Walk : Relatives

By : Relation : $Relation

Aggr Compute : MaxAge : Max : $Age

Aggr Compute : MinAge : Min : $Age

Aggr Compute : TotSal : Sum : $Salary

Here, we are walking to the sub-collection ‘Relatives’ and performing grouping and aggregation.

Variables in Remoting

In a Tally.NET Environment, where Tally at the remote end sends request to the Tally Company at the Server, all client requests must contain the dependencies, based on which data is gathered. In other words, any request sent to the server must accompany the values configured at the client to extract data from the server. For example, a Collection of Ledgers falling under a user selected group must accompany the request sent to the server. Hence, the request to the server must contain the Variable value which signifies the Group name.

Only the configuration information which is relevant to the data to be fetched from the Server needs to be sent to the Server, and not the ones which are User Interface related, like Show Vertical Balance Sheet, Show Percentages, etc.

When a Collection is sent to the Server, all the dependencies, i.e., variable values, are enclosed within the requests automatically.

Example: 1

[Collection : User Ledger Coll]

Type : Ledger

Child of : ##UserSelectedGroup

While sending this collection to the server, the value for the variable UserSelectedGroup is also passed to the server automatically and the server responds accordingly.

Example: 2

[Collection : Emp Coll]

Type : Cost Centre

Filter : EmpSpouseName

[System : Formula]

EmpSpouseName : $SpouseName = ##CLVEMP[1].Relatives[1].Name

Value of CLVEMP[1].Relatives[1].Name will be enclosed within the request to the server.

In some cases, variable values will not be remoted automatically like Child Of : $FuncName, which in turn returns the variable value through the Function. Such variables need to be remoted using an adhoc ‘Compute’ within the collection. This ‘Compute’ is required to set a manual dependency on the variable and hence, consider it while sending request to Server. Consider the following example:

[Collection : User Ledger Coll]

Type : Ledger

Child of : $$UserFunc

[Function : UserFunc]

00 : RETURN : ##FuncVar

In this example, the function UserFunc returns the value through the variable ‘FuncVar’. Hence, the variable ‘FuncVar’ needs to be remoted using an adhoc ‘Compute’ as follows:

[Collection : User Ledger Coll]

Type : Ledger

Child of : $$UserFunc

Compute : FuncVar : ##FuncVar

 

Release 2.0

Collection Attribute ‘Parm Var’ Introduced

As we already know, the ‘Collection’ Artefact evaluates the various attributes either during initialization or at the time of gathering the collection. It may require various inputs from the Requestor context for the same. For example, the evaluation of ‘Child of’ and ‘Filter’ attributes happens at the time of gathering the collection. It requires certain values from Requestors context like $name. In ‘Filter’ attribute, if $name of each object is to be compared with $name of the Requestors context, then we have to refer it as $ReqObject:$name. The direct reference of values/expressions from the report elements and objects in the collection at various points, creates a few issues as follows:

  • Code complexity is increased, as observed in the Filter example above.
  • The performance is impacted, as there is are repeated references in case of Filters.
  • In a Remote Environment; where the Requestor Context is not available within the collec­tion at the Server side

In order to overcome the above, a new Collection attribute ‘Parm Var’ has been introduced.

We already have the capability of declaring inline variables at collection level using the Attributes Source Var, Compute Var and Filter Var. These are context-free structures available within the collection for various evaluations. For storing values in these, the various object contexts available are Source Objects, Target Objects, etc. One more attribute called ‘Parm Var’ has been introduced in the collection, which is a context-free structure available within the collection. The requestors Object context is available for the evaluation of its value. This is evaluated only once in the context of caller/requestor. This happens at collection initialization and the expression provided to it is evaluated and stored as a variable which can be referred within any of the attributes of the collection anytime and is made available at the Server end by sending it with the XML Request.

Collection Attribute – Parm Var

The attribute ParmVar evaluates the value of the variable based on the requestor object’s context.

Syntax

Parm Var : <Variable Name> : <Data Type> : <Formula>

Where,

<Variable Name> is the name of variable.

<Data Type> is the data type of the variable.

<Formula> can be any expression which evaluates to the value of ‘Variable’ data type.

Example

[Part : Groups and Ledgers]

Lines : Groups and Ledgers

Repeat : Groups and Ledgers : List of Groups

Scroll : Vertical

[Line : Groups and Ledgers]

Fields : GAL Particulars

Right Fields : GAL ClosBal

Explode : List of Ledgers : ##ExplodeFlag

[Part : List of Ledgers]

Lines : List of Ledgers

Repeat : List of Ledgers : Smp List of Ledgers

[Collection : Smp List of Ledgers]

Type : Ledger

Child Of : $Name

In the collection Smp List of Ledgers, the Child of attribute is evaluated based on the method $Name which is available from the Group Object in context. The line Groups and Ledgers (Requestor Object) is associated with a Group Object.

In a Remote environment, when such a Report is being displayed at the Clients end, the request for the collection gathering goes to the Server End. At the server end, the Requestor Context is not available. So, the evaluation of $Name will fail. To overcome such a situation, a new attribute called “Parm Var” has been introduced, which is a context-free structure available within the collection. It evaluates the expression based on the Requestors Context, thereby available at the Server Side also.

The Collection is Redefined as follows using the attribute ParmVar.

[Collection : Smp List of Ledgers]

Type : Ledger

Child Of : ##ParmLedName

Parm Var : ParmLedName : String : $Name

The value of variable ParmLedName is evaluated at the Client side based on method $name available from Group Object Context, and sent to the Server. While gathering the objects at the server side, the attribute ChildOf is evaluated, which uses the variable ParmLedName instead of $Name, available at the Server.

Default TDL Changes

In the release 2.0, many new features like Remote Edit, SMS support, etc., have been introduced. The TDL language is also enriched with new capabilities to support these features. Using the new language capabilities, the source code of Tally.ERP 9 Release 2.0 has also been enhanced. The changes have been made in many definitions. For example, the values of some of the attributes have been changed, new attributes have been added and formulas have been rewritten.

Although, it has been tried to ensure maximum backward compatibility, there may be cases where the application developer may require to validate/rewrite the existing TDL codes to make them compatible with Tally.ERP 9 Release 2.0. In this section, the changes have been summarised in terms of listing the definitions. Although sincere efforts have been made in the direction of providing a comprehensive listing of definitions, one may come across a few cases where changes have been made. If any of these definitions are being used in customisations, one must refer to the source code changes available with the latest Release of TDE.

Mandatory ‘Fetch’ at the Collection Level

This release onwards, Fetch is mandatory in every collection. All the methods which are required to be used in a Report are to be fetched at the Collection level.

Voucher Creation

Whenever a new Voucher is being created, it is important to take care of the following:

  • The variable name “SVViewName” has to be set to System Names
    • AcctgVchView – For all Accounting vouchers
    • InvVchView – For all Inventory vouchers, except Stock Journal voucher
    • PaySlipVchView – For Payroll vouchers
    • ConsVchView – For Stock Journal voucher
  • The method ‘PersistedView’ has to be set to the value of the variable ‘SVViewName’.

Example

00 : Set : SVViewName : $$SysName:AcctgVchView

10 : NEW OBJECT : Voucher

         |

         |

20 : Set Value : PersistedView : ##SVViewName

30 : CREATE TARGET

Extract Collections List and Usage as Tables

Many existing ‘collection’ definitions have been converted as Extract Collections. So, if these collections are used in any of the user TDLs, the code needs to be rewritten for Tally.ERP 9 Release 2.0. Many fields which were using the old collections as Tables have been modified to use the Extract Collections now. The ‘Table’ Attribute has been changed for those fields.

The following Table shows the fields in which extract collections are used in the ‘Table’ attribute:

Field Name

Table Name OLD

Extract Collection/ Table Name

EI AccAllocName

Inv SalesLedgersAlloc

Inv Purch Ledgers

Inv Sales Income Ledgers

Inv Purch Expense Ledgers

NonInv Purch Support

Ledgers

NonInv Sales Support

Ledgers

Inv SalesLedgersAlloc Extract

Inv Purch Ledgers VchExtract

Inv Sales Income Ledgers Extract

Inv Purch Expense Ledgers Extract

NonInv Purch Support Ledgers –

VchExtract

NonInv Sales Support Ledgers –

VchExtract

EI Consignee

Party Ledgers, Cash

Ledgers Invoice Ledgers

Party Cash Ledgers Extract Invoice Ledgers Extract

EICommonLED

Inv Sales Ledgers Inv Purch Ledgers Inv Sales Income Ledgers Inv Purch Expense Ledgers

Inv Sales Ledgers Extract Inv Purch Ledgers Extract Inv Sales Income Ledgers Extract Inv Purch Expense Ledgers Extract

VCH VATClass

VCH VAT Sales ClassificationVCH VCH VAT Purc

ClassificationVCH

VCH VAT Sales

ClassificationVCH Extract VCH VAT Purc ClassificationVCH Extract

VCH AccAllocVAT Class

VCH VAT Sales

ClassificationVCH VCH VAT Purc

ClassificationVCH

VCH VAT Sales

ClassificationVCH Extract VCH VAT Purc ClassificationVCH Extract

VCH POS PartyContact

Party Ledgers

Party Ledgers Extract

VCHACC StockItem

Vch Stock Item

Vch Stock Item Extract

VCHJRNLStockItem

Vch Stock Item

Vch Stock Item Extract

ACGLLed

GainLoss Ledgers

GainLoss Ledgers Extract

ACLSFixedLed

Cash Class Ledgers

Cash Class Ledgers Extract

ACLSLed

Cash Ledgers Normal

Ledgers Normal Ledgers, Cash Ledgers Non

CENVAT Ledgers Non CENVAT Ledgers, Cash Ledgers,

Cash Ledgers VchExtract Normal Ledgers Extract Normal Cash Ledgers Extract Non CENVAT Ledgers Extract Non CENVAT Cash Ledgers Extract

EI AccDesc

Sales Support Ledgers Purchase Support Ledgers

Sales Support Ledgers VchExtract Purchase Support Ledgers VchExtract

VCH AccVATClass

SD Sales Classification Etc…

SD Sales Classification Extract Etc …

VCHIndentStockItem

Vch Stock Item

Vch Stock Item Extract

VCHBATCH Godown

Stockable Godown JOB Stockable Godown

Stockable Godown VchExtract JOB Stockable Godown

VchExtract

VCHBATCH OrdrName

Active Batches

Active Batches VchExtract

VCHBATCH NrmlName

Active Batches

Active Batches VchExtract

VCHBATCH JrnlName

Active Batches

Active Batches VchExtract

EI VATClass

SD Sales Classification VCH VAT Sales ClassificationVCH VCH VAT Purc ClassificationVCH VAT Sales With Rate

ClassificationVCH VAT Purc With Rate

ClassificationVCH Addl VAT Sales With Rate

ClassificationVCH Addl VAT Purc With Rate

ClassificationVCH CessOn VAT Sales With Rate

ClassificationVCH CessOn VAT Purc With Rate

ClassificationVCH CST Sales With Rate

Classification CST Purc With Rate Classification

SD Sales Classification Extract VCH VAT Sales ClassificationVCH Extract VCH VAT Purc ClassificationVCH Extract VAT Sales With Rate ClassificationVCH Extract VAT Purc With Rate

ClassificationVCH Extract Addl VAT Sales With Rate

ClassificationVCH Extract Addl VAT Purc With Rate

ClassificationVCH Extract

CessOn VAT Sales With Rate ClassificationVCH Extract

CessOn VAT Purc With Rate ClassificationVCH Extract CST Sales With Rate Classification Extract CST Purc With Rate

Classification Extract

VCHBATCH GRNName

Active Batches

Active Batches VchExtract

POS BatchName

Active Batches

Active Batches VchExtract

VCHBATCH

DealerGodown

Stockable DealerGodown

Stockable DealerGodown

VchExtract

VCHBATCH

ExciseMfgrGodown

Stockable

ExciseMfgrGodown

Stockable ExciseMfgrGodown VchExtract

VCHBILL TDSLedger

TDS Ledger Table

TDS Ledger Table VchExtract

VCHBILL STaxLedger

Service Tax Ledger Table

Service Tax Ledger Table

VchExtract

VCHCSTCAT Name

Voucher Cost Category

Voucher Cost Category

VchExtract

VCHCST Name

Cost Centre All Cost Cen­tre

Cost Centre VchExtract All Cost Centre VchExtract

STKVCH Ledger

Party Ledgers, Cash Led­gers

Party Cash Ledgers Extract

PF CashBank Ledger

Cash Ledgers

Cash Ledgers VchExtract

VCH AttdEmpName

Payroll

DeactvationEmployees

Payroll

DeactvationEmployeesExtract

VCH AttdType

List of Attendance Types

List of AttdTypesExtract

VCH AutoAttdType

List of Attendance Types

List of AttdTypesExtract

VCH EmpName

Payroll Cost Centres

Manual Vch Employees Under Category

Payroll CostCentres

AsVCHExtract Manual AsVchEmployees Under

CategoryExtract

PAYROLLFixedLed

Payroll Liab Ledgers

Payroll Liability LedgersExtract

Payroll VCH Emp- Cat­Particulars

List of CostCategories

List of CostCategories Extract

Payroll VCH Emp- Par­ticulars

Payroll Cost Centres

Manual Vch Employees Under Category

Payroll CostCentres VCHExtract Manual Vch Employees Under CategoryExtract

PayrollVCHPayhead Name

Vch Pay Heads

Vch Pay Heads Extract

Payroll FunctionAuto- CategoryName

Payroll Vch Categories

Payroll Vch Categories Extract

Payroll FunctionAu-toC­stTables

Payroll Cost Centres AutoVch Employees Under Category

AutoVch PyrlCostCentres

VCHExtract AutoVch Employees Under CategoryExtract

Payroll FunctionAuto- PayheadName

Payroll Ledgers

AutoVch PayrollLedgersExtract

TDSAutoLedger

Normal Ledgers

Normal Ledgers Extract

TDSFilter Bank

Cash Class Ledgers

Cash Class Ledgers Extract

EI TrackOrder

InvSalesOrders

InvPurcOrders

InvSalesOrders, Not Applicable, EndOfList, NewNumber

InvPurcOrders, Not Applicable,

EndOfList, NewNumber

EI SalesOrder

InvSalesOrders

InvPurcOrders

InvSalesOrders, Not Applicable, EndOfList, NewNumber

InvPurcOrders, Not Applicable, End- OfList, NewNumber

SRVTPartyName

Service Party Ledgers

Service Party Ledgers Extract

SRVTPartyBillName

Pending Party Bills

Pending Party Bills Extract

Modified Definition List and Corresponding Changes

Changes in ‘Set As’

Definition Type

Definition Name

Part

VCH Excise SubCat Tax Rate

 

Trader PurcTypeofDuty

 

VCH Excise SubCat Tax Rate

Field

VCH Excise SubCat Tax Rate

 

Trader PurcTypeofDuty

 

TDS TaxPartyLedger

 

VCH TaxPymtDetails

 

Trader PLARG23SlNo

 

Trader SupplierRG23No

 

Trader OriginalRefNo

 

Trader MfgrImprName

 

Trader DN SupplierInvNo

 

Trader DN SupplierInvDate

 

Trader DN NatureofPurc

 

Trader DN QtyPurchased

 

Trader DN QtyReturn

 

Trader DN AssessableValue

 

Trader CN SupplierInvNo

 

Trader CN SalesInvDate

 

Trader CN SalesInvNo

 

Trader CN QtySold

 

Trader CN QtyReturn

 

Trader CN SplAEDOfCVDNotPassOn

 

DealerInv AmtofDuty

 

DealerInv DutyPerUnit

Options added in Alter Mode

In the definition [Form: Voucher], the option for ‘Alter’ mode is added and it is used to list all the fetches.

Definition Type

Definition Name

Form

Voucher

‘Fetch Object’ Added:

Definition Type

Definition Name

Field

VCH S tockItem

‘Compute Var ’ and ‘Fetch’ Attributes Added

Definition Type

Definition Name

Collection

Vouchers of FBT Category Calc

 

Memo Vouchers of FBT Category Calc

 

FBTCategoryCalc

 

Vouchers of Regular FBT Category Calc

 

Vouchers of Recovered FBT Category Calc

 

VCHInTNo

 

VCHInTNoG

 

VCHInTNoB

 

VCHInTNoBG

 

VCHOutTNo

 

VCH OutTNoG

 

VCH OutTNoB

 

VCH OutTNoBG

 

TaxBill Details

 

PayFunctionCaterotyCollection

 

PayFunctionEmployeeCollection

 

AllStatLedgersSlabSummary

 

AllPFStatLedgers

 

Admin AutoFil JrnlEmployees

 

AutoFil PF Ledgers

 

Admin AutoFil Employees

 

AdminAutoPayableColl

 

AdminAutoPayableColl PayrollSrc

 

AdminAutoPayableCollJrnl

 

AdminAutoPayableColl JrnlSrc

 

PFESI EmployeeFilter Summary

 

PFESI EmployeeFilter Vouchers

 

Excise RG23DNoColl

 

Trader ListOfPurcCleared

 

Trader ListOfPurcNonCleared

 

Trader ListOfMultiPurcCleared

 

Trader ListOfMultiPurcNonCleared

 

ExciseDealer Inventory Entries

 

ExciseDealerInvoice InventoryEntries

 

TDS DeductSameVoucher

 

TDS TaxObjPartyBills

 

TDS ITIgnoreNOP

 

TDSDuty LedTable

 

TaxObj AgstTableDebitNote

 

TaxObj AgstTable

 

SRCTaxObj AgstTable

 

TDS CommonPartyLedger

 

TaxObj AdvAgstTable

 

TaxObj DedTable

 

Pending TCS Bills

 

PndgTaxBillsTillCurVchDate

 

TaxBillColl

 

TCS Vouchers of Party

 

Pending Tax Bills

 

BankColl

 

InvSalesOrders

 

ExciseInvSalesOrders

 

InvPurcOrders

 

InvOutTrackNumbers

 

InvInTrackNumbers

 

Pending Sales Orders

 

VCHSo

 

Pending Purc Orders

 

VCHPo

 

VCH OutTNo Src

 

InPending Tracking Numbers

 

OutPending Tracking Numbers

 

Pending Bills

 

STX SalePending TaxObj

 

Pending STaxParty Bills

 

STX CrDrNotePending TaxObj

 

STX CategorywisePending TaxObj

 

STX RcptPending TaxObj

 

STXSource

 

STX SalePending TaxObj

 

STX JV SalePending TaxObj

 

STXTaxObjOutput GAR7PymtAlloc

 

STXTaxObjInput GAR7PymtAlloc

Definition Type

Definition Name

Function

ESIDeductionPayFunction

 

ESIEligibilityPayFunction

 

ESIContributionPayFunction

 

PFNormalPayFunction

 

PTNormalPayFunction

 

PTMonthlyPayFunction

 

FirstEPF12PayHeadAbsVal Function

 

FirstEPF833PayHeadAbsVal Function

 

PFNormalVchPayFunction

 

PTMonthlyVCHPayFunction

 

PTNormalVchPayFunction

 

ESIDeductionVchPayFunction

 

ESIEligibilityVCHPayFunction

 

ESIEligibilityOnCurrentEarnVch

 

ESIEligibilityOnSpecifiedFrmlVch

 

ESIContributionVchPayFunction

 

FirstEPF12PayHeadAbsVchVal Function

 

FirstEPF833PayHeadAbsVchVal Function

 

IsExciseRG23DNoExistsFunc

 

IsSpecialAEDOfCVDExistsInStkItem

 

SetTDSPymtDetails

 

VoucherFill

 

OrderObjExists

 

TrackingObjExists

 

FillUsingVoucher

 

CopyBatchAllocationsValues

 

STCatCheck

 

STCatRate

 

STCatCessRate

 

STCatSecondaryCessRate

 

STCatAbatmentNo

 

STCatAbatPer

 

STCatCheck

Few Attributes added and ‘DebugExec’ Action Used

 

Release 3.0

Collection Attribute ‘WalkEx’ Introduced

With every release, performance improvements are being brought, especially with respect to the data gathering and processing artefact ‘Collection’, used to gather and deliver data to presentation layers. Performance is enhanced drastically if collection is gathered judiciously as per usage.

Sometime back, the Collection attribute ‘Keep Source’ had been introduced for performance enhancement. This was used to retain the source collection gathered once with the specified Interface Object, i.e., either with the current Object or its parents/owners. It drastically improved the performance in scenarios where the same source collection was referred multiple times within the same Object hierarchy chain.

Similarly, there are scenarios where there is Union of multiple collections using the same source collection, and each collection walks over its sub objects across different paths, and computes/ aggregates the values from sub level. In such cases, significant CPU cycles will be utilized in gathering and walking over the same Source Object along different paths more than once.

A new attribute WalkEx has been introduced, which when specified in the resultant collection, allows us to specify a collection list. The source collection specification is available in the resultant collection. The collections referred in WalkEx do not have any source collection specified and contain attributes only to walk the source collection and aggregate over Sub Objects of an already gathered collection. The advantage of using WalkEx is that all walk paths specified in the collection list are traversed in a single pass for each object in the source collection. This results in improvements in performance drastically.

Collection Attribute – WalkEx

Syntax

[Collection : <Collection Name>]

WalkEx : <Collection Name1>, <Collection Name2>,..

Where,

<Collection Name1>, <Collection Name2>, and so on, are the collection names specifying Walk and aggregation/computation attributes.

Example

The requirement here is to generate a Report displaying Item Wise and Ledger Wise amount totals for all Vouchers.

Using the Union Approach

;;The source collection “Voucher Source” is a Collection of Vouchers

[Collection : VoucherSource]

Type : Voucher

;;The collection using “Voucher Source” as a source collection, and walking over Ledger Entries Sub-Object, aggregating Amount by grouping over Ledger Name

[Collection : Ledger Details]

Source Collection : VoucherSource

Walk : AllLedgerEntries

By : Particulars : $LedgerName

Aggr Compute : Tot Amount : Sum: $Amount

Keep Source : ().

;;The collection using Voucher Source as a source collection, and walking over Inventory Entries Sub-Object, aggregating Amount by grouping over Stock Item Name

[Collection : StockItem Details]

Source Collection : Voucher Source

Walk : AllInventoryEntries

By : Particulars: $StockItemName

Aggr Compute : TotAmount : Sum: $Amount

Keep Source : ().

;;The Resultant Collection, which is a union of objects from the above two collections “ Ledger Details” and “ StockItem Details”

[Collection : Union LedStk Vouchers]

Collection : Ledger Details, StockItem Details

In this example, both the collections ‘Ledger Details’ and ‘StockItem Details’ are using the same Collection ‘Voucher Source’. We can observe that while gathering and summarizing values from the source collection, each object of the collection ‘Voucher Source’ is traversed twice for aggregating objects over two different paths, i.e., once for ‘Ledger Entries’ and then for ‘Inventory Entries’. The report finally uses the Union collection ‘Union LedStk Vouchers’ to render the same.

Let us now move on to the new approach using “WalkEx” to achieve the same

Using the WalkEx Approach

;;The source collection “Voucher Source” is a Collection of Vouchers

[Collection : VoucherSource]

Type : Voucher

/* The collection “ UnionLed StkVouchers” is the resultant collection which will contain all the Objects obtained out of walks and multiple walks over the same Source Collection. The Report finally uses this Collection. The attribute WalkEx is specified which has value s as collection names “Ledger Detail s ” and “StockItem Details”*/

[Collection : Union LedStk Vouchers]

Source Collection : Voucher S ource

WalkEx : Ledger Details, StockItem Details

Keep Source : ().

/*The Collection “Ledger Details” walks over “ AllLedgerEntries” Sub-Objects and aggregates the amount by grouping over Ledger Name. Note the absence of source collection. */

[Collection : Ledger Detail s ]

Walk : AllLedgerEntries

By : VchStockItem : $LedgerName

Aggr Compute : VchLedAmount : Sum : $Amount

/*The Collection “StockItem Details” walks over “ AllInventoryEntries” Sub-Objects and aggregates the amount by grouping over Stock Item Name. Note the absence of Source Collection in this. */

[Collection : StockItem Details]

Walk : AllInventoryEntries

By : VchStockItem : $StockItemName

Aggr Compute : VchLedAmount : Sum : $Amount

The Collections used within ‘WalkEx’ use the same Source Collection. Each Object of “Voucher Source” is walked across “Ledger Entries” and “Inventory Entries” in a single pass. Thus, there is an exponential improvement in performance as it traverses each object only once, to gather the values for the resultant collection. In the case of Union Collection, for every Collection using different walk path, the Source Collection Object is being traversed again and again.

‘Walk Ex’ Attribute – Usage Implications

Let us consider the following code design, to understand the implication on various other collection attributes, in cases where ‘Walk Ex’ is used.

;; Source Collection

[Collection : SrcColl]

;;Resultant Collection “ResColl” is using the Source Collection “Src Coll”, and Walk Ex Collections “WalkEx Coll1 ”and “Walk Ex Coll 2” are specified

[Collection : ResColl]

Source Collection : Src Coll

WalkEx : Walk Ex Coll 1, Walk Ex Coll 2

;;Walk Ex Coll 1

[Collection : Walk Ex Coll 1]

Walk : Path1, SubPath1, SubSubPath1

By : GroupName1 : $Method1

;;Walk Ex Coll 2

[Collection : Walk Ex Coll 2]

Walk : Path2, SubPath2, SubSubPath2

By : GroupName2 : $Method2

The following table shows the attributes of ‘Collection’ definition and their applicability in the Resultant collection as well as WalkEx collections.

Attributes

Resultant Collection

Walk Ex-Collections

Source Collection

Specified and applicable

Ignored

Keep Source

Specified and applicable

No significance

Is Client Only

Specified and Considered

Ignored

Sorting

Specified and applicable

Ignored

Filtering

Specified and applicable

Ignored

Max

Specified and applicable

No significance

Parm Var

Specified and Considered

Ignored but to be inherited from the resultant collection

Source Var

Specified and Considered

Specified and applicable

ComputeFilter Var

Specified and applicable

Specified and applicable

Fetch

Specified and applicable

Specified and applicable

Compute

Specified and applicable

Specified and applicable

Aggr Compute

No significance

Specified and applicable

WalkBy

If Specified these two attributes WalkEx will be ignored

Specified and applicable

Directory as a Data Source

As we are already aware, a collection can be populated dynamically using the data available from a variety of external data sources. A common attribute ‘Data Source’ is used to specify the Type and identity of the source from where the data is to be retrieved. Thereafter, the data is available as objects and the associated information can be extracted from them using the corresponding methods. For example, if the data is populated from an XML file, the tag names are referred to as the method names. In case the data is populated from a compound variable, the corresponding member variable names are referred to as method names.

Prior to this release, the Data Sources supported were:

  • XML available over HTTP/HTTPS using Post/Get methods
  • XML File available within the local disk or over a network
  • Output XML from an External DLL
  • Specific Objects from Current/Parent Report
  • Variable

Syntax

Data Source : <Type> : <Identity> [:<Encoding>]

Where,

<Type> specifies the type of data source: File Xml/HTTP Xml/Report/Parent Report/DLL/Variable

<Identity> can be file path, scope, etc., depending on the type specification.

<Encoding> can be ASCII or UNICODE. This is Optional. The default value is UNICODE.

From release 3.0 onwards, the collection attribute Data Source has been enhanced to support “Directory” as data source type. This will enable to gather all information pertaining to the contents of the disk directory/folder. Each folder constituent, i.e., either File or Directory, along with its corresponding details, are available as an object in the collection.

Let us consider the directory/folder “ABC”, as shown in the following figure:

Figure_1._Folder_path_(3.0).jpg

The folder contains two files “a.txt” and “b.txt” and the folder “abcsub”. In order to retrieve the item details along with the corresponding information like type, size and date modified within a collection, the attribute ‘Data Source’ can be specified with the new enhanced syntax as:

Syntax

[Collection : <Collection Name>]

Data Source : <Type> : <Identity> [:<Encoding>]

Where,

<Collection Name> is the name of the collection where the data is populated as objects.

<Type> specifies the type of data source. As per the new enhancement, it is “Directory”.

<Identity> is the Directory/folder Path, when the type specified is ‘Directory’

<Encoding> can be ignored for Type “Directory”.

The following code will populate the collection “ABC Contents” with the folder contents from the path “C:\ABC”. In this case, each of the items, i.e., a.txt, b.txt and “abcsub”, will be available as separate objects of the collection. The related information pertaining to each object will be available as methods $name, $filesize, $IsDirectory, $IsReadOnly, $IsHidden, etc.

[Collection : ABC Contents]

Data Source : Directory : “C:\ABC”

Note: $filesize is applicable only if the object is of type FILE.

Release 3.6

New methods LastModifiedDate and LastModifiedTime for File Properties

In Collection definition, Directory as a Data Source was supported in Release 3.0, where the properties of the file, i.e., Name, FileSize, IsDirectory, IsReadOnly and IsHidden, were supported as the Methods. In Release 3.6, two new methods called LastModifiedDate and LastModifiedTime have been introduced, to extract additional file properties in Tally.

This can be very useful in Integration scenarios with Tally using external Files. The last imported date and time can be validated against the Last Modified Date and Time of the File prior to importing from the file.

Method – $LastModifiedDate

$LastModifiedDate – It returns the date on which the file was last altered. The format supported is dd-mm-yyyy.

Syntax

$LastModifiedDate

Example

[Collection: ListofFiles]

Data Source : Directory : “C:\”

Format : $Name, 25

Format : $FileSize, 15

Format : $IsReadOnly, 15

Format : $LastModifiedDate, 15

Here, $LastModifiedDate will return the date on which the file was last modified, for example, 27-May-2012.

Method – $LastModifiedTime

$LastModifiedTime – It returns the time at which the file was last altered. The format supported is hh:mm:ss (24 hours)

Syntax

$LastModifiedTime

Example

[Collection : ListofFiles]

Data Source : Directory : “C:\”

Format : $Name, 25

Format : $FileSize, 15

Format : $IsReadOnly, 15

Format : $LastModifiedDate, 15

Format : $LastModifiedTime, 15

Here, $LastModifiedTime will return the time at which the file was last modified, e.g., 16:28:18.

 

Release 5.4.8

Conditional WalkEx

The condition parameter of the Collection attribute, WalkEx is now enhanced to check for every Source Object.

Syntax

Walk Ex: <Collection> [:Condition]

Condition is an optional parameter. When provided, each source object will be evaluated based on the condition to decide if Walk Ex (of the specified collection) has to be executed.

Other Enhancements

Please click the function/attribute name to know more.

  • $$IsCollSrcObjChanged : Currently, in Extract Collections while walking the sub-objects, there is no direct way of identifying if the source object context has changed. For this purpose, a new function IsCollSrcObjChanged is provided to identify when a source object is changed during a Walk.
  • $$CollSrcObj : A new function CollSrcObj is provided to evaluate expression in the context of source object while walking the current object.
  • Source Fetch : A new attribute Source Fetch is provided to fetch methods from source object context while walking the current object.
  • Aggr Compute : Apart from the keywords Sum, Min and Max, the collection attribute Aggr Compute is enhanced to support the keyword Last to extract the method value from the last object.
  • ReWalk and ReCompute : The collection attributes ReWalk and ReCompute are provided for re-computation in collections.
  • Prefetch and Source Prefetch : New attributes Prefetch and Source Prefetch are provided to pre-fetch the object method and retain the values for the subsequent usage within the current context, without having to re-evaluate the expression (in the Object Method) each time it is used.
Post a Comment