Lesson 21. Editing Register Records in the Document Form
Estimated duration of the lesson is 40 minutes.
In our infobase, as in any other, we have to provide a way of entering opening balances for a register. This is needed in order for users to be able to begin working with our infobase not from scratch but instead have some sort of initial state taken from their previous accounting system (even if that was kept by pen and ink).
The task of entering opening balances is different from other algorithms that modify our infobase registers, in that it involves making direct changes to the registers. It will not use any intermediate algorithms (filling in document data, posting documents, error checking for the data provided in documents, etc.).
Let us review an example of entering opening balances in the BalanceOfMaterials accumulation register.
To perform this task, we will create a document where we will manually edit the records it creates in the BalanceOfMaterials register within the document form itself.
In the Designer Mode
Create a new Document configuration object named InputOpeningProductBalances.
On the Register Records tab deny document posting (since we will create the register records ourselves) and indicate that the document's records will be located in the BalanceOfMaterials accumulation register (fig. 21.1).
Next go to the Forms tab and create the default document form.
In the form editor on the Attributes tab expand the default attribute of the Object form and then expand the register records collection named Register Records, locate the row BalanceOfMaterials and drag it to the form controls window. Confirm when prompted "Add table columns?" (fig. 21.2).
Note that the properties palette of this table will automatically connect it to the data of register record set Object.RegisterRecords.BalanceOfMaterials in the Data row.
Let us slightly modify the form appearance.
In the form controls window add a group of fields with Horizontal as a grouping type and drag Number and Date document fields to this group.
Fig. 21.1. Disabling document posting
Fig. 21.2. Editing form of the Input Opening Product Balances document
Also swap locations of the table fields BalanceOfMaterialsRegisterRecords
Fig. 21.3. Modified form of the Input Opening Product Balances document
Finally, edit the command interface of the document form so that the navigation panel made it possible to go to the list of BalanceOfMaterials register records related to the document.
To do so, in the upper left window of the form editor navigate to the Command Interface tab.
In the Navigation Panel group use the Go To subgroup to enable visibility for the command to open the Balance Of Materials register (fig. 21.4).
In the editor of the Document configuration object InputOpeningProductB alances use the Subsystems tab to specify that it belongs to the Accounting subsystem.
Finally, edit the command interface of this subsystem (Common4 Subsystems4All subsystems).
Fig. 21.4. Editing form command interface
Highlight Accounting in the list of subsystems and in the commands list for this subsystem enable visibility for the command named Input Opening Product Balances: New in the group Action Panel.New.
In the 1C:Enterprise Mode
Launch 1C:Enterprise in the debugging mode and test our document.
Click Input Opening Product Balances in the action panel of the Accounting section.
Create a document to output opening balances to the BalanceOfMaterials register and populate it with the following data (fig. 21.5).
Fig. 21.5. Document Input Opening Product Balances No. 1
Note that the document date does not match the dates of the individual records we are creating in the document's register records.
Click Write (marked with a diskette icon) and use the document form navigation panel to go to the records created by our document in the BalanceOfMaterials register (fig. 21.6).
Fig. 21.6. Records of the BalanceOfMaterials register
So we have accomplished our purpose: on the one hand, by providing a document date, we can record the moment when changes were made to the register records, while on the other hand we can give each of the register records we create its own value for the Period field.
Now let us place some "stricter" demands on how our document creates register records and take a look at two standard options.
Software-Based Editing of Register Records
In the Designer Mode
The first requirement that we will implement is that register records must be generated with the same date as the date of the document. In other words, we'll synchronize the register records' date with the document date.
To do so, create an event handler BeforeWrite for the document form and add the following code to this handler (listing 21.1).
Listing 21.1. BeforeWrite Event Handler of the Document Form
For Each RegisterRecord in Object.RegisterRecords.BalanceOfMaterials Do RegisterRecord.Period = Object.Date; EndDo;
In the 1C:Enterprise Mode
Launch 1C:Enterprise in the debugging mode again, open our document and click Write.
If you now open the records created by the document in the BalanceOfMaterials register, you will see that the value of the Period field of all the records is now equal to the document date (fig. 21.7).
Fig. 21.7. Modified records of the BalanceOfMaterials register
We could call that good enough, but only for the situations where the document is written interactively.
If you try to use software tools to call for the Write() method of the document's object, it will be written without using the document form. This means that the document form's BeforeWrite event will not be called for and the handler code will not be activated.
To make it possible to synchronize the period of document's register records with the document date and in the event of software-based recording of the Document object, we will need to use the BeforeWrite event handler for the Document object, rather than the document form.
For interactive document recording the BeforeWrite event will first be called for the document form and then by the Document object (see the event chart in the section titled "Sequence of Events when Writing Documents from a Document Form").
In the Designer Mode
Therefore, we will now return to the Designer and delete the added code from the form's module and then create a BeforeWrite event handler in the module for the Document object InputOpeningProductBalances.
To do so, on the Other tab of the editor of this configuration object open the object module and add the following code (listing 21.2).
Listing 21.2. BeforeWrite event handler of the object module
Procedure BeforeWrite(Cancel, WriteMode, PostingMode) // Determine whether we need to update register record dates UpdateRegisterRecordsDate = IsNew() Or RegisterRecords.BalanceOfMaterials.Modified(); If Not UpdateRegisterRecordsDate Then // Verify that the date changed Query = New Query; Query.SetParameter("CurDocument", Ref); Query.Text = "SELECT | Date |FROM | Document.InputOpeningProductBalances |WHERE Ref = &CurDocument"; Selection = Query.Execute().Choose(); Selection.Next(); UpdateRegisterRecordsDate = Selection.Date <> Date; EndIf; // Assign the new date to all, if required If UpdateRegisterRecordsDate Then If Not RegisterRecords.BalanceOfMaterials.Selected() AND Not RegisterRecords.BalanceOfMaterials.Modified() Then RegisterRecords.BalanceOfMaterials.Read(); EndIf; For Each RegisterRecord In RegisterRecords.BalanceOfMaterials Do RegisterRecord.Period = Date; EndDo; EndIf; EndProcedure
As you can see, in this case the handler contains more code, due to the additional checks that are performed because both interactive and softwarebased recording of the object is possible.
Let us walk through the handler contents in greater detail. If a new document is recorded or its register records are changed, we need to update the register records dates. If not, we will use a query to read the document date from the database and compare it to the date specified for the recorded object. If the dates do not match, we will also need to update the register records dates.
Before a date is specified, we check whether a record set was read from the Register Records property of the object and if it has been modified. If both conditions are false, it means that the record set in the object's Register Records property is empty and that this condition is not due to its modification. In this case, to prevent errant deletion of register records (overwriting with an empty record set), we preliminary read the register records from the register into the record set for the Register Records property.
Then, as in the previous case, we set the required date for all the records in that set. When the Document object is recorded, this record set will be written to the accumulation record.
In the 1C:Enterprise Mode
Launch 1C:Enterprise in the debugging mode and verify that once we set a new date for our document (e.g. 5/1/2010) and save it, the records in the accumulation register have the new date as well.
In the process of saving a document, we can control not only the period for the accumulation register records, but also the values of other register fields.
For instance, by applying the same principle we could create an Operations document that would allow us to enter manual operations into the accounting register.
In that case in addition to controlling the period for register records, you will need to manage the values in the Active field (toggling document postings on and off), etc.
Location for Event Handlers
In conclusion we should say that the choice of a handler that will contain the procedure code depends on the logics of the object that is created. If the configuration does not support software-based writing of objects, you can select a handler of the form module. If it allows for software modification of objects as well, it makes sense to choose a handler from the object's module.
Note that neither of these methods prevents modification of registers using the object Register<...>RecordSet.<register name>. Therefore, if the configuration logics suggest possibility of software-based modifications to a RecordSet object, the handler's code should be located in the event handler of this record set. All attempts to modify register data ultimately come down to writing a record set.
- What is the purpose of the document to enter opening balance?
- How does one create such a document?
- How does one modify register value when entering opening balances using software tools?
- When should one use form module and when should one use object module to host event handlers?