В процессе разработки на платформе 1С:Предприятие 8 в режиме обычных форм (ОФ) часто возникает задача: необходимо обновить данные в открытой форме списка справочника или документа после того, как изменения были внесены извне — например, из другой обработки, формы выбора или программного кода. В отличие от управляемых форм, где многие механизмы синхронизации работают «из коробки», обычные формы требуют от программиста более детального понимания механизмов взаимодействия объектов. Рассмотрим подробно, как реализовать перечитывание данных, чтобы пользователь сразу увидел актуальные изменения.
Проанализируем наиболее правильный и эффективный с точки зрения архитектуры платформы способ. Если мы меняем данные объекта (например, реквизит справочника) и записываем его, система должна как-то узнать, что списки, отображающие этот тип данных, устарели. Для этого существует глобальный метод ОповеститьОбИзменении.
Разберем ситуацию: у вас открыта форма списка справочника Контрагенты, и из внешней обработки вы меняете категорию одного из них. После выполнения метода Записать() в коде обработки следует вызвать оповещение системы:
// В коде обработки после изменения объекта
НовыйОбъект = СсылкаНаКонтрагента.ПолучитьОбъект();
НовыйОбъект.Категория = Справочники.Категории.НайтиПоНаименованию("VIP");
НовыйОбъект.Записать();
// Оповещаем систему, что конкретный объект изменился
ОповеститьОбИзменении(НовыйОбъект.Ссылка);
Почему это удобно? Метод ОповеститьОбИзменении посылает сигнал всем открытым формам. Если форма списка отображает данные того типа, который был передан в параметре, она автоматически инициирует обновление своего динамического списка (СправочникСписок или ДокументСписок). Вам не нужно искать форму программно или писать дополнительный код внутри самой формы списка.
Иногда требуется более гибкий подход. Например, когда нужно обновить не весь список, а выполнить какие-то дополнительные действия на форме или обновить специфические реквизиты, не связанные напрямую с данными объекта. В этом случае мы используем связку метода Оповестить и события формы ОбработкаОповещения.
Рассмотрим реализацию по шагам:
Процедура КнопкаВыполнитьНажатие(Кнопка)
// Программное изменение данных...
// ...
// Отправляем произвольное сообщение всем открытым формам
Оповестить("ОбновитьСписокКонтрагентов", , ЭтаФорма);
КонецПроцедуры
ОбработкаОповещения:
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
// Проверяем, наше ли это событие
Если ИмяСобытия = "ОбновитьСписокКонтрагентов" Тогда
// Вызываем метод обновления основного списка формы
ЭлементыФормы.СправочникСписок.Обновить();
// Можно также добавить визуальное обновление всей формы
ЭтаФорма.Обновить();
КонецЕсли;
КонецПроцедуры
Этот способ позволяет передавать параметры (например, структуру с условиями обновления) и гарантирует, что действие будет выполнено именно тогда, когда это нужно разработчику.
Выясним причину, почему в одних случаях используют Обновить(), а в других — ОбновитьСтроки(). Это критически важно для производительности приложения и удобства пользователя.
ЭлементыФормы.ИмяСписка.Обновить() заставляет систему полностью сбросить кэш данных и выполнить запрос к базе данных заново. Это гарантирует 100% актуальность данных, но может привести к «морганию» списка и временной потере фокуса на текущей строке при больших объемах данных.ОбновитьСтроки() может не убрать её сразу.Пример использования в коде формы:
// Полное обновление данных (тяжелая операция)
ЭлементыФормы.СправочникСписок.Обновить();
// Только визуальное обновление текущих строк (легкая операция)
ЭлементыФормы.СправочникСписок.ОбновитьСтроки();
Рассмотрим ситуацию, когда обновление должно происходить автоматически при активизации формы или в моменты «простоя» системы. У формы существует стандартное событие ОбновлениеОтображения. Оно вызывается платформой достаточно часто (когда система не занята обработкой других действий).
Некоторые разработчики используют его для принудительного обновления списка, как в следующем примере:
Процедура ОбновлениеОтображения()
// В некоторых случаях это помогает поддерживать список в актуальном состоянии
ЭлементыФормы.СправочникСписок.ОбновитьСтроки();
КонецПроцедуры
Важное предостережение: Будьте крайне осторожны с вызовом Обновить() внутри ОбновлениеОтображения. Это может создать бесконечную петлю: обновление данных инициирует перерисовку формы, что снова вызывает ОбновлениеОтображения, и так до бесконечности, что приведет к зависанию интерфейса.
Если специфика бизнес-процесса такова, что данные в списке меняются постоянно сотнями пользователей (например, очередь заказов), можно прибегнуть к стандартному механизму автообновления. Проанализируем, как это настроить программно для конкретного элемента формы:
Процедура ПриОткрытии()
// Включаем автоматическое обновление списка каждые 10 секунд
ЭлементыФормы.СправочникСписок.АвтоОбновление = Истина;
ЭлементыФормы.СправочникСписок.ПериодАвтоОбновления = 10;
КонецПроцедуры
Этот метод не требует написания сложного кода взаимодействия, но создает дополнительную нагрузку на сервер базы данных, так как запросы будут выполняться циклично, даже если пользователь не активен.
Проанализировав все доступные инструменты, мы можем сделать следующие выводы для практической работы:
ОповеститьОбИзменении(Ссылка). Это самый экономичный и правильный путь.Оповестить() и ОбработкаОповещения.ОбновитьСтроки().Обновить().Выбор конкретного метода зависит от требований к производительности и сложности вашей задачи. Комбинируя эти подходы, можно добиться плавного и отзывчивого интерфейса даже в «старых» обычных формах 1С.