Automatic recalculation of document totals
You have probably noticed that, when filling the document, you needed to enter the total in each row. That is a nuisance and the natural impulse is to automate the document, so that the total is automatically calculated every time there is a change to the price or quantity of materials in a row.
It is actually easily accomplished. To do so, you will first create a custom document form, and then use the 1C:Enterprise script.
So far you always used the predefined object forms generated by 1C:Enterprise. Now you have come to the point when you need a slight modification of the document form logic, and that means you need to create a custom form for the GoodsReceipt document where you will define the required algorithm using 1C:Enterprise script. The platform will use that custom form instead of the default form.
In Designer mode
In 1C:Enterprise mode
Now let us see how it works.
- Start 1C:Enterprise in the debug mode, open the list of Goods receipt documents, and open any of the two documents created earlier.
If you change the quantity in any document row, the row total is recalculated automatically.
Document form
Let us create a custom document form.
- In Designer, open the editor of the GoodsReceipt document configuration object.
- Click the Forms tab.
As you can see, no default forms are available yet. - In the Document field, click the Open button .
-OR-
Click the Add button above the list of forms (fig. 4.17).
Fig. 4.17. Creating a document form
The platform opens yet another helpful developer tool: the form wizard (fig. 4.18).
Fig. 4.18. The form wizard
It is a typical wizard where you enter data in a specific order and use the Next and Back buttons for navigation. - Click Document form, keep the default values in all other fields, and click Finish (see fig. 4.18).
Note that the DocumentForm form subordinate object is added to the GoodsReceipt document configuration object (fig. 4.19), and that the form editor displaying this form is now open (fig. 4.20).
Fig. 4.19. New document form in Designer
Fig. 4.20. Form editor
The form editor combines multiple windows of interconnected editors. We will not discuss all of the actions available in the form editor and will only cover the issues that are required to complete the basic operations related to our task.
For detailed description of the form editor, see the "Form Editor" section in the "Development Tools" chapter of 1C:Enterprise. Developer Guide.
For now we will only discuss the document form preview pane (located at the bottom) and the form controls editor pane (in the top left corner).
When you develop configuration object forms, you cannot simply draw a form. You only can specify the form controls, which are automatically arranged within the form.
Form controls in the upper left pane are arranged in a tree. The controls are arranged top-to-bottom and left-to-right within the form, with higher-priority items going first.
You can edit the tree on the Elements tab. This is how you can edit the form layout.
You see that based on the configuration description of the GoodsReceipt document the platform created a structure of controls that defines the form layout.
These controls serve various purposes and have different behaviors. However, all of them display data stored in the database and provide interaction with that data.
You can drag the tree items to change the positions of form controls (such as tabular section attributes). The result is immediately displayed in the document form preview at the bottom of the form editor. Note that you do not have to think of specific locations (in pixels) for the form controls, their sizes and dockings to other controls. The platform takes care of this.
You can use the property palette to modify control properties, which can affect their view in the form. You can also modify the structure of form controls: create a field, a group of fields, or a tabular section, and link these controls to form data.
But for now you do not have to do any of this. You only need to focus on the tabular section items: MaterialsQuantity, MaterialsPrice, and MaterialsTotal (see fig. 4.20).
Every time a user changes a value in the Quantity or Price field, the Total field value should automatically change to Quantity*Price.
Obviously, to do so you have to use 1C:Enterprise script to write a command that executes something like Total = Quantity*Price when a value in the Quantity or Price field is changed. But how are we going to "capture" that point of change?
Event handler
As you have already seen, the platform can handle the objects described in the configuration tree: it displays their data, provides the options for adding items, and so on. So the platform has some standard algorithms for this.
But developers are only satisfied with these standard algorithms in the very basic scenarios. Actual tasks are much more diverse. This is why the platform features events that are connected to various moments of standard operations. These include the events related to user interaction with forms and form controls.
Using 1C:Enterprise script, developers can interpose in the events and define custom algorithms that are executed when those events occur. This is exactly what you will do now.
- Double-click the MaterialsQuantity form control.
-OR
Right-click the MaterialsQuantity form control and then click Properties. - Scroll down the property palette window to see the list of events that can be linked to this field.
It is obvious that you need the OnChange event that occurs when the field value is changed. - In the OnChange field, click the Open button (fig. 4.21).
Fig. 4.21. Creating the OnChange event handler for the Quantity tabular section field
The platform prompts you to select the event handler type (fig. 4.22).
Fig. 4.22. Selecting event handler type - Keep the default Create on client option.
We will not explain these options for now, as they are described in the Compilation directives section.
Then the platform generates a handler procedure template for this event in the form module and opens the Module tab of the form editor.
Fig. 4.23. OnChange handler template for the Quantity tabular section field
Modules store 1C:Enterprise script algorithms. There are several module types intended for storing algorithms related to various aspects of applied solution functioning. In this case it is a form module because handlers of all interactive events linked to form controls are stored in the form module. - Add the following script to the MaterialsQuantityOnChange() procedure body (listing 4.1).
Listing 4.1. Procedure MaterialsQuantityOnChange()TabularSectionRow = Items.Materials.CurrentData; TabularSectionRow.Total = TabularSectionRow.Quantity * TabularSectionRow.Price;
Let us examine this script.
The first line creates the TabularSectionRow variable that will store the object containing data of the tabular section row that requires recalculation.
1C:Enterprise script features weak data typing, which allows using variables without declaring them first (without specifying their types beforehand). In this line the variable is created on the fly and its type is defined by the type of the value assigned to it.
Since we are now in the form module, all the properties and methods of the ManagedForm 1C:Enterprise script object are available within this module. Hence you can call them directly. In this line after the equality sign a collection of form controls is called using one of the ManagedForm object attributes: Items.
The collection of form controls is a FormAllItems 1C:Enterprise script object that contains all of the form controls. This is basically a script analog of the root of the form control tree.
You can get a form control by specifying its name as the property of this object, separated by "." (dot). In this example the tabular section of the Materials document is called (Items.Materials).
A tabular section of a document is a FormTable 1C:Enterprise script object. You can get the row that is being edited using the CurrentData property (Items.Materials.CurrentData) of the FormTable script object.
So once the first line of the handler procedure is executed, the TabularSectionRow variable stores a FormDataStructure object. This object contains data stored in the current row of the document tabular section (Items.Materials.CurrentData).
Once you get this object, you can call the data of a specific column of the tabular section using the column name as the object property. For example, using TabularSectionRow.Quantity allows you to get the number located in the Quantity cell of the row being edited.
Hence, the second line of the handler procedure calculates the value of the Total column by multiplying the values in the Quantity and Price columns.