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

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

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

Анализ исходной ситуации

Рассмотрим типичный пример кода, который часто приводит к подобной проблеме. Программист пытается добавить строку в коллекцию Объект.Показатели непосредственно в клиентской процедуре:


&НаКлиенте
Процедура ДобавитьОбновитьСтрокуКонечныеОстатки()
    ТекДанные = Элементы.ТЧ_ШПЗ.ТекущиеДанные;
    ТекШПЗ = ТекДанные.ШПЗ;  
    
    Если Не ЗначениеЗаполнено(ТекШПЗ) Тогда 
        Возврат;
    КонецЕсли; 
    
    КонечныеОстаткиМассивСтрок = Объект.Показатели.НайтиСтроки(Новый Структура("ЭтоКонечныйОстаток,ШПЗ", Истина, ТекШПЗ));
    
    Если КонечныеОстаткиМассивСтрок.Количество() = 0 Тогда
        СтрокаОстатков = Объект.Показатели.Добавить(); 
    Иначе
        СтрокаОстатков = КонечныеОстаткиМассивСтрок[0]; 
    КонецЕсли;
    
    СтрокаОстатков.ШПЗ = ТекШПЗ;
    СтрокаОстатков.ЭтоКонечныйОстаток = Истина; 
    СтрокаОстатков.Номенклатура = ИскомаяНоменклатура; 
    
    // Попытки обновить интерфейс, которые часто не помогают:
    ЭтаФорма.ОбновитьОтображениеДанных(Элементы.Показатели);
    ЭтаФорма.Элементы.Показатели.Обновить();
КонецПроцедуры

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

Причина 1: Несоответствие пути к данным

Разберем ситуацию, когда элемент формы типа «Таблица» на самом деле связан не напрямую с Объект.ТабличнаяЧасть, а с неким вспомогательным реквизитом формы (например, деревом или таблицей значений). В типовых конфигурациях, таких как ЗУП 3.1 или ERP 2.5, это встречается повсеместно. Данные копируются из объекта в реквизит формы при открытии и обратно при записи. Если вы добавляете строку в Объект.Показатели, а на форме отображается реквизит ТаблицаПоказателей, то изменений вы не увидите до момента синхронизации этих структур.

Что нужно сделать: проверьте свойство ПутьКДанным у элемента таблицы на форме. Если там указано не Объект.Показатели, значит, вам нужно вносить изменения именно в тот источник, который указан в этом свойстве.

Причина 2: Проблема идентификаторов строк

Платформа 1С отрисовывает строки, ориентируясь на их внутренние идентификаторы. При программном добавлении на клиенте иногда происходит сбой в логике обновления индексов. Одним из «хаков», заставляющих графическую оболочку принудительно пересчитать видимые области, является установка фокуса на новую строку.

Попробуем модифицировать наш код следующим образом:


НоваяСтрока = Объект.Показатели.Добавить();
// Заполнение данных
НоваяСтрока.ШПЗ = ТекШПЗ;
// ...
// Принудительная установка текущей строки
Элементы.Показатели.ТекущаяСтрока = НоваяСтрока.ПолучитьИдентификатор();

Этот метод заставляет таблицу «прокрутиться» к новой строке и физически создать её визуальный компонент.

Причина 3: Использование серверного метода для синхронизации

Если клиентские манипуляции не помогают, проанализируем самый надежный, хоть и более ресурсоемкий способ — переход на сервер. Метод ДанныеФормыВЗначение и обратный ему ЗначениеВДанныеФормы гарантируют полную перерисовку связанных элементов интерфейса, так как для платформы это выглядит как масштабное изменение данных.

Рассмотрим шаги реализации:

  1. Создаем процедуру &НаСервере.
  2. Конвертируем данные формы в прикладной объект.
  3. Добавляем строку в объектную табличную часть.
  4. Возвращаем результат в данные формы.

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

Этот подход устраняет любые проблемы с кэшированием на клиенте, так как ЗначениеВДанныеФормы инициирует полное обновление всех коллекций формы.

Причина 4: Влияние фильтров и условного оформления

Выясним еще одну неочевидную причину: на таблицу формы могут быть наложены невидимые отборы. Если вы добавляете строку, которая не удовлетворяет условиям текущего отбора (например, программно установленного через Элементы.Показатели.Отбор), строка будет добавлена в данные, но не отобразится на экране.

Аналогично работает Условное оформление. Если в форме задано правило, скрывающее строки при определенных условиях (например, если не заполнено ключевое поле), то новая пустая строка будет скрыта мгновенно в момент создания. Проанализируйте вкладку «Условное оформление» в свойствах формы.

Рекомендации по выбору метода обновления

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

Использование вышеописанных методик позволит вам избежать «зависания» интерфейса и обеспечит корректную работу пользователя с табличными частями в любых конфигурациях 1С.

← На главную