So now your calculation algorithm has a single "bottleneck" left: checking whether the calculation register data is up-to-date.
Up to this point, you have used the utility Recalculation report to determine whether the calculation register data is up-to-date (the report is empty) or requires recalculation.
Let us create a procedure that checks whether calculation register data requires recalculation and performs the recalculation if needed.
Since the only way to get totals for employee accruals in your configuration is the EmployeeAccruals report, in order to call the procedure you will create the report form and add the Recalculate button to the form command bar. This button will run the recalculation of register data.
In Designer mode
Let us create the report form.
- Open the configuration object editor for the EmployeeAccruals report.
- On the Forms tab, in the Report form field, click the Open button and create the default report form.
- In the upper right pane of the form editor, click the Commands tab, click the Form command tab, and create the Recalculate command (fig. 18.28).
Fig. 18.28. Adding a form command
Let us specify the action for this command.
- In the Action field, click the Open button.
- Click Create on client and then click OK.
This adds the Recalculate() procedure template to the form module.
- Add the call of the RecalculateAccruals() procedure defined in the Calculations common module to the Recalculate() procedure (listing 18.8).
Listing 18.8. Recalculate() command handler
&AtClient Procedure Recalculate(Command) Calculations.RecalculateAccruals(PredefinedValue( "ChartOfCalculationTypes.MainAccruals.Salary")); Calculations.RecalculateAccruals(PredefinedValue( "ChartOfCalculationTypes.MainAccruals.Bonus")); EndProcedure
- Create the RecalculateAccruals() procedure in the Calculations common module (listing 18.9).
Listing 18.9. RecalculateAccruals() procedure
Procedure RecalculateAccruals(RequiredCalculationType) Export // Selecting records from the recalculation record set in the following order: // records from document1 for the listed employees // records from document2 for the listed employees, and so on Query = New Query( "SELECT | AccrualsRecalculation.RecalculationObject, | AccrualsRecalculation.Employee |FROM | CalculationRegister.Accruals.Recalculation AS AccrualsRecalculation |WHERE | AccrualsRecalculation.CalculationType = &RequiredCalculationType |TOTALS BY | AccrualsRecalculation.RecalculationObject"); Query.SetParameter("RequiredCalculationType", RequiredCalculationType); EmployeeList = New ValueList; // Iterating through the grouping by recorder SelectionByRecorder = Query.Execute().Select(QueryResultIteration.ByGroups); While SelectionByRecorder.Next() Do Recorder = SelectionByRecorder.RecalculationObject; // Iterating through the employee grouping for the selected recorder // and creating the employee list SelectionByEmployee = SelectionByRecorder.Select(); EmployeeList.Clear(); While SelectionByEmployee.Next() Do EmployeeList.Add(SelectionByEmployee.Employee); EndDo; // Getting the calculation register record set for the selected recorder RecordSet = CalculationRegisters.Accruals.CreateRecordSet(); RecordSet.Filter.Recorder.Value = Recorder; RecordSet.Read(); CalculateAccruals(RecordSet, RequiredCalculationType, EmployeeList); RecordSet.Write( , True); // Removing the recalculated records from the recalculation RecalculationRecordSet = CalculationRegisters.Accruals.Recalculations.Recalculation.CreateRecordSet(); RecalculationRecordSet.Filter.RecalculationObject.Value = Recorder; RecalculationRecordSet.Write(); EndDo; EndProcedureIn the beginning of the procedure a query selects recalculation records that contain the calculation type passed to the procedure, grouped by recalculation object.
Next, the procedure iterates through the query results to generate a list of employees for each recalculation object, reads the corresponding calculation register records, and calls the CalculateAccruals procedure(), which you used earlier to calculate records in the EmployeeAccruals document.
Once the calculation of records is completed, the procedure writes the record set without generating recalculation records, and clears the recalculation records for the recalculation object that has just been processed.
- Return to the EmployeeAccruals report form.
So you specified the action (the command execution handler) for the Recalculate command. To be able to use the command, you have to create a button in the form and link it to the command (in the Command name button property).
The simplest way to do it is to drag the command from the Form command pane to the form controls pane.
- Drag the Recalculate command to the MainCommandBar group of form controls.
This adds the Recalculate button, which is linked to the command, to the form (fig. 18.29).
Fig. 18.29. Adding a button to a form
In 1C:Enterprise mode
Let us test the recalculation of calculation register records.
- Start 1C:Enterprise in the debug mode.
- Clear the posting of all Employee accrual documents, and then post Employee accrual # 1 and Employee accrual #2.
- Create the Employee accruals report (fig. 18.30).
Fig. 18.30. Employee accruals report
- Open the Employee accrual #1 document, change Johnson’s salary to 10 000, and post the document.
- In the Employee accruals report, click the Recalculate button.
You can see that the bonuses for Johnson and Walkman are recalculated (fig. 18.31).
Fig. 18.31. Service message window
- In the report, click Create.
This is required for the report to display up-to-date data. The resulting report contains the new value for Johnson’s bonus (fig. 18.32).
Fig. 18.32. Employee accruals report
- Post Employee accrual # 3 and then, in the report, click Recalculate.
You can see that Johnson’s bonus and salary are recalculated (fig. 18.33).
Fig. 18.33. Service message window
- In the report, click Create.
The resulting report contains up-to-date salary and bonus values (fig. 18.34).
Fig. 18.34. Employee accruals report