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

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

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

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

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

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

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

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

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

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

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

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

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

&НаКлиенте

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

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

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

Здесь Список — имя элемента формы (таблицы), а не реквизита. Если таблица называется иначе, например «СписокДокументов», вызов будет Элементы.СписокДокументов.Обновить(). Метод доступен только на клиенте, поэтому директива &НаКлиенте обязательна.

Если обновление нужно инициировать из серверной процедуры (например, после массовой обработки данных), вынесите вызов в клиентскую обёртку: серверная процедура выполняет изменения, а клиентская после её завершения вызывает Обновить().

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

Обновление после записи элемента и при оповещении форм

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

В форме элемента после записи:

&НаКлиенте

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

Оповестить("Запись_Номенклатура", , ЭтотОбъект);

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

В форме списка:

&НаКлиенте

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

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

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

КонецЕсли;

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

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

Обновление при активации формы и по таймеру

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

&НаКлиенте

Процедура ПриАктивизации()

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

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

Для мониторинга в реальном времени используют ПодключитьОбработчикОжидания() с интервалом, например 30–60 секунд. Обработчик вызывает Элементы.Список.Обновить(). Ставить интервал меньше 10–15 секунд не стоит: каждый вызов выполняет запрос к серверу, и при большом числе пользователей это создаёт заметную нагрузку.

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

Программное изменение запроса и параметров списка

Иногда «обновить список» означает не перечитать данные, а перестроить запрос: изменить текст, параметры или отбор. Реквизит динамического списка доступен на сервере, и у него есть свойства ТекстЗапроса, Параметры, ОсновнаяТаблица, ПроизвольныйЗапрос.

&НаСервере

Процедура УстановитьПараметрНаСервере()

Список.Параметры.УстановитьЗначениеПараметра("Организация", ТекущаяОрганизация);

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

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

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

Обычные формы и табличные поля

В обычных формах (режим «Обычное приложение») динамический список отображается табличным полем, и обновление выполняется методом самого табличного поля:

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

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

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

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

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

Сравнение вариантов

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

Универсальный способ для управляемой формы. Перечитывает выборку по текущим настройкам. Не сбрасывает отборы пользователя.

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

Подходит, когда данные меняются в других формах. Требует согласованных имён событий во всех формах конфигурации.

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

Для мониторинга изменений других пользователей. Создаёт нагрузку на сервер; интервал — от 30 секунд.

Изменение параметров запроса

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

Проверка результата и типичные ошибки

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

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

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

Новая запись появилась в списке
Норма

Строка видна после Обновить() без переоткрытия формы

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

Запись есть в базе, но не в списке — проверьте отбор и имя элемента

Текущая строка после обновления
Норма

Позиция сохранена или список спозиционировался корректно

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

Курсор сброшен на первую строку при каждом обновлении — сократите частоту вызовов

Нагрузка при таймере
Норма

Форма не подвисает, сервер отвечает стабильно

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

Периодические задержки интерфейса — увеличьте интервал или перейдите на оповещения

Наиболее частые ошибки при работе с обновлением динамического списка:

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

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

Итог

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

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

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

Почему вызов Список.Обновить() выдаёт ошибку «Метод объекта не обнаружен»?

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

Список с произвольным запросом не обновляется после записи документа. Что делать?

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

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

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

Как сохранить позицию текущей строки после обновления?

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

Можно ли обновлять список автоматически каждые 5 секунд?

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

После изменения параметра запроса список не перечитал данные. В чём причина?

Обычно изменение параметра через Список.Параметры.УстановитьЗначениеПараметра() обновляет список автоматически. Если этого не произошло, добавьте на клиенте вызов Элементы.Список.Обновить() и проверьте, что параметр реально используется в тексте запроса или отборе компоновки.