Почему не обновляется таблица на форме при добавлении первых строк в 1С?

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

Разберем распространенную ситуацию, с которой сталкиваются разработчики при работе с управляемыми формами в 1С:Предприятие 8.3. Из формы подбора или в результате серверной обработки в документ передаются строки. На сервере выполняется программное добавление элементов в коллекцию ДанныеФормыКоллекция (например, Объект.Список). Однако если изначально табличная часть была пустой, добавленные строки не отображаются на клиенте до тех пор, пока пользователь вручную не кликнет по элементу управления или не переведет на него фокус.

При этом вызов метода ОбновитьОтображениеДанных(Элементы.Список) не даёт нужного эффекта, а при пошаговой отладке кода интерфейс обновляется корректно. Выясним причину такого поведения и рассмотрим несколько эффективных способов решения проблемы.

Причины возникновения проблемы

Проанализируем механику работы платформы 1С при взаимодействии сервера и клиента:

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

Способ 1: Явная установка текущей строки на клиенте

Наиболее простое и быстрое решение — после возврата из серверной процедур фокусировать элемент таблицы на первой добавленной строке. Для этого используется получение идентификатора строки коллекции.

Рассмотрим пример клиентского кода:


// Вызов серверной процедуры добавления строк
ЗаполнитьТаблицуНаСервере();

// Принудительно устанавливаем фокус на первую строку
Если Объект.Список.Количество() > 0 Тогда
    Элементы.Список.ТекущаяСтрока = Объект.Список[0].ПолучитьИдентификатор();
КонецЕсли;

Явная установка свойства ТекущаяСтрока активирует графический элемент таблицы формы, заставляя его полностью перерисовать содержимое.

Способ 2: Использование ЗначениеВДанныеФормы или метода Загрузить()

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

Рассмотрим пример серверной процедуры с использованием ЗначениеВДанныеФормы:


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

Альтернативный вариант — применение метода Загрузить() непосредственно к коллекции формы:


&НаСервере
Процедура ЗаполнитьТаблицуНаСервере()
    
    ТаблицаСДанными = ПолучитьТаблицуИзХранилища();
    Объект.Список.Загрузить(ТаблицаСДанными);
    
КонецПроцедуры

Метод Загрузить() и функция ЗначениеВДанныеФормы() полностью сбрасывают состояние коллекции на клиенте и инициируют её полную переинициализацию в интерфейсе.

Способ 3: Полное обновление отображения данных формы

Если необходимо обновить форму без передачи конкретного элемента управления, можно вызвать метод ОбновитьОтображениеДанных() для всей формы целиком, не передавая параметров.


&НаКлиенте
Процедура ПослеЗаполнения()
    
    ЗаполнитьТаблицуНаСервере();
    
    // Обновляем всю форму целиком, а не отдельный элемент таблицы
    ЭтаФорма.ОбновитьОтображениеДанных();
    
КонецПроцедуры

Способ 4: Использование промежуточной коллекции на клиенте

В случаях, когда данные обрабатываются в неконтекстной серверной процедуре, можно передать коллекцию формы как параметр и применить функцию КопироватьДанныеФормы() на клиенте:


&НаКлиенте
Процедура ОбработатьИОбновить()
    
    // Создаем временную коллекцию на основе текущей
    СписокВременный = Объект.Список;
    
    // Обрабатываем данные в неконтекстном вызове
    ОбработатьДанныеНаСервере(СписокВременный);
    
    // Копируем полученный результат обратно в реквизит формы
    КопироватьДанныеФормы(СписокВременный, Объект.Список);
    
КонецПроцедуры

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

← На главную