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

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

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

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

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

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

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

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

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

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

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

Обновление списка программно из формы

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

&НаКлиенте

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

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

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

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

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

bsl
&НаКлиенте
Процедура ПослеЗаписиДокумента(Результат, ДопПараметры) Экспорт
    Элементы.Список.Обновить();
КонецПроцедуры

Обновление через оповещения между формами

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

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

&НаКлиенте

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

Если ИмяСобытия = "Запись_ЗаказПокупателя" Тогда

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

КонецЕсли;

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

Для стандартных объектов платформа сама рассылает оповещения с именем вида «Запись_ИмяОбъекта», поэтому во многих случаях достаточно только обработчика в форме списка. Если изменение выполняется нестандартно — например, групповой обработкой через серверную процедуру, — оповещение нужно отправить явно из кода.

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

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

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

&НаКлиенте

Процедура ПриОткрытии(Отказ)

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

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

&НаКлиенте

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

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

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

Интервал выбирайте осознанно. Каждое обновление — это запрос к базе: при интервале в несколько секунд и большом списке вы создадите постоянную нагрузку на СУБД. Для большинства сценариев достаточно 30–120 секунд. Обязательно отключайте обработчик при закрытии формы через ОтключитьОбработчикОжидания в ПриЗакрытии, иначе вызовы будут продолжаться и приводить к ошибкам.

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

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

&НаКлиенте

Процедура ВыполнитьОбработку(Команда)

ВыполнитьОбработкуНаСервере();

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

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

&НаСервере

Процедура ВыполнитьОбработкуНаСервере()

// изменение данных

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

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

Особенности и ограничения динамических списков

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

Ещё одно ограничение: обновление не поможет, если запись не попадает в выборку из-за отбора. Если после изменения данных строка «исчезла» из списка, проверьте установленные отборы и параметры запроса — возможно, запись просто перестала им соответствовать, и это корректное поведение.

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

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

Проверка результата и выбор подходящего способа

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

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

Маршрут решения

Как выбрать способ обновления

Данные изменились в этой же формеВызовите Элементы.Список.Обновить() после завершения изменения
Данные меняются в другой открытой формеИспользуйте ОповеститьОбИзменении() и ОбработкаОповещения в форме списка
Данные меняют обмен, фоновые задания или другие пользователиПодключите обработчик ожидания с интервалом от 30–60 секунд
Список с произвольным запросом без основной таблицыОбновляйте только программно — автоматического обновления не будет
Контрольные точки

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

Появление новой записи
Норма

После записи объекта строка видна в списке без ручного F5

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

Запись появляется только после закрытия и открытия формы

Позиция курсора
Норма

После обновления текущая строка сохраняется

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

Список сбрасывается в начало при каждом обновлении

Нагрузка
Норма

Интервал таймера не вызывает заметных пауз в интерфейсе

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

Форма периодически «подвисает» при обновлении

Итог

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

Динамический список в 1С 8 обновляется вызовом Элементы.Список.Обновить() на клиенте. Между формами используйте оповещения, для внешних изменений — таймер с интервалом от 30–60 секунд. Не вызывайте обновление на сервере и не злоупотребляйте частыми обновлениями.

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

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

Чаще всего запись выполнена программно (обработкой или фоновым заданием), и платформа не рассылает системное оповещение. Добавьте явный вызов ОповеститьОбИзменении() после записи или обновите список программно. Также проверьте, попадает ли документ под отбор списка.

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

Обновить() у элемента списка заново выполняет запрос к базе и перечитывает данные. ОбновитьОтображениеДанных() лишь перерисовывает уже загруженные данные. Если изменились записи в базе, нужен именно Обновить().

Можно ли обновить динамический список на сервере?

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

Какой интервал автообновления выбрать?

Зависит от объёма данных и требований к актуальности. Для большинства рабочих мест достаточно 60–120 секунд. Интервал меньше 10–15 секунд на больших таблицах создаёт заметную нагрузку на СУБД — начинайте с большего значения и уменьшайте только при реальной необходимости.

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

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

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

Только если у списка указана основная таблица — тогда платформа обновляет его при записи объектов этой таблицы. Без основной таблицы автоматического обновления нет, используйте программные вызовы или оповещения.