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