Конструктор запросов в 1С: от первого запроса до временных таблиц
Содержание
Конструктор запросов собирает текст запроса на языке 1С мышкой: выбираете таблицы, перетаскиваете поля, расставляете условия и соединения — система сама пишет корректный синтаксис с ВЫБРАТЬ, ИЗ, ГДЕ. Открывается он правым щелчком в тексте модуля, в консоли запросов и в схеме компоновки данных.
Разберём по шагам: где вызвать конструктор в 1С 8.3, что делает каждая вкладка, как создать простой запрос, соединить таблицы, посчитать итоги , подставить параметры и не посадить производительность на медленных конструкциях.
Где открыть конструктор запросов в 1С 8.3
Инструмент один, но точек входа несколько — зависит от того, где вы пишете запрос.
- 🧩 В Конфигураторе или 1С:EDT, в модуле. Напишите
Запрос = Новый Запрос;и присвоениеЗапрос.Текст = "";. Поставьте курсор внутрь кавычек, нажмите правую кнопку →Конструктор запроса. Если текста ещё нет — конструктор создаст новый; если текст уже есть — откроет его для правки. - 🧩 Конструктор запроса с обработкой результата. В том же контекстном меню. Он генерирует не только текст, но и обвязку: создание объекта
Запрос, выполнение и циклПока Выборка.Следующий() Цикл. Удобно для первого каркаса кода. - 🧩 Консоль запросов. Внешняя обработка (не входит в типовую поставку, берётся на диске ИТС). Открываете её в режиме
1С:Предприятие, жмёте кнопку конструктора над полем текста и сразу прогоняете запрос по рабочим данным, не трогая код. - 🧩 Схема компоновки данных (СКД). В наборе данных типа «Запрос» есть кнопка
Конструктор запроса. Там же доступен расширенныйКонструктор запроса компоновки данных— с вкладками для вычисляемых полей и настроек отчёта. - 🧩 Динамический список формы. В свойстве списка
Настройка списка→Открытьвызывается тот же конструктор, когда список строится произвольным запросом.
Если пункт Конструктор запроса в меню серый — курсор стоит не внутри строкового литерала. Кликните между кавычек в Запрос.Текст.
Из каких вкладок состоит окно конструктора
Слева — дерево доступных таблиц (справочники, документы, регистры, их табличные части и виртуальные таблицы). В центре — поля выбранной таблицы. Справа собирается результат. Сверху — вкладки, каждая отвечает за свою часть запроса.
| Вкладка | За что отвечает | Какой оператор формирует |
|---|---|---|
| Таблицы и поля | источники и выбираемые поля | ВЫБРАТЬ … ИЗ |
| Связи | соединения нескольких таблиц | СОЕДИНЕНИЕ … ПО |
| Условия | отбор строк | ГДЕ |
| Группировка | свёртка по полям | СГРУППИРОВАТЬ ПО |
| Объединения/Псевдонимы | склейка запросов, имена полей | ОБЪЕДИНИТЬ, КАК |
| Порядок | сортировка результата | УПОРЯДОЧИТЬ ПО |
| Итоги | многоуровневые итоги | ИТОГИ … ПО |
| Дополнительно | РАЗЛИЧНЫЕ, ПЕРВЫЕ N | модификаторы выборки |
Вкладка Связи появляется, только когда таблиц в запросе больше одной. Вкладка Порядок и флажок Автоупорядочивание управляют сортировкой — без них порядок строк не гарантирован.
Создание простого запроса: пошаговая инструкция
Соберём выборку номенклатуры без пометки удаления.
- На вкладке
Таблицы и поляраскройте веткуСправочникии перетащитеНоменклатурав среднюю колонку «Таблицы». - Из списка полей перетащите в правую колонку
Ссылка,Наименование,Артикул. - Перейдите на вкладку
Условия, перетащите туда полеПометкаУдаления. В строке условия включите флажок «Произвольное» и впишитеНЕ Номенклатура.ПометкаУдаления. - На вкладке
ПорядокдобавьтеНаименованиедля сортировки по алфавиту. - Нажмите
ОК— конструктор вставит готовый текст в модуль.
Результат выглядит так:
ВЫБРАТЬ
Номенклатура.Ссылка,
Номенклатура.Наименование,
Номенклатура.Артикул
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
НЕ Номенклатура.ПометкаУдаления
УПОРЯДОЧИТЬ ПО
Номенклатура.Наименование
КАК Номенклатура — это псевдоним таблицы. Конструктор назначает его автоматически, через псевдоним удобнее обращаться к полям. Готовый текст всегда можно открыть конструктором повторно — он разберёт его обратно по вкладкам, если синтаксис корректен.
Соединения таблиц: левое, внутреннее и полное
Когда данные лежат в разных таблицах, их связывают на вкладке Связи. Добавьте вторую таблицу на Таблицы и поля, вернитесь на Связи и задайте условие соединения — обычно равенство ключевых полей.
Тип соединения определяют два флажка «Все» у левой и правой таблицы:
- Оба флажка сняты — внутреннее соединение (
ВНУТРЕННЕЕ СОЕДИНЕНИЕ). В результат попадут только строки, для которых есть пара в обеих таблицах. - Флажок «Все» у левой таблицы — левое соединение (
ЛЕВОЕ СОЕДИНЕНИЕ). Берутся все строки левой таблицы, недостающие поля правой заполняютсяNULL. - Флажок у правой — правое соединение. На практике его переворачивают в левое, меняя таблицы местами.
- Оба флажка — полное соединение (
ПОЛНОЕ СОЕДИНЕНИЕ): все строки обеих таблиц.
Пример: строки реализации и цена номенклатуры из регистра сведений.
ВЫБРАТЬ
Товары.Номенклатура,
Товары.Количество,
Цены.Цена
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Товары
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК Цены
ПО Товары.Номенклатура = Цены.Номенклатура
После левого соединения в поле Цена могут появиться NULL — там, где цены нет. Оборачивайте такие поля в ЕСТЬNULL(Цены.Цена, 0), иначе арифметика и сравнения дадут неожиданный результат.
Частая ошибка новичков — обращаться к реквизиту ссылочного поля через точку: Товары.Номенклатура.Артикул. Платформа молча добавляет левое соединение со справочником. Для одного-двух полей это терпимо, но в отчёте на тысячи строк такие «точки» заметно тормозят — лучше соединить таблицы явно.
Агрегатные функции и группировка данных
Чтобы свернуть строки и посчитать суммы, количество или максимум, нужна группировка. Перенесите поля на вкладку Группировка: часть — в «Группировочные поля», часть — в «Суммируемые поля», выбрав для них функцию.
Доступны СУММА, КОЛИЧЕСТВО, МИНИМУМ, МАКСИМУМ, СРЕДНЕЕ. Для подсчёта уникальных значений — КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Поле).
ВЫБРАТЬ
Продажи.Номенклатура,
СУММА(Продажи.Количество) КАК Количество,
СУММА(Продажи.Сумма) КАК Сумма
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Продажи
СГРУППИРОВАТЬ ПО
Продажи.Номенклатура
Правило простое: каждое поле в ВЫБРАТЬ либо стоит под агрегатной функцией, либо перечислено в СГРУППИРОВАТЬ ПО. Нарушите — конструктор или платформа выдадут ошибку о недопустимом поле в списке группировки.
Не путайте группировку с вкладкой Итоги. Итоги добавляют к детальным строкам отдельные итоговые строки по иерархии (ИТОГИ СУММА(…) ПО …) — они нужны отчётам, а не обычной выборке в коде.
Параметры запроса и виртуальные таблицы
Жёстко зашитые даты и значения в тексте запроса — плохая идея. Вместо них ставят параметры: имя со знаком &. В условии выберите поле, в правой части укажите &НачалоПериода, &КонецПериода и так далее.
ГДЕ
Продажи.Дата МЕЖДУ &НачалоПериода И &КонецПериода
В коде значения передаются до выполнения:
Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(ДатаОтчёта));
Запрос.УстановитьПараметр("КонецПериода", КонецДня(ДатаОтчёта));
Результат = Запрос.Выполнить();
Отдельная история — параметры виртуальных таблиц. У регистров есть виртуальные таблицы: Остатки, Обороты, ОстаткиИОбороты, СрезПоследних, СрезПервых. Когда вы перетаскиваете такую таблицу, на вкладке Таблицы и поля становится активной кнопка Параметры виртуальной таблицы. Период и условия отбора задавайте именно там — платформа применит их внутри, до расчёта итогов. Это быстрее, чем фильтровать результат в ГДЕ.
ВЫБРАТЬ
Остатки.Номенклатура,
Остатки.Склад,
Остатки.КоличествоОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &Склад) КАК Остатки
&Период в виртуальной таблице остатков — это момент, НА который считается остаток. Для оборотов за интервал используйте таблицу Обороты с двумя границами периода.
Временные таблицы, пакеты и подзапросы
Для сложной логики один запрос разбивают на пакет. Включите режим пакетного запроса — в конструкторе появится область Пакет запросов сверху, где запросы добавляются по очереди. Результат любого из них можно положить во временную таблицу оператором ПОМЕСТИТЬ, а следующий запрос уже читает её.
ВЫБРАТЬ
Товары.Номенклатура,
Товары.Количество
ПОМЕСТИТЬ ВременныеТовары
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
Товары.Ссылка.Проведён
;
ВЫБРАТЬ
ВременныеТовары.Номенклатура,
СУММА(ВременныеТовары.Количество) КАК Количество
ИЗ
ВременныеТовары КАК ВременныеТовары
СГРУППИРОВАТЬ ПО
ВременныеТовары.Номенклатура
Чтобы временные таблицы жили между запросами пакета, объекту Запрос назначают менеджер:
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Рядом с временными таблицами работают подзапросы и объединения. Подзапрос — это запрос внутри секции ИЗ или ГДЕ, его тоже можно собрать конструктором (кнопка создания вложенного запроса в области таблиц). Объединение складывает результаты нескольких запросов: ОБЪЕДИНИТЬ ВСЕ оставляет все строки и работает быстрее, ОБЪЕДИНИТЬ дополнительно убирает дубли. Для больших выборок почти всегда нужен ОБЪЕДИНИТЬ ВСЕ.
При объединении важно, чтобы все запросы отдавали одинаковое число полей в одном порядке и совместимых типов — иначе платформа откажется собирать текст. Имена колонок берутся из первого запроса, поэтому псевдонимы задавайте именно в нём.
Практическое правило: если в одном запросе появляется соединение с подзапросом, который сам содержит группировку, вынесите подзапрос во временную таблицу. Читается легче, и платформе проще построить план.
Оптимизация запросов и типичные ошибки
У конструктора нет собственного окна с планом выполнения — его показывает СУБД. Чтобы увидеть, как запрос отработал на SQL Server, снимают план через профилировщик СУБД или анализируют замер в технологическом журнале. Внутри самой 1С ориентируются на время выполнения и на правила, которые почти всегда дают эффект.
Прежде чем встраивать запрос в код, прогоните его в консоли запросов на рабочей копии базы. Консоль показывает число полученных строк и время выполнения — этого достаточно, чтобы сравнить два варианта одного запроса и выбрать быстрый. Там же удобно подобрать значения параметров и убедиться, что отбор отсекает именно то, что нужно. Если строк вернулось заметно больше ожидаемого — почти всегда виновата кратность соединения.
Чего избегать:
- ❌ Соединения с подзапросами и виртуальными таблицами. СУБД плохо оценивает их размер. Выносите промежуточный результат во временную таблицу и соединяйтесь с ней.
- ❌ Получение данных через точку от ссылки (
Док.Контрагент.ИНН). Каждая точка — скрытое левое соединение. На объёмах заменяйте явными соединениями. - ❌ Фильтр по вычисляемому полю в
ГДЕ. Условие по выражению, а не по индексируемому полю, заставляет СУБД читать всю таблицу. - ❌ Отбор в
ГДЕвместо параметров виртуальной таблицы. Регистр сначала посчитает итоги по всем данным, и только потом вы их отфильтруете. - ❌
ВЫБРАТЬ *— в языке 1С звёздочки нет, но привычка тянуть все поля сохраняется. Берите только нужные колонки.
Ещё две ошибки, которые ломают уже не скорость, а результат. Первая — потерянные NULL после внешних соединений: без ЕСТЬNULL суммы занижаются, а условия = 0 не срабатывают. Вторая — неуникальная связь, когда одной строке слева соответствует несколько справа: строки задваиваются, и СУММА завышается в разы. Проверяйте кратность соединений до того, как доверитесь цифрам.
Частые вопросы
Можно ли редактировать текст запроса руками, а потом снова открыть конструктором?
Чем конструктор запроса отличается от конструктора с обработкой результата?
Запрос, установку параметров, Выполнить() и цикл обхода выборки. Второй удобен для быстрого каркаса, но сгенерированный цикл обычно приходится дорабатывать.Почему в условиях нельзя писать конкретную дату, а нужен параметр?
&Дата подставляется до выполнения и позволяет переиспользовать запрос с разными значениями. Зашитая дата делает запрос одноразовым, а строковые даты в тексте ещё и приводят к ошибкам преобразования типов.Как отобрать только первые N строк?
Дополнительно укажите число в поле «Количество» (оператор ПЕРВЫЕ N). Чтобы результат был предсказуемым, обязательно задайте сортировку на вкладке Порядок — без неё «первые» строки произвольны.В выборке задвоились строки — что проверить?
РАЗЛИЧНЫЕ на вкладке Дополнительно.