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