Как правильно обновить табличную часть на общей форме в управляемом приложении 1С?

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

При разработке управляемых форм (в частности, общих форм конфигурации) разработчики часто сталкиваются с ситуацией, когда данные, заново сформированные или измененные в табличной части на сервере, не отражаются на клиенте. Главная причина заключается в особенностях работы с контекстом формы и неверном использовании функций преобразования данных.

Причина проблемы: почему данные не появляются на клиенте?

В стандартных формах объектов (например, элементов справочников или документов) присутствует основной реквизит Объект. Обращение к данным объекта на сервере обычно происходит через функции РеквизитФормыВЗначение() и ЗначениеВРеквизитФормы().

Однако в общих формах по умолчанию реквизит Объект отсутствует. Табличная часть, созданная непосредственно как реквизит формы, хранится на сервере в виде объекта ДанныеФормыКоллекция. Попытки вызвать процедуры преобразования с некорректными параметрами (например, передача строк с путями "ЭтотОбъект.Товары") либо приводят к ошибкам выполнения, либо не передают данные на клиентскую часть.

Способ 1. Прямая работа с коллекцией формы (Рекомендуемый)

В контекстных серверных процедурах с директивой &НаСервере реквизит формы табличного типа уже доступен напрямую как объект ДанныеФормыКоллекция. Это означает, что для изменения данных не требуется предварительно конвертировать его в ТаблицаЗначений.

Рассмотрим пример прямого обхода и заполнения реквизита Товары на сервере:


&НаСервере
Процедура ЗаполнитьТаблицуНаСервере()
    
    // Прямой обход строк коллекции формы
    Для Каждого Стр Из Товары Цикл
        // Изменяем или заполняем значения колонок
        Стр.Номенклатура = НайтиИлиСоздатьНоменклатуру(Стр.Штрихкод);
    КонецЦикла;
    
    // Добавление новой строки в коллекцию на форме
    НоваяСтрока = Товары.Добавить();
    НоваяСтрока.Количество = 1;

КонецПроцедуры

Все изменения, внесенные в коллекцию ДанныеФормыКоллекция на сервере, автоматически синхронизируются с клиентом и отображаются на форме при завершении серверного вызова.

Способ 2. Загрузка из таблицы значений через метод Загрузить()

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


&НаСервере
Процедура ЗаполнитьИзТаблицыЗначений(ТаблицаИсточник)
    
    // Загружаем данные напрямую в реквизит формы
    Товары.Загрузить(ТаблицаИсточник);

КонецПроцедуры

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

Способ 3. Использование функций ЗначениеВДанныеФормы и РеквизитФормыВЗначение

Если для выполнения алгоритмов обработку необходимо выполнить именно в типе ТаблицаЗначений, важно соблюдать правила передачи параметров:

  1. При вызове РеквизитФормыВЗначение("Товары") первым параметром передается имя реквизита формы в виде строки (без префиксов и пробелов).
  2. При обратном сохранении используется метод ЗначениеВРеквизитФормы(ТЗ, "Товары") либо ЗначениеВДанныеФормы(ТЗ, Товары), где второй параметр — сам реквизит формы, а не строка.

&НаСервере
Процедура ОбработатьТаблицуЧерезТЗ()
    
    // Преобразуем реквизит формы в прикладной объект ТаблицаЗначений
    ТЗ = РеквизитФормыВЗначение("Товары");
    
    // Выполняем необходимую обработку таблицы
    // ...
    
    // Возвращаем обновленные данные обратно в реквизит формы
    ЗначениеВРеквизитФормы(ТЗ, "Товары");

КонецПроцедуры

Резюме и рекомендации

Проанализировав работу с табличными частями на общих формах, выделим главные правила:

  1. Не используйте обращение к реквизиту Объект на общих формах, если этот реквизит не был создан вручную.
  2. Работайте с реквизитами формы табличного типа напрямую через объект ДанныеФормыКоллекция — это наиболее эффективный способ без лишних конвертаций.
  3. Используйте метод .Загрузить() для быстрого переноса данных из результата запроса или таблицы значений.
  4. Убедитесь, что серверный код выполняется в контексте формы (директива &НаСервере), так как в вызовах &НаСервереБезКонтекста реквизиты формы недоступны.
← На главную