При проектировании регистров накопления разработчики нередко сталкиваются с необходимостью связать движения с конкретной строкой документа, позицией заказа или дополнительным числовым параметром. Платформа 1С:Предприятие технически позволяет назначить измерению регистра числовой тип, однако такое архитектурное решение несет скрытые риски для производительности и целостности базы данных. Разберем по шагам, к каким последствиям приводит числовое измерение и какими способами следует решать подобные задачи.
Основное назначение регистра накопления с видом Остатки — хранение агрегированных количественных и суммовых показателей по заданной комбинации измерений. Когда мы вводим числовое измерение, выполняющее роль идентификатора (например, номера строки документа или произвольного индекса), мы сталкиваемся со следующими проблемами:
333, а при списании из-за человеческого фактора или логики заполнения подставилось 334, по первому значению зависнет положительный остаток, а по второму образуется отрицательный. Проанализируем типичный сценарий: любое изменение порядка строк в табличной части документа-основания меняет числовые привязки, в результате чего движения перестают «схлопываться».Числовой тип в измерениях допустим и успешно применяется, когда он отражает реальное непрерывное или дискретное потребительское свойство номенклатуры, по которому действительно требуется раздельный учет остатков. Например, учет партий продукции по показателям: кислотность, жирность, процент содержания вещества или крепость. В таком случае число является физической характеристикой партии, а не суррогатным идентификатором строки.
Также числовые измерения вида НомерСтроки встречаются в типовых конфигурациях (например, в подсистемах распределения взаиморасчетов), но их поддержка требует сложнейших алгоритмов автоматического выравнивания движений и контроля партий при любом редактировании документов.
Если задача заключается в том, чтобы связать товарные позиции заказа с адресами доставки или операциями выполнения услуг, рассмотрим проверенные шаблоны проектирования, рекомендуемые стандартами разработки 1С.
Если привязка номенклатуры к адресу нужна исключительно внутри одного документа (например, заказ содержит две разные табличные части — «Товары» и «АдресаДоставки»), в регистр эту связь выносить не нужно. Достаточно добавить в обе табличные части числовой реквизит КлючСвязи.
Рассмотрим пример связи строк при обработке проведения:
Для Каждого СтрТовары Из ТаблицаТовары Цикл
Отбор = Новый Структура("КлючСвязи", СтрТовары.КлючСвязи);
СтрокиАдресов = ТаблицаАдреса.НайтиСтроки(Отбор);
Для Каждого СтрАдрес Из СтрокиАдресов Цикл
// Формируем движения регистра или сопоставляем данные
КонецЦикла;
КонецЦикла;
В регистр накопления при этом передаются только агрегированные данные (Заказ, Номенклатура), а внутренняя детализация не перегружает структуру итогов.
Когда требуется учитывать остатки в сложном разрезе нескольких сущностей (Заказ, Вид услуги, Адрес), добавление множества разнородных измерений в регистр неэффективно. Вместо этого создают служебный справочник КлючиАналитикиУслуг, реквизитами которого выступают все необходимые аналитики. В регистре накопления создается всего одно измерение ссылочного типа:
Функция ПолучитьКлючАналитики(Заказ, ВидУслуги, Адрес)
Ключ = Справочники.КлючиАналитикиУслуг.НайтиПоРеквизитам(
Новый Структура("Заказ, ВидУслуги, Адрес", Заказ, ВидУслуги, Адрес)
);
Если Не ЗначениеЗаполнено(Ключ) Тогда
НовыйОбъект = Справочники.КлючиАналитикиУслуг.СоздатьЭлемент();
НовыйОбъект.Заказ = Заказ;
НовыйОбъект.ВидУслуги = ВидУслуги;
НовыйОбъект.Адрес = Адрес;
НовыйОбъект.Записать();
Ключ = НовыйОбъект.Ссылка;
КонецЕсли;
Возврат Ключ;
КонецФункции
Такой подход сохраняет целостность ссылочных данных, обеспечивает быстродействие индексов СУБД и исключает появление несогласованных записей при ручном вводе.
Выясним причину, по которой адрес часто пытаются включить в регистр накопления: желание получить всю информацию в одном отчете. Однако адрес — это статическая характеристика выполнения, а не накапливаемый ресурс. Правильнее хранить количественные остатки в регистре накопления в укрупненном разрезе (Заказ, Номенклатура), а адресную маршрутизацию фиксировать в независимом регистре сведений. В отчетах эти таблицы связываются левым соединением по общему ключу заказа, что гарантирует точный учет остатков без деградации базы данных.