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