Почему при программном заполнении табличной части не заполняются зависимые поля?

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

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

Причина проблемы: отсутствие цепочки серверных событий

Когда пользователь работает с формой интерактивно и выбирает номенклатуру в поле ввода, платформа 1С автоматически инициирует выполнение серверного обработчика события ПриИзменении. Именно в этом обработчике обычно прописана логика заполнения связанных данных, таких как единица измерения, цена или ставка НДС.

Когда вы программно добавляете строку в коллекцию ДанныеФормыКоллекция (например, через Добавить()) и просто присваиваете значение полю, вы работаете с клиентским представлением данных. В этом случае вызов штатных процедур ПриИзменении не происходит. Платформа просто «не знает», что нужно выполнить пересчет зависимых реквизитов, так как «цепочка событий» была разорвана.

Способ 1: Заполнение объекта на сервере (рекомендуемый)

Самый архитектурно верный способ — это выполнение всей логики заполнения на сервере. Вместо того чтобы пытаться «манипулировать» элементами формы на клиенте, создайте или заполните объект документа непосредственно на сервере.

Рассмотрим пошагово, как это сделать правильно:

  1. Получите ссылку на документ или создайте новый объект через Документы.ХХХХХ.СоздатьДокумент().
  2. Заполните табличную часть объекта на сервере. При программном заполнении объекта 1С все механизмы заполнения (включая подстановку единиц измерения по номенклатуре) сработают штатно, так как вы работаете с данными объекта, а не с их клиентским представлением.
  3. Используйте метод ЗначениеВРеквизитФормы(), чтобы перенести заполненные данные в форму документа.

Этот подход гарантирует, что все механизмы типовой конфигурации будут соблюдены.

Способ 2: Вызов экспортной процедуры из модуля формы

Если по каким-то причинам вам необходимо заполнять данные именно на клиенте и после этого сразу открывать форму, можно поступить следующим образом:

  1. Откройте модуль формы вашего документа.
  2. Создайте там новую экспортную процедуру (например, ЗаполнитьДанныеПоНоменклатуре(СтрокаТЧ)), которая содержит вызов стандартной логики заполнения.
  3. Вызывайте эту процедуру из своей внешней обработки сразу после того, как добавили строку в табличную часть формы.

Пример структуры кода в модуле формы документа:


// В модуле формы документа
&НаСервере
Процедура ЗаполнитьСтрокуНаСервере(СтрокаТЧ) Экспорт
    // Здесь вызываем штатную логику, которая обычно срабатывает при изменении номенклатуры
    // Например:
    Объект.Товары.ЗаполнитьЕдиницуИзмерения(СтрокаТЧ);
КонецПроцедуры

Внешняя обработка при этом будет выглядеть так:


ФормаДок = ПолучитьФорму("Документ.ХХХХХ.Форма.ФормаДокумента");
Для каждого СтрокаТЗ из ТЗНормы Цикл
    НовСтр = ФормаДок.Товары.Добавить();
    НовСтр.Номенклатура = СтрокаТЗ.Номенклатура;
    
    // Вызываем процедуру формы, которая принудительно заполнит зависимые данные
    ФормаДок.ЗаполнитьСтрокуНаСервере(НовСтр);
КонецЦикла;
ФормаДок.Открыть();

Способ 3: Передача параметров при открытии

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

В самой форме документа, в обработчике ПриСозданииНаСервере, вы можете проанализировать переданные параметры:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Если Параметры.Свойство("ДанныеДляЗаполнения") Тогда
        // Заполняем документ полученными данными
        // Здесь сработают все механизмы заполнения объекта
    КонецЕсли;
КонецПроцедуры

Итог: что выбрать?

Мы выяснили, что прямая запись в реквизиты формы не запускает необходимые серверные обработчики. Чтобы избежать пустых полей при программном заполнении:

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

← На главную