Разработка и Конфигурация · 11 мин
Как обновить динамический список на форме в 1С
Как обновить динамический список на форме в 1С: методы Обновить, Элементы.Список.Обновить, программное выполнение запроса, обновление при записи и активации формы.
Динамический список на форме 1С не всегда обновляется сам: после записи объекта, изменения настроек запроса или добавления данных другим пользователем таблица может показывать устаревшие строки. Разработчику доступно несколько способов принудительного обновления — от простого вызова метода Обновить() у расширения динамического списка до перезапуска запроса с новыми параметрами.
Выбор способа зависит от ситуации: нужно ли просто перечитать текущую выборку, обновить список после редактирования элемента в отдельной форме или сбросить пользовательские настройки отбора. Ниже разобраны все рабочие варианты с примерами кода, типичными ошибками и способами проверки результата.
Примеры актуальны для управляемых форм на платформе 8.3 с режимом совместимости «Такси» и обычными формами — там, где поведение отличается, это оговорено отдельно.
Как устроено обновление динамического списка
Динамический список — это объект, который выполняет запрос к базе данных и отображает результат порциями по мере прокрутки. Платформа кэширует выборку, поэтому простое изменение данных в информационной базе не приводит к мгновенному изменению таблицы на форме. Список перечитывается при определённых событиях: открытии формы, записи объекта из формы списка, изменении отбора или порядка.
Ключевой момент: обновление выполняется на клиенте через расширение динамического списка, а не через сам реквизит формы типа «ДинамическийСписок». Поэтому код Список.Обновить() в модуле управляемой формы вызовет ошибку — у объекта ДинамическийСписок такого метода нет. Правильное обращение идёт через коллекцию Элементы.
Понимание этого разделения избавляет от самой распространённой ошибки новичков — попытки вызвать обновление у реквизита формы вместо элемента формы, отображающего список.
Базовое обновление через Элементы.Список.Обновить()
В управляемой форме динамический список отображается элементом формы типа «Таблица», у которого есть расширение динамического списка с методом Обновить(). Типовой код выглядит так:
&НаКлиенте
Процедура ОбновитьСписок(Команда)
Элементы.Список.Обновить();
КонецПроцедуры
Здесь Список — имя элемента формы (таблицы), а не реквизита. Если таблица называется иначе, например «СписокДокументов», вызов будет Элементы.СписокДокументов.Обновить(). Метод доступен только на клиенте, поэтому директива &НаКлиенте обязательна.
Если обновление нужно инициировать из серверной процедуры (например, после массовой обработки данных), вынесите вызов в клиентскую обёртку: серверная процедура выполняет изменения, а клиентская после её завершения вызывает Обновить().
&НаКлиенте
Процедура ОбновитьСписок(Команда)
Элементы.Список.Обновить();
КонецПроцедурыОбновление после записи элемента и при оповещении форм
Когда элемент справочника или документ редактируется в отдельной форме, список не узнает об изменении автоматически, если запись выполнена нестандартным способом. Стандартный механизм — оповещение форм методом Оповестить() и обработчик ОбработкаОповещения() в форме списка.
В форме элемента после записи:
&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
Оповестить("Запись_Номенклатура", , ЭтотОбъект);
КонецПроцедуры
В форме списка:
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "Запись_Номенклатура" Тогда
Элементы.Список.Обновить();
КонецЕсли;
КонецПроцедуры
Платформа сама рассылает стандартное оповещение ОповеститьОбИзменении(Ссылка) при записи объекта, и динамический список основной таблицы обычно реагирует на него без дополнительного кода. Ручная обработка нужна, когда список построен на произвольном запросе, объединяющем несколько таблиц, — тогда платформа не может определить, какие изменения влияют на выборку.
Обновление при активации формы и по таймеру
Если данные в базе меняют другие пользователи или фоновые задания, список полезно обновлять при возврате пользователя на форму. Для этого служит обработчик ПриАктивизации() самой формы (не таблицы):
&НаКлиенте
Процедура ПриАктивизации()
Элементы.Список.Обновить();
КонецПроцедуры
Для мониторинга в реальном времени используют ПодключитьОбработчикОжидания() с интервалом, например 30–60 секунд. Обработчик вызывает Элементы.Список.Обновить(). Ставить интервал меньше 10–15 секунд не стоит: каждый вызов выполняет запрос к серверу, и при большом числе пользователей это создаёт заметную нагрузку.
Не забудьте отключить обработчик ожидания при закрытии формы вызовом ОтключитьОбработчикОжидания(), иначе процедура продолжит срабатывать и вызовет ошибки обращения к несуществующим элементам.
Программное изменение запроса и параметров списка
Иногда «обновить список» означает не перечитать данные, а перестроить запрос: изменить текст, параметры или отбор. Реквизит динамического списка доступен на сервере, и у него есть свойства ТекстЗапроса, Параметры, ОсновнаяТаблица, ПроизвольныйЗапрос.
&НаСервере
Процедура УстановитьПараметрНаСервере()
Список.Параметры.УстановитьЗначениеПараметра("Организация", ТекущаяОрганизация);
КонецПроцедуры
После изменения параметров или отбора список обычно обновляется автоматически — платформа отслеживает изменение настроек компоновки. Если этого не произошло (например, параметр менялся в обход механизма настроек), дополнительно вызовите Элементы.Список.Обновить() на клиенте.
При смене текста запроса учитывайте ограничение: состав полей нового запроса должен быть совместим с уже настроенными отборами и порядком, иначе пользователь получит ошибку компоновки при следующем обращении к списку.
Обычные формы и табличные поля
В обычных формах (режим «Обычное приложение») динамический список отображается табличным полем, и обновление выполняется методом самого табличного поля:
Процедура КнопкаОбновитьНажатие(Кнопка)
ЭлементыФормы.Список.ОбновитьСтроки();
КонецПроцедуры
Для списков, построенных через объект СправочникСписок или ДокументСписок с произвольным запросом, дополнительно может потребоваться повторное выполнение запроса — присвоение текста запроса заново или вызов Обновить() у объекта списка до обновления строк табличного поля.
Обратите внимание: в обычных формах нет разделения на клиентский и серверный контекст в том виде, в каком оно есть в управляемых, поэтому код проще, но возможности компоновки данных и произвольных отборов там ограничены.
Сравнение вариантов
Универсальный способ для управляемой формы. Перечитывает выборку по текущим настройкам. Не сбрасывает отборы пользователя.
Подходит, когда данные меняются в других формах. Требует согласованных имён событий во всех формах конфигурации.
Для мониторинга изменений других пользователей. Создаёт нагрузку на сервер; интервал — от 30 секунд.
Когда нужно не просто перечитать данные, а изменить условия выборки. Выполняется на сервере.
Проверка результата и типичные ошибки
Признак корректного обновления — таблица перечитывает данные: появляются новые записи, исчезают удалённые, изменённые строки показывают актуальные значения, а текущая строка по возможности сохраняет позицию. Если после вызова Обновить() ничего не меняется, проверьте, тот ли элемент формы вы обновляете и не отфильтрована ли нужная запись текущим отбором.
Как проверить результат
Строка видна после Обновить() без переоткрытия формы
Запись есть в базе, но не в списке — проверьте отбор и имя элемента
Позиция сохранена или список спозиционировался корректно
Курсор сброшен на первую строку при каждом обновлении — сократите частоту вызовов
Форма не подвисает, сервер отвечает стабильно
Периодические задержки интерфейса — увеличьте интервал или перейдите на оповещения
Наиболее частые ошибки при работе с обновлением динамического списка:
Отдельного упоминания заслуживает ситуация с толстым клиентом и файловой базой: там кэширование выборки может отличаться, и иногда помогает только переоткрытие формы. Это крайняя мера — сначала убедитесь, что обновление вызывается у правильного элемента и после фактического завершения записи данных.
Что важно запомнить
Обновление динамического списка выполняется методом Обновить() у элемента формы на клиенте. Для списков с произвольным запросом добавляйте обработку оповещений, для мониторинга — таймер с разумным интервалом. Изменение параметров запроса делайте на сервере, а обновление отображения — на клиенте.
Частые вопросы
Почему вызов Список.Обновить() выдаёт ошибку «Метод объекта не обнаружен»?
Потому что обновление вызывается у реквизита формы типа «ДинамическийСписок», а метод Обновить() есть только у элемента формы — таблицы, отображающей список. Используйте Элементы.ИмяТаблицы.Обновить() в клиентской процедуре.
Список с произвольным запросом не обновляется после записи документа. Что делать?
Платформа автоматически отслеживает изменения только основной таблицы списка. Для произвольного запроса с соединениями добавьте в форму элемента вызов Оповестить() после записи, а в форме списка — обработчик ОбработкаОповещения() с вызовом Элементы.Список.Обновить().
Как обновить список из серверной процедуры управляемой формы?
Напрямую — никак: расширение динамического списка недоступно на сервере. Разделите логику: серверная процедура изменяет данные или параметры запроса, а клиентская процедура после её вызова выполняет Элементы.Список.Обновить().
Как сохранить позицию текущей строки после обновления?
Перед обновлением запомните текущую ссылку: ТекущаяСсылка = Элементы.Список.ТекущаяСтрока, после обновления установите Элементы.Список.ТекущаяСтрока = ТекущаяСсылка. Это работает, если запись не удалена и проходит условия текущего отбора.
Можно ли обновлять список автоматически каждые 5 секунд?
Технически да, через ПодключитьОбработчикОжидания(), но это создаёт постоянную нагрузку на сервер и мешает пользователю, сбрасывая прокрутку. Рекомендуемый минимум — 30 секунд, а лучше заменить таймер на механизм оповещений между формами.
После изменения параметра запроса список не перечитал данные. В чём причина?
Обычно изменение параметра через Список.Параметры.УстановитьЗначениеПараметра() обновляет список автоматически. Если этого не произошло, добавьте на клиенте вызов Элементы.Список.Обновить() и проверьте, что параметр реально используется в тексте запроса или отборе компоновки.