К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как программно обновить динамический список на форме 1С

Способы программного обновления динамического списка на форме 1С: метод Обновить(), Элементы.Список.Обновить(), оповещения форм и настройка автообновления.

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

Основной инструмент — метод Обновить() таблицы формы, связанной с динамическим списком. Дополнительно платформа предлагает механизм оповещений (Оповестить / ОбработкаОповещения), стандартное событие записи объекта и свойство динамического списка «АвтоматическоеОбновление» вместе с настройкой периода обновления. Выбор способа зависит от того, кто и где изменил данные.

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

Как устроено обновление динамического списка

Динамический список — это реквизит формы с произвольным или основным запросом, который платформа выполняет при открытии формы и при определённых действиях пользователя. Сам по себе список не отслеживает изменения в базе: он перечитывает данные только тогда, когда его об этом «просят» — интерактивно (клавиша F5, команда «Обновить») или программно.

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

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

Базовый способ: метод Обновить() у таблицы формы

Самый простой и часто используемый вариант — вызов метода Обновить() у элемента формы, связанного с динамическим списком. Предположим, на форме есть таблица с именем «Список», отображающая одноимённый реквизит. Тогда обновление выглядит так:

&НаКлиенте

Процедура ОбновитьСписок(Команда)

Элементы.Список.Обновить();

КонецПроцедуры

Тот же вызов можно выполнить и в серверной процедуре формы, если логика изменения данных выполняется на сервере:

&НаСервере

Процедура ЗаполнитьДанныеНаСервере()

// ... запись или изменение данных

Элементы.Список.Обновить();

КонецПроцедуры

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

bsl
Элементы.Список.Обновить();

Обновление из другой формы через оповещения

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

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

// Форма, которая меняет данные

&НаКлиенте

Процедура ПослеЗаписи(ПараметрыЗаписи)

Оповестить("ИзмененыДанныеЗаказов");

КонецПроцедуры

// Форма со списком

&НаКлиенте

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)

Если ИмяСобытия = "ИзмененыДанныеЗаказов" Тогда

Элементы.Список.Обновить();

КонецЕсли;

КонецПроцедуры

Для стандартных объектов (справочники, документы) часто не нужно даже придумывать своё событие: платформа сама рассылает оповещение о записи объекта, и динамические списки основной таблицы реагируют на него автоматически. Своё оповещение требуется, когда данные меняются нестандартно — например, через запись наборов регистров, групповую обработку или обмен.

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

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

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

Ключевые свойства: «АвтоматическоеОбновление» (включает механизм) и «ПериодАвтоматическогоОбновления» (интервал в секундах). Программно их можно установить так:

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Список.АвтоматическоеОбновление = Истина;

Список.ПериодАвтоматическогоОбновления = 60;

КонецПроцедуры

Период обновления следует выбирать осознанно. Слишком частое обновление (каждые 5–10 секунд) на больших таблицах создаёт постоянную нагрузку на СУБД и может заметно «подтормаживать» клиентское приложение, особенно если в запросе списка есть соединения и виртуальные таблицы. Для большинства сценариев достаточно интервала от 30 до 120 секунд, а для мониторов в реальном времени лучше продумать лёгкий запрос без тяжёлых соединений.

Обновление после программной записи и в фоновых заданиях

Когда данные записываются программно в той же форме (например, обработчик создаёт документы методом Записать()), достаточно после завершения операции вызвать Элементы.Список.Обновить(). Если запись выполняется в цикле, обновление разумно делать один раз после цикла, а не после каждой итерации — иначе список будет перечитываться многократно.

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

&НаКлиенте

Процедура ПослеЗавершенияФоновогоЗадания()

Элементы.Список.Обновить();

КонецПроцедуры

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

Способы обновления списка

Элементы.Список.Обновить()

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

Оповестить + ОбработкаОповещения

Для обновления из другой формы того же сеанса. Требует согласованного имени события в обеих формах.

Автообновление по таймеру

Для изменений из других сеансов и фоновых процессов. Создаёт регулярную нагрузку на СУБД.

Типичные ошибки и ограничения

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

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

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

Типичные ошибки
01
Вызов Список.Обновить() у реквизита вместо Элементы.Список.Обновить() — метод не найден, обновления нет
02
Опечатка в имени события оповещения — форма списка никогда не получает сигнал
03
Обновление списка внутри цикла записи — десятки лишних перечитываний и зависание формы
04
Слишком маленький период автообновления на тяжёлом запросе — нагрузка на СУБД у всех пользователей

Как проверить, что обновление работает корректно

Проверка проста: откройте форму списка, измените данные тем способом, который должен вызывать обновление (запишите объект из другой формы, дождитесь таймера, выполните обработку), и убедитесь, что новая или изменённая строка появилась в списке без ручного нажатия F5.

Дополнительно стоит проверить поведение при активном отборе: если изменённая запись не подходит под установленный отбор, она не появится — и это норма, а не ошибка обновления. Также полезно замерить, сколько времени занимает перечитывание списка на реальном объёме данных: если список «задумывается» на несколько секунд, нужно оптимизировать запрос (убрать лишние соединения, добавить индексы по полям отбора), а не увеличивать частоту обновлений.

Контрольные точки

Как проверить результат

Появление изменённых строк
Норма

После записи данные видны без нажатия F5

Тревожный признак

Строки появляются только после ручного обновления

Текущая позиция в списке
Норма

Курсор остаётся на той же записи

Тревожный признак

Список перескакивает или сбрасывает позицию при каждом обновлении

Скорость перечитывания
Норма

Обновление занимает доли секунды

Тревожный признак

Форма подвисает на секунды — нужен разбор запроса списка

Частые вопросы

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

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

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

Чаще всего запись не попадает под установленный отбор или отбор по периоду. Проверьте настройки отбора в «Настроить список» и параметры запроса. Также убедитесь, что транзакция записи завершена — незакоммиченные данные список не увидит.

Как обновить список на форме, открытой у другого пользователя?

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

Обновление сбрасывает позицию курсора — как этого избежать?

Перед обновлением запомните текущую строку через Элементы.Список.ТекущаяСтрока, а после обновления восстановите её присваиванием того же значения. Это работает, если запись не удалена и попадает под отбор.

Чем отличается Обновить() от перечитывания через изменение параметров запроса?

Изменение параметра или отбора формирует новый запрос с новыми условиями, а Обновить() перечитывает данные с теми же настройками. Если меняются только данные в базе — достаточно Обновить(), если условия выборки — меняйте параметры.

Итог

Что важно запомнить

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