Using types for manipulating non-object data
All entities that are supported by the 1C:Enterprise 8 development model and are stored in a database can be divided into object and nonobject ones. Since these entities differ by nature, manipulating these entities using 1C:Enterprise of script tools also differs greatly. For information on object entities manipulation, see section Using data types for manipulating database objects. This section provides information on manipulating nonobject entities.
Nonobject entities are registers (information register, accumulation register, accounting register, and calculation register), and sequences and recalculations of calculation registers. Constants are also nonobject entities, but they are not reviewed in this section, as the database stores one value for each constant and they are not difficult to handle. We will review nonobject entities on the example of an accumulation register and an information register. Note that an information register is the only register you can use without a recorder, so its usage model is more expansive in comparison with other recorders, and its use with the recorder is mostly similar to other nonobject entities.
Data storage model
From the point of view of the 1C:Enterprise data model, a database stores records for nonobject entities. A record is not a database object. No internal identifier is supported for it. A record can be described in full with the values of its fields. Therefore, if you delete a certain record and then write a new one with exactly the same values of all the fields, you will obtain the same database state from the point of view of the applied solution logics. This is a principal difference between a record and an object as part of object entities, since a database object has an internal identifier, and you cannot create the same object twice.
For instance, if you have an accumulation register that stores the movements of the stock from the goods and warehouses perspective, each record is fully defined fully by the type of goods, a warehouse, and the specified quantity. Indeed, from the point of view of the applied solution logics, such a record describes the movement of a certain quantity of a certain product along a certain warehouse. You can create a second record like this and the two would not differ unless the field values differ. An object that represents a physical person may have some personal characteristics that do not depend on the field values. This person can change the name, last name, and passport data, but the person still remains the same object.
An important consequence of the specifics of nonobject entities described above is the inability to write references to these records to the database fields. It should be noted however that there is a unique key for each entity in 1C:Enterprise. This platform uses the unique key to handle various tasks. For instance, you can target a certain record in a table box. For all nonobject entities that have a recorder, the unique key includes a recorder and a line number. A line number is used to ensure that the record is unique and to sort records within the recorder. A combination of dimensions and the period (if the register is periodic) functions like a unique key for information registers that are not subordinate to recorders.
If an information register is subordinate to a recorder, its unique character is also supported by a combination of fields: a recorder, a line number, dimensions, and a period. The first is defined by its subordination to the recorder, while its basic applied logics (storing resource values by a combination of dimensional values and the period) define the second. If you set that the periodicity of the register is defined by the recorder's position in the timeline, the unique dimension key includes a recorder as well to ensure additional period detailing within a second.
Subordination to a recorder
Subordination of records to a recorder is mandatory for all registers, except for information registers. The subordination of records is also mandatory for sequences and recalculations. Records that are subordinate to a certain recorder are called register records.
Subordination of register records to the recorder defines the lifetime of these records from the point of view of the applied logics. The recorder (document) is considered to define whether these records exist or not. As a rule, register records are created by the document with the help of 1C:Enterprise script tools in the process of posting. Records that reference the recorder can be created without a recorder, but these records are still deemed subordinate to the recorder. You cannot write a record without specifying a recorder. If you delete a recorder, its subordinate records are also deleted.
Unlike tabular sections, register records are subordinate to the recorder, but they are not part of it. When a document is read, its subordinate register records are not read, and while it is written, they are not written automatically. However, when a recorder is deleted, its records are deleted too. You can have records automatically deleted when objects are posted or unposted. This service option is set in document properties as part of the configuration. Therefore, register records are not part of an object, but are subordinate to it.
In 1C:Enterprise 8, the availability of register records subordinate to the document (recorder) is not strictly related to the Posted state of the document or to the deletion mark. Documents that have not been posted or have been marked for deletion can also have records. For instance, this is used for documents intended for direct input (manual input) of register records. In this scenario, the user inputs register records directly, so the posting concept makes no sense. If the Posted or DeletionMark field is modified directly (without using the SetDeletionMark() method or the UndoPosting event), register records are not deleted.
Therefore, connections between register records and documents are quite flexible. On the other hand, ensuring the logical integrity of connections between documents and their register records demands some effort on the part of the configuration developer. For instance, it is more complicated to edit document records in the form than to edit tabular sections (which are an integral document part). The simplest register usage is creation of register records at the time of posting. In this case, you only need to ensure that register records are written in the posting handler, and the platform automatically supports other logical connections.
Data types used for manipulating objects in 1C:Enterprise script
The AccumulationRegistersManager type provides access to the managers of specific registers. You can use the AccumulationRegisters global context property to call this type.
The AccumulationRegisterManager type provides access to common actions that relate to a specific accumulation register. You can use its methods to perform actions applicable to the register and not to its specific records. For instance, methods of this manager can be used to create an object for manipulating records (RecordSet), to obtain a register selection, and so on. The manager is a sort of entry point to a specific register in the 1C:Enterprise script object model.
The register manager also provides a set of methods to perform actions related to the main purpose of the register. You can obtain balances and turnovers for an accumulation register or obtain slices of the first or last records of an information register. Note that these methods are handy for performing these actions in simple scenarios only. Similar data can be obtained via virtual query tables. Queries are more flexible. From the system performance point of view, calling queries and calling manager methods do not differ much.
Note that the system can contain a single object of the AccumulationRegistersManager type and a single object of the AccumulationRegisterManager.XXXX type for each register (where XXXX is a register name).
A record set is the main type used for modifying the data of nonobject entities. Type AccumulationRegisterRecordSet should be used to read, modify, and delete register records. A record set always operates a set of records filtered by some criteria. To describe these criteria, use the Filter property of a record set. Registers that are subordinate to the recorder are always filtered by recorder.
In practice, a record set is a collection of records that can be read and written. A record set provides only one method for modifying data: Write(). Unlike the methodology used in manipulating object entities, there is no deletion concept for nonobject entities. A record set can only be written. At the same time, all the existing records that satisfy the current filtering criterion are replaced with the records that are stored in the set. Therefore, to delete a set of records, you need to set the filter and then write the set without adding any records to it.
You can also write a set without replacing its items. This is controlled by the Write() method parameter. Writing without replacing means that new records are added to the database without deleting the existing ones. Note that line numbers are adjusted to ensure sequencial numbering of records within a recorder. Usually, writing without replacing is used when a large volume of register records needs to be written.
You do not have to read a record set to write data (which makes the deffenenbce with similar object operations).
No locking concept can be applied to the data of nonobject entities (we are not talking about transaction locks, of course). Therefore, when a set is written, data that has been modified in another session or another set in this session after reading a record set might be overwritten. Remember this when using record sets for interactive editing.
Information registers that are not subordinate to recorders deserve attention as well. You can use filters with different combinations of dimensions and periods for record sets of information registers that are not subordinate to recorders. The image below shows some possible filters.
Note that a set can be read and written without filtering data by any fields. In this case, all register records will be read and therefore written. If one makes a mistake in a module (for instance, reading a record set or applying a filter is missing), writing a set can result in the complete clearing of a register, since writing without a filter actually replaces the entire register with the content of a record set.
Records in accumulation register record sets have the AccumulationRegisterRecord type. This type is only used to write data in a record set. This value is never used separately from a set of records.
Besides a record set, the InformationRegisterRecordManager type is also provided for an information register that is not subordinate to the recorder. This type is used to read and write a single register record. First of all, it is used to edit a single record in the form. With this type, you can also read a record with certain key field values, modify the fields (including the key ones), and then write the record.
This is an auxiliary type. It uses two record sets to work with a register (with filters that correspond to the key fields of the record being read and written respectively). Therefore, by implementing handlers in a record set module, you can fully control register data modification, including the scenarios when data is modified with the help of a record manager.
The AccumulationRegistersRecordKey type can be used for unique identification of a register record. For example, it is used to identify rows of a table box that represents a register list. You can activate any row you need. Key properties are defined by the fields that form a unique register key. These are dimensions, a period, and a recorder for information registers (the recorder is only included if periodicity by a recorder's position in the timeline is used). A recorder and a row number are used for other registers. A key for a register record can be created with the help of a manager.
The AccumulationRegisterSelection type can be used for dynamic iteration of register records. A selection feature of non-object tables does not differ much from that of reference tables. Note that a selection always reads record data in full (all fields are read).
The AccumulationRegisterList type can be used to dynamically view register records in the TableBox control. You can set up the structure of the fields (columns) that are read, as well as set up filtering and sorting. The list reads data in portions as the user navigates through a table box.
The register also defines several extensions of controls and forms that can be used to interactively input and view register data. Extensions are not data types, they simply add specific properties, methods, and events to the corresponding objects. In addition, extensions define any unusual behavior of forms and controls when a user configures the system and interacts with it.
An extension for editing a single record in a form is also supported for information registers, together with the extensions that show a list and a record set in the form. In this case, the information register record manager acts as the main form attribute.