Зачем явно указывать регистратор при формировании движений по регистру накопления?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Стандартный механизм и код автора

Для начала проанализируем ситуацию, описанную в вопросе. В модуле документа при формировании движений по регистру накопления используется следующий код:


Движение = Движения.ПланированиеПоступления.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
Движение.Регистратор = Ссылка;
Движение.Период = Дата; 
Движение.Планирование = Ссылка;
Движение.Номенклатура = стр.Номенклатура;
Движение.Склад = Склад; 
Движение.Количество = стр.Количество;

Здесь Движение.Регистратор = Ссылка; вызывает основной вопрос. Давайте выясним причины, по которым такая строка появляется в коде.

Причина 1: Универсальность кода и вынос логики в общие модули

Современные стандарты разработки 1С (например, применяемые в библиотеке стандартных подсистем — БСП) рекомендуют выносить логику проведения из модуля документа в общие модули. Это позволяет переиспользовать код, вызывать проведение из внешних обработок или выполнять групповое перепроведение более гибко.

Рассмотрим ситуацию: если процедура формирования движений находится в общем модуле, она может работать не с коллекцией Движения конкретного объекта, а с произвольным объектом типа РегистрНакопленияНаборЗаписей. В этом случае платформа не всегда может автоматически определить регистратора, если набор записей создан «вручную» через РегистрыНакопления.ИмяРегистра.СоздатьНаборЗаписей(). Явное указание регистратора гарантирует, что процедура будет работать корректно в любом контексте.

Причина 2: Использование метода «Загрузить» из таблицы значений

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


ТаблицаДвижений = Движения.ПланированиеПоступления.ВыгрузитьКолонки();
// ... заполнение ТаблицаДвижений в цикле ...
НоваяСтрока = ТаблицаДвижений.Добавить();
НоваяСтрока.Регистратор = Ссылка;
НоваяСтрока.Период = Дата;
// ... заполнение остальных полей ...

Движения.ПланированиеПоступления.Загрузить(ТаблицаДвижений);

Когда мы используем метод Загрузить(), платформа полностью заменяет содержимое набора записей данными из таблицы. Если в таблице значений колонка Регистратор не будет заполнена, то после загрузки в наборе записей поле Регистратор окажется пустым. Хотя при записи набора через коллекцию Движения платформа может попытаться восстановить это значение, явное заполнение в ТЗ считается «хорошим тоном» и защищает от логических ошибок при сложных манипуляциях с данными.

Причина 3: Доступ к значению до момента записи в базу данных

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

Если в процессе проведения документа нам требуется передать структуру движения в другую функцию для дополнительных расчетов или проверок, и эта функция ожидает заполненного поля Регистратор, нам придется заполнить его явно. В противном случае функция получит ПустаяСсылка или Неопределено, что приведет к ошибке в расчетах.

Причина 4: Проведение «от имени» другого документа

Как было верно замечено в обсуждении, регистратор не всегда совпадает с тем документом, в модуле которого пишется код. Хотя это встречается редко и обычно в специфических архитектурных решениях, техническая возможность записи движений по другому регистратору существует (при использовании объекта НаборЗаписей). В таких случаях явное присвоение Движение.Регистратор = СсылкаНаДругойДокумент; является единственным способом связать запись регистра с нужным владельцем.

Причина 5: Наследование опыта и «оборонительное программирование»

Многие разработчики, работавшие с ранними версиями платформы 8.0 или перешедшие с 7.7, привыкли к тому, что контроль над ключевыми полями должен быть полным. Явное указание Регистратор = Ссылка и Период = Дата — это элемент «оборонительного программирования». Это не несет никакой нагрузки на производительность (операция присваивания ссылки в памяти выполняется мгновенно), но визуально подтверждает, что разработчик контролирует состав полей записи.

Резюмируем:

  1. Для коллекции Движения внутри модуля документа явное указание регистратора чаще всего является избыточным, но безвредным.
  2. Для универсальных механизмов в общих модулях это обязательное требование для стабильной работы кода.
  3. При работе с Таблицами Значений и методом Загрузить() заполнение колонки регистратора необходимо для корректного переноса данных.
  4. Для безопасности — это гарантирует наличие данных в поле до фактической записи объекта в БД.

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

← На главную