In this release, there have been enhancements in User Defined Functions, Collections and Actions. We will see in depth the changes for the Actions - Print, Upload, Export and Mail. It is now possible to program the configurations for these Actions. This breakthrough capability has enabled to deliver the mass mailing feature in the product Tally.ERP 9.
Collection attribute Keep Source is enhanced to accept a new value, i.e., Keep Source : (). This has been done with the aim to improve the performance. The Loop Collection capability has paved the way for displaying and operating on Multi-Company Data, along with ease of programming.
The TDL language has been enriched with more and more procedural capabilities by introducing the Function $$LoopIndex and Looping construct FOR RANGE. There have been some changes in the Action NEW OBJECT as well.
With the introduction of the function $$SysInfo, it is now possible to retrieve all system-related information consistently using a single function.
In Tally.ERP 9, the actions Print , Export , Mail and Upload depend upon various parameters like Printer Name, File Name, Email To, etc. Prior to execution of these actions, the relevant parameters are captured in a Configuration Report. These parameters are persisted as system variables, so that the next time, these can be considered as default settings.
There are situations when multiple reports are being printed or mass mailing is being done in a sequence. Subsequent to each Print or Email Action, if a configuration report is popped up for user inputs, this interrupts the flow, thereby requiring a dedicated person to monitor the process, which is time-consuming too. This issue has been addressed in the recent enhancements in Tally.ERP 9, where the configuration report can be suppressed by specifying a logical parameter. Also, the variables can be set prior to invoking the desired action. Before exploring the new enhancements, let us see the existing behaviour of the actions Print, Email, Export and Upload.
Presently, in Tally.ERP 9, whenever any of these actions is invoked, a common Configuration report SVPrintConfiguration is displayed to accept the user inputs. The user provides the details in the configuration screen, based on the action being executed. The action gets executed based on the values provided in the configuration report.
The existing syntax of these actions was:
Syntax
<Action Na m e> : <Report Name>
Where,
< Action Name > can be any of Mail, Upload, Print or Export.
< Report Name > is the name of the Report.
For successful execution of these actions, along with the Report Name, additional action-specific parameters are also required. These action specific parameters are passed by setting the values of variables through the configuration report - ‘SVPrintConfiguration’.
The default configuration report 'SVPrintConfiguration' is invoked only when the Report specified does not contain the Print attribute in its own definition. The ‘Print’ attribute allows the user to specify his own configuration settings, whenever any of these Actions is invoked.
Example
Mail : Balance Sheet
The action Mail needs information regarding the To e-mail ID, From e-mail ID, CC e-mail ID, Email server name, etc., which are provided through the Configuration report.
For example, a report needs to be mailed to multiple e-mail IDs in one go. Currently, for every mail, the configuration screen is displayed, and every time, the user has to manually provide To email ID, From email ID, etc. So, whenever any of the above actions is executed, a configuration report is displayed, which requires user inputs. In some scenarios, this behaviour is not desirable. Configuration settings can be specified once, and the user should be able to use it multiple times.
The action syntax has been enhanced to avoid the display of configuration screen repeatedly.
The global actions Print, Export, Mail and Upload have been enhanced to suppress the Configuration Screen. These actions now accept an additional logical parameter. Based on the value of the logical parameter, the configuration report is suppressed.
The new enhanced syntax of these actions is:
Syntax
<Action Na m e> : <Report Name> : <Logical Value>
Where,
< Action Name > can be any of Mail , Upload , Print or Export .
< Report Name > is name of the Report.
< Logical Value > can be TRUE , FALSE , YES or NO .
With the new syntax, it is possible to configure the values of the report only once and then mail it to the specified e-mail addresses, without repeated display of the configuration report.
Example
10 : MAIL : Ledger Outstandings : TRUE
As the Configuration Report is not displayed, the values of the mail action specific variables like 'SVPrintFileName' , 'SVOutputName' , etc., must be specified for the successful execution of these actions.
The action MailEx is also used to mail the specified report to recipients. When you use the action MailEx, you can pre-configure the mailing information. It accepts only one parameter.
Following are the action-specific variables and their acceptable values:
The action-specific Variables can be classified into four categories based on their usage.
Common Variables
SVOutputType - The value of this variable is one of the predefined button type keywords like Print Button, Export Button, Upload Button and Mail Button. The variables’ value is used by the functions $$ InMailAction , $$ InPrintAction , $$ InUploadAction and $$ InExportAction to determine the execution of the correct option in the form 'SVPrintConfiguration'. For example, if the value of 'SVOutputType' is 'Print Button', then the optional form 'SV PrintConfig' in the report 'SVPrintConfiguration' is executed.
SVPrintFileName - This variable accepts the output location as value. The value of this variable is specific to each action. The usage of each action is explained in detail, along with the action.
SVExportFormat - The value of this variable is the name of the format to be used with the actions Mail, Upload and Export. The values are SDF, ASCII, HTML, EXCEL, XML, AnsiSDF, AnsiASCII, AnsiXML, AnsiHTML and AnsiExcel, which are set using $$SysName.
Example
01 : SET : SVExportFormat : $$SysName:Excel
SVExcelExportUpdateBook - This is a logical value and can be used only if the 'Excel' format is used. If the value is set to YES, then the existing file is overwritten; otherwise, it will ask for "Overwrite" confirmation.
SVBrowserWidth , SVBrowserHeight - These variables are used to set the width and height of the page when the format is HTML.
As soon as the user executes a Print action, the following screen is displayed:
This screen captures the user inputs such as the "Printer Name", "No. of Copies" to be printed, etc. The various action specific variables required by the ‘Print’ action are modified, based on the user inputs. Following variables are used by Print action:
SVPrintMode - This variable used by ‘Print’ action accepts the printing mode as the value. The Print mode can be ‘Neat’, ‘DMP’ or ‘Draft’, which are system names. Default mode is Neat mode.
SVPrintFileName - This variable is applicable for ‘Print’ action, only if ‘Print To File’ option is selected by the user, while printing in DOT Matrix or Quick/Draft format. In this case, the variable
‘SVPrintFileName’ accepts filename using function $$MakeExportName, to add right extensions.
SVPrintToFile - This is a logical value which determines if the print output should be saved in a file. If the value is TRUE, the output is saved in the file specified in the variable 'SVPrintFileName'. If the vale is FALSE, then the variable 'SVPrinterName' must contain a valid printer name.
SVPrinterName - It accepts a printer name as a value for printing. The default value is taken from the system settings available in Control Panel for Printers and Faxes.
SVPreview - This is a logical variable and is applicable only for ‘Print’ action with ‘Neat’ mode format. If the value is set to YES, then the preview of the report is displayed. Otherwise, the report is printed, without displaying the preview.
SVPrintCopies - It is applicable only for ‘Print’ action. It accepts a number to print multiple copies.
SVPrePrinted - The variable is applicable only for ‘Print’ action, and it specifies whether a pre-printed stationary or plain paper is to be used for printing.
SVPrintRange - It is applicable only for Print action. It determines the range of pages to be printed.
SV Draft Split Names - It accepts a logical value to determine if the long names should be split into multiple lines.
SV Draft Split Numbers - It accepts a logical value to determine if the long numbers should be split into multiple lines.
SVPrintStartPageNo - It is applicable only for Print action. It allows to specify starting page no. SVPosMode - It determines if POS mode is to be used. The default value of this variable is NO.
V ariabl e s S pecif i c to Action – Export
The following screen is displayed when the user executes ‘Export’ action.
This screen captures the user inputs such as "Export Format","Output File Name", etc. The action ‘Export’ uses the variables 'SVExportFormat' , 'SVPrintFileName' , etc.
SVPrintFileName - For the Export action, the value of this variable is the output file name. The path can be specified directly, or the function $$ MakeExportName can be used to create the output path. The function $$ MakeExportName suffixes the extension based on the export format, if only the file name is passed as a parameter.
Syntax
$$MakeExportName : <String Formu l a> : <Export format>
Where,
< String Formula > is a string formula which evaluates to the path\filename.
< Export format > is the name of the format which has to be used while exporting.
Example
$$MakeExportName : "C:\Tally.ERP\abc.xls" : Excel
When the user executes ‘Mail’ action, following screen is displayed to capture the mailing details:
For successful execution of ‘Mail’ action, user has to enter the above details. The URL is then created using function $$ MakeMailName , and the value is stored in variable ‘SVPrintFileName’ .
SVPrintFileName - This variable accepts the URL location as value. Function $$ MakeMailName is used to construct the URL. The mail is sent to specified mail addresses using the given server.
Syntax
$$MakeMailName :<ToAddress> :<SMTP Sever name> :<From Address>:<CC Address> :<Subje c t>:<Username> :<Password>:<Use SSL flag>
Where,
< T o Address> is the e-mail id of the receiver.
<S M T P Se rv e r N a me> is the name of the server from which the mail is sent.
<From Addre s s> is the send e r's e-mail id.
<CC Address> is the em a il-id where the copy of the mail is to be sent.
<Subje c t> is the subj e ct of the mail.
<User Name> is the user id on the secured server.
<Password> is the p assword for the user id on the sec u red serve r .
<Use SSL Fl a g> c an be TRU E / F A L S E OR YE S / N O . If the Us e SS L flag is s et to TRUE, then the User n ame and Password must be specifie d , i.e . , they can't be e m pty.
Example:
$$MakeMailName:"xyz@xyz.com":"abc"+"<"+"abc@abc.com"+">"smtp.gmail.com":"abc@gmail.com":"":"Your outstanding+
payment":+abc@gmail.com:abc123:True
Following screen is displayed to capture details of the folder where the report is to be uploaded:
Based on information entered by the user, the URL of the upload site is created using function $$MakeHTTPName or $$MakeFTPName , and the value is stored in variable 'SVPrintFileName' . SVPrintFileName - It accepts the URL of upload site. The URL is constructed using the functions $$MakeHTTPName or $$MakeFTPName , depending on protocol selected by the user for upload. Function $$MakeFTPName is used for creating the file transfer protocol, based on specifications.
Syntax
$$MakeFTPName : <FtpServer> : <FtpUser> : <FtpPassword> : <FtpPath>
Where,
< FtpServer > is the FTP server name.
< FtpUser > is the FTP user name.
< FtpPassword > is the FTP password.
< FtpPath > is the full path of the folder on the FTP server.
Example:
$$MakeFTPName:"ftp://ftp.microsoft.com":"":"":"dbook.xml"
Function $$MakeHTTPName is used for creating the Hyper Text Transfer Protocol for the specified security features.
Syntax
$$MakeHTTPName : <HttpUrl> : <HttpIsSecure> : <HttpUserName> : <HttpPassword> : <CompanyName>
Where,
< HttpUrl > is the HTTP URL name.
< HttpIsSecure > is a logical attribute which checks whether the HTTP is secure or not.
< HttpUserName > is the HTTP user name.
< HttpPassword > is the HTTP password.
< CompanyName > is the name of the Company.
Example
$$MakeHTTPName:"https://www.abc.com":Yes:"guestuser":"pswd99":"ABC Company Ltd"
Report "Bill-wise details" is to be mailed to each party with their respective Bill Details. However, mails to all parties should be sent at one key stroke, without the e-mail configuration screen popping up multiple times. As of now, a user has to manually enter email IDs for each ledger.
Solution : Following steps need to be implemented:
Step 1 : Create Function
[Function : FuncEmailingOutstanding]
Variable : LedgerName : String
Step 2 : Create Local Formulae for enhanced readability of code
Local Formula : FromAddress : "abc" + "<abc@abc.com>"
Local Formula : ToAddress : if $$IsEmpty:$Email then "abc@abc.com" else $Email
Local Formula : Subject : ##LedgerName + "(Bill-wise Details)"
Step 3 : Set the values of common variables used in ‘Mail’ action
03a : SET : SVExportFormat : $$SysName:HTML
Step 4 : Walk the Ledger Collection to retrieve the email-id of the ledger
01 : WALK COLLECTION : SDLedger
Step 5 : Set the values of the variables used in ‘Mail’ action
02 : SET : LedgerName : $Name
03b : SET : SVMailEmbedImage : @@AsAttach
03c : SET : ExplodeFlag : "Detailed"
03d : SET : SVPrintFileName : $$MakeMailName:@ToAddress:“smtp,gmail.com”:@FromAddress:"admin@tallysolutions.com":@Subject :"" :"":FALSE
Step 6 : Call the action
04 : MAIL : Ledger Outstandings : TRUE
;; TRUE is meant to suppress the configuration report
06 : END WALK
|
|
08 : RETURN
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.
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 collection data has to be kept available at 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 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 sub group.
[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
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 report, parent report, collection/s and external data sources like excel, XML, etc.
It is possible to gather the 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. 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.
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
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.
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, V ouchernumber, VoucherT y peName, A mount, M a sterID , Ledger N ame
Compute : Owner C o mpany : $$LoopC o llObj: $ 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
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 , BaseUnit s, Clos i ngBalan c e
;;Loop Collection
[Collection : GrpCm p Coll]
Type : Member Lis t : Co m pany
Child Of : # #SVCurr e ntComp a ny
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 following table:
Co m pany Name |
S tock 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 StkColl |
Objects in collection GrpCmpSSLoopCollection |
Objects in collection GrpCmpSSRepeatColl |
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 |
Various reports can be generated in Tally.ERP 9 relevant to the user’s business requirement. All the reports are generated in 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. The 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 to the current company A forcefully, and their closing balance is displayed in the column as follows:
Ledger Name |
A Closi n g Balance |
L1 |
100 |
L2 |
200 |
L3 |
300 |
L4 |
400 |
L5 |
500 |
L6 |
600 |
When an a d ditional column is a dded f or c o mpany B, the report is displ a yed as follows:
Ledger Name |
A Closi n g Balance |
B Closi n g Balance |
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 Closi n g Balance |
B Closi n g Balance |
C Closi n g Balance |
L1 |
100 |
||
L2 |
200 |
||
L3 |
300 |
||
L4 |
400 |
||
L5 |
500 |
||
L6 |
600 |
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.
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 context of HTTP Post, the usage remains as it is.
The user-defined function can use a newly introduce looping construct which iterates for the given range of values, and the action New Object has been enhanced to accept a logical value.
As explained earlier, TDL allows different looping constructs for varied usage. The existing loop constructs allow us to loop on the objects in collection or on the tokenized string or condition based looping of a set of statement.
There are scenarios where the looping is to be performed for a range of values. For this, a new loop FOR RANGE has been introduced. The newly introduced loop construct allows to loop on a range of numbers or date. This loop can be used to repeat a loop for the given range of specified values. The range can either be incremental or decremental. The FOR RANGE loop can be used to get the Period Collection-like functionality.
Syntax
FOR RANGE : <Iterator Var> : <Data type> : <StartRangeExpr> : <EndRangeExpr> [:<Increment Expr>[:<DateRangeKeyword>]]
Where,
< Iterator Var Name > is the name of the variable used for the iteration. This variable is created implicitly.
< Data Type > can be Number or Date only.
< StartRangeExpr > is an expression which evaluates to number or date values. It refers to the starting value of the range.
< EndRangeExpr > is an expression which evaluates to number or date values. It refers to the end value of the range.
< Increment Expr > is an expression which evaluates to a number by which the <StartRange- Expr> value is incremented. It is optional, and the default value is 1.
< DateRangeKeyword > is optional, and only applicable if the data type is Date. The values can be any one of 'Day', 'Week', 'Month' and 'Year'.
Example
|
01 : FOR RANGE : It e ratorVar : Number : 2 : 10 : 2
02 : LIST ADD : Ev e nNo : ##It e ratorV a r
03 : END FOR
|
The values 2,4,6,8,10 are added in the List variable 'EvenNo', as the range of value is 2 to 10, and the value is incremented by 2 with each iteration.
Example
The following code snippet is used to calculate the number of weeks elapsed between System date and Current Date set in Tally.
|
09 : FOR RANGE : IteratorVar : Date : # #SVCurrentDate : $$MachineDate :
1 : "Wee k "
10 : LOG : ##I t eratorVar
20 : INCREME N T : Cnt
30 : END FOR
50 : LOG : "No of weeks Back Dated : " + $$S t ring: # #Cnt
60 : RETURN : ##C n t
|
Assume that the range for this is from 15 - Mar - 2009 to 30 - Mar - 2009. The values 15-Mar-2009, 22-Mar-2009 and 29-Mar-2009 are logged, as the increment is done by a 'Week'. So, there are three iterations of the loop. The number of weeks is logged using the counter.
Example
|
09 : FOR RANGE : IteratorVar : Date : ##SVFromDate:##SVToDate : 1 : "Month"
10 : LOG : $$MonthEnd:##IteratorVar
20 : END FOR
|
Assume that the range for this is from 1-Jan-2009 to 5-Mar-2009. The values 31-Jan-2009, 28- Feb-2009 and 31 -Mar -2009 are logged.
The TDL programming community is now aware about the enhancements that have been introduced in TDL language and are efficiently implementing the same in the programs.
A vast area of possible extensions is unlocked by the User Defined Functions in TDL. User defined functions gave the sequential control in the hands of the TDL programmers. Many actions and looping constructs have been introduced in User Defined Functions in TDL. During the sequential execution, the loops are used to iterate through a set of values. TDL allows nested loops as well.
There are scenarios where the loop counter is required for some evaluation. Presently, a variable is defined and then at the end of loop, its value is incremented. This variable can be used for some calculations, if required. To avoid this inline declaration of variable which is solely used as a counter, a new function $$Loop Index has been introduced.
The function $$LoopIndex gives the count of how many times the current loop is executed. In case of nested loops, the additional parameter <outer loop index number> can be used in the inner loop to get the current iteration count of the outer loop.
Syntax
$$LoopIndex [:<Outer Loop Index Expr>]
Where,
< Outer Loop Index Expr > can be any expression which evaluates to a number. It is optional, and the outer loop index number in the nested loop hierarchy from the inner most loop to the outer most loop. For the current loop, the value is 0 by default, for the parent loop 1, and so on.
Consider f ollowing example:
[Function : LoopIndex Test]
|
|
05 : WALK COLLECTION : ………
|
WHILE : …….
|
|
FOR : ……….
SET : Var: $$LoopIndex LOG : ##Var
|
END FOR
SET : Var1: $$LoopIndex:1
|
END WHILE
|
|
END WALK
The variable Var will hold the count of number of times the FOR loop is executed, while the variable Var1 will have the count of ‘WALK Collection’ loop execution.
The action ‘ New Object ’ takes two parameters Object Type and Object Identifier. The syntax is:
Syntax
NEW OBJECT : <Object Type> : [:<Object Identifier>]
Where,
< Object Type > is the type of the object to be created,
< Object Identifier > is the unique identifier of the object. This parameter is optional. In case this is not specified, it creates a blank object of the specified type.
The actions Save Target/Alter Target/Create Target are used along with New Object for specific usage. There are three scenarios to consider for this:
● In case a Blank Object is created using ‘New Object’ without specifying the Object Identifier, the actions ‘Save Target’ and ‘Create Target’ will work, while ‘Alter Target’ would fail.
● In case an existing object is brought into context by specifying Object Identifier with ‘New Object’, the actions ‘Save Target’ and ‘Alter Target’ will work, while ‘Create Target’ would fail.
Note: Save Target’ saves the current Object, whether it is a blank new Object, or an existing Object for Alteration.
● When an Object Identifier is specified with ‘New Object’ and the object does not exist in the database, the Action ‘Save Target’ fails, as ‘New Object’ does not create a blank object.
In order to overcome the scenario (3), the Action ‘New Object’ has been enhanced to accept an additional parameter ‘Force Create Flag’ along with the Object Identifier. This forces the creation of an empty blank object, in case the Object with Identifier does not exist in the database.
Syntax
NEW OBJECT : <Object Type> : [:<Object Identifier>[:<Forced Create Flag>]]
Where,
< Object Type > is the type of the object to be created,
< Object Identifier > is the unique identifier of the object.
< Forced Create Flag > is an Optional Flag and is required only if < Object Identifier > is specified. If the Flag is set to TRUE, then if the object identified by < Object Identifier > exists, the object is altered; otherwise, a new empty object of the specified type is created.
Example
|
01: NEW OBJECT : Group : ##EGroupName : TRUE
02: SET VALUE : Name : ##NGroupName
03: SAVE TARGET
|
If the ledger identified by '##EGroupName' exists in Tally database, then the objects are altered by the action SAVE TARGET; else, a new object is created as the Forced flag is set to 'YES'.
A new function $$SysInfo has been introduced to get system related information. Click here to know more about the function SysInfo.