Динамический список в 1С не обновляется: причины, код и диагностика

· 9 мин

Содержание

Чтобы обновить динамический список в 1С 8.3 из кода, вызовите на клиенте Элементы.Список.Обновить(). Если запись изменили в другой форме или на сервере, правильнее сообщить об этом всем открытым спискам: ОповеститьОбИзменении(Ссылка). Пользователю без программиста хватит команды Ещё → Обновить или сочетания Ctrl+Shift+R.

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

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

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

Типичные причины:

  • 🔕 Нет оповещения. Объект записан программно (обработкой, регламентным заданием, на сервере), а открытая форма списка об этом не знает.
  • 🐢 Медленный запрос. Произвольный запрос с соединениями, вложенными запросами и виртуальными таблицами выполняется секундами, и список выглядит «застывшим».
  • 🔒 Ожидание на блокировке. Чужая долгая транзакция держит таблицу, чтение ждёт.
  • 🚫 Права доступа . Пользователь не видит часть записей или колонок, и ему кажется, что данные не пришли.
  • 🧩 Ошибка в запросе или параметрах. Параметр не установлен, поле удалено из метаданных — список пуст или выдаёт ошибку.
  • 💾 Устаревший локальный кэш. После обновления конфигурации клиент держит старые описания форм.
Диагностика: выберите симптом

Способ 1. Сброс кэша клиента 1С вручную

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

Перед очисткой кэша пользователь должен закрыть все окна 1С на своём компьютере. Сеансы других пользователей это не затрагивает, но несохранённые документы в своём сеансе пропадут.

Вариант А: параметр запуска /ClearCache

  1. В окне запуска выделите базу и нажмите Изменить.
  2. Дойдите до последней страницы мастера.
  3. В поле «Дополнительные параметры запуска» впишите /ClearCache.
  4. Нажмите Готово и запустите базу один раз.
  5. Уберите параметр, иначе кэш будет сбрасываться при каждом входе и запуск замедлится.

Вариант Б: удаление папок кэша

Закройте 1С и удалите содержимое каталогов кэша. Папки с длинными именами вида GUID соответствуют отдельным базам.

rem Windows: каталоги кэша текущего пользователя
rd /s /q "%APPDATA%\1C\1cv8\<GUID-базы>"
rd /s /q "%LOCALAPPDATA%\1C\1cv8\<GUID-базы>"

Если непонятно, какой GUID относится к нужной базе, ориентируйтесь на дату изменения папки или удалите все папки-GUID. 1С создаст их заново, пользователь потеряет только локальные настройки окон.

Сброс настроек самой формы списка

Отдельно от кэша хранятся пользовательские настройки списка: отборы, сортировка, видимость колонок. Сброс делается прямо в форме: Ещё → Изменить форму → Стандартные настройки — для расположения колонок, и Ещё → Настроить список → Стандартные настройки — для отборов и сортировки.

Способ 2. Программное обновление динамического списка

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

ИнструментГде вызыватьКогда подходит
Элементы.Список.Обновить()Клиент, форма самого спискаНужно перечитать конкретный список здесь и сейчас
ОповеститьОбИзменении(...)Клиент, любая формаОбъект изменён, и все открытые списки этого типа должны обновиться
Оповестить("Событие", ...) + ОбработкаОповещенияКлиентНужна своя логика: обновить, спозиционироваться, пересчитать итоги

Обновить() в форме списка

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

&НаКлиенте
Процедура ОбновитьСписок(Команда)
	ТекущаяСсылка = Элементы.Список.ТекущаяСтрока;
	Элементы.Список.Обновить();
	Если ТекущаяСсылка <> Неопределено Тогда
		Элементы.Список.ТекущаяСтрока = ТекущаяСсылка;
	КонецЕсли;
КонецПроцедуры

Запоминание текущей строки спасает пользователя от прыжка в начало таблицы.

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

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

&НаКлиенте
Процедура ПровестиВыделенные(Команда)
	Выделенные = Элементы.Список.ВыделенныеСтроки;
	ПровестиНаСервере(Выделенные);
	// обновить все открытые списки документов этого вида
	ОповеститьОбИзменении(Тип("ДокументСсылка.РеализацияТоваровУслуг"));
КонецПроцедуры

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

Своё оповещение для связанных форм

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

// в форме документа
&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
	Оповестить("ИзмененыЦеныНоменклатуры", Объект.Ссылка);
КонецПроцедуры

// в форме списка регистра
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
	Если ИмяСобытия = "ИзмененыЦеныНоменклатуры" Тогда
		Элементы.Список.Обновить();
	КонецЕсли;
КонецПроцедуры

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

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

&НаСервере
Процедура УстановитьПериод()
	Список.Параметры.УстановитьЗначениеПараметра("ДатаОтчета", ДатаОтчета);
КонецПроцедуры

Для отбора из кода используйте Список.Отбор или функции БСП вроде ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка — если они есть в вашей конфигурации. Не меняйте ТекстЗапроса ради отбора: это пересоздаёт настройки и сбрасывает пользовательские.

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

У таблицы формы есть свойства автообновления: флаг и период в секундах. Их задают в палитре свойств элемента таблицы в конфигураторе или из кода. Подходит для «табло»: очереди заказов, статусов ЭДО.

Не ставьте маленький период на тяжёлый список. Каждый открытый экземпляр формы будет нагружать сервер. Десять пользователей с периодом 5 секунд — это 120 запросов в минуту только от одной формы.

Способ 3. Ускорить запрос динамического списка

Когда обновление «есть, но медленное», проблема в запросе. Откройте форму в конфигураторе, дважды щёлкните реквизит Список и проверьте настройки.

Что смотреть в первую очередь:

  1. Динамическое считывание данных. Флаг должен быть включён. Тогда список читает порцию строк под видимую область, а не всю таблицу целиком.
  2. Основная таблица. Для произвольного запроса укажите основную таблицу. Без неё платформа хуже строит выборку порциями, а у списка пропадают стандартные команды.
  3. Виртуальные таблицы. Остатки и обороты регистров — дорогие. Если без них нельзя, передавайте период параметром и не берите остатки «на сейчас» без условий.
  4. Соединения по составным полям. Соединение по полю «Регистратор» или по составному типу множит обращения к таблицам. Уточняйте тип через ВЫРАЗИТЬ.
  5. Отбор и сортировка по неиндексированным полям. Пользователь сортирует по реквизиту без индекса — сервер перебирает таблицу. Для часто используемых реквизитов включите индексирование в свойствах метаданных.

Обработчик ПриПолученииДанныхНаСервере

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

&НаСервереБезКонтекста
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
	Для Каждого КлючИЗначение Из Строки Цикл
		ДанныеСтроки = КлючИЗначение.Значение.Данные;
		ДанныеСтроки.Комментарий = СокрЛП(ДанныеСтроки.Комментарий);
	КонецЦикла;
КонецПроцедуры

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

Способ 4. Найти блокировки и долгие транзакции

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

Как это проявляется:

  • 🕐 список открывается через 20–30 секунд, а иногда с ошибкой о превышении времени ожидания блокировки;
  • 🕐 другим пользователям в это же время тоже медленно;
  • 🕐 после окончания обработки всё снова работает быстро.

Что делать:

  1. Откройте консоль администрирования серверов 1С и посмотрите сеансы базы. Долгий сеанс с высоким временем вызова — первый подозреваемый.
  2. В конфигурациях на БСП откройте Администрирование → Обслуживание → Активные пользователи — видно, кто и с какого компьютера работает.
  3. Перенесите массовые операции (перепроведение, загрузку обменов) на нерабочее время.
  4. Если конфигурация работает в автоматическом режиме блокировок, обсудите с разработчиком перевод на управляемый — в нём чтение для списков почти не конфликтует с записью.

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

В файловом варианте базы блокировки грубее: одна запись может притормозить чтение у всех. Если пользователей больше 5–7 и списки регулярно подвисают, это повод думать о переходе на клиент-серверный вариант.

Способ 5. Проверить права доступа к данным списка

Динамический список читает только то, что разрешено роли. Отсюда два разных симптома.

СимптомВероятная причинаЧто проверить
У бухгалтера 100 документов, у менеджера 12Ограничение доступа на уровне записей (RLS)Группы доступа, профили, настройки ограничения по организациям
Колонка у пользователя пустая, у админа заполненаНет права чтения на реквизит или связанную таблицуРоль, права на поля
Ошибка «Недостаточно прав» при открытииПроизвольный запрос берёт таблицу без права чтенияПрава роли на все таблицы из текста запроса

Как проверить быстро:

  1. Войдите под пользователем с проблемой (или создайте тестового с тем же профилем).
  2. Сравните количество строк со списком под администратором.
  3. В конфигурациях на БСП откройте Администрирование → Настройки пользователей и прав и посмотрите группы доступа пользователя.

Разработчику: если в произвольный запрос списка добавлена таблица «для красоты» — например, регистр с ценами, — проверьте, есть ли на неё права у всех ролей, которые открывают форму.

Способ 6. Разобрать ошибку через журнал регистрации

Если список выдаёт ошибку, а пользователь успел закрыть окно, подробности остались в журнале регистрации.

Где открыть:

  • в пользовательском режиме конфигураций на БСП — Администрирование → Обслуживание → Журнал регистрации;
  • в конфигураторе — Администрирование → Журнал регистрации.

Как искать:

  1. Нажмите Установить отбор.
  2. Укажите интервал, когда пользователь видел проблему, — лучше 10–15 минут.
  3. Отберите по пользователю и уровню «Ошибка».
  4. Откройте событие и прочитайте комментарий: там текст исключения и, как правило, модуль и строка.

Что обычно находится:

  • 🧾 «Поле объекта не обнаружено» — реквизит переименовали или удалили, а запрос или обработчик формы ссылается на него;
  • 🧾 ошибки в ПриПолученииДанныхНаСервере — обращение к полю, которого нет в запросе списка;
  • 🧾 превышение времени ожидания блокировки — см. предыдущий раздел.

Если журнал пуст, а проблема плавающая, включите технологический журнал на сервере на короткий период. Он покажет длительность запросов СУБД и ожидания на блокировках. Не оставляйте его включённым надолго — он быстро занимает диск.

Как не допускать зависаний динамических списков

Профилактика дешевле разбора. Короткий набор правил для разработки и сопровождения:

  • ✅ Каждая программная запись объекта на клиенте заканчивается ОповеститьОбИзменении.
  • ✅ Динамическое считывание включено; основная таблица указана.
  • ✅ Колонки-вычисления — через ПриПолученииДанныхНаСервере, а не через подзапросы.
  • ✅ Автообновление включено только там, где оно нужно, и с разумным периодом — от 30–60 секунд.
  • ✅ Массовые операции идут ночью или регламентными заданиями.
  • ✅ После обновления конфигурации новые формы проверяются под обычным пользователем, а не только под администратором.
Перед выпуском формы со списком
Выполнено: 0 / 6

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

Можно ли обновить динамический список из серверной процедуры?
Метод Обновить() доступен только на клиенте. На сервере можно изменить параметр или отбор — список перечитается после возврата на клиент.
Почему после Обновить() теряется текущая строка?
Если запись ушла из выборки или сменилась сортировка, курсор сбрасывается. Сохраните ТекущаяСтрока до обновления и верните после.
Обновится ли список в другой открытой вкладке?
Да, если вы вызвали ОповеститьОбИзменении с нужной ссылкой или типом. Обновить() затрагивает только одну форму.
Видят ли другие пользователи изменения сразу?
Нет. Оповещение работает внутри одного сеанса. У других список обновится при прокрутке, повторном открытии, по Ctrl+Shift+R или по таймеру автообновления.
Чем отличается динамический список от таблицы значений на форме?
Таблица значений хранит данные в форме и обновляется только вашим кодом. Динамический список читает базу сам, порциями, и подходит для больших объёмов.