On this page
|
The Release 4.8 of Tally.ERP 9 comes with a number of TDL enhancements in Data Import, Events, Actions, Functions, etc., which have been discussed ahead in detail.
Updation of data is vital for all kinds of reports generated in any business organisation. Hence, the designed system must be robust enough to accept the data with appropriate validation and controls. ‘Garbage in, Garbage Out’, as we have commonly heard, means that any invalid data entered into the system would result in an invalid output. Tally allows updation of data through various sources. They are:
o Manual Data Entry
o Data Updation thr o ugh Us e r Defin e d Functio n s, fr o m any External Source
o Data Import from X ML/SDF fil e s, S ynchro n ization and Third P arty Application Request
Whenever data is received for updation from any source, validations like matching of Debit/Credit Totals, availability of dependent masters in the data while importing voucher, etc., are done prior to updating the database. These basic validations, without which Objects cannot exist in the database, are taken care of by the Tally platform, irrespective of the data source. However, there are certain business rules/controls like Entry outside Current Accounting Period not being accepted, Sales to Party exceeding Credit Limits not being allowed, etc., which also need to be applied. In the case of User Interface, these controls are provided within the default application, so that when the user makes entries, the data is accepted only after these controls are passed. While updating the Data through a User Defined Function, the programmer can apply the relevant checks prior to importing the Objects in the Tally Database.
Before this Release, during data import from XML/SDF files, Synchronization or from an external request, the data could not be validated for these business rules, and hence, the data import could not be stopped even if the Object was invalid. In Release 4.8, a few Enhancements have been made to give appropriate controls to the Programmer during the process of importing the data from any source. Thus, it empowers the TDL Programmer to take any desired action while Importing the Data. These enhancements are as listed below:
● Apart from the three existing Import File Events, namely ‘ START IMPORT ’, ‘ IMPORT OBJECT ’ and ‘ END IMPORT ’, a new Event ‘ After Import Object ’ has been introduced to perform the desired action after importing every Object.
● Two Logical System Variables ‘SVImportObject’ and ‘SVContinueImport’ have been introduced, which give control to the TDL Programmer to conditionally import the Objects, or to terminate the Import Process.
● Enhancements have also been introduced for sending a customized response to the requesting application, in case of SOAP Request.
● To complement all the above Enhancements, a set of new Functions like $$ImportInfo , $$HTTPInfo , $$ImportType , $$LastImportError , etc., have been introduced.
The Import Events ‘Start Import’, ‘Import Object’ and ‘End Import’ are available in Tally.ERP 9 since Release 3.0. All these Import Events can be used within the Definition ‘Import File’.
● The Event ‘ Start Import ’ is invoked only once, at the beginning of Data Import.
● The Event ‘ Import Object ’ is invoked for every Object, prior to importing the Object in current context.
● The Event ‘ End Import ’ is invoked only once, at the end of Data Import.
In Release 4.8, a new event After Import Object has been introduced to allow the TDL Programmer to take any desired action, every time an Object is imported. This Event will help the user to create appropriate logs after Importing of each Object, terminate the Import Process based on some condition, track/record changes that can be used for preparing the response (for SOAP requests), etc.
Syntax
[Import File : <Import File Definition Name>]
On : After Import Object: <Logical Condition Expr> : <Action Keyword> : <Action Parameters>
Where,
< Logical Condition Expr > is a logical expression, which when evaluates to TRUE, executes the given Action.
< Action Keyword > is the Action to be taken once the System Event is triggered.
< Action Parameters > are the parameters required for the particular Action.
Example
[Import File : All Masters]
On : After Import Object : Yes : Call : Update Log
On : End Import : Yes : Call : Show Log
[Function : Update Log]
00 : If : $$ImportAction = "Errors"
;; New Function introduced to check whether the updation of current object is successful or encountered with an error
10 : Log : $$LastImportError
;; New Function to return the Error encountered during last Import Object
20 : End If
[Function : Update Log]
10 : Exec Command : TDLFunc.Log
In this example, after import of each Object, the Event ‘After Import Object’ is triggered, which calls a Function ‘Update Log’ to update the logs with Error String, if any. Once the Import Ends, the Event ‘End Import’ is triggered, thereby calling the Function ‘Show Log’ to open the File TDLFunc.Log for browsing through the errors occurred, if any.
Note: The currently imported object is available as the object in context.
The Events ‘Start Import’, ‘Import Object’, ‘After Import Object’ and ‘End Import’ provide some controls to the TDL Programmer. Inspite of having these controls, the Objects would get imported after performing the Actions corresponding to the Events, irrespective of the user choice. Hence, to give complete control to the user to take the suitable action, two new Logical System Variables ‘SVImportObject’ and ‘SVContinueImport’ have been introduced.
With the help of the System Variable ‘SVImportObject’, the TDL Programmer is empowered to decide whether to import the current object or not. It is a logical variable which communicates the same information to the system. If this Variable is set to FALSE or NO, the current Object will not be imported. The default value of this variable is TRUE or YES. Ideally, the value of this variable needs to be set/altered only at the Event ‘Import Object’, which is triggered prior to importing the current Object.
Example
[#Import Fi l e : All Masters]
On : Import Object : $$Is S tockIte m :Call: D ontover r ideExi s tingItem
[Function : DontoverrideExistingItem]
00 : IF : $$IsEmpty:$Name:StockItem:$Name
10 : Set : SVImportObject : True
15 : Msg Box : "Creation" : "Stock Item" + $Name + "being created"
20 : Else :
30 : Set : SVImportObject : False
35 : Msg Box : "Alteration" : "Stock Item" + $Name + "already + exists and cannot be altered"
40 : End If
In this example, the Event ‘Import Object’ is triggered while importing the Masters and the Function ‘DontoverrideExistingItem’ is invoked only if the current Object is of Type ‘Stock Item’. This Function checks if the current Stock Item is available in the Tally Database. If the Stock Item is not found, then the Variable ‘SVImportObject’ is set to TRUE, which instructs the system to continue to import the current Stock Item Object. If the Stock Item is found in the current Company being Imported, the Variable ‘SVImportObject’ is set to FALSE, which prohibits the Importing of the current Stock Item Object.
With the help of System Variable ‘SVContinueImport’, the TDL Programmer gets the control to decide whether to terminate the Import Process, or to continue further. It is a Logical Variable which communicates the same information to the System. If the Logical value of the Variable is set to FALSE or NO, the import process will be terminated. The default value is TRUE. Ideally, the value of this variable needs to be set/altered only at the Event ‘Import Object’ or ‘After Import Object’, since these events are triggered before and after the importing of every Object.
Example
[#Import File : Vouchers]
On : Start Import : Yes : Call : InitializeSystemVariable
On : Import Object : Yes : Call : IncrementSystemVariable
On : After Import Object : ##SystemVarforImport= 50 : Call : TerminateImportProcess
[Function : InitializeSystemVariable]
00 : Set : SystemVarforImport : 1
[Function : IncrementSystemVariable]
00 : Increment : SystemVarforImport
[Function : TerminateImportProcess]
00 : Set : SVContinueImport : False
In this example, it is intended to import only 50 Objects, beyond which, the Import process should be terminated. A variable ‘SystemVarforImport’ is initialized at the ‘Start Import’ Event. During the ‘Import Object’ Event, the value of this variable is Incremented for each Object. After importing 50 Objects, the Import Process is terminated by setting the Variable ‘SVContinueImport’ to FALSE.
When a SOAP Request is received to Import Data from an external application, Tally.ERP 9 imports the data and sends an appropriate default response to the Third Party Client. The default response sent to the requesting Clients after Importing the Data is as follows:
<RESPONSE>
<CREATED>3</CREATED>
<ALTERED>2</ALTERED>
<LASTVCHID>87</LASTVCHID>
<LASTMID>0</LASTMID>
<COMBINED>0</COMBINED>
<IGNORED>0</IGNORED>
<ERRORS>0</ERRORS>
<CANCELLED>0</CANCELLED>
</RESPONSE>
However, the various Clients sending requests have disparate Integration solutions implemented and hence, the expectation is that the response must be in the formats prescribed by their Integration Solutions. Thus, in order to provide flexibility to the TDL Programmer by supporting the required formats in disparate Integration scenarios, a new Import File Attribute ‘Response Report’ has been introduced.
The attribute ‘Response Report’ has been introduced in the ‘Report File’ definition to allow the TDL Programmer to send the response back to the requesting clients. It accepts the Report Name as the parameter. This Report will be used to construct the XML Response, which will be sent back to the Clients.
Syntax
[Import File : <Import File Name>]
Response Report : <Report Name>
Where,
< Import File Name > is any Import File Definition Name, for which the appropriate Response needs to be constructed.
< Report Name > is the Name of the Report which is used to construct the XML Response to be sent to the Client.
Example
[Import File : Vouchers]
Response Report : TallyCustomResponse
;; Report to be defined with appropriate XML Tags
In this example, the Response Report ‘TallyCustomResponse’ needs to be defined, with appropriate XML Tags. However, to update the values like the no. of vouchers created, altered, etc., some platform functions are required, which are explained in the next topic ‘Functions Introduced’.
The Response report can also be used for recording additional information and using it at the time of preparation of response. When the Response report is specified, the system will only send the output as created in the Response Report, and hence, the TDL programmer has to make sure that the required output is generated from this Report. If the requestor wants to know what happened to the individual objects sent, it is now possible to track the same using these Enhancements and send an appropriate response for each.
The Function $$ HttpInfo is used for getting the details of the URL Host, Content-Length and Header information available during the receiving of the SOAP request. This Function accepts two parameters - ‘InfoType’ and ‘Info Sub Type’. Info Type accepts the URL, the Content-Length and the Header. Info Sub Types can appear only for Info Type Header. When Info Type is Header, all the Header details like UNICODE, Connection, Content-Type, etc., can be extracted.
Syntax
$$HTTPInfo : <Info Type>
$$HTTPInfo : Header : <Info Sub Type>
Where,
< Info Type > can be URL, Content-Length or Header.
< Info Sub Type > is necessary only if the Info Type is a Header, and can consist of any Request Header information.
Let us see some examples with respect to the SOAP Request as seen in Figure 1.
Example
$$HTTPInfo:ContentLength
From the SOAP request received, the function extracts the ContentLength and returns the value as 12512.
$$HTTPInfo:Header:ContentType
From the SOAP request received, the function extracts and returns the value of the Header Content-Type, which is text/xml; charset=Utf-16 in this case.
$$HTTPInfo:Header:Unicode
From the SOAP Request received, the function extracts the value of the Header UNICODE, which is YES in this case.
The Function $$ HTTPInfo can be used to retrieve any value from the Header. For example, to retrieve the Mobile Number from an SMS received through ‘NatLangQuery’ Event, we can use the expression $$HTTPInfo:Header:MobileNumber
The Function $$ ImportType is used to determine the type of Import, i.e., the source of data. The possible Import Types could be ‘Sync’, ‘Migration’, ‘Remote’, ‘NatLang’, ‘SOAP’ and ‘Manual’.
Syntax
$$ImportType
Here, the Function returns the source of data, which could be any one of the above sources.
This function is used to indicate the status of Import, i.e., whether the current Object was Created, Altered, etc. The possible results are ‘Created’, ‘Altered’, ‘Ignored’, ‘Combined’, and ‘Error’.
Syntax
$$ImportAction
Here, the function returns the status of the Import of current object.
The Function $$LastImportError can be used to extract the Import error description for the last object imported, which is helpful to retrieve after every import, and appropriate error logs can be maintained and displayed at the end of the Import Process. In case there is no Error while Importing the current Object, it would return the value as ‘Empty’.
Syntax
$$LastImportError
Here, the function returns the Import error description for the last object imported.
The Function $$ImportInfo can be used to extract the details of the Imported Objects in terms of Number of Objects Created, Altered, Ignored, Combined, etc., and Errors encountered. This Function accepts a parameter InfoType .
Syntax
$$ImportInfo : <Info Type>
The permissible values for the parameter ‘Info Type’ are ‘Created’, ‘Altered’, ‘Ignored’, ‘Combined’ and ‘Errors’. This Function returns the Number of Objects Imported as specified by the parameter Info Type. For instance, if the parameter ‘Info Type’ is specified as ‘Created’, the function returns the Number of Objects Created during the Import Process and if the Parameter contains Errors, it returns the Number of Errors encountered during the Import Process.
Example
$$ImportInfo:Altered
This will return the total number of Objects altered during the Import Process.
Event Framework has undergone significant changes during the recent past with the introduction of System Events ‘System Start’, ‘System End’, ‘Load Company’, ‘Close Company’ and ‘Timer’.
In this Release, four new System Events viz., two Events for Object Deletion and two for Voucher Cancellation, have been introduced. With the introduction of these Events, whenever an Object is subject to Deletion or Cancellation, these events get triggered, which allows the TDL Programmer to take some appropriate action. Only on confirmation of Deletion or Cancellation, these events are triggered. In other words, only when the user confirms the deletion or cancellation of the object by responding with a YES, the relevant events get triggered.
Irrespective of the Source of Deletion or Cancellation, i.e., from an external XML Request, Tally User Interface, Remote Tally User Interface, etc., the appropriate events get triggered. Any Object deletion or cancellation event gets triggered only at the Server end. Let us understand these System Events in detail.
Two new System Events Before Delete Object and After Delete Object have been introduced in this release. These events get triggered whenever any of the primary Objects defined in Tally Schema is deleted. For example, Object Company, Voucher, Ledger, etc.
As the names suggest, the Events Before Delete Object and After Delete Object are triggered before and after the deletion of the Object, respectively. The Current Object context would be available in both these Events. Triggering of the Event After Delete Object confirms the successful Deletion of the Object.
Syntax
[System : E v ents]
<Label> : Before Delete Object : <Logi c al Condition Expr>: <Action Keywor d > : <Action Paramet e rs>
<Label> : After Delete Object : <Logical Condition Expr> : <Action Keywor d > : <Action Paramet e rs>
Where,
< Label > is a Unique and Meaningful Name assigned to the System Event handler.
< Logical Condition Expr > is a Logical Expression, which when evaluates to TRUE, executes the given Action.
< Action Keyword > is the Action to be taken once the System Event is triggered.
< Action Parameters > are the parameters required for the particular Action.
Both these even t s are mutually exclusive. In other words, the System Event ‘ Before Delete Object ’ need not be necessarily triggered in order to trigger the System Event ‘ After Delete Object ’, and vice versa.
Example
[System : Event]
BeforeStockItemDeletion : Before Delete Object : $$IsStockItem:Call:BeforeDeleteObjectFunc
AfterStockItemDeletion : After Delete Object : $$IsStockItem:Call:AfterDeleteObjectFunc
[Function : BeforeDeleteObjectFunc]
00 : Log : "Before Delete Object Event starts here"
10 : Log : $Name + “under the Stock Group” + $Parent + “is being deleted by ” + $$CmpUserName
20 : Log : $MasterID
30 : Log : "Before Delete Object Event ends here"
[Function : AfterDeleteObjectFunc]
00 : Log : “Stock Item ” + $Name + “ Deleted”
In this example, the events are invoked only when the Stock Item Object is actually being deleted. Since the object context is available both before and after the object deletion, the object details such as Name, MasterID and Parent can be logged in either of the events. The Event ‘After Delete Object’ confirms the Object Deletion.
Similar to Delete Object Events, two new System Events Before Cancel Object and After Cancel Object have been introduced. Cancellation is applicable only to the Object ‘Voucher’. As the names suggest, the Events Before Cancel Object and After Cancel Object are triggered before and after cancellation the of the ‘Voucher’ object, respectively. The Current Object context would be available in both these Events. Triggering of the Event After Cancel Object confirms the successful Cancellation of the ‘Voucher’ Object.
Syntax
[System : Events]
<Label> : Before Cancel Object : <Logical Condition Expr> : <Action Keyword> : <Action Parameters>
<Label> : After Cancel Object : <Logical Condition Expr> : <Action Keyword> : <Action Parameters>
Where,
< Label > is a Unique and Meaningful Name assigned to the System Event handler.
< Logical Condition Expr > is a Logical Expression, which when evaluates to TRUE , executes the given Action.
< Action Keyword > is the Action to be taken once the System Event is triggered.
< Action Parameters > are the parameters required for the particular Action.
Both these System Ev e nts are mutually exclusive , i.e., the Ev en t ‘Before Cancel O b ject’ need not be necess a rily trig g ered in order to trigger the Event ‘A f ter C ancel Object’, and vice versa.
Example
[System : Event]
BeforeVchCancellation: Before Cancel Object : Yes : Call : BeforeCancelObjectFunc
AfterVchCancellation: After Cancel Object : Yes : Call : AfterCancelObjectFunc
[Function : BeforeCancelObjectFunc]
Local Formula : StrMasterID: $$String:$MasterID
00 : Log : "Before Cancel Object Event " + @StrMasterID + “starts here”
10 : Log : $VoucherNumber
20 : Log : $VoucherTypeName
30 : Log : "Before Cancel Object Event " + @StrMasterID + “ends here”
[Function : AfterCancelObjectFunc]
Local Formula : StrMasterID : $$String:$MasterID
01 : Log : “Voucher with MasterID ” + @StrMasterID + “ cancelled”
In this example, the System Events Before Cancel Object and After Cancel Object are triggered the moment any voucher is cancelled. Since the object context is available both before and after the cancellation of the object, the details such as Voucher Number, Voucher Type Name, Master ID and Date of the cancelled voucher can be logged through both the user defined functions. The Event After Cancel Object confirms the Voucher Object Cancellation.
Points to remem b er
● The System Events for Object Deletion or Cancellation will be triggered when an Object gets deleted or cancelled from any Source, viz.,from an External Third Party Request, from the Tally User Interface or from Remote Tally.
● In case multiple vouchers are selected, and subsequently cancelled or deleted:
● The Event is triggered as many times as the number of vouchers selected. For instance, if five Vouchers are selected for Deletion in Daybook, the System Events for Deletion would be triggered five Times, once for each Voucher.
● Only the methods fetched in the Collection used in the Report displaying the list of Vouchers would be available in the Deletion or Cancellation Context. For instance, if multiple Vouchers are selected in Daybook, only the methods fetched in the Collection used in Daybook would be available in the current context. However, the entire Voucher Object context (including all the methods) can be associated by using the Object Association Syntax within the User Defined Function, i.e., Object : Voucher : ”ID :” + ($$String:$MasterID), and all the methods will be available in the context.
● In case of Remote Login, when the remote user deletes or cancels an object, these events are triggered at the server.
We are aware of object-specific events like ‘Focus’ , ‘ Form Accept ’, ‘ Before Print ’ and ‘ After Print ’, which were introduced in previous releases at various User Interface Objects.
In this Release, four new object-specific events viz., the Event Load at Report, the Event Reject at Form, the Event Accept at Field and the Event After Import Object at ‘ Import File ’ definition, have been introduced to provide control in the hands of the TDL developer to perform any desired action, whenever these events are triggered.
Let us understand these Object-Specific Events in detail.
The Event Load has been introduced at the ‘Report’ Definition. This event is triggered before the Report is displayed to the user. In other words, when this event is triggered, the Report is constructed and updated with variables, object context and the data. The Event ‘Load’ provides control to the TDL Layer, before Tally gets into wait loop, where the user will start operating on the Report. It may allow storing of the current state, etc.
Syntax
ON: Load : <Condition Expr> : <Action Keyword> : <Action Parameters>
Where,
< Logical Condition Expr > is a Logical Expression, which when evaluates to TRUE, executes the specified Action.
< Action Keyword > is the Action to be executed, once the System Event is triggered.
< Action Parameters > are the parameters required for the given Action.
Example
[#Report: ProfitandLoss]
On : Load : @@IsLossIncurred : CALL : ShowMsgifLossEncountered
In this example, once the user loads or displays the report ProfitandLoss, the ‘Load’ event invokes the Function ShowMsgifLossEncountered, if the System Formula IsLossIncurred evaluates to TRUE.
The Event Reject has been introduced at the ‘Form’ Definition. This event gets executed in the Edit Mode, when the user quits the current Form without accepting or saving it. It allows the Programmer to perform the desired action on rejection of the Form. Once the Event ‘Reject’ is used at the Form Definition, the default Action ‘Form Reject’ is overridden, as a result of which, the action Form Reject has to be explicitly specified.
Syntax
ON : Reject : <Condition Expr> : <Action Keyword> : <Action Parameters>
ON : Reject : <Condition Expr> : Form Reject
Where,
< Logical Condition Expr > is a Logical Expression, which when evaluates to TRUE, executes the given Action.
< Action Keyword > is the Action to be taken, once the System Event is triggered.
< Action Parameters > are the parameters required for the given Action.
Example
[#Form : Accounting Voucher]
On : Reject : Yes : Call : TDLRejectFunc
On : Reject : Yes : Form Reject
[Function : TDLRejectFunc]
00 : Msg Box : Status : "The form is rejected"
In this example, when the form is rejected, the Function TDLRejectFunc is invoked, which displays the message “The form is rejected”. Once the execution of the function is over, the form gets rejected due to the explicit Action ‘Form Reject’.
The Event ‘Accept’ has been introduced at the Field Definition. This event gets executed the moment an editable Field is accepted. Once the Event ‘Accept’ is used at the Field Definition, the default Action ‘Field Accept’ is overridden, as a result of which, the action ‘Field Accept’ to accept the Field contents, has to be explicitly specified.
When a Field is accepted, the event sequence runs in the following order:
● The Field value is validated through the ‘Validate’ attribute
● The ‘Modifies’ Variable is modified/updated.
● The Event ‘Accept’ is executed
● The Sub-Form is invoked
Note: If the validation fails, then this event will not be executed, as it will result in an error to the user.
Syntax
ON : Accept : <Condition Expr> : <Action Keyword> : <Action Parameters>
ON : Accept : <Condition Expr> : Field Accept
Where,
< Logical Condition Expr > is a Logical Expression, which when evaluates to TRUE, executes the given Action.
< Action Keyword > is the Action to be taken, once the System Event is triggered.
< Action Parameters > are the parameters required for the given Action.
Example
[#Field : Qty Primary Field]
On : Accept : @@IsNegativeClosQty : Call : MsgBoxforNegative
On : Accept : @@IsNegativeClosQty : Field Accept
Here, the event Accept is triggered on accepting the Field Qty Primary Field, which in turn, invokes the function MsgBoxforNegative . Once the function terminates, the field is accepted.
A new Event ‘After Import Object’ has been introduced to empower the TDL programmers to perform some action every time an Object is imported. This Event helps to create appropriate logs after Importing each Object, or terminate the Import Process based on some condition.
Note: For more details about the Event ‘After Import Object’, including the syntax and example, refer to the first topic ‘Data Importing Enhancements’.
The introduction of User Defined Functions in TDL has empowered the TDL Programmers with one of the most important needs, i.e., Automation of Data Entry. Irrespective of the data source, one can make use of User Defined Functions to update the database without much user intervention. However, in comparison to Import of Data through XML/SDF Files, updation of data through User Defined Functions takes a much longer time. A performance lag has been observed while updating data with User Defined Functions, as compared to updating data of a similar size by the Import method. In order to give a uniform user experience and better performance, the approach followed in data import has now been extended to data updation through User Defined Functions.
Importing of Data implicitly follows a Batch Posting approach, wherein the data to be incorporated in the database is updated in batches, thereby improving the performance. This approach has now been extended to data updation through User Defined Functions, with the introduction of two new Actions, namely START BATCH POST and END BATCH POST . Batch Posting Mode accumulates sets of Objects into batches, and pushes a whole batch of data into the database at a time, which optimizes the performance. Batch Posting Mode also requires the size of the Batch, which can be set as a parameter to the Action START BATCH POST .
The Actions START BATCH POST and END BATCH POST are procedural actions which can only be used within User Defined Functions. These Actions indicate that all the Data Updation Actions falling between the Actions START BATCH POST and END BATCH POST must be updated to the database in Batches. Instead of the data being directly updated to the database, the data is updated to a temporary file, and once the Batch Size limit is reached, the entire data is flushed from the temporary file into the database.
A Batch is a set of objects, wherein the batch size can be specified by the TDL Programmer as an optional parameter to the Action START BATCH POST. In the absence of this parameter, the default size of the batch is considered as 100 Objects. On encountering the batch size limit, the temporary file posts/flushes the data into the Tally database. On completion of the posting of the previous batch of data, the subsequent batch posting iteration takes place, and this cycle continues till the entire data is updated to the database. The bigger the batch size, the lesser the total number of batches, and the better the performance. The operation will be accomplished faster if the Batch Size specified is optimal. A very high Batch Size, beyond a particular point, may also deteriorate the performance. Hence, striking the right balance and specifying the optimal batch size is important to achieve the best performance.
Syntax
START BATCH POST [:<Batch Size>]
NEW OBJECT: <Object Type>: <Object Name> : <Forced Update Flag>
Action 1
Action 2
:
:
Action n
SAVE TARGET
END BATCH POST
Where,
<Batch Size> is the size of each batch.
Note: In the absence of Action END BATCH POST , the End of the User Defined Function is assumed as the end of Batch Posting. However, it is recommended to specify END BATCH POST , especially in presence of nested loops/ large volume of data.
Example
[Function : Create Ledgers]
Parameter : pNumberofLedgers : Number : 1000
000 : START BATCH POST : 500
010 : For Range : i : Number: 1: ##pNumberofLedgers
020 : New Object : Ledger
030 : Set Value : Name : “Customer " + $$String:##i
040 : Set Value : Parent : "Sundry Debtors"
050 : Create Target
060 : End For
070 : END BATCH POST
In this example, when the Function “Create Ledgers” is invoked, 1000 Ledgers, ranging from “Customer 1” to “Customer 1000”, are created under the group ‘Sundry Debtors’. If the Batch Posting feature was not used, the database files would get locked and released for updating every object, and this would continue till all the Objects were updated. Thus, 1000 cycles would take place, affecting the performance adversely. However, with Batch Posting approach, these Objects are updated in 2 batches of 500 Objects each, i.e., the database is locked and released only twice, thus improving the performance vastly. The impact of this enhancement can be observed during updation of data of large volume. For instance, the following table shows the statistics of time taken for creating 1000 ledgers using the given code, but with different Batch Size:
Particulars |
Batch Size |
Approx. time taken |
Without Actions START BATCH POST and END BATCH POST |
NA |
3 Minutes 29 Seconds |
With Actions START BATCH POST and END BATCH POST |
100 |
4 Seconds |
500 |
2 Seconds |
|
1000 |
1 Second |
Table 1. Batch Posting Statistics
As seen in the table, with the usage of the Actions START BATCH POST and END BATCH POST, the time taken reduces significantly. Also, it is noticed that with increase in the Batch Size, the performance keeps improving. The operation will be accomplished faster if the specified Batch Size is equal to the total number of Objects being updated, i.e., in this case, specifying the Batch Size as 1000 will give optimal performance as 1000 objects will be posted to the database at a time.
Greater the Batch Size, better the performance of data updation. However, the database files are locked from the beginning till the end of the write operation of each Batch. This results in unavailability of the Database for data updation from other sources executing parallelly, like data entry in a Multi-User Environment, Data Synchronization, etc. Thus, a higher value of Batch Size will improve the performance, but will slow down the simultaneous updation of Data. Hence, determining the Optimal Batch Size is necessary to strike the right balance for getting the best performance. A very high Batch Size, beyond a particular point, may deteriorate the performance.
Points to remember
● Actions START BATCH POST and END BATCH POST are not be used in a nested manner. If used so, only the first instance is considered, while the remaining ones are ignored.
● A Batch can only be ended or closed in a Function where it is initiated. If the user misses the closing part, the System will END the batch implicitly.
● One must backup the data prior to using the Batch Posting Feature, as incorrect usage of the same may lead to corruption/loss of data.
● For Import of Data also, we have a parameter similar to Batch Size, i.e., Import Batch Size, which can be used to improve the performance while Importing Data. This parameter can be specified in Tally.INI, in the absence of which, it is set to 100 by default. Setting this parameter to a higher value will decrease the time taken for Import, but will increase the wait time for other simultaneous data updation operations. Setting it to -1 will disable the Batch Posting feature for Import of Data, which means that the Data Import would consume a longer time, as every Object would need to be updated to the database individually.
These are asynchronous message boxes, i.e., the message box continues to appear till the action ‘End Msg Box’ is encountered or the function is terminated, whichever is earlier. Unlike action ‘Msg Box’, this action is executed asynchronously, i.e., it does not expect a key press from user. When executed, it displays the message box, and continues to execute the subsequent Actions.
Syntax
Start MSG BOX : <Title Expression> : <Message Expression>
<Action 1>
:
<Action n>
End MSG BOX
Where,
< Title Expression > is the value that is displayed on the title bar of the message window.
< Message Expression > is the actual message displayed in the box. It can be an expression as well, i.e., the variable values can be concatenated and displayed in the display area of the box.
Example
[Function : M sgBox A ctions]
Variable : C o unter : Num b er
Variable : TotalCount : Num b er : 100
Returns : N u mber
Local Formula : StrTotalCou n t : ($$S t ring:##TotalCo u nt)
Local Formula : StCounter : ($$String:##Counter)
00 : Start M sg Box : Stat u s : "T h is Fun c tion cr e ates” + @St rTotalC o unt + “ Ledgers”
10 : Sta r t Progr e ss : # # TotalCo u nt : # # SVCurre n tCompa n y : "Cre a ting Le d gers" : "Please wait"
20 : W hile : # #Count e r < ##T o talCou n t
30 : New O b ject : Ledger : "L e dger" + @StrC o unter : Y es
40 : S e t Value : Name : " Ledger" + @St r Counter
50 : S e t Value : Par e nt : " Sundry D ebtors"
60 : Save T arget
70 : Incre m ent : Count e r
80 : Show P rogres s : ##Cou n ter
90 : E nd While
100 : End Progress
110 : End Msg Box
Here, the action ‘Start Msg Box’ invokes the message box and retains it till action ‘End Msg Box’ is encountered. Thus, the message box will continue to appear from label 00 to 110. In absence of ‘End Msg Box’, the msg box is automatically terminated when the Function MsgBox Actions ends.
Note: If nested Start Msg Box is executed, then the previous Message box is overwritten. At any time, only one Message Box can be displayed.
An Action ‘ Execute TDL ’ was introduced in Release 3.6 to load a TDL dynamically, execute some action, and then unload the TDL or keep it, depending on the Logical Value. With this Action, the TDL would get loaded. However, the execution of action was mandatory. In Release 4.8, an action ‘Load TDL’ has been introduced to load the TDL/TCP dynamically for only the current session of Tally. However, if the TDL File is already loaded due to being specified in Tally.INI, or through previous execution of the Action ‘Load TDL’/‘Execute TDL’, it will not be loaded again. On closing the current session of Tally.ERP 9, the dynamically loaded file(s) will not be available for the subsequent Tally Session.
Syntax
LOAD TDL : <TDL/TCP File Path Expression>
Where,
<TDL/TCP File Path Expression> evaluates to the path of the TDL/TCP File to be loaded dynamically.
Example
[Button : Load Dynamic TDL]
Key : Alt + L
Action : Load TDL : @@TDLFilePath
[System : Formula]
TDLFilePath : “C:\Tally.ERP9\TDL\Samples.tcp”
In this example, on triggering the button ‘Load Dynamic TDL’, the action ‘Load TDL’ loads the TDL from “C:\Tally.ERP9\TDL\Samples.tcp”. If this TDL is already loaded due to being specified in Tally.INI, or previous execution of the Action ‘Load TDL’, then the same will not be loaded again.
Note: Local TDLs will be loaded at the Remote End if ‘Allow Local TDLs’ is enabled to the user logged in.
To unload the TDL dynamically from the current Tally Session, the Action ‘Unload TDL’ has been introduced. With this Action, the local TDL File(s), including the ones added through Tally.ini and those added dynamically using Actions ‘Load TDL’ or ‘Execute TDL’, can be unloaded. However, they would be unloaded only for the current Tally Session, and in the subsequent session, all the TDL/TCP files specified in Tally.INI will be loaded once again. Using this action, the Files can be unloaded by specifying either the TDL /TCP file name or the GUID of the TCP File.
Syntax
UNLOAD TDL : <TDL/TCP File Path Expression or GUID Expression>
Where,
< TDL/TCP File Path Expression or GUID Expression > evaluates to the path of the TDL/TCP File or GUID of the TCP File to be unloaded dynamically.
Example
[Button : Unload Dynamic TDL]
Key : Alt + U
Action : Un l oad TDL : @@TCPFileGU I D
[System : Fo r mula]
TCPFileGUID : “c29 0 1088-3 4 9b-434b - 946c-9 a da601fd 6 b7”
In this example, on triggering the button ‘Unload Dynamic TDL’, the Action ‘Unload TDL’ unloads the Compiled TDL with the GUID “c2901088-349b-434b-946c-9ada601fd6b7”. If the particular TDL is not found to be loaded, then the same is ignored. If the TCP File was dynamically loaded, then the same is removed from the List of TDL Files. However, if the TCP File was available in Tally.INI, then the same is removed temporarily and reloaded in the subsequent session of Tally.
Note:
♦ Account/Remote TDL file(s) cannot be unloaded using Action ‘Unload TDL’.
♦ Once a TDL is unloaded explicitly, if one attempts to load such TDL file(s) by changing the TDL Configuration, the file(s) will not be loaded in that session.
A new function ‘IsTDLLoaded’ has been introduced to check if a particular TDL is already loaded. This function returns TRUE if the particular TDL/TCP file is already loaded, and FALSE if it is not.
Based on the result of this function, further actions like Loading and Unloading of TDL, or executing a Report from the dynamically loaded TDL File, etc., can be performed.
Syntax
$$IsTDLLoaded : <TDL/TCP File Path Expression or GUID Expression>
Where,
< TDL/TCP File Path Expression or GUID Expression > evaluates to the path of the TDL/TCP File or GUID of the TCP File to be checked, whether it is loaded or not.
Example
[Function : Display First TDL Report]
00 : If : $$IsTDLLoaded:@@TCPFileGUID
10 : Display : First TDL Report
20 : Unload TDL : @@TCPFileGUID
30 : End If
[System : Formula]
TCPFileGUID : “c2901088-349b-434b-946c-9ada601fd6b7”
In this example, if the TDL with GUID “c2901088-349b-434b-946c-9ada601fd6b7” is loaded, then the Report ‘First TDL Report’ will get displayed. Subsequently, the TDL is unloaded.
It is used to get the details of URL Host, ContentLength and Header information available during the receiving of the SOAP request. It accepts two parameters - ‘InfoType’ and ‘Info Sub Type’.
The Function $$ImportType is used to determine the type of Import, i.e., the source of data. The possible Import Types could be ‘Sync’, ‘Migration’, ‘Remote’, ‘NatLang’, ‘SOAP’ or ‘Manual’.
This function is used to indicate the status of Import, i.e., whether the current Object was Created, Altered, etc. The possible results are ‘Created’, ‘Altered’, ‘Ignored’, ‘Combined’, and ‘Error’.
The Function $$LastImportError can be used to extract the Import error description for the last object imported, which is helpful to retrieve after every import, and appropriate error logs can be maintained and displayed at the end of the Import Process. In case there is no Error while Importing the current Object, it would return the value as ‘Empty’.
The Function $$ImportInfo is useful to extract the details of the Imported Objects in terms of Number of Objects Created, Altered, Ignored, Combined, etc., and Errors encountered. This Function accepts a parameter ‘InfoType’.
Note: For de t ails of the functions $$HttpInf o, $$ I mpor t T y pe , $$ I mpor t Action , $$La s tImportEr r or a nd $ $ Impo r tIn f o , refer to the section ‘Da t a Im p or t ing Enhance m ents’.
To support Banking, two new Primary Objects, i.e., objects of Type ‘Pay Link’ and ‘Party Pay Link’ have been introduced. These Objects are similar to Bills, i.e., with each transaction by individual payment modes like ‘Cheque’, ‘Inter-Branch Transfers’, etc., a ‘Pay Link’ object is created with respect to Bank and a ‘Party Pay Link’ object is created with respect to transaction to Party.
Along with the Object Types ‘Pay Link’ and ‘Party Pay Link’, three new attributes have been introduced for the ‘Collection’ definition. These attributes can be used for accessing the appropriate indexes within the collection to fetch the data. They are primarily used in the banking module.
Collection Attribute - Transaction Type
This a ttribute filters the transactions based on the Link mast e r T ransaction type. It acce p ts SysName as p arameter to i d entify the type of b a nking transaction, e.g ., ‘Cheq u e’, ‘Cr e dit Card’, ‘I n ter-Bank T ransfers’, etc. It is applicable only for collections of T ype ‘Pay Link’/‘Party Pay Link’.
Syntax
[Collection: <Collection Name>]
Transaction Type: $$S y sName:<Type Of Transaction>
Where,
<Type of transaction> is the link master transaction type used in banking. It can be Cash, Cheque, ATM, ECS, Cheque/DD, Interbank Transfer, Same Bank Transfer, Electronic Cheque and Electronic DD/PO.
It filters the transactions based on the (Primary) Status of Banking transactions stored in Link Master against each transaction. It accepts SysName as parameter, such as ‘Returned’, ‘Cancelled’, etc. It is applicable only for Collections of Type ‘Pay Link’ or ‘Party Pay Link’.
Syntax
[Collection : <Collection Name>]
Primary Status : $$SysNa m e:<Status Paramete r >
Where,
<Status Parameter> is the primary status of each transaction. It can be 'StatusTransacted’, ‘Unstable’, ‘Cancelled’ and ‘Returned’.
This attribute filters the transactions based on the additional status of each transaction type. It accepts SysName as Parameter, such as ‘Exported’, ‘Approved’, ‘Not Approved’, etc. This is applicable only for Collections of Type ‘Pay Link’.
Syntax
[Collection : <Collection Name>]
Sec o ndary Status : $$Sy s Name : <Status Param e ter>
Where,
< Status Parameter > is the secondary status of each transaction. It can be ‘Exported’, ‘Approved’, ‘Not approved’ or ‘Primary’.
Example
[Collection : Pay Link Coll]
Type : Pay Link
Child of : "ICICI"
Transaction Type : $$SysName:NEFT
Primary Status : $$SysName:StatusTransacted
Secondary Status : $$SysName:NotApproved
Fetch : *
Here, the Collection Pay Link Coll consists of Objects of Type Pay Link. The transaction type filters the collection of Type ‘Pay Links’ for transactions only of type NEFT, that are filtered with primary status as ‘Status Transacted’ and secondary status as ‘Not Approved’.
Hyper Text Transfer Protocol, commonly referred to as HTTP, is a communication protocol which is used to deliver data on the World Wide Web. In other words, HTTP provides a standardized way for computers to communicate with each other. HTTP specification includes information about how the client’s request data will be constructed, how it will be sent to the server and how the server should respond to these requests.
Tally.ERP 9, being the complete business solution, also supports HTTP Protocol for exchanging messages between Tally and any Third Party Application. During interactions with the Third Party Applications, Tally.ERP 9 can act as a Client, as a Server or both.
As a Client, Tally.ERP 9 constructs appropriate requests in XML Format, sends the same to the specified URL Host, i.e., the Server, which could be any Third Party Application, including Tally. It then receives the response from the Server over HTTP. As a Server, Tally acts as per the incoming request from any Third Party Client, generates an XML Response and sends it to the Client. Usually, except the default Tally-to-Tally Data Synchronization, the Integration solutions are built by the TDL Programmer. While building such a solution, they require some debugging tools like logs to confirm if the right requests and responses are being communicated over HTTP.
A Configurable option is provided in Tally to log all the Information exchanged over HTTP, which if enabled, records the Request/Response communication between Tally and external applications. This helps the developers to debug and resolve the issues, if any, while setting up integrated solutions. HTTP Log information would be written to the file TallyHTTP.Log in the working Tally Application Directory. Previously, though this log was mainly used for development and debugging purposes, it was also available in the Normal Mode (Release Mode). Due to this, HTTP Requests/Responses would be unnecessarily logged for the users of Tally.ERP 9, who were usually not even consuming those logs. Also, it would needlessly consume some amount of time to update the HTTP Log on each occasion. Hence, from Release 4.8 onwards, ‘Enable HTTP Log’ Option has been removed from the Normal Mode of Tally.ERP 9, and will be available only in the Developer Mode. In other words, the Tally.ERP 9 users cannot see and enable HTTP Logs through the Advanced Configuration Screen (F12) in Normal Mode. However, for development and debugging purposes, the same can be seen and enabled by the Developers/Integrators, while running Tally.ERP 9 in Developer Mode.
Note: Tally Application can be executed in Developer Mode, using the parameter DevMode. For instance, if the Tally Application is installed in C:\Tally.ERP 9, then it can be executed in Developer Mode as C:\Tally.ERP9\Tally.Exe /DevMode.
At times, programmers would not want to log certain sensitive HTTP Information, inspite of HTTP Logs being enabled in Developer Mode. In order to explicitly control the Logs, the requestor can additionally send a Header DISABLELOG, set to YES, which will disable the current log, irrespective of the Configuration or the Mode in which Tally is running. The default value is NO, i.e., in the absence of this Header, the HTTP Information will be logged to the file TallyHTTP.log, if Tally.ERP 9 is working in Developer Mode and HTTP Log is enabled in Configuration.
In the above figure, we can see that the Header DisableLog is set to NO , due to which the information exchange between Tally and external application has been logged. If DisableLog would have been set to YES , then irrespective of Tally being run in Developer Mode and ‘ Enable HTTP Log ’ option being enabled, the HTTP information would not be logged to TallyHTTP.Log.
A UDF can be used to store additional information into the Tally database. UDFs are stored in the current object context. Whenever a UDF is created and used in an already existing report, the data is stored in the context of the current object, i.e., it is always associated to the object to which the report is associated.
Previously, if the TDL or the TCP was lost or corrupted, then there was no way by which we could know the UDF details like the UDF Number, and hence, the retrieval of data related to the UDF was quite difficult. In the present Release, an XML attribute Index, within the UDF ‘List Tag’, has been introduced to help retrieve the original UDF number corresponding to the data available within the Objects associated with it. This UDF number will be available in the Index attribute in the UDF List Tag, even when the TDL is not attached or is unavailable. The Index attribute will be available for Simple as well as Aggregate UDFs.
Example
<UDF:TESTUDFNO.LIST DESC="‘Test UDF No’"ISLIST="YES" TYPE="String" INDEX="1010">
<UDF:TESTUDFNO DESC="‘Test UDF No’">Raam</UDF:TESTUDFNO></UDF:TESTUDFNO.LIST>
Here, the UDF number (1010) is displayed under the ‘Index’ Attribute in the UDF List Tag.
● Till now, the Date data type used to support values from 1-1-1901 to 1-1-2099. From this release onwards, the support has been extended to the date 31-12-9999.
● Also, the following prefix century behaviour has been introduced (when a 2 digit year value is entered by the user) in the Date field. The century value prefixed by the system will depend upon (i) the 2-digit year value passed by the user (ii) the system year. Thus, the different cases that are possible are as follows.
Case I: The year entered by the user is greater than or equal to 50 |
Case II: The year entered by the user is less than 50 |
|
When the current year as per the system date is greater than or equal to 50 |
In this case, the system will consider the year entered to be belonging to the same century as the system date. Example: If the System Date is 1-1- 2098, then if the user enters 86, it will be considered as 2086, i.e., of the same century as in system year. |
The system will consider the year entered to be belonging to the next century compared to the system date. Example: If the System Date is 1-1- 2098, then if the user enters 24, it will be considered as 2124, i.e., of the next century compared to system yr. |
When the current year as per the system date is lesser than 50 |
The system will consider the year entered to belong to the previous century compared to system date. Example: If the System Date is 1-1-2014, and the user enters the year as 86; the system will consider it as 1986, i.e., of the previous century. |
The system will consider the year entered by the user to belong to the same century as the system date. Example: If the System Date is 1-1-2014, then if user enters 24; it will be considered as 2024 i.e. of the same century as system year. |