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