Динамический список в 1С не обновляется: причины, код и диагностика
Содержание
Чтобы обновить динамический список
в 1С 8.3 из кода, вызовите на клиенте Элементы.Список.Обновить(). Если запись изменили в другой форме или на сервере, правильнее сообщить об этом всем открытым спискам: ОповеститьОбИзменении(Ссылка). Пользователю без программиста хватит команды Ещё → Обновить или сочетания Ctrl+Shift+R.
Частое заблуждение: «список завис — значит, сломался кэш, надо чистить». На практике кэш виноват реже всего. Обычно программа записала объект и никого не оповестила, тяжёлый запрос не успевает отдать данные или у пользователя нет прав на часть полей. Ниже — способы по порядку: от безопасных к тем, что затрагивают других пользователей.
Почему динамический список в 1С не обновляется
Динамический список не держит данные в памяти формы. Он читает их из базы порциями, когда пользователь листает таблицу, и перечитывает при определённых событиях. Если событие не наступило — на экране старая картина.
Типичные причины:
- 🔕 Нет оповещения. Объект записан программно (обработкой, регламентным заданием, на сервере), а открытая форма списка об этом не знает.
- 🐢 Медленный запрос. Произвольный запрос с соединениями, вложенными запросами и виртуальными таблицами выполняется секундами, и список выглядит «застывшим».
- 🔒 Ожидание на блокировке. Чужая долгая транзакция держит таблицу, чтение ждёт.
- 🚫 Права доступа . Пользователь не видит часть записей или колонок, и ему кажется, что данные не пришли.
- 🧩 Ошибка в запросе или параметрах. Параметр не установлен, поле удалено из метаданных — список пуст или выдаёт ошибку.
- 💾 Устаревший локальный кэш. После обновления конфигурации клиент держит старые описания форм.
Способ 1. Сброс кэша клиента 1С вручную
Кэш помогает, когда симптомы начались сразу после обновления конфигурации или платформы: формы показывают старые колонки, сохранённые настройки конфликтуют с новыми полями, список ведёт себя иначе на одном компьютере.
Перед очисткой кэша пользователь должен закрыть все окна 1С на своём компьютере. Сеансы других пользователей это не затрагивает, но несохранённые документы в своём сеансе пропадут.
Вариант А: параметр запуска /ClearCache
- В окне запуска выделите базу и нажмите
Изменить. - Дойдите до последней страницы мастера.
- В поле «Дополнительные параметры запуска» впишите
/ClearCache. - Нажмите
Готовои запустите базу один раз. - Уберите параметр, иначе кэш будет сбрасываться при каждом входе и запуск замедлится.
Вариант Б: удаление папок кэша
Закройте 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. Ускорить запрос динамического списка
Когда обновление «есть, но медленное», проблема в запросе. Откройте форму в конфигураторе, дважды щёлкните реквизит Список и проверьте настройки.
Что смотреть в первую очередь:
- Динамическое считывание данных. Флаг должен быть включён. Тогда список читает порцию строк под видимую область, а не всю таблицу целиком.
- Основная таблица. Для произвольного запроса укажите основную таблицу. Без неё платформа хуже строит выборку порциями, а у списка пропадают стандартные команды.
- Виртуальные таблицы. Остатки и обороты регистров — дорогие. Если без них нельзя, передавайте период параметром и не берите остатки «на сейчас» без условий.
- Соединения по составным полям. Соединение по полю «Регистратор» или по составному типу множит обращения к таблицам. Уточняйте тип через
ВЫРАЗИТЬ. - Отбор и сортировка по неиндексированным полям. Пользователь сортирует по реквизиту без индекса — сервер перебирает таблицу. Для часто используемых реквизитов включите индексирование в свойствах метаданных.
Обработчик ПриПолученииДанныхНаСервере
Если в колонке нужно показать вычисляемое значение (статус, иконку, цвет), не тяните его подзапросом. Добавьте колонку в запрос пустой, а заполните её в обработчике ПриПолученииДанныхНаСервере у элемента таблицы. Он вызывается только для строк, которые реально отображаются.
&НаСервереБезКонтекста
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
Для Каждого КлючИЗначение Из Строки Цикл
ДанныеСтроки = КлючИЗначение.Значение.Данные;
ДанныеСтроки.Комментарий = СокрЛП(ДанныеСтроки.Комментарий);
КонецЦикла;
КонецПроцедуры
Обработчик работает без контекста формы. Тяжёлые запросы внутри цикла по строкам убивают весь выигрыш — собирайте данные одним запросом по массиву ключей.
Способ 4. Найти блокировки и долгие транзакции
Если список «замирает» только в определённые часы — при закрытии месяца, массовом перепроведении, обмене — ищите чужую транзакцию.
Как это проявляется:
- 🕐 список открывается через 20–30 секунд, а иногда с ошибкой о превышении времени ожидания блокировки;
- 🕐 другим пользователям в это же время тоже медленно;
- 🕐 после окончания обработки всё снова работает быстро.
Что делать:
- Откройте консоль администрирования серверов 1С и посмотрите сеансы базы. Долгий сеанс с высоким временем вызова — первый подозреваемый.
- В конфигурациях на БСП откройте
Администрирование → Обслуживание → Активные пользователи— видно, кто и с какого компьютера работает. - Перенесите массовые операции (перепроведение, загрузку обменов) на нерабочее время.
- Если конфигурация работает в автоматическом режиме блокировок, обсудите с разработчиком перевод на управляемый — в нём чтение для списков почти не конфликтует с записью.
Принудительное завершение сеанса обрывает работу пользователя: незаписанные данные пропадут, а транзакция откатится. Делайте это только после предупреждения человека и понимания, что именно он выполняет.
В файловом варианте базы блокировки грубее: одна запись может притормозить чтение у всех. Если пользователей больше 5–7 и списки регулярно подвисают, это повод думать о переходе на клиент-серверный вариант.
Способ 5. Проверить права доступа к данным списка
Динамический список читает только то, что разрешено роли. Отсюда два разных симптома.
| Симптом | Вероятная причина | Что проверить |
|---|---|---|
| У бухгалтера 100 документов, у менеджера 12 | Ограничение доступа на уровне записей (RLS) | Группы доступа, профили, настройки ограничения по организациям |
| Колонка у пользователя пустая, у админа заполнена | Нет права чтения на реквизит или связанную таблицу | Роль, права на поля |
| Ошибка «Недостаточно прав» при открытии | Произвольный запрос берёт таблицу без права чтения | Права роли на все таблицы из текста запроса |
Как проверить быстро:
- Войдите под пользователем с проблемой (или создайте тестового с тем же профилем).
- Сравните количество строк со списком под администратором.
- В конфигурациях на БСП откройте
Администрирование → Настройки пользователей и прави посмотрите группы доступа пользователя.
Разработчику: если в произвольный запрос списка добавлена таблица «для красоты» — например, регистр с ценами, — проверьте, есть ли на неё права у всех ролей, которые открывают форму.
Способ 6. Разобрать ошибку через журнал регистрации
Если список выдаёт ошибку, а пользователь успел закрыть окно, подробности остались в журнале регистрации.
Где открыть:
- в пользовательском режиме конфигураций на БСП —
Администрирование → Обслуживание → Журнал регистрации; - в конфигураторе —
Администрирование → Журнал регистрации.
Как искать:
- Нажмите
Установить отбор. - Укажите интервал, когда пользователь видел проблему, — лучше 10–15 минут.
- Отберите по пользователю и уровню «Ошибка».
- Откройте событие и прочитайте комментарий: там текст исключения и, как правило, модуль и строка.
Что обычно находится:
- 🧾 «Поле объекта не обнаружено» — реквизит переименовали или удалили, а запрос или обработчик формы ссылается на него;
- 🧾 ошибки в
ПриПолученииДанныхНаСервере— обращение к полю, которого нет в запросе списка; - 🧾 превышение времени ожидания блокировки — см. предыдущий раздел.
Если журнал пуст, а проблема плавающая, включите технологический журнал на сервере на короткий период. Он покажет длительность запросов СУБД и ожидания на блокировках. Не оставляйте его включённым надолго — он быстро занимает диск.
Как не допускать зависаний динамических списков
Профилактика дешевле разбора. Короткий набор правил для разработки и сопровождения:
- ✅ Каждая программная запись объекта на клиенте заканчивается
ОповеститьОбИзменении. - ✅ Динамическое считывание включено; основная таблица указана.
- ✅ Колонки-вычисления — через
ПриПолученииДанныхНаСервере, а не через подзапросы. - ✅ Автообновление включено только там, где оно нужно, и с разумным периодом — от 30–60 секунд.
- ✅ Массовые операции идут ночью или регламентными заданиями.
- ✅ После обновления конфигурации новые формы проверяются под обычным пользователем, а не только под администратором.
Частые вопросы про обновление динамического списка
Можно ли обновить динамический список из серверной процедуры?
Обновить() доступен только на клиенте. На сервере можно изменить параметр или отбор — список перечитается после возврата на клиент.Почему после Обновить() теряется текущая строка?
ТекущаяСтрока до обновления и верните после.Обновится ли список в другой открытой вкладке?
ОповеститьОбИзменении с нужной ссылкой или типом. Обновить() затрагивает только одну форму.Видят ли другие пользователи изменения сразу?
Ctrl+Shift+R или по таймеру автообновления.