В процессе разработки в среде 1С:Предприятие программисты часто сталкиваются с ситуацией, когда данные в базе уже изменены (например, изменен срок годности, наименование или артикул), но на форме в гиперссылке или поле ввода по-прежнему отображается старая информация. При этом, если открыть карточку объекта, данные внутри будут актуальными. В этой статье мы подробно разберем, почему возникает этот эффект «залипших» данных и как гарантированно обновить визуальное представление ссылки.
Для начала проанализируем ситуацию с точки зрения архитектуры платформы. Когда мы видим на форме гиперссылку (реквизит с типом СправочникСсылка), платформа не запрашивает данные из базы при каждой перерисовке интерфейса. Для экономии трафика и ускорения работы интерфейса используется механизм кэширования представлений.
Представление — это строковая информация об объекте, которая формируется на сервере и передается клиенту. Платформа запоминает эту строку на стороне клиента. Если вы программно изменили объект в одной форме или в фоновом задании, клиентское приложение, отображающее ссылку на этот же объект в другой форме, может просто «не знать», что текстовое описание объекта (его представление) уже не актуально. В итоге мы получаем классический баг: «внутри» (в базе) данные правильные, а «снаружи» (в интерфейсе) — старые.
Рассмотрим основной способ, который позволяет принудительно обновить кэш. В платформе существует метод ОповеститьОбИзменении(). Этот метод сообщает всем открытым формам текущего клиентского сеанса, что данные конкретного объекта изменились, и их нужно перечитать.
Разберем по шагам, как это работает:
ОповеститьОбИзменении(СсылкаНаОбъект).Посмотрим на пример кода, который нужно использовать после записи объекта, чтобы интерфейс мгновенно среагировал:
// Пример вызова в управляемой форме
&НаКлиенте
Процедура ПослеЗаписиОбъекта(ОбъектСсылка)
// Сообщаем системе, что кэш представлений для этой ссылки пора обновить
ОповеститьОбИзменении(ОбъектСсылка);
КонецПроцедуры
Часто проблема усугубляется, если в справочнике используется переопределенное представление. Давайте разберем, как это устроено. В модуле менеджера справочника существует специальный обработчик ОбработкаПолученияПредставления. Если программист решил, что вместо стандартного наименования в ссылке должен отображаться, например, «Артикул + Наименование + Срок годности», он пишет код именно там.
Если данные, которые участвуют в формировании этой строки, изменились, а метод ОповеститьОбИзменении не был вызван, пользователь будет видеть старую «склеенную» строку. Проанализируем пример такого обработчика:
// В модуле менеджера справочника Номенклатура
Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Формируем динамическое представление
Представление = Строка(Данные.Наименование) + " (годн. до " + Формат(Данные.СрокГодности, "ДФ=dd.MM.yyyy") + ")";
КонецПроцедуры
Важный момент: если в поле Данные не приходят нужные реквизиты (например, СрокГодности), платформа может неверно сформировать строку или использовать стандартную обработку. Проверьте, чтобы в свойствах объекта был правильно настроен «Основной реквизит» или «Панель данных».
Рассмотрим ситуацию, когда замена гиперссылки на обычное поле ввода не приносит результата. Это происходит потому, что и гиперссылка, и поле ввода используют один и тот же механизм получения текста ссылки. Если вы используете динамические списки, то ситуация может быть еще сложнее: списки имеют свои механизмы обновления данных.
В случае с динамическими списками, помимо ОповеститьОбИзменении, иногда требуется вызов метода Обновить() самого списка на форме. Однако помните, что ОповеститьОбИзменении является более «легким» и предпочтительным методом, так как он точечно обновляет данные, не заставляя сервер заново выполнять тяжелый запрос динамического списка.
Если использование ОповеститьОбИзменении не решило проблему, стоит выяснить, не является ли причиной локальный кэш конфигурации на компьютере пользователя. Иногда кэш метаданных повреждается, и платформа «забывает» обновлять интерфейсные элементы. В таких случаях помогают следующие шаги:
%AppData%\Local\1C\1Cv8 и %AppData%\Roaming\1C\1Cv8.ОповеститьОбИзменении работает только внутри одного клиентского сеанса. Если данные изменил пользователь А, а пользователь Б смотрит на форму, у пользователя Б представление обновится только при переоткрытии формы или автоматическом обновлении списка.Мы выяснили, что несоответствие данных в гиперссылке и внутри объекта — это не баг платформы, а особенность работы механизма оптимизации трафика. Для решения этой проблемы мы рекомендуем:
ОповеститьОбИзменении(Ссылка) после программного изменения реквизитов объекта, влияющих на его отображение.ОбработкаПолученияПредставления модуля менеджера.Используя эти подходы, вы обеспечите актуальность данных в интерфейсе и избавите пользователей от путаницы с неверными датами или наименованиями в ссылках.