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

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

В процессе разработки на платформе 1С:Предприятие 8 (особенно при работе с обычными формами в таких конфигурациях, как «Комплексная автоматизация 1.1» или «УПП 1.3») программисты часто сталкиваются с неочевидным поведением интерфейса. Одна из таких проблем — внезапное и ресурсозатратное обновление формы списка документов (например, Заказ покупателя) при выполнении простейших действий в дочернем окне, например, при установке галочки в списке привязанных файлов. Рассмотрим подробно причины этого поведения и способы оптимизации работы системы.

Анализируем механизм взаимосвязи форм через владельца

Первым делом проанализируем ситуацию, когда одна форма открывается из другой. В 1С существует понятие «Владелец формы». Когда мы открываем список файлов из формы документа, мы часто передаем владельца, чтобы дочерняя форма могла взаимодействовать с родительской. Рассмотрим типичный код открытия:


ФормаВыбора = Справочники.ХранилищеДополнительнойИнформации.ПолучитьФормуСписка();
ФормаВыбора.ВладелецФормы = ЭтаФорма; // Вот здесь устанавливается связь
ФормаВыбора.Открыть();

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

Выясняем причины автоматического обновления: системные оповещения

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

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

В конфигурациях типа КА 1.1 список заказов часто содержит колонки, отображающие наличие файлов (иконка скрепки). Эта колонка работает через запрос к хранилищу данных. Следовательно, изменение в хранилище файлов дает сигнал списку документов: «Твои данные могли стать неактуальными, перечитай их».

Способ 1: Управление владельцем формы

Самый простой и действенный метод, который был найден опытным путем: отказаться от передачи владельца формы при открытии, если это не критично для логики работы. Если форме списка файлов не нужно напрямую обращаться к методам или элементам формы заказа, лучше открывать ее независимо.

Проанализируем разницу в подходе:

  1. При открытии с владельцем: платформа связывает контексты. Любое изменение данных в подчиненной форме вызывает рефреш владельца.
  2. При открытии без владельца: форма становится самостоятельным окном. Обновление родительского списка может произойти только в том случае, если сработает глобальное ОповеститьОбИзменении, но интенсивность этого процесса обычно ниже, так как нет прямой иерархической связи.

Способ 2: Настройка свойства «Обновление при изменении»

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

Рассмотрим варианты настройки этого свойства:

Установка значения «Не обновлять» для табличного поля списка документов позволит избежать «подвисаний» интерфейса, когда пользователь работает с файлами. Однако помните, что в этом случае актуальные данные (например, статус заказа или наличие файлов) появятся в списке только после ручного обновления (кнопка F5 или кнопка «Обновить» на панели).

Способ 3: Оптимизация обработчиков оповещений

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


Процедура ПриИзмененииГалочки(Элемент)
    // Код записи данных
    Если ВладелецФормы <> Неопределено Тогда
        Оповестить("ОбновитьФорму", Новый Структура("ИмяЭлемента","ИзмененСписокФайлов"));
    КонецЕсли;
КонецПроцедуры

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

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


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

Почему замер производительности показывает «львиную долю» в форме списка?

Выясним причину, почему именно список документов «съедает» ресурсы. В обычных формах при обновлении динамического списка происходит следующее:

  1. Платформа сбрасывает кэш считанных записей.
  2. Инициируется выполнение основного запроса списка к базе данных.
  3. Если в списке включены раскраски строк, используются механизмы ПриВыводеСтроки или ПриПолученииДанных, они вызываются для каждой отображаемой записи.

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

Рекомендация: Проверьте обработчик ПриПолученииДанных в форме списка заказов. Постарайтесь кэшировать результаты запросов или минимизировать количество обращений к базе данных внутри этого обработчика.

Итоги и рекомендации

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

  1. Проверить, обязательно ли передавать ВладелецФормы при открытии списка файлов. Если нет — убрать передачу владельца.
  2. Установить свойство табличного поля ОбновлениеПриИзменении в значение Не обновлять, если мгновенная синхронизация списка документов с изменениями в файлах не требуется.
  3. Проверить наличие явных вызовов Оповестить() и ОповеститьОбИзменении() в коде обработки «галочки».
  4. Оптимизировать код в событии ПриПолученииДанных формы списка документов, чтобы минимизировать нагрузку при обновлении списка.

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

← На главную