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

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

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

Суть проблемы: почему обычное присваивание не помогает

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

Почему это происходит? Платформа 1С в целях оптимизации трафика между клиентом и сервером кэширует строковые представления ссылочных объектов на стороне клиента. Один раз получив текст «ООО Ромашка» для конкретной ссылки, клиентское приложение будет хранить его в памяти. До тех пор, пока кэш не будет очищен или инвалидирован, платформа не пойдет в базу данных за новым представлением, считая, что оно не изменилось.

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

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

Разберем пример кода, который необходимо выполнить на клиенте после записи измененного объекта:


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

// Теперь на клиенте оповещаем систему об изменениях
ОповеститьОбИзменении(СсылкаНаОбъект);

Что происходит в системе после вызова этого метода:

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

Решение №2: Использование методов БСП

Если ваша конфигурация построена на базе «Библиотеки стандартных подсистем» (БСП), мы рекомендуем использовать специализированные программные интерфейсы. Это обеспечит более стабильную работу и корректную обработку событий в рамках всей системы.

Рассмотрим использование метода общего назначения:


// На клиенте
ОбщегоНазначенияКлиент.ОповеститьОбИзмененииОбъектов(СсылкаНаЭлемент);

Этот метод удобен тем, что он может принимать как одну ссылку, так и массив ссылок, что полезно при массовом изменении данных.

Почему не помогают Прочитать() и ОбновитьОтображениеДанных()?

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

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

Особый случай: ОбработкаПолученияПредставления

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

Практические советы и выводы

Посмотрим на общую схему действий при программном изменении представления объекта:

  1. Выполните изменение реквизитов объекта (например, Наименование) на сервере.
  2. Обязательно вызовите метод Записать() для объекта.
  3. Верните ссылку на измененный объект на клиент (если процедура была серверной).
  4. На клиенте вызовите ОповеститьОбИзменении(Ссылка).

Важное замечание: Если вам нужно обновить представления сразу всех элементов определенного справочника (например, после масштабной групповой обработки), вы можете передать в метод тип объекта:

ОповеститьОбИзменении(Тип("СправочникСсылка.Номенклатура"));

Это приведет к полной очистке кэша для данного типа, что гарантированно обновит все поля на всех открытых формах пользователя.

Использование правильных механизмов оповещения платформы об изменениях — залог создания отзывчивого и корректного интерфейса, который не вводит пользователя в заблуждение устаревшими данными.

← На главную