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

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

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

Как обновить динамический список в 1С: вручную по F5, программно через Элементы.Список.Обновить(), автоматически по таймеру и после записи документа. Примеры кода.

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

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

Ручное обновление списка пользователем

Самый простой способ — обновить список вручную. В форме списка любого справочника или документа нажмите клавишу F5 либо кнопку «Ещё → Обновить» (в некоторых конфигурациях кнопка вынесена прямо на панель формы). Платформа заново выполнит запрос динамического списка и покажет актуальные данные.

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

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

Программное обновление через метод Обновить()

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

&НаКлиенте

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

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

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

Здесь Список — имя реквизита формы типа «ДинамическийСписок» и одновременно имя элемента формы (таблицы), который этот список отображает. Если элемент формы называется иначе, используйте его имя. Метод доступен и на клиенте, и на сервере, но чаще вызывается на клиенте, чтобы не делать лишний серверный вызов.

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

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

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

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

&НаКлиенте

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

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

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

КонецЕсли;

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

Стандартные формы элементов при записи сами рассылают оповещения вида «Запись_<ИмяОбъекта>», поэтому типовые формы списков обновляются автоматически, когда вы редактируете элемент из этого же списка. Проблемы возникают, когда данные меняет ваша собственная обработка или фоновое задание — тогда оповещение нужно отправить явно.

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

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

&НаКлиенте

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

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

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

&НаКлиенте

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

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

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

&НаКлиенте

Процедура ПриЗакрытии(ЗавершениеРаботы)

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

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

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

Порядок настройки автообновления
  1. 1
    Определите имя элемента формы, связанного с динамическим списком
  2. 2
    В ПриОткрытии подключите обработчик ожидания с нужным интервалом
  3. 3
    В процедуре обработчика вызовите Элементы.Список.Обновить()
  4. 4
    В ПриЗакрытии отключите обработчик ожидания
  5. 5
    Откройте форму и проверьте, что список обновляется без действий пользователя

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

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

&НаКлиенте

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

ОповеститьОбИзменении(ДокументСсылка);

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

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

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

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

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

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

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

Проверьте, вызывается ли ОповеститьОбИзменении при записи

Обновление тормозит формуТяжёлый запрос списка

Замерьте время выполнения запроса, упростите соединения

После обновления сбрасывается позицияНорма для полного перечитывания

Используйте ОповеститьОбИзменении вместо полного Обновить

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

Типичные ошибки и как их избежать

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

Отдельная ошибка — попытка обновить список, который ещё не создан: например, вызов Обновить() в ПриСозданииНаСервере до того, как элементы формы сформированы. Переносите вызов в ПриОткрытии на клиенте.

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

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

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

Появляется после обновления без переоткрытия формы

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

Видна только после закрытия и открытия формы

Работа формы при автообновлении
Норма

Список обновляется, форма не подвисает

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

Форма периодически замирает на время выполнения запроса

Нагрузка на сервер
Норма

Обновления не влияют на работу других пользователей

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

Жалобы на замедление при открытой форме-мониторе

Итог

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

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

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

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

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

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

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

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

Автоматически об этом ваш сеанс не узнает: оповещения работают только внутри одного сеанса. Варианты — обновление по таймеру (ПодключитьОбработчикОжидания), ручное обновление по F5 или механизм системы взаимодействия/длительных опросов в сложных случаях. На практике чаще всего достаточно таймера с интервалом 30–60 секунд.

Можно ли обновить не весь список, а одну строку?

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

Обновление списка подвешивает форму на несколько секунд. Что делать?

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

Нужно ли обновлять список после закрытия формы элемента?

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