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