Как обновить отображение измененного наименования ссылки в табличной части управляемой формы 1С 8.3

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

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

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

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

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

Основное решение: использование метода ОповеститьОбИзменении

Наиболее правильным и платформенным решением является вызов глобального клиентского метода ОповеститьОбИзменении(). Этот метод сообщает клиентскому приложению, что объект базы данных был модифицирован, благодаря чему сбрасывается кэш представлений и элементы интерфейса перерисовываются с актуальными данными.

Рассмотрим по шагам реализацию данного подхода:

  1. Выполняем программную модификацию и запись ссылочного объекта на сервере (например, в неконтекстной серверной процедуре или общем модуле).
  2. Возвращаем измененную ссылку на сторону клиента.
  3. Вызываем метод ОповеститьОбИзменении() на клиенте, передавая в него ссылку на измененный объект.

Посмотрим на пример кода в модуле управляемой формы:


&НаСервереБезКонтекста
Функция ПереименоватьХарактеристикуНаСервере(СсылкаНаХарактеристику, НовоеНаименование)
    
    ХарактеристикаОбъект = СсылкаНаХарактеристику.ПолучитьОбъект();
    Если ХарактеристикаОбъект <> Неопределено Тогда
        ХарактеристикаОбъект.Наименование = НовоеНаименование;
        ХарактеристикаОбъект.Записать();
        Возврат ХарактеристикаОбъект.Ссылка;
    КонецЕсли;
    
    Возврат Неопределено;

КонецФункции

&НаКлиенте
Процедура ТоварыХарактеристикаНажатие(Элемент, СтандартнаяОбработка)
    
    ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    СтандартнаяОбработка = Ложь;
    
    // Выполняем изменение на сервере
    ИзмененнаяСсылка = ПереименоватьХарактеристикуНаСервере(ТекущиеДанные.Характеристика, "Новое наименование характеристики");
    
    // Оповещаем систему об изменении объекта для сброса клиентского кэша
    Если ЗначениеЗаполнено(ИзмененнаяСсылка) Тогда
        ОповеститьОбИзменении(ИзмененнаяСсылка);
    КонецЕсли;

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

Важно: метод ОповеститьОбИзменении() доступен исключительно в клиентском контексте (тонкий, толстый или веб-клиент). В него можно передавать как конкретную ссылку на объект, так и массив ссылок или даже тип объектов (например, Тип("СправочникСсылка.ХарактеристикиНоменклатуры")), если модификация производилась массово.

Альтернативные способы обновления данных

Если по каким-либо причинам глобальное оповещение использовать нежелательно, рассмотрим дополнительные варианты решения задачи.

1. Принудительный сброс значения реквизита на клиенте

Клиентское приложение можно принудительно заставить перечитать строковое представление, кратковременно очистив значение реквизита в текущей строке табличной части и вернув его обратно:


&НаКлиенте
Процедура ОбновитьПредставлениеТекущейСтроки()
    
    СтрокаТЧ = Элементы.Товары.ТекущиеДанные;
    Если СтрокаТЧ <> Неопределено Тогда
        ТекущаяСсылка = СтрокаТЧ.Характеристика;
        СтрокаТЧ.Характеристика = ПредопределенноеЗначение("Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка");
        СтрокаТЧ.Характеристика = ТекущаяСсылка;
    КонецЕсли;

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

2. Синхронизация данных через преобразование объекта на сервере

Если в процессе обработки документа на сервере перезаписываются связанные структуры данных, можно синхронизировать объект формы целиком с последующим оповещением:


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

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

После выполнения серверной синхронизации для корректного отображения ссылочных колонок на клиенте всё равно рекомендуется выполнить ОповеститьОбИзменении().

Таким образом, использование метода ОповеститьОбИзменении() является наиболее быстрым, надежным и стандартным способом обновления представлений ссылок в управляемых формах 1С 8.3.

← На главную