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

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

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

Анализ проблемы: почему данные «зависают»?

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

Причина кроется в механизмах работы Тонкого клиента и Веб-клиента. Для минимизации сетевого трафика платформа 1С активно использует кэширование. Когда клиентское приложение получает ссылку из базы, оно запрашивает её текстовое представление (строку) только один раз. После этого соответствие УникальныйИдентификатор — Представление сохраняется в локальном кэше сеанса. До тех пор, пока платформа считает кэш актуальным, она не будет обращаться к серверу за новым именем, даже если в самой базе данных запись уже была обновлена другим процессом или программным кодом.

Решение проблемы с помощью метода ОповеститьОбИзменении

Выясним причину, по которой стандартные методы обновления формы не помогают. Методы типа ЭтаФорма.Прочитать() или Элементы.Дерево.Обновить() работают с данными самой формы или обновляют состав строк, но они не сообщают платформе, что кэшированные строковые представления ссылок стали невалидными.

Для того чтобы «сбросить» этот кэш, существует специальный метод глобального контекста — ОповеститьОбИзменении(). Проанализируем, как его правильно применять.

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


// Выполняем изменение объекта на сервере
ОбъектПользователь = ТекСтр.ПользовательСсылка.ПолучитьОбъект();
ОбъектПользователь.Наименование = "Новое наименование пользователя";
ОбъектПользователь.Записать();

// Оповещаем систему о том, что данные справочника изменились
// Это заставит платформу очистить кэш представлений для этого типа
ОповеститьОбИзменении(Тип("СправочникСсылка.Пользователи"));

После вызова этой команды платформа пометит все кэшированные данные по справочнику Пользователи как устаревшие. При следующей перерисовке формы система принудительно обратится к базе (или серверному кэшу) за актуальными строковыми представлениями.

Точечное обновление или обновление по типу?

Рассмотрим подробнее варианты вызова метода ОповеститьОбИзменении. В параметре метода можно передавать как тип данных, так и конкретную ссылку.

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

Особенности работы с динамическими списками и деревьями значений

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

Посмотрим на пример комплексного обновления интерфейса, если изменения вносятся из внешней обработки:


&НаКлиенте
Процедура ПереименоватьИОбновить()
    // Вызываем серверную процедуру изменения данных
    РезультатИзменения = ИзменитьИмяНаСервере();
    
    Если РезультатИзменения.Успешно Тогда
        // Сбрасываем кэш представлений для конкретной ссылки
        ОповеститьОбИзменении(РезультатИзменения.Ссылка);
        
        // Дополнительно можно вызвать встроенное обновление интерфейса
        ОбновитьОтображениеДанных();
    КонецЕсли;
КонецПроцедуры

Роль обработчика ОбработкаПолученияПредставления

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

Рекомендации по использованию

Подводя итог, разберем основные шаги, которые помогут избежать проблем с обновлением интерфейса:

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

← На главную