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