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