Lesson 4-5
IR write mode
There are two write modes available:
An independent IR stores records that don’t belong to any of the documents, i.e. contain primary data. Our Prices IR will be filled out with the secondary data - a copy of the PriceChange tabular section rows - so we need to select “Subordinate to recorder” here.
We will need to check the content of the IR, so let’s add it to the Inventory subsystem.
We also need to specify the PriceChange document as a recorder for the IR.
IR dimensions, resources, and attributes
As it was mentioned earlier, period plus dimensions comprise the IR’s unique key, meaning that you cannot have two records with the same period and the same dimensions in the IR. It also means that you can momentarily read the IR record having specific period and dimensions’ values. For our task, we need to be able to set a price for any material or service once a day. Therefore, the only dimension we need is the CatalogRef.MaterialsAndServices.
Now we need to add a price itself but here is a question: what the price would be - a resource or an attribute? This decision was pretty obvious for Accumulation registers: a resource is what is summed up in the Balance table of the AR, whereas attributes are just some additional information that won’t make it to the Balance table at all.
There is no that kind of difference between resources and attributes in an information register - they are pretty much interchangeable in terms of functionality and performance. But the Platform keeps dividing them into these two categories to emphasize the difference in their purpose:
- We use resources to store the values whose history we are to keep track of
- We use attributes to store additional (not mission-critical) information
Therefore, we need to add the Price as a resource.
One more thing that differs an IR from AR - is that there is no Balance table in the Information register. But there can exist two additional tables containing secondary data and serving the same goal - to speed up the execution of frequent and task-critical queries.
These tables are called First and Last Slice tables.
IR slice tables
When you use an Information register to store the history of some values’ changes, your most common task is to read the current status of those values. We use the Prices information register to store the materials’ prices change history. We are obviously going to need the current price of materials very often.
Let’s take a look at the scheme of materials price changes history.
Prices are changed at different points in time. M1 on our diagram was last time changed at moment T5, M2 - at T6 and M3 - at T4. It would be a really nontrivial task - to get all latest prices with one query. Therefore, the Platform provides us with the virtual table that we can simply SELECT this data from. If you run the Query Builder, you will see this table in the list.
Note, that there is another table, called Prices.SliceFirst that can be used to get the first assigned values of prices (although, this is not what we need in our case).
You can (and for our purposes, you should) ask the Platform to store the last slice in a separate physical table. It will significantly increase the performance of the queries getting the last historical data.
OK, let’s fill out the register we created with data.
Posting the PriceChange document
To do so, we need to implement the Posting event handler in the PriceChange document. Let’s ask the Register record wizard to do the job.
In the Register records wizard form we need to tell the Platform where to get the data for the IR from:
- InformationRegister.Prices.MaterialOrService = Document.PriceChange.MaterialAndServices.MaterialOrService
- InformationRegister.Prices.Price = Document.PriceChange.MaterialAndServices.NewPrice
After pressing OK in this form we will get the following source code:
Procedure Posting(Cancel, Mode) //{{__REGISTER_REGISTERRECORDS_WIZARD // This fragment was built by the wizard. // Warning! All manually made changes will be lost next time you use the wizard. // register Prices RegisterRecords.Prices.Write = True; For Each CurRowMaterialsAndServices In MaterialsAndServices Do Record = RegisterRecords.Prices.Add(); Record.Period = Date; Record.MaterialOrService = CurRowMaterialsAndServices.MaterialOrService; Record.Price = CurRowMaterialsAndServices.NewPrice; EndDo; //}}__REGISTER_REGISTERRECORDS_WIZARD EndProcedure
Now we need to implement the auto filling out of the Price field in Services document form.
Auto filling out the Price field
Here is the resulting code we’ve got in the Services document form module:
&AtClient Procedure MaterialsAndServicesMaterialOrServiceOnChange(Item) Item.Parent.CurrentData.Price = GetCurrentPrice(Object.Date, Item.Parent.CurrentData.MaterialOrService); EndProcedure &AtServer Function GetCurrentPrice(Date, Ref) Filter = New Structure; Filter.Insert("MaterialOrService", Ref); CurrentPrice = InformationRegisters.Prices.GetLast(Date, Filter); Return CurrentPrice.Price; EndFunction
Lesson 4-4 | Course description| Lesson 5-1