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

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

Как программно заполнить динамический список в 1С

Как программно настроить динамический список в 1С: произвольный запрос, параметры, отборы, основная таблица и типичные ошибки с примерами кода.

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

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

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

Что такое динамический список и когда нужен произвольный запрос

Динамический список — реквизит формы типа «ДинамическийСписок», который платформа использует для отображения списков справочников, документов, регистров. Он построен на механизме компоновки данных: платформа формирует запрос, применяет отборы и сортировку, постранично считывает данные и автоматически обновляет их при записи объектов.

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

  • нужно объединить данные нескольких таблиц (например, документы и остатки по ним);
  • требуются виртуальные таблицы регистров — остатки, обороты, срезы последних;
  • нужны вычисляемые поля, группировки, итоги, условная логика через ВЫБОР;
  • список должен показывать данные, отфильтрованные сложным условием, которое не выразить стандартным отбором.

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

Настройка произвольного запроса в конфигураторе

Простейший путь — задать запрос статически, в свойствах реквизита формы. Откройте форму в конфигураторе, выделите реквизит типа «ДинамическийСписок» и в палитре свойств установите флаг «Произвольный запрос». После этого станет активной строка «Настройка списка», где открывается конструктор: на вкладке «Запрос» вводится текст, на вкладках «Параметры» и «Отбор» — значения и условия.

Пример запроса, показывающего заказы с остатками по ним:

ВЫБРАТЬ

Заказы.Ссылка КАК Заказ,

Заказы.Контрагент КАК Контрагент,

ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток

ИЗ

Документ.ЗаказПокупателя КАК Заказы

ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ЗаказыПокупателей.Остатки КАК Остатки

ПО Заказы.Ссылка = Остатки.Заказ

Обратите внимание: поле ссылки на объект (Заказ в примере) обязательно должно присутствовать в выборке, иначе платформа не сможет корректно работать со строками списка — открывать объекты, позиционироваться, обновлять. Для списков с возможностью интерактивного изменения данных также потребуется указать основную таблицу.

Программная установка текста запроса

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

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Список.ПроизвольныйЗапрос = Истина;

Список.ОсновнаяТаблица = "Документ.РеализацияТоваровУслуг";

ТекстЗапроса =

"ВЫБРАТЬ

| Реализация.Ссылка КАК Ссылка,

| Реализация.Контрагент КАК Контрагент,

| Реализация.СуммаДокумента КАК Сумма

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Реализация

|ГДЕ

| Реализация.Организация = &Организация";

Список.УстановитьТекстЗапроса(ТекстЗапроса);

Список.Параметры.УстановитьЗначениеПараметра("Организация", ТекущаяОрганизация);

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

Ключевые моменты этого кода. Свойство «ОсновнаяТаблица» стоит указывать, если список должен поддерживать стандартные команды: создание, копирование, пометку на удаление. Без основной таблицы эти команды будут недоступны или поведут себя неочевидно. Установку параметра выполняют после установки текста запроса — иначе параметр может не найтись.

Менять текст запроса можно и позже, например при переключении закладок формы. После вызова УстановитьТекстЗапроса список перечитывается автоматически, дополнительно вызывать обновление не требуется.

Передача параметров и работа с отборами

Параметры запроса устанавливаются через коллекцию «Параметры» динамического списка. Типичная ошибка — обращение к параметру, которого нет в тексте запроса: платформа выдаст ошибку «Параметр не найден». Поэтому параметр сначала объявляют в тексте (&Имя), затем устанавливают значение.

Список.Параметры.УстановитьЗначениеПараметра("НачалоПериода", НачалоМесяца(ТекущаяДатаСеанса()));

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

Отборы, которые пользователь может менять интерактивно, лучше реализовывать не через ГДЕ в тексте запроса, а через коллекцию отбора списка. Тогда условие добавляется и снимается без изменения запроса:

ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));

ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Контрагент");

ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;

ЭлементОтбора.ПравоеЗначение = ВыбранныйКонтрагент;

ЭлементОтбора.Использование = Истина;

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

Способы ограничить данные списка

Условие ГДЕ в тексте запроса

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

Отбор через Список.Отбор

Подходит для интерактивных фильтров. Виден пользователю, может сочетаться с быстрым поиском и настройками формы.

Параметры запроса

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

Динамический список на схеме компоновки данных

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

Схема = ПолучитьМакет("СхемаСпискаДокументов");

Список.УстановитьСхемуКомпоновкиДанных(Схема);

Список.УстановитьНастройки(Схема.НастройкиПоУмолчанию);

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

Учтите, что при работе через СКД отладка сложнее: итоговый запрос формируется компоновщиком, и ошибки вида «поле не найдено» часто возникают из-за несовпадения имён полей в наборе данных и в настройках.

Маршрут решения

Как выбрать способ заполнения

Нужен список одной таблицы с фильтрамиОставьте автоматический запрос, настройте только отбор — программный код не требуется
Нужны соединения, виртуальные таблицы, вычисляемые поляВключите ПроизвольныйЗапрос и задайте текст через УстановитьТекстЗапроса()
Пользователь должен менять колонки и группировкиИспользуйте схему компоновки данных через УстановитьСхемуКомпоновкиДанных()
Данные не хранятся в базе или получаются расчётомДинамический список не подходит — используйте таблицу значений на форме

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

После изменения параметров или отбора в коде список обычно перечитывается сам. Если данные изменились извне (например, фоновое задание записало документы) и список не обновился, вызовите:

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

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

Для диагностики итогового запроса полезно временно вывести его в журнал регистрации или скопировать текст запроса в консоль и выполнить с теми же параметрами. Так видно, какие условия реально ушли на СУБД.

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

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

Число строк в списке
Норма

Совпадает с результатом того же запроса в консоли

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

Строк меньше — платформа добавила скрытые условия или отбор

Открытие объекта из списка
Норма

Двойной щелчок открывает нужный объект

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

Ничего не происходит — в запросе нет поля ссылки или оно не уникально

Команды создания и копирования
Норма

Кнопки работают и создают объект нужного типа

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

Команды недоступны — не указана основная таблица

Отбор пользователем
Норма

Фильтр применяется и отображается в настройках списка

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

Отбор «слетает» — условие зашито в текст запроса, а не в отбор компоновки

Типичные ошибки и ограничения

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

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

Наконец, избегайте вызова УстановитьТекстЗапроса в часто срабатывающих обработчиках (например, при активизации строки): каждая установка вызывает полное перечитывание списка и лишнюю нагрузку на СУБД. Меняйте параметры, а не текст, если структура запроса не изменилась.

Типичные ошибки
01
Установка значения параметра, которого нет в тексте запроса — ошибка «Параметр не найден» при открытии формы
02
Отсутствие поля ссылки в выборке — список показывается, но объекты не открываются и не обновляются
03
Попытка добавить строки в список как в таблицу значений — динамический список читает только данные базы через запрос
04
Тяжёлый запрос без отбора по периоду — форма открывается долго, пользователи жалуются на зависания
05
Смена текста запроса в частых обработчиках — постоянное перечитывание и лишняя нагрузка на СУБД

FAQ

Можно ли заполнить динамический список из таблицы значений?

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

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

Чаще всего платформа добавила собственные условия: отбор, оставшийся от настроек пользователя, условие по основной таблице или разделители данных в разделённой информационной базе. Проверьте коллекцию Список.Отбор и пользовательские настройки формы, а также выполните запрос под тем же пользователем.

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

Параметры указываются в скобках виртуальной таблицы в тексте запроса, например: РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ). Значения этим параметрам присваиваются стандартно — через Список.Параметры.УстановитьЗначениеПараметра().

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

Не обязательно, но рекомендуется, если список должен поддерживать интерактивные команды: создание, копирование, пометку удаления, открытие объекта. Без основной таблицы список становится фактически отчётным — только для просмотра.

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

Найдите нужный элемент в коллекции Список.Отбор.Элементы и установите ему Использование = Ложь либо удалите методом Удалить(). Если отбор задан условием ГДЕ в тексте запроса, снять его можно только заменой текста запроса.

Итог

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

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