Особенности использования типов, предназначенных для манипулирования необъектными данными

Все хранимые в базе данных сущности поддерживаемые в модели разработки 1С:Предприятия 8 можно разделить на объектные и необъектные. Так как различается сама природа этих сущностей, то существенные различия имеются и в способах манипулирования этими сущностями во встроенном языке. Про манипулирование объектными сущностями рассказывается в разделе "Особенности использования типов данных, предназначенных для манипулирования объектами базы данных". В данном разделе рассматриваются особенности манипулирования необъектными сущностями.

К необъектным сущностям относятся регистры (регистр сведений, регистр накопления, регистр бухгалтерии, регистр расчета), а также последовательности и перерасчеты регистров расчетов. Так же к необъектным сущностям относятся константы, однако в этом разделе мы их затрагивать не будем, так как для каждой константы в базе данных хранится одно значение и работа с ними не вызывает сложностей. Рассматривать необъектные сущности мы будем на примере регистра накопления и регистра сведений. Следует заметить, что только для регистра сведений допускается возможность его использования без регистратора, поэтому модель его использования шире, чем у других регистров, а вариант его использования с регистратором в основном аналогичен другим необъектным сущностям.

Модель хранения данных

С точки зрения модели данных 1С:Предприятия для необъектных сущностей в базе данных хранятся записи. Запись не является объектом базы данных. Для нее не поддерживается внутреннего идентификатора. Запись полностью описывается значениями своих полей. Это значит, что, удалив некоторую запись и записав новую с точно такими же значениями всех полей, мы получим то же состояние базы данных с точки зрения логики прикладного решения. Это принципиально отличает запись от объекта в объектных сущностях, так как объект базы данных имеет внутренний идентификатор и один и тот же объект нельзя создать дважды.

Например, если у нас есть регистр накопления, хранящий движения складских запасов товаров в разрезе товаров и складов, то каждая запись полностью определяется товаром, складом и количеством. Действительно, с точки зрения логики прикладного решения такая запись описывает движение некоторого товара по некоторому складу в некотором количестве. Можно записать вторую такую же запись, и они ничем не будут отличаться, если не отличаются значения полей. Объект, например, физическое лицо, имеет некоторую "самость" независящую от значений полей. У него может измениться имя, фамилия, паспортные данные, но он будет продолжать оставаться тем же объектом.

Уникальность записей

Важным следствием описанного отличия необъектных сущностей является отсутствие возможности записывать ссылки на эти записи в поля базы данных. Однако, следует заметить, что в модели 1С:Предприятия у каждой сущности есть уникальный ключ. Наличие уникального ключа необходимо системе для решения самых разных задач. Например, это позволяет позиционироваться в табличном поле на некоторую запись. Для всех необъектных сущностей, имеющих регистратор, уникальный ключ включает регистратор и номер строки. Номер строки собственно и используется для обеспечения уникальности записей, а также для упорядочивания записей в пределах регистратора. Для регистров сведений не подчиненных регистратору в качестве уникального ключа выступает совокупность измерений и периода, если регистр периодический.

Если регистр сведений подчинен регистратору, то для него фактически поддерживается уникальность и по сочетанию полей: регистратор и номер строки, и по измерениям и периоду. Первое определяется его подчинением регистратору, а второе его основной прикладной логикой – хранением значений ресурсов по комбинации значений измерений и периоду. Если для регистра выбрана периодичность по позиции регистратора, то в уникальный ключ по измерениям входит и регистратор, как дополнительная детализация периода в пределах секунды.

Подчинение регистратору

Подчинение записей регистратору обязательно для всех регистров кроме регистров сведений, а также обязательно для последовательностей и перерасчетов. Записи регистров подчиненные регистратору называются движениями.

Подчинение записей регистров регистратору определяет время жизни этих записей с точки зрения прикладной логики. Считается, что регистратор (документ) определяет наличие этих записей. Как правило, записи регистров создаются документом средствами встроенного языка в процессе проведения. Хотя допускается создание записей, ссылающихся на регистратор, без участия регистратора, но все равно эти записи считаются подчиненными регистратору. Запись нельзя записать без указания регистратора. При удалении регистратора подчиненные ему записи удаляются.

В отличие от табличных частей, записи регистров подчинены регистратору, но не являются его частью. При считывании документа подчиненные ему записи регистров не считываются, а при записи автоматически не записываются. Обеспечивается только удаление записей при удалении регистратора. Также существует возможность автоматического удаления записей при проведении и отмене проведения. Эта возможность настраивается в свойствах документа в конфигурации и является сервисной. Таким образом, записи регистров не являются частью объекта, а подчинены ему.

В 1С:Предприятии 8 наличие записей регистров подчиненных документу (регистратору) не связано жестко с состоянием документа "проведен" и с пометкой удаления. Допускается наличие записей и у непроведенного документа и у помеченного на удаление. Например, это используется для создания документов предназначенных для непосредственного ввода движений регистров – ручного ввода. В этом случае пользователь непосредственно вводит записи регистров и понятие проведения бессмысленно. При непосредственном изменении полей Проведен и ПометкаУдаления (без использования методов УстановитьПометкуУдаления() и записи с режимом ОтменаПроведения) удаление движений не производится.

Таким образом, модель связи движений с документом обладает достаточной гибкостью. Вместе с тем поддержание логической целостности связи документов и его движений требует усилий от разработчика конфигурации. Например, организация редактирования движений документа в форме сложнее, чем организация редактирования табличной части (являющейся неотъемлемой частью документа). Наиболее простой моделью использования регистров является создание движений при проведении. В этом случае достаточно реализовать запись движений в обработчике проведения, а вся остальная логика будет поддерживаться системой автоматически.

Типы данных, используемые для манипулирования во встроенном языке

Тип РегистрыНакопленияМенеджер предназначен для доступа к менеджерам конкретных регистров. К нему можно обратиться с помощью свойства глобального контекста РегистрыНакопления.

Тип РегистрНакопленияМенеджер предоставляют доступ к общим действиям, относящимся к конкретному регистру накопления. С помощью его методов выполняются действия, относящиеся к регистру, а не к его конкретным записям. Например, методы менеджера позволяют создать объект, предназначенный для манипулирования записями (НаборЗаписей), получить выборку регистра и т.д. Менеджер является своего рода "точкой входа" в конкретный регистр в объектной модели встроенного языка.

Менеджер регистра также имеет набор методов для выполнения действий связанных с основным назначением регистра. Например, для регистра накопления это получения остатков и оборотов, а у регистра сведений получение среза первых и среза последних записей. Следует заметить, что эти методы предназначены только для удобного выполнения указанных действий в простых случаях. Аналогичные данные могут быть получены виртуальными таблицами запросов. При этом в запросах обеспечивается большая гибкость. С точки зрения производительности обращение к запросам и методам менеджера существенно не различается.

Заметим, что объекты типа РегистрыНакопленияМенеджер и РегистрНакопленияМенеджер.ХХХХ (где ХХХХ имя регистра) имеются в системе в единственном экземпляре.

Основным типом, предназначенным для модификации данных необъектных сущностей, является набор записей. Тип РегистрНакопленияНаборЗаписей предназначен для чтения, модификации и удаления записей регистра. Набор записей всегда оперирует множеством записей отбираемых по некоторому условию. Для описания условия у набора записей есть свойство Отбор. Для регистров подчиненных регистратору отбор устанавливается всегда по регистратору.

Фактически, набор записей является коллекцией записей, которую можно прочитать и записать. Набор записей имеет только один метод для изменения данных – Записать(). В отличие от техники, используемой при манипулировании объектными сущностями, для необъектных сущностей нет понятия удаления. Набор записей может быть только записан. При этом выполняется замещение всех существующих записей удовлетворяющих текущему отбору на записи, хранящиеся в наборе. Соответственно для удаления множества записей следует установить отбор и, не добавляя записей в набор, выполнить запись набора.

Существует возможность записывать набор без замещения. Это регулируется параметром метода Записать(). При записи без замещения выполняется запись новых записей в базу данных без удаления существующих. Заметим, что при этом будет обеспечиваться корректировка номеров строк, для обеспечения последовательной нумерации записей в пределах регистратора. Обычно запись без замещения используется при необходимости записи большого объема движений регистров.

В отличие от работы с объектами, набор записей необязательно считывать, чтобы выполнить запись.

Для данных необъектных сущностей не существует понятия блокировки (речь идет, разумеется, не о транзакционной блокировке). Соответственно при записи набора могут быть изменены данные, которые были изменены другой сессией или другим набором в этой сессии уже после считывания набора записей. Это обстоятельство следует учитывать при использовании наборов записей для интерактивного редактирования.

Следует отдельно остановиться на регистрах сведений не подчиненных регистратору. Для наборов записей регистров сведений не подчиненных регистратору может использоваться отбор с различными комбинациями измерений и периода. На рисунке приведены некоторые примеры возможных отборов.

Следует обратить внимание на то, что допускается чтение и запись набора без установки отбора по каким-либо полям. В этом случае будет выполняться чтение и соответственно запись всех записей регистра. При ошибках в написании модулей (например, пропущенном вызове чтения набора или пропущенной установке отбора) запись набора может привести к полной очистке регистра, так как запись при неустановленном отборе фактически замещает весь регистр на содержимое набора записей.

Запись в наборе записей регистра накопления имеет тип РегистрНакопленияЗапись. Данный тип используется только для записи в наборе записей. Это значение не используется отдельно от набора записей.

Для регистра сведений не подчиненного регистратору кроме набора записей существует так же тип РегистрСведенийМенеджерЗаписи. Этот тип предназначен для чтения и записи одной записи регистра. Прежде всего, он используется для организации редактирования одной записи в форме. Он позволяет прочитать запись с определенными значениями ключевых полей, изменить поля, в том числе и ключевые, и записать.

Этот тип является вспомогательным. Для работы с регистром он использует два набора записей (с отборами соответствующими соответственно ключевым полям считанной и записываемой записи). Соответственно реализация обработчиков в модуле набора записей позволят полностью контролировать изменения данных регистра, в том числе и тогда, когда они выполняются с помощью менеджера записи.

Тип РегистрНакопленияКлючЗаписи предназначен для уникальной идентификации записи регистра. Например, он используется для идентификации строки табличного поля отражающего список регистра. Это позволяет активизировать необходимую строку. Свойства ключа определяются полями образующими уникальный ключ регистра. Для регистров сведений это измерения, период и регистратор, если используется периодичность по позиции регистратора. Для других регистров это регистратор и номер строки. Ключ записи регистра может быть создан с помощью менеджера.

Тип РегистрНакопленияВыборка предназначен для динамического обхода записей регистра. Механизм выборок для необъектных таблиц не имеет существенных отличий. Следует учитывать, что выборка всегда считывает данные записей целиком (считываются все поля).

Тип РегистрНакопленияСписок предназначен для динамического просмотра записей регистра в элементе управления ТабличноеПоле. У него может быть настроен состав считываемых полей (колонок), отбор и сортировка. Список осуществляет считывание данных порциями в процессе навигации пользователем в табличном поле.

Кроме указанных типов значений регистр определяет несколько расширений элементов управления и форм, предназначенных для интерактивного ввода и просмотра, данных регистра. Расширения не являются типами данных, а добавляют специфические свойства, методы и события к соответствующим объектам. Кроме того, расширения определяют некоторое специфическое поведение форм и элементов управления при конфигурировании и работе пользователя с системой.

Для регистров сведений кроме расширений для показа в форме списка и набора записей поддерживается расширение для редактирования в форме одной записи. В этом случае в качестве основного реквизита формы выступает менеджер записи регистра сведений.