Как обновить форму списка документов в обычных формах 1С при изменении связанных данных?

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

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

Рассмотрим подробно способы решения этой проблемы, начиная от использования штатных механизмов оповещений платформы 1С и заканчивая оптимальными архитектурными подходами.

Способ 1. Использование механизма оповещений (Оповестить и ОбработкаОповещения)

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

Схема работы включает следующие шаги:

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

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


Процедура ПослеЗаписи(ПараметрыЗаписи)
    // Передаем имя события, параметр и источник
    Оповестить("ОбновитьСостояниеЗаказов", Новый Структура("Ссылка", Ссылка), ЭтотОбъект);
КонецПроцедуры

В форме списка заказа, где требуется обновить отображение данных, необходимо назначить обработчик события ОбработкаОповещения:


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

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

Способ 2. Вызов системного метода ОповеститьОбИзменении()

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

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


// Передаем ссылку на измененный объект или его тип
ОповеститьОбИзменении(Ссылка);

Этот способ удобен тем, что не требует написания ручной обработки в событии ОбработкаОповещения, если список построен на стандартном динамическом списковом механизме платформы.

Способ 3. Автоматическое обновление списка по таймеру или через настройки

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

Вариант A: Интерактивная настройка списка

Пользователь может самостоятельно включить автообновление таблицы. Для этого в меню формы списка нужно перейти: Действия — Настройка списка — Прочее и установить флаг «Обновлять автоматически каждые ... сек».

Вариант Б: Использование обработчика ожидания

Выясним, как программно настроить фоновое обновление формы с заданным интервалом с помощью метода ПодключитьОбработчикОжидания.

В модуле формы списка добавляется следующий код:


Процедура ПриОткрытии()
    // Подключаем обновление каждые 60 секунд
    ПодключитьОбработчикОжидания("ОбновитьСписокПоТаймеру", 60);
КонецПроцедуры

Процедура ОбновитьСписокПоТаймеру()
    ЭлементыФормы.ДокументСписок.Обновить();
КонецПроцедуры

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

Архитектурные рекомендации по повышению производительности

Проанализируем частую проблему производительности: расчет состояния выполнения заказа непосредственно в событии ДокументСписокПриПолученииДанных. При прокрутке списка данное событие вызывается для каждой видимой строки, и выполнение тяжелых запросов к базе данных в этот момент приводит к существенным "зависаниям" интерфейса.

Чтобы избежать этой проблемы, рекомендуется использовать следующую схему:

  1. Создать регистр сведений (например, «Состояния заказов»), где ключевым измерением будет ЗаказПокупателя, а ресурсом — Состояние.
  2. В подписках на события при проведении или отмене проведения любых связанных документов (оплаты, отгрузки) выполнять расчет и записывать итоговое состояние в этот регистр сведений.
  3. В форме списка выводить состояние как обычное поле запроса/регистра, избегая вычислений "на лету" в событии ПриПолученииДанных.

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

← На главную