Objects, Collections, and Internal Object Structure
TDL is completely an object-oriented language. Whether it is creating an interface or storing some information in the Tally database, the fundamental artifact is an Object. All the interfaces and data storing elements are objects.
This topic gives a detailed conceptual understanding of objects, collections, and collection capabilities in terms of the fundamental data gathering and processing element of TDL. This topic starts by giving an understanding of the concept of an object in general. Progressively this topic explains the object structure and type of objects available in TDL. Then, the focus completely moves on to collections, their construction, sources, and capabilities.
Objects
Any information that is stored in a computer is referred to as data. The 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. Database Management System (DBMS) is used to access information from a database. 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.
All information related to an entity is referred to as an object. For example, an employee is an entity bearing properties like Employee Code, Employee Name, Salary, and so on. Each entity contains its own set of values for these attributes.
In order to store and manipulate this information, we need some procedures. These procedures are termed as methods that operate on data. Data and methods combined together are referred to as an Object. Objects are persisted or stored in the database. There can be a relationship established between various objects which can be
maintained and defined as per the database structure adopted. Tally follows a hierarchical data structure. The hierarchical data structure in detail is explained under the subsequent section ‘Tally Object Structure’.
Tally Object Structure
By design, the Tally database is hierarchical in nature i.e., objects are stored in a tree-like structure.
- Each node in the tree can be a tree in itself. In this structure, a parent can have multiple children but every child can have only one parent.
- A child can further have multiple children. All the characteristics of a child are inherited from its parent and no child can exist without a parent.
- Multiple objects are collectively referred to as a Collection. In other words, a collection contains multiple objects where an object can further contain methods and collections.
- Methods are used to retrieve stored values and collection consists of further objects.
The following diagram demonstrates the hierarchical data structure of the Tally database.
Whether it is an interface that is to be created or a data that needs to be persisted into the Tally database, the object follows a hierarchical structure. In order to construct a report, we can have a form that may contain multiple parts, each part subsequently can contain multiple lines which in turn is made up of fields. Based on the containership, a complete hierarchy of interface objects are created.
Similarly, all the data which is persisted into the Tally database has a predefined hierarchy. Any manipulations to the existing data need to strictly adhere to the hierarchy.
Let us understand the database object structure with an example of a Ledger object.
Ledger is the Base/Primary object. This object has methods Name, Parent, Opening Balance, and a collection of secondary objects Ledger Bill Allocations which can further contain multiple opening bills.
Each bill allocation object further has methods, Name, Bill Date, Bill Due Date, and Bill Amount. These Ledger Bill Allocation sub-objects are collectively referred to as Bill Allocations collection.
Object Types
As we already know that whether an Interface needs to be constructed or the data needs to be stored/manipulated, TDL uses Objects. Let us now understand the classification of objects based on their application and usage in various aspects. This is pictorially represented as shown below.
Interface Objects
Objects that are used for rendering the user interface are interface objects. The Report, Form, Part, Line, Field, Menu, Table, and Button are Interface objects. Interface objects like Report and Menu are independent items and can exist on their own. The objects Form, Part, Line, Table, and Field come into existence only when they are contained by their parent in the interface object hierarchy chain.
Data Objects
A data object is a region of storage that contains a value or group of values. Each value can be accessed using its identifier i.e., method or a more complex expression that refers to the sub-objects. Every interface object is associated with a data object to perform various operations like adding, retrieving, or altering information stored in the data objects. These data objects can either be internal objects or external objects.
Internal Objects
Internal objects are objects provided by the platform. These data objects which are stored as a part of the Tally database can be manipulated by the Tally user i.e., Data can be added, deleted, or updated from within Tally. There are several Internal objects like Company, Group, Ledger, Stock Group, Stock item, Unit of measure, Voucher Type, Cost Category, Cost Centre, Budget, and so on.
TDL/External Objects
Objects which cannot be stored as a part of the Tally database are classified as external objects and are used for some intermediate data manipulations and temporary storage. These objects are further categorized as
- Static objects
- Dynamic objects
Static objects are objects hardcoded in the TDL code and can be used for some specific purposes like accepting Inputs from the user during auto column reports, displaying in a report, etc. These objects can neither be added nor be altered by the Tally user.
Dynamic objects are temporary objects created in memory for performing various manipulations. The associated values for these objects can change during the execution of Tally. The source of these objects can be from a variety of data sources like ODBC, XML, DLL, and so on.
Collections
The fundamental data gathering and processing element of TDL is the collection definition. The bulk of aggregation, chaining, and integration capabilities are delivered using collections.
A collection is a group of objects/collections. The source of objects in the collection can be either an internal/TDL object. Each object in the collection follows a hierarchical structure i.e., it can further contain sub-collections within itself.
A collection is created using the collection definition.
Syntax
[Collection: <Collection Name>]
Where,
<Collection Name> is the identifier assigned to the desired collection of objects.
Example
[Collection: NewTDLCollection]
Types of Collections
As we have already seen, a collection is a group of multiple objects/collections, where each object can contain multiple methods and sub-collections.
Based on the type of collections available in TDL, its usage in default TDL/source code and constituents we can classify them as
- Simple Collections
- Compound Collections
The simple collection has multiple objects which contain a single method and contains zero sub-collections. Default TDL collections, Names, and Addresses are examples of simple collections.
The compound collection has multiple objects containing multiple methods and sub-collections. Ledgers and Stock items are examples of compound collections.
Populating a Collection
The data processing artifact in TDL provides extensive capabilities to construct and gather data from various data sources such as a collection of internal objects, collection of TDL objects, collection of objects available through ODBC driver, collection of objects from HTTP XML, collection of DLL objects.
It is also possible to construct a collection by aggregating/grouping data from lower levels in the object hierarchy chain. We can create a collection of selected/unselected objects in a Report, Parent Report, or from a Variable as well.
Using Internal Objects
Internal objects are objects predefined by the platform. We can populate internal objects using the attribute Type for the collection. This attribute determines the type or sub-type of the object the collection will hold.
Syntax
[Collection: <Collection Name>]
Type : <Object Type>:[<Parent Type>]
Where,
<Object Type> is the name of the primary object or sub-type.
<Parent Type> is the name of the parent object of the sub-type. This is an optional parameter and requires to be specified only if object-type is a sub-collection type.
If both object types and parent types are specified and if the current object context does not belong to the parent type, then attribute Child Of is mandatory which acts as an identifier to the parent type.
Primary Objects
Collection gathered using primary objects directly.
Example
[Collection: LedgerList]
Type : Ledger
The above code indicates collection Ledger List consists of Ledger objects
Sub Objects
Collection gathered using sub-collection/secondary collection.
Example
[Collection: Ledger Vouchers]
Type : Vouchers :Ledger
Child Of : ##LedgerName
Where variable LedgerName contains the ledger name selected by the user thereby gathering all the vouchers of the selected ledger.
Using External Objects
A collection can be populated using TDL/external Objects gathered from a variety of data sources. These objects can either be static/dynamic. We will now take the various cases of constructing a collection using the same.
Static Objects
Static objects are hardcoded objects’ as they are hardcoded in the TDL and object manipulations like addition, deletion, etc. cannot be performed with these objects by the Tally user. These values do not change during the execution of the program. The collection of these objects can be created by using attribute ‘List Name’ or ‘Object’.
Collection Attribute – List Name
The attribute List Name is used when field input needs to be limited to the given Table or List.
Example
[Collection: NameOfCourses]
List Name : BCom, BBM, BA, BCA, BSc
When we display this collection as a table we would receive the above objects as a list.
Collection Attribute – Object
Attribute Object is used to create a collection using objects which are created by the TDL programmer. The definition Object is used to define and assign values to the methods of such Objects. Object definition may contain zero or more user defined methods. If the Object contains a method Name, automatically it is being displayed
in the Table else Collection attribute Format must be used to display user defined method.
Object is similar to List Name attribute if objects defined contains only one method to be displayed in the Table.
Example
[Collection : CourseDetails]
Objects : Course1, Course2, Course3
Format : $CourseName, 30
We have created a collection using the objects Course1, Course2, Course3 which are defined subsequently. Format is used to specify the method name to be displayed in the table for user choice. Symbol prefix $ is used to extract value from the method CourseName and 30 indicates the width to be used for displaying the course name. Each object used in the Collection definition must be defined as shown below:
[Object : Course1]
CourseName: “BCom”
Duration : “3 Years”
[Object : Course2]
CourseName: “Bsc”
Duration : “3 Years”
[Object : Course1]
CourseName: “BBM”
Duration : “4 Years”
CourseName and Duration are user-specified methods and values to the right of the colon are the corresponding method values. When the above list is displayed for user selection and the user selects any course, the corresponding value for Duration can be extracted and displayed to the user.
Using Dynamic Objects
Dynamic objects are created dynamically from external sources like HTTP, XML, DLL, ODBC, XML File, etc. from selected objects in a Report, variables, and using information pertaining to a disk directory. Object manipulations like addition, deletion, etc. can be performed with these objects by the Tally user. These values change during the
execution of the program. The various attributes used for populating a collection using dynamic objects are discussed below.
Using an In-Memory Object
A collection can be populated using the attribute New Object which is using an object type specification as defined by the programmer. This is a very useful capability from the point of view of ‘In Memory Object manipulations’ required specifically in edit (alter/create) mode. This attribute will independently govern the type of object to be added to the collection on-the-fly. The following is now supported in the collection.
Syntax
New Object: <Type-of-Object>: <Condition>
Where,
<Type-of-Object> is the object specification as defined by the object definition.
<Condition> the object will be populated as per the condition specified.
Example
This collection can be used in a Report opened in edit mode (create/alter).
[Collection: Coll Customer]
New Object : Customer Data
;; New TDL Object defined
[Object: Customer Data]
Storage : Name : String
Storage : CustId : String
;; Compound Collection
Collection : PhoneColl : Phone
Collection : AddressColl : Address
[Object: Phone]
Storage : OfficeNo : String
Storage : HomeNo : String
Storage : Mobile : String
[Object: Address]
Storage : AddrLine1 : String
Storage : AddrLine2 : String
Using HTTP/HTTPS – XML Objects
The objects of a collection can also be obtained from remote XML using HTTP or HTTPS. Any data can be gathered from HTTP/HTTPS/web-service using XML request response. The received XML gets converted automatically to TDL objects and is available natively in TDL reports as $ based methods. The attributes in collection for gathering XML based data from a remote server over HTTP or HTTPS are RemoteURL, RemoteRequest, XMLObjectPath, and XMLObject.
Whenever the collection is being referred, the XML request is sent to the destined HTTP or HTTPS server, and the resultant XML data is fetched and is populated in the collection.
The attributes given below are provided specifically for using the source as HTTP XML. The generic attribute Data Source can also be used for the same which is discussed subsequently.
Syntax
[Collection: <Collection Name> ]
Remote URL :<HTTP/HTTPS URL Address>
Remote Request :<Request-Report-Name> , <Pre-Request-Edit-Report> :<Encoding Type>
XML Object Path : <Start-node> : <Path-to-start-node>
XML Object : <TDL-Object-Name>
Where,
The attribute Remote URL is used to specify the URL of the HTTP/HTTPS server delivering the XML data.
The attribute Remote Request is used to specify the report name which is to be sent to the HTTP/HTTPS server as an XML request, if the report requires user inputs, then it has to be accepted before the request is sent.
Pre-Request-Edit-Report specifies the name of the report which accepts the user input.
The attribute XML Object Path must contain the path to walk in the response XML which will be gathered as collection objects and is converted to TDL objects. By default, the root node is assumed to be the object Path.
Start Node allows you to specify the name and position of the XML node from which the data should be extracted. It takes two parameters as follows
<Node Name>: <Position>
<Path to Start Node> is used to specify the path to reach the <Start Node> from the root node.
The path specification is
<Root-node>: <Child Node> : <Start Pos>: <Child Node>: <Start Pos>:….
The attribute XML Object is used to specify the TDL object specifications with their respective Data types.
Using an SQL Object from an ODBC Source
Collection can also gather objects from various databases like Excel, Access, SQL, Oracle, etc. using the ODBC interface. Attributes ODBC, SQL, and SQL objects are used for gathering objects in the collection from the external data source using ODBC.
Syntax
[Collection: <Collection Name>]
ODBC : <ODBC Driver Connection Strings; File Path>
SQL : <SQL Select Query>
SQLObject : <TDL-Object-Name>
Where,
ODBC attribute is used to specify the ODBC driver connection strings along with file name and path
SQL attribute is used to specify the select statement for retrieving the required rows of the Table/Sheet
SQLObject attribute is used to specify the corresponding TDL object specifications with their respective data types.
Using Various Data Sources
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.
The collection attribute Data Source is used to populate data to a collection dynamically from a variety of data sources. This attribute accepts the Type and Identity of the data source from where the data is to be retrieved.
Some of the external sources supported in TDL using:
- XML available over HTTP/HTTPS
- XML File available over a Network
- JSON File available over HTTP/ a Network
- Output XML from an external DLL
- Specific objects from Current/Parent report
- Variable
- Directory
Syntax
DataSource : <Type> : <Identity>: [<Encoding>]
<Type> specifies the type of data source. The available data source types are File XML, HTTP XML, ODBC, Report, Parent Report, DLL, Variable, Directory, PlugIn XML, AxPlugIn XML, Rule Set, Num Set, Flag Set, File JSON, and HTTP JSON.
<Identity> Data source file path or the scope keywords
<Encoding> ASCII or UNICODE. This is an optional parameter. The default value is UNICODE.
XML Available Over HTTP/HTTPS/Network
The type specification will be File XML/HTTP XML depending on whether this is an XML available in the network or over an HTTP/HTTPS.
Example 1: XML File as Data Source
[Collection: My XML Coll]
Data Source : File XML : “C:MyFile.xml”
In the above example, 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 2: HTTP as Data Source
[Collection: My XML Coll]
Data Source : HTTP XML : “http:\localhostMyFile.xml”: ASCII
In the above code snippet, the type is HTTP XML as the data source is obtained through HTTP. The encoding of the file MyFile.XML is ASCII.
JSON File available over HTTP/Network
The type specification will be File JSON/HTTP JSON depending on whether this is the JSON file in the network or over an HTTP.
Example: Reading data from a GET Request
[Collection: TSPLGetBranchesColl]
Data Source : HTTP JSON: ” http://localhost/HttpJson/getbranchlist.php”
JSON Object Path : “BranchName:1”
The above code snippet sends a GET request to the URL mentioned and receives a list of branches as a response in JSON format.
Output XML from an External DLL
By using this attribute, we can invoke the DLL and convert the returned values into TDL objects for further processing. The value returned by the DLL is an XML. The type specification, in this case, is Plugin XML or AxPlugin XML. For DLL Objects, Plugin XML is used for C++ DLL, and for DLLs created in VB, VB.Net, etc. applications, AxPlugin.XML can be used. In this case, Identity is the Class Name.
Example:
[Collection: InputXMLCollection]
Data Source : AxPlugin XML : TestDLL.Class1
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 XML response received from the DLL is populated in the collection InputXMLCollection.
Specific Objects from Current/Parent Report
Collection can be created using specific objects from the current and parent report. The type specification in this case is Report/Parent Report. Identity is the scope specification keyword and is Selected Lines, UnSelected Lines, Current Line, All Lines, Line and Sorting Methods.
Example 1
[Collection: Selected Objects from Report]
Data Source : Report : Selected
In the above example, the selected objects of the current report are gathered in the collection and any further operations can be performed on these objects.
Example 2
[Collection: Selected Objects from Parent Report]
Data Source : Parent Report : Selected
In the above example, the selected objects of the parent report are gathered in the collection. Variable Collection can be created using the variable elements as the source. The type specification, in this case, is Variable. Identity is the Variable Name.
Example 3
[Collection: LV List Collection]
Data Source: Variable: SLVEmp
The elements of the Simple List Variable SLVEmp will be available as objects in the collection LV List Collection. Directory The collection can be created using the information pertaining to the contents of the disk directory/folder. The type specification, in this case, is a directory. Identity is the path of the directory.
Example
[Collection: ABC Contents]
Data Source: Directory: “C:ABC”
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. The syntax for the association to override the default association by using the value ‘Object Identifier Formula’.
Syntax
Object : <ObjectType> [: <Object Identifier Formula>]
Where,
< ObjectType > is a type of primary Object.
< Object Identifier Formula > 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.
Specifying Object Attribute in 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 you can use the attribute ‘Object Ex’ at part level.
Specifying ObjectEx Attribute in Part Definition
The attribute ‘Object Ex’ provides the ease of using a 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.
Line Level Object Association
An object can be associated with a Line by Part attribute Repeat’. The Part attribute ‘Repeat’ can be used to support the following.
- Extraction of collection from any Data object.
- Extraction of collection from UI Object associated Data object.
Attribute – Repeat
Syntax
Repeat : <Line Name> : <Collection Name> : [<Supplier Collection> : <SeekTypeKeyword> : <SeekCondition>]
Where,
< Collection 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
Accessing Data Directly 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 used 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
Collection – the data processing artifact of TDL, delivers immense capabilities in terms of:
- Data Retrieval/Extraction – Various attributes/actions provided help in populating a collection by using internal object types and also to push data into the same. The filtering capabilities allow conditional retrieval of specific data as well. Also, the searching and indexing capabilities facilitate faster retrieval enhancing the performance improvements.
- Data Presentation – The various processing attributes allow aggregation, chaining, combining and sorting facilities which are largely focused on advanced presentation of data as per complex business requirements.
- Integration – The various attributes allow the retrieval of data into collection from external data bases like HTTP/HTTPS/ODBC/DLL and so on.
In previous topics, 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
- Data Retrieval/Extraction
- Declaring Required Methods
- Union and Looping
- Filtering
- Sorting
- Searching
- Advanced Capabilities
- Grouping and Aggregation
- Usage As Tables
- Integration Capabilities using HTTP XML Collection
- Dynamic Object Support
- Collection Capabilities for Remoting
Basic Capabilities
Data Retrieval/Extraction
We have covered this capability in the previous sections on populating the collection.
Declaring Required Methods
Attribute – Fetch
After specifying the objects on the basis of which collection is constructed, it is mandatory to specify the required methods which are to be accessed from the objects. Fetch attribute is used to specify the required methods. The methods names are necessarily the internal methods available by default.
Syntax
Fetch : <Existing-Method-Name-in-Source>
Where,
<Existing-Method-Name-in-Source > refers to the methods, sub objects, and UDFs of the current object which are gathered in the collection.
Example
[Collection: Vouchers]
Type : Voucher
Fetch : Date, Narration
However, it would be difficult to specify each and every method from the current object. Also fetching only the method names of a collection is not sufficient, we do require its sub-collection and its methods. Hence wild cards can be used.
The two wild characters can be used in Fetch attribute specification ? and *
- ? is used to fetch all the methods of object in current context.
- * is used to fetch all the methods and sub collections of the object in context.
Example:1
To fetch all methods of object
[Collection: Vouchers]
Type :Voucher
Fetch 😕
Example:2
To fetch all methods and sub-collections of Voucher object
[Collection: Vouchers]
Type :Voucher
Fetch :*
Example:3
To fetch the methods Date, VoucherNumber, Narration and all the methods of collection Inventory Entries.
[Collection: Vouchers]
Type : Voucher
Fetch : Date, VoucherNumber, Narration, InventoryEntries.*
Attribute – Fetch Object
When multiple methods of a Single Object/Multiple Objects of the same type are required, then that Object can be fetched at Report, Form, Field and Function levels.
Report Level
The attribute Fetch Object attribute at the Report level, takes an expression instead of a variable name that evaluates to the name of an object.
Syntax
Fetch Object : <Object Type> : <Expression>: <List of methods>
Example
Fetch Object: Ledger: ##LedgerName: Name, Parent, ClosingBalance
Here, since the Object name is an expression, we need to prefix the variable name with ##.
Form Level
Attribute Fetch Object is used at Form level. In scenarios where multiple forms are available at a report; for each form, we require to fetch methods pertaining to different objects.
Syntax
Fetch Object : <Object Type> : <Expression>: <List of methods>
Example
[!Form:AccoutingViewVoucher]
Switch : AccVoucherView:NormalAccoutingViewVoucher:NOT$$IsAttendance:##SVVoucherType
Switch : AccVoucherView:AttdAccoutingViewVoucher:$$IsAttendance:##SVVoucherType
[!Form: AttdAccoutingViewVoucher]
Fetch Object: AttendanceType:@@AttdEntryList:AttendanceProductionType,AttendancePeriod,BaseUnits
[!Form: NormalAccoutingViewVoucher]
Fetch Object : Ledger: @@AllLedEntryList : Name, Parent, ReserveName
Field Level
There may be scenarios where we may need to Fetch Object values dynamically based on the current field values. For example, the field may be associated with a Table of ledgers. Based on the ledger selected, the corresponding methods of the Object require to be fetched. In such cases, this attribute will be useful.
Syntax
Fetch Object : <Object Type> : <Expression>: <List of methods>
Example
[Field: LED VAT Class]
Fetch Object: TaxClassification : $$Value : FirstAlias,RateofVAT,TaxType
Function Level
There may be scenarios where the method values need to be fetched based on the Object name passed as a parameter to the function. In such cases, ‘Fetch Object’ at the function level is required. If we have already fetched the object methods at the Report or Field level, the same will be propagated to the called function. In case it
is not fetched earlier, the same can be fetched at the Function level as well. This enables dynamic fetching of Objects.
Syntax
Fetch Object : <Object Type> : <Expression>: <List of methods>
Example
[Function: FillUsingTrackingObj]
Parameter :pTrackKey:String
Fetch Object :Tracking Number :##pTrackKey: *.*
In case the same set of methods for multiple objects needs to be fetched, the multiple Object Names need to be specified in the syntax of ‘Fetch Object’, separated by the Fetch separator character.
Function – $$FetchSeparator
This function returns C_FETCH_SEPARATOR character that is used for separating multiple object names in FETCH OBJECT attribute. There may be scenarios where the same set of methods needs to be fetched from multiple objects. In that case, it is possible to specify multiple object names in the ‘Fetch Object’ syntax, separated by the character which is returned from the function $$FetchSeparator.
Example
Fetch Object: Ledger: “Debtor North” +$$FetchSeparator + “Debtor South”: Name, Parent, ClosingBalance
Attribute – Fetch Values
This is a report level attribute which allows computation of values for user defined (external) methods, based on the current Object context available.
Syntax
Fetch Values: < List of Methods >
Example
[Report: VAT Classification]
Object : Tax Classification
Fetch Values: MasterID, CanDelete
Attribute – Multi Objects
This is a Report level attribute which is required to be specified, in case Multiple Objects of the same collection are being added/modified in a Report. It is required specifically in case of multi master creation or alteration.
Example
[Report: Multi Ledger]
Multi Objects: Ledger Under MGroup
Attribute – Compute
The specification of all internal methods which are required is handled by the Fetch attribute. In case, the external methods are to be computed for each object of the collection, the same needs to be specified by using the ‘Compute’ attribute.
Syntax
Compute : <Method-Name> : <Method-Formula>
Example:1
The internal method can be accessed by a different name by using the attribute compute.
[Collection: Vouchers]
Type :Voucher
Compute :VchDate : $Date
Example:2
The parent of the ledger and Stock item is computed at each object level of the voucher by referring to the corresponding Stock Item/Ledger Master.
[Collection: Vouchers]
Type :Voucher
Fetch :LedgerName
Compute :LedParent : $Parent:Ledger:$LedgerName
Compute :ItemParent: $Parent:StockItem:$StockItemName
In this example the LedParent and ItemParent is computed for the first object of the sub collections ‘Ledger Entries’ and ‘Inventory Entries’.
Union and Looping
‘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.
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:
As we already know, multiple objects of the same type are gathered in a collection. However at times it is insufficient for a report to have objects from only one object type. We may require to construct a collection which combines the objects of multiple collections. This operation is termed as a Union. We will be referring to the final collection in all our explanations as a ‘Resultant Collection’. Each component collection which is used to arrive at the resultant collection is referred to as a ‘Data Collection’. There are two ways in which the resultant collection is constructed.
- By specifying a list of data collections where each data collection is discrete in itself. This is referred to as Union pictorially shown as below:
Attribute – Collection
The attribute Collection is used to specify the various collections. This attribute combines all objects belonging to various collections within a single collection.
Syntax
Collection : <List of Data Collections>
Where,
<List of Data Collections> is a comma separated list of collection.
Example
[Collection: GroupAndLedger]
Collections : AllGroups, AllLedgers
[Collection: AllGroups]
Type : Group
[Collection: AllLedgers]
Type : Ledger
In the above example, the resultant collection ‘GroupAndLedger’ consists of all objects of groups as well as ledgers.
- By specifying a list of data collections where the same data collection is repeated over each object of another collection. This is referred to as looping and is shown in the image below:
TDL gives developer a capability to dynamically gather data collections in context of each object of another collection. ‘Collection’ attribute accepts two additional optional parameters i.e. Loop collection Name and Looping criteria. The collection names in the list of collection are referred as data collections. The collection on which the repetition is done is referred as loop collection. The collection in which data is populated is referred as a resultant collection.
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 loop collection. In the resultant collection objects are delivered as TDL objects. This makes it mandatory to fetch the required methods in the
data collection.
Syntax
Collection : <List of Data Collection>:[<Loop Collection Name>[:<Condition for Loop Collection>]]
Where,
<List of Data Collection> is comma separated list of data collections.
<Loop Collection Name> is the name of loop collection and it is optional.
<Condition for Loop Collection> is optional. The condition is evaluated on each object of the loop collection.
Example
The resultant collection will contain all the voucher objects for all the companies that are loaded.
[Collection: All Company Vouchers]
Collections : All Vouchers : All Companies
[Collection: All Vouchers]
Type : Voucher
Fetch : Date, VoucherNumber, VoucherTypeName, Amount,
Fetch : MasterID, LedgerName
Compute : CompanyName: $$LoopCollObj:$Name
[Collection: All Companies]
Type : Company
Fetch : Name
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.
In TDL, filter is applied on the collection and all the objects that satisfy the given condition are retrieved and populated in the collection. Attributes Child Of, Belongs To and Filter are available to filter and it is pictorically represented as below:
Attribute – Child Of
Attribute Child Of is a context sensitive attribute. The Child Of 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
[Collection : <Collection Name>]
Type : <Primary Object Type> or Type : <Sub Type>: <Primary Object Type>
Child Of : <String Formula>
- If the collection is constructed using the first Type syntax the expression in Child Of must evaluate to identifier for the parent of the primary object type.
Example
[Collection: My Collection]
Type :Ledger
Child Of :$$GroupSundryDebtors
If the type is Object Ledger, then the Child Of can evaluate to Sundry Debtors to gather all the ledgers under the Group Sundry Debtors .
- If the collection is constructed using the second Type syntax the expression in Child Of must evaluate to identifier for the primary object type.
[Collection: My Collection]
Type : Voucher : Ledger
Child Of : “ABC led”
If the Type attribute contains sub-type as vouchers and primary object type as ledger then Child of attribute must identify the ledger name for which all the vouchers will be gathered. If the object context for the primary object-type is available, then the Child Of specification is optional.
The following code will return all the ledgers under the group blank. By default, Tally returns the ledger ‘Profit and Loss’.
Child Of : “”
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 up to the lowermost level. Belongs To takes a logical value.
Syntax
Belongs To : <Logical Value>
Where,
< Logical Value > can be either Yes or No .
Example
[Collection : My Collection]
Type : Ledger
Child Of : $$GroupSundryDebtors
Belongs To : Yes
The above 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 : <Filter Name>
Where,
< Filter Name > is the name of a system formula.
Example
[Collection : LtdDebtors]
Type : Ledgers
Child Of : $$GroupSundryDebtors
Filter : NameFilter
[System : Formula]
NameFilter : $Name contains “Ltd” OR $Name contains “Limited”
First the Child Of is applied to filter all Sundry Debtor Ledgers and then an additional filter NameFilter is applied to to get only those ledgers whose name contains “Ltd” or “Limited”.
Filter can filter values based on any methods or UDF values within the current object whereas Child Of can only accept specific object identifiers as specified by the platform.
Sorting
Sorting refers to the arrangement of objects in a specific order within the collection. Objects of a collection can be sorted by specifying the sort sequence using the Sort attribute. The ordering is done on the basis of a specific method and the sort order can either be ascending or descending. For descending order, negative symbol must be prefixed.
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 Expressions>
Where,
< List of Expressions > 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
In the above collection, sorting will happen firstly on Closing Balance method in ascending order and then by Name in descending order.
Original Collection Before Sorting
Name | Closing Balance |
Global Traders | 10,000 |
Prism Softlinks | 25,000 |
Universal Computers | 10,000 |
Arvind Kumar | 12,500 |
Fortune Computer Services | 5,000 |
Janata Timbers | 7,000 |
Resultant Collection after Sorting on Closing Balance
Name | Closing Balance |
Fortune Computer Services | 5,000 |
Janata Timbers | 7,000 |
Global Traders | 10,000 |
Universal Computers | 10,000 |
Arvind Kumar | 12,500 |
Prism Softlinks | 25,000 |
In the table of sorted objects, please observe that when both the objects Universal Computers and Global Traders contain the same Closing Balance, the objects are further sorted on Name in descending order.
Searching
Collection capabilities are used 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.
‘Search Key’ attribute is used to specify the keys which are indexed for instant access. This implies that a unique key is created for every object which can be used to instantly access the corresponding objects and its values.
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 My Ledgers . In the Field, value $ClosingBalance 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.
The function $$CollectionFieldByKey will not work at menu level
Advanced Capabilities
Extraction and Chaining
To extract information from the collection using other collections, including its sub-objects, with the choice of methods, filters and sort-order. Specific attributes have been added at the collection level to achieve the same. As discussed the 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.
The function $$CollectionField will not work at menu level
Grouping & Aggregation
The language capability facilitates the creation of large summary aggregated objects very fast in a single operation which allows the developer to walk down the object hierarchies and gather values to summarize them in a single scan. The attributes used for aggregation and grouping are Walk, By and AggrCompute. The table below will give clarity on what is meant by grouping & aggregation.
Original Collection before Aggregation:
Student Name | Subject | Marks |
Krishna | English | 100 |
Radha | Maths | 95 |
Gopal | English | 75 |
Krishna | Maths | 97 |
Krishna | Science | 75 |
Radha | English | 90 |
Resultant Collection after Aggregation by Student Name:
Student Name | Total | Min | Max |
Krishna | 252 | 75 | 97 |
Radha | 185 | 90 | 95 |
Gopa | 75 | 75 | 75 |
In the above example we have the various rows as listed in the table Source. These rows need to be grouped on the basis of Student Name, i.e., all the rows having the same Student Name will be grouped together. Based on the grouping, the total, minimum and maximum of marks need to be calculated. This is termed as aggregation. The final set of rows which we achieve after applying the grouping criteria and aggregating the required columns is the table aggregated.
As we already know Tally follows a hierarchical data structure. In that case we will not have flat tabular structure as above. The language provides capabilities to walk down the hierarchy of the objects available in the source and perform grouping and aggregation on the same. Let us now discuss the various attributes for achieving the above.
Attribute – Source Collection
Source Collection specifies the collections to be used for source data. Multiple source collections can be used which can either be specified as a comma separated list or can be listed in several lines. The aggregation and grouping is applied thereafter on the source collection objects. The final collection which is arrived at is referred to as ‘summary collection’ in our discussions.
Syntax
Source Collection : <Collection Name>, <Collection Name>, ….
Where,
<Collection Name> is any predefined collection, the methods and sub objects of which are available to the current collection for further processing.
Example
[Collection: Vouchers Collection]
Type : Voucher
[Collection: Summary Collection]
Source Collection : Vouchers Collection
;;The ‘Summary Collection’ uses Vouchers Collection as source data.
Attribute – Walk
Attribute Walk allows us to traverse the hierarchy of sub objects which are available in the source. This will generate a set of objects which are required to be grouped and aggregated. Walk is optional and if not specified, the first level objects are only available for aggregation. Walk can be specified to any depth within the source object. This
gives enormous flexibility and power. The walk list has to be specified in the order in which they occur in the source object.
Syntax
Walk : <Sub-Object Type/ Sub-Collection>[, <Sub-Object Type/ Sub-Collection> …]
Where,
<Subobject Type/Subcollection> is the name of the sub objects/sub collection.
Example
[Collection: Vouchers Collection]
Type : Voucher
[Collection: Summary Collection]
Source Collection : Vouchers Collection
Walk :Inventory Entries
In the summary collection, by specifying Walk : Inventory Entries, the aggregation can be performed on the objects available by traversing till inventory entries collection. In case, objects pertaining to Batch Allocations are required, then walk can be written as:
[Collection: Summary Collection]
Source Collection :Vouchers Collection
Walk :Inventory Entries, Batch Allocations
Attribute – By
After walking to the desired level and generating the final set of objects to be aggregated, the next step is to identify the method on which grouping needs to be performed. This is termed as the grouping criteria. Attribute ‘By’ allows us to specify the grouping criteria.
Syntax
By : <Method-Name>: <Method-Formula>
Example:1
Grouping objects based on Stock Item name.
[Collection: Vouchers Collection]
Type : Voucher
[Collection: Summary Collection]
Source Collection : Vouchers Collection
Walk : Inventory Entries
By :StockItemName : $StockItemName
In Summary Collection, all objects having the same Stock Items names are grouped. This is specified with the ‘By’ attribute.
Example:2
Grouping objects based on party ledger name and then on Stock Item Name.
[Collection: Vouchers Collection]
Type : Vouchers: Voucher Type
Child Of : $$VchTypeSales
[Collection: Summary Collection]
Source Collection :Vouchers Collection
Walk :Inventory Entries
By :PartyLed : $PartyLedgerName
By :StockItemName : $StockItemName
In ‘Summary Collection’, all vouchers objects are grouped first on party ledger name and then by Stock Item Name.
Attribute – Aggr Compute
This is the final step in the whole process where aggregation operations like sum, max, min are applied to the methods on which aggregation is to be performed. This is done after the grouping criteria is specified. The aggregation will be done on the objects which are grouped together. The method on which aggregation is required can be of data type Number, Quantity, Rate or Amount.
Syntax
Aggr Compute : <Method-Name> : <Aggr-Type> : <Method-Formula>
Where,
<Method–Name> refers to the method name assigned to the result of the aggregated method
<Aggr–Type> takes operation to be performed on the given method within the given criteria i.e. Sum, Max or Min.
<Method–Formula> is the method name on which aggregation operation needs to be performed.
Example
After grouping the voucher objects on the basis of party ledger name and stock item name the sum of BilledQty needs to be computed.
[Collection: Vouchers Collection]
Type : Voucher
[Collection: Summary Collection]
Source Collection :Vouchers Collection
Walk :Inventory Entries
By :PartyLedgerName : $LedgerName
By :StockItemName : $StockItemName
Aggr Compute :TotBilledQty : Sum : $BilledQty
This is done by specifying the Aggr Compute attribute. The sum of Billed Qty for StockItem for a particular party is available with the method name “TotBilledQty” within the Summary Collection.
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.
Union of Summary Collections
There are scenarios where we have 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.
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 : VoucherSource
Walk : AllInventoryEntries
By : Particulars:$StockItemName
Aggr Compute : Tot Amount : 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
As seen from the example above both the collections Ledger Details and StockItem Details are using the same collection Voucher Source. We can observe that while gathering, 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 again for Inventory Entries.
The report finally uses the union collection Union LedStk Vouchers to render the same. In such cases, significant CPU cycles will be utilized in gathering and walking over the same source object along different paths more than once.
Using the WalkEx Approach
The attribute WalkEx 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.
Syntax
[Collection: <Collection Name>]
WalkEx: <Collection Name1>, <Collection Name2>, …..
Where,
<Collection Name1>, <Collection Name2> are the collection names specifying Walk and aggregation/ computation attributes.
;;The source collection “Voucher Source” is a Collection of Vouchers
[Collection: VoucherSource]
Type : Voucher
/* The collection “UnionLedStkVouchers” 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 values as collection names “Ledger Details” and “StockItem Details”*/
[Collection: Union LedStk Vouchers]
Source Collection : VoucherSource
WalkEx : Ledger Details, StockItem Details
Keep Source : ().
/*The Collection ”Ledger Details” is walked over “AllLedgerEntries” SubObjects and aggregates the amount by grouping over Ledger Name. Note that the absence of source collection */
[Collection: Ledger Details]
Walk : AllLedgerEntries
By : VchStockItem : $LedgerName
Aggr Compute : VchLedAmount : Sum : $Amount
/*The Collection ”StockItem Details” is walked over “AllInventoryEntries” SubObjects 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 the WalkEx uses 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: Src Coll]
…
/* Resultant Collection “Res Coll” is using the Source Collection “Src Coll”, and Walk Ex Collections “Walk Ex Coll 1” and “Walk Ex Coll 2” are specified */
[Collection: Res Coll]
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 | WalkEx 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 |
Compute/Filter 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 |
Walk/By | If specified, these two attributes will be ignored | Specified and applicable |
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 is used 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:
- 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 this 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 TallyPrime delivers. With remote access through Tally.NET Server, it will be possible for any authorized user to access TallyPrime from anywhere.
At collection level to achieve remoting capabilities the attributes Fetch, Compute and AggrCompute are 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 you can use the 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> is the name of the collection where the data is populated.
<String Expression>is 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 Source: HTTP 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 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:
- Source Collection
- Source Var
- Walk
- Compute Var
- By
- Aggr Compute
- Compute
- Filter Var
- Filter
With 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:
- The ‘Type‘ attribute is evaluated, and the objects of the specified type are identified.
- 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’.
- 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’.
- Steps 2 and 3 are repeated for each group in the collection ‘Test ComVar’.
- 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:
- Value of the variable SrcVar is evaluated, and referred in the Filter attribute of the collection ‘CFBK Voucher’.
- In the collection ‘Smp Stock Item’, the value of the variable Str Var is evaluated on the first object of source collection ‘CFBK Voucher’.
- Then, ‘Walk’ is performed and the Inventory Entry objects are collected.
- 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.
- The grouping is done on the resultant value of IName variable.
- The value of the method $BilledQty is computed.
- The variable Fin Obj Var retains a logical value if the method $BilledQty is greater than 100.
- Based on the value of Fin Obj Var, filtering is done.
- Finally, the collection is populated with the filtered objects.