Разработка и Конфигурация · 12 мин
Менеджер запросов 1С:Предприятие — что это и как с ним работать
Что такое менеджер запросов в 1С:Предприятие, как устроен объект Запрос, пакетные запросы, временные таблицы, параметры и типичные ошибки разработчика.
Менеджер запросов в 1С:Предприятие — это механизм платформы, который позволяет программно формировать и выполнять запросы к базе данных на встроенном языке запросов 1С. Через него разработчик получает данные из справочников, документов, регистров и других объектов, не обращаясь к СУБД напрямую. В коде механизм представлен объектом Запрос, который создаётся конструктором Новый Запрос.
Главная особенность подхода — декларативность: вы описываете, какие данные нужны и по каким условиям, а платформа сама транслирует текст запроса в SQL для конкретной СУБД (MS SQL Server, PostgreSQL, Oracle, IBM DB2 или файловый вариант). Это избавляет от необходимости писать диалектно-зависимый код, но требует понимания того, как платформа исполняет запрос, чтобы не получить узкое место в производительности.
Менеджер запросов применяется практически везде: при заполнении табличных частей документов, построении отчётов, проверке остатков, обменах данными, фоновых обработках. Умение грамотно работать с объектом Запрос — базовый навык разработчика 1С, и именно ошибки на этом уровне чаще всего становятся причиной медленных проведений документов и тяжёлых отчётов.
Что такое объект «Запрос» и как он устроен
Объект Запрос создаётся встроенным конструктором и содержит текст запроса на языке запросов 1С — диалекте, внешне похожем на SQL, но оперирующем объектами конфигурации: Справочник.Номенклатура, Документ.РеализацияТоваровУслуг, РегистрНакопления.ТоварыНаСкладах.Остатки и так далее.
Минимальный рабочий пример выглядит так:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Товар,
| Номенклатура.Артикул КАК Артикул
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ПометкаУдаления";
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
// обработка строки
КонецЦикла;
Метод Выполнить() отправляет запрос на исполнение и возвращает объект РезультатЗапроса. Из него данные получают двумя способами: методом Выбрать() — последовательная выборка с минимальным расходом памяти, или методом Выгрузить() — загрузка всего результата в таблицу значений. Выборка подходит для обхода больших наборов данных, выгрузка — когда нужен произвольный доступ к строкам, сортировка или поиск.
Параметры запроса: зачем нужны и как передавать
Параметры — это именованные значения, которые подставляются в текст запроса при выполнении. В тексте они обозначаются символом &: ГДЕ Номенклатура.Родитель = &Группа. Значение задаётся через коллекцию Запрос.УстановитьПараметр("Группа", СсылкаНаГруппу).
Использовать параметры нужно всегда, а не конкатенировать значения прямо в текст запроса. Это не только защита от ошибок и неявных преобразований типов, но и вопрос производительности: СУБД может повторно использовать план выполнения параметризованного запроса, тогда как каждый новый текст с «зашитыми» значениями компилируется заново.
Отдельный важный случай — передача списка значений или массива в условие В (&СписокСсылок). Платформа корректно разворачивает массивы и списки значений в набор условий, поэтому фильтрация по нескольким элементам делается одним параметром, а не циклом с динамической сборкой текста.
Виртуальные таблицы и их параметры
Регистры накопления и сведений предоставляют виртуальные таблицы: Остатки, Обороты, ОстаткиИОбороты, СрезПоследних, СрезПервых. Это не физические таблицы, а программно формируемые представления, у которых есть собственные параметры: период, условие отбора, список измерений.
Ключевое правило производительности: отбор нужно задавать в параметрах виртуальной таблицы, а не в секции ГДЕ основного запроса. Условие Остатки(Период = &Дата, Склад = &Склад) заставит платформу рассчитать остатки только по нужному складу, тогда как фильтр в ГДЕ сначала вычислит остатки по всем складам и лишь потом отбросит лишние строки.
Также помните, что обращение к виртуальным таблицам остатков без учёта итогов может приводить к пересчёту больших объёмов данных. Если отчёт работает по историческим периодам, убедитесь, что итоги по регистрам рассчитаны на нужные даты — это заметно ускоряет выполнение.
Пакетные запросы и временные таблицы
Один объект Запрос может содержать несколько запросов, разделённых точкой с запятой, — это пакетный запрос. Промежуточные результаты помещаются во временные таблицы конструкцией ПОМЕСТИТЬ ИмяТаблицы, а финальный запрос читает их как обычные источники.
Типовой сценарий: сначала отобрать нужные ссылки во временную таблицу, затем соединить её с виртуальной таблицей остатков. Это решает две задачи: ограничивает расчёт виртуальной таблицы только нужными элементами и позволяет переиспользовать отбор в нескольких местах пакета.
Запрос.Текст =
"ВЫБРАТЬ
| Товары.Ссылка КАК Номенклатура
|ПОМЕСТИТЬ ВТ_Товары
|ИЗ
| Справочник.Номенклатура КАК Товары
|ГДЕ
| Товары.Родитель = &Группа
|;
|ВЫБРАТЬ
| Остатки.Номенклатура КАК Номенклатура,
| Остатки.КоличествоОстаток КАК Остаток
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(
| &Дата,
| Номенклатура В (ВЫБРАТЬ Т.Номенклатура ИЗ ВТ_Товары КАК Т)
| ) КАК Остатки";
Для явного управления временными таблицами существует объект МенеджерВременныхТаблиц: он позволяет передавать временные таблицы между разными запросами и контролировать их время жизни. Внешнюю таблицу значений можно передать в запрос через параметр и конструкцию ПОМЕСТИТЬ — это стандартный способ соединить данные, полученные извне (например, из файла обмена), с данными базы.
- 1Создайте объект Запрос и при необходимости присвойте ему Новый МенеджерВременныхТаблиц
- 2Напишите первый запрос пакета с конструкцией ПОМЕСТИТЬ для отбора нужных ссылок
- 3Добавьте через точку с запятой финальный запрос, читающий временную таблицу
- 4Установите все параметры через УстановитьПараметр
- 5Выполните запрос и проверьте результат через Выбрать() или Выгрузить()
Консоль запросов и конструктор: инструменты разработчика
Писать сложный запрос вслепую в модуле — плохая практика. В конфигураторе доступен конструктор запроса: визуальный инструмент, где выбираются таблицы, поля, связи и условия, а текст формируется автоматически. Он вызывается из контекстного меню при редактировании текста запроса в модуле.
Для отладки на реальных данных используют консоль запросов — внешнюю обработку, которая выполняет текст запроса с заданными параметрами и показывает результат в виде таблицы. В типовых конфигурациях на БСП есть встроенная консоль кода/запросов, для остальных случаев существуют общедоступные консоли. Отлаживайте запрос в консоли на копии базы, добейтесь корректного результата и только потом переносите текст в модуль.
Дополнительно полезно смотреть план выполнения запроса на стороне СУБД (для клиент-серверного варианта) или технологический журнал с событиями DBMSSQL/DBPOSTGRS — так видно, какие операции занимают время и где отсутствуют индексы.
При отладке пакетного запроса в консоли выполняйте пакет целиком, а не только финальный запрос — иначе временные таблицы не будут созданы и вы получите ошибку о несуществующей таблице. Многие консоли позволяют просматривать содержимое временных таблиц пакета отдельно, что сильно упрощает поиск ошибки.
Производительность: на что смотреть в первую очередь
Большинство проблем с запросами сводится к нескольким причинам. Первая — соединения и условия по неиндексированным полям: если отбор идёт по реквизиту, по которому нет индекса, СУБД сканирует таблицу целиком. Проверьте, что у реквизитов, участвующих в отборах, включено свойство «Индексировать» (или добавлен индекс в конфигурации).
Вторая — обращение «через точку» к полям составного типа и разыменование в условиях: это порождает дополнительные неявные соединения. Третья — левые соединения больших таблиц без предварительного сужения: сначала сузьте каждую сторону отборами, потом соединяйте. Четвёртая — получение избыточных полей: выбирайте только те колонки, которые реально используются.
И последнее — не забывайте про итоги регистров и режим разделения итогов в клиент-серверном варианте. Запросы к остаткам на актуальную дату при отключённом разделении итогов могут блокировать параллельное проведение документов.
Как проверить результат
Доли секунды — единицы секунд на типовых выборках
Десятки секунд и более на простых отборах — ищите сканирование таблиц
Используются индексы (Index Seek / Index Scan по узкому диапазону)
Полное сканирование крупных таблиц, дорогие соединения
Только нужные колонки, нет обращений через точку в условиях
ВЫБРАТЬ * или разыменование реквизитов в секции ГДЕ
Когда запрос не нужен: альтернативы
Не каждая задача требует объекта Запрос. Получение одного объекта по известной ссылке, обход подчинённых элементов небольшого справочника, чтение реквизитов уже открытого объекта — всё это дешевле и проще сделать объектными средствами. Запрос оправдан там, где нужна выборка по условию, группировка, соединение нескольких источников или агрегатные функции.
Для отчётов вместо программного запроса часто лучше подходит СКД (система компоновки данных): она строится поверх того же языка запросов, но добавляет настройки отборов, группировок и оформления без изменения кода. Программный объект Запрос остаётся для логики проведения, обменов и обработок, где результат нужен в коде, а не на экране.
Как выбрать подход
Частые вопросы о менеджере запросов 1С
Чем объект «Запрос» отличается от консоли запросов?
Объект Запрос — это программный механизм платформы, который выполняет запросы из кода конфигурации. Консоль запросов — инструмент разработчика (обычно внешняя обработка), который использует тот же объект для интерактивной отладки текста запроса и просмотра результатов.
Можно ли через запрос изменить данные в базе?
Нет. Язык запросов 1С предназначен только для чтения: в нём нет аналогов INSERT, UPDATE и DELETE. Изменение данных выполняется объектными средствами (запись документов, наборов записей, элементов справочников).
Почему запрос быстро работает в файловой базе и медленно на сервере?
Файловый вариант выполняет запрос иначе, и на малых объёмах разница незаметна. На клиент-серверном варианте проявляются проблемы плана выполнения: отсутствие индексов, неудачные соединения, отборы в ГДЕ вместо параметров виртуальных таблиц. Анализируйте план запроса на стороне СУБД.
Как передать таблицу значений в запрос?
Установите таблицу значений как параметр, а в тексте запроса выберите из неё поля через конструкцию ПОМЕСТИТЬ: «ВЫБРАТЬ Т.Колонка ПОМЕСТИТЬ ВТ ИЗ &Таблица КАК Т». Далее временная таблица используется в соединениях как обычный источник.
Что такое МенеджерВременныхТаблиц и когда он обязателен?
Это объект, управляющий временными таблицами запроса. Он обязателен, если временные таблицы нужно передавать между разными объектами Запрос или читать их содержимое отдельными запросами. Внутри одного пакетного запроса временные таблицы живут и без явного менеджера.
Как узнать, какой SQL сформировала платформа?
Включите технологический журнал с событиями DBMSSQL (или аналогом для вашей СУБД) — в нём фиксируются фактические обращения к базе. Для клиент-серверного варианта также доступны средства просмотра планов выполнения самой СУБД.
Что важно запомнить
Менеджер запросов 1С — это объект Запрос и язык запросов платформы для чтения данных. Используйте параметры вместо конкатенации, отборы — в параметрах виртуальных таблиц, а сложную логику — через пакетные запросы с временными таблицами. Отлаживайте запросы в консоли на копии базы и проверяйте план выполнения при проблемах со скоростью.