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