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

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

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

Выясним причину: «Эффект пустой ссылки»

Для начала проанализируем ситуацию с технической точки зрения — поможет отладчик кода 1С для интерфейса. Основная причина кроется в механизме оптимизации динамического списка. Когда мы открываем форму нового объекта (например, нового Транспортного Средства), его ссылка Объект.Ссылка еще не сформирована в базе данных (она пустая). Динамический список, связанный с этим объектом по параметру (например, ГДЕ Пропуска.Владелец = &Владелец), инициализируется с пустым значением параметра.

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

Решение №1: Глобальное оповещение об изменении

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

Рассмотрим шаг за шагом, как это внедрить. В форме элемента, где расположен ваш динамический список, необходимо найти (или создать) обработчик события, которое отвечает за создание новой записи в списке. — для этого подойдёт гибкая настройка обработчиков событий форм. Обычно это происходит после закрытия формы создания пропуска или программного добавления. Нам нужно вызвать код на клиенте:


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

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

Решение №2: Явная установка параметров запроса

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

Разберем по шагам реализацию:

  1. Переходим в модуль формы основного объекта.
  2. В процедуре ПослеЗаписиНаСервере или в клиентском обработчике после записи вызываем обновление параметров.

&НаСервере
Процедура ОбновитьПараметрыСпискаНаСервере()
    // Принудительно устанавливаем параметр, даже если он совпадает с текущим
    ЗначениеПараметра = Список.Параметры.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("Владелец"));
    Если ЗначениеПараметра <> Неопределено Тогда
        Список.Параметры.УстановитьЗначениеПараметра("Владелец", Объект.Ссылка);
    КонецЕсли;
КонецПроцедуры

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

Решение №3: Проверка свойства «Основная таблица»

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

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

Решение №4: Принудительное обновление интерфейса

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


&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    // Глобальное обновление всех форм и списков
    ОбновитьИнтерфейс();
КонецПроцедуры

Хотя этот метод считается «тяжелым» для производительности, в случае с первой записью он гарантирует, что пользователь увидит актуальные данные. Однако рекомендуем сначала пробовать ОповеститьОбИзменении.

Дополнительные рекомендации

Разберем еще один нюанс, связанный с транзакциями. Если вы добавляете запись программно в процедуре ПриЗаписи на сервере, помните, что динамический список на клиенте не увидит ее до тех пор, пока транзакция не будет полностью завершена. Если стандартного поведения недостаточно, можно реализовать самодельный обработчик ПослеЗаписи объекта, который гарантированно сработает после успешного завершения транзакции.

Подведем итог: для решения проблемы с обновлением первой записи в динамическом списке используйте связку из правильно настроенной Основной таблицы и вызова метода ОповеститьОбИзменении(Тип("ВашТип")). Чтобы сделать работу со списком еще удобнее, можно реализовать флажок в динамическом списке для групповых операций или предусмотреть программное перемещение колонки для гибкой настройки интерфейса под нужды пользователя.

← На главную