Конструктор запросов в 1С: от первого запроса до временных таблиц

· 9 мин

Содержание

Конструктор запросов собирает текст запроса на языке 1С мышкой: выбираете таблицы, перетаскиваете поля, расставляете условия и соединения — система сама пишет корректный синтаксис с ВЫБРАТЬ, ИЗ, ГДЕ. Открывается он правым щелчком в тексте модуля, в консоли запросов и в схеме компоновки данных.

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

Где открыть конструктор запросов в 1С 8.3

Инструмент один, но точек входа несколько — зависит от того, где вы пишете запрос.

  • 🧩 В Конфигураторе или 1С:EDT, в модуле. Напишите Запрос = Новый Запрос; и присвоение Запрос.Текст = "";. Поставьте курсор внутрь кавычек, нажмите правую кнопку → Конструктор запроса. Если текста ещё нет — конструктор создаст новый; если текст уже есть — откроет его для правки.
  • 🧩 Конструктор запроса с обработкой результата. В том же контекстном меню. Он генерирует не только текст, но и обвязку: создание объекта Запрос, выполнение и цикл Пока Выборка.Следующий() Цикл. Удобно для первого каркаса кода.
  • 🧩 Консоль запросов. Внешняя обработка (не входит в типовую поставку, берётся на диске ИТС). Открываете её в режиме 1С:Предприятие, жмёте кнопку конструктора над полем текста и сразу прогоняете запрос по рабочим данным, не трогая код.
  • 🧩 Схема компоновки данных (СКД). В наборе данных типа «Запрос» есть кнопка Конструктор запроса. Там же доступен расширенный Конструктор запроса компоновки данных — с вкладками для вычисляемых полей и настроек отчёта.
  • 🧩 Динамический список формы. В свойстве списка Настройка списка → Открыть вызывается тот же конструктор, когда список строится произвольным запросом.

Если пункт Конструктор запроса в меню серый — курсор стоит не внутри строкового литерала. Кликните между кавычек в Запрос.Текст.

Из каких вкладок состоит окно конструктора

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

ВкладкаЗа что отвечаетКакой оператор формирует
Таблицы и поляисточники и выбираемые поляВЫБРАТЬ … ИЗ
Связисоединения нескольких таблицСОЕДИНЕНИЕ … ПО
Условияотбор строкГДЕ
Группировкасвёртка по полямСГРУППИРОВАТЬ ПО
Объединения/Псевдонимысклейка запросов, имена полейОБЪЕДИНИТЬ, КАК
Порядоксортировка результатаУПОРЯДОЧИТЬ ПО
Итогимногоуровневые итогиИТОГИ … ПО
ДополнительноРАЗЛИЧНЫЕ, ПЕРВЫЕ Nмодификаторы выборки

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

Создание простого запроса: пошаговая инструкция

Соберём выборку номенклатуры без пометки удаления.

  1. На вкладке Таблицы и поля раскройте ветку Справочники и перетащите Номенклатура в среднюю колонку «Таблицы».
  2. Из списка полей перетащите в правую колонку Ссылка, Наименование, Артикул.
  3. Перейдите на вкладку Условия, перетащите туда поле ПометкаУдаления. В строке условия включите флажок «Произвольное» и впишите НЕ Номенклатура.ПометкаУдаления.
  4. На вкладке Порядок добавьте Наименование для сортировки по алфавиту.
  5. Нажмите ОК — конструктор вставит готовый текст в модуль.

Результат выглядит так:

ВЫБРАТЬ
    Номенклатура.Ссылка,
    Номенклатура.Наименование,
    Номенклатура.Артикул
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    НЕ Номенклатура.ПометкаУдаления
УПОРЯДОЧИТЬ ПО
    Номенклатура.Наименование

КАК Номенклатура — это псевдоним таблицы. Конструктор назначает его автоматически, через псевдоним удобнее обращаться к полям. Готовый текст всегда можно открыть конструктором повторно — он разберёт его обратно по вкладкам, если синтаксис корректен.

Соединения таблиц: левое, внутреннее и полное

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

Тип соединения определяют два флажка «Все» у левой и правой таблицы:

  • Оба флажка сняты — внутреннее соединение (ВНУТРЕННЕЕ СОЕДИНЕНИЕ). В результат попадут только строки, для которых есть пара в обеих таблицах.
  • Флажок «Все» у левой таблицы — левое соединение (ЛЕВОЕ СОЕДИНЕНИЕ). Берутся все строки левой таблицы, недостающие поля правой заполняются NULL.
  • Флажок у правой — правое соединение. На практике его переворачивают в левое, меняя таблицы местами.
  • Оба флажка — полное соединение (ПОЛНОЕ СОЕДИНЕНИЕ): все строки обеих таблиц.

Пример: строки реализации и цена номенклатуры из регистра сведений.

ВЫБРАТЬ
    Товары.Номенклатура,
    Товары.Количество,
    Цены.Цена
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК Товары
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК Цены
    ПО Товары.Номенклатура = Цены.Номенклатура

После левого соединения в поле Цена могут появиться NULL — там, где цены нет. Оборачивайте такие поля в ЕСТЬNULL(Цены.Цена, 0), иначе арифметика и сравнения дадут неожиданный результат.

Частая ошибка новичков — обращаться к реквизиту ссылочного поля через точку: Товары.Номенклатура.Артикул. Платформа молча добавляет левое соединение со справочником. Для одного-двух полей это терпимо, но в отчёте на тысячи строк такие «точки» заметно тормозят — лучше соединить таблицы явно.

Агрегатные функции и группировка данных

Чтобы свернуть строки и посчитать суммы, количество или максимум, нужна группировка. Перенесите поля на вкладку Группировка: часть — в «Группировочные поля», часть — в «Суммируемые поля», выбрав для них функцию.

Доступны СУММА, КОЛИЧЕСТВО, МИНИМУМ, МАКСИМУМ, СРЕДНЕЕ. Для подсчёта уникальных значений — КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Поле).

ВЫБРАТЬ
    Продажи.Номенклатура,
    СУММА(Продажи.Количество) КАК Количество,
    СУММА(Продажи.Сумма) КАК Сумма
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК Продажи
СГРУППИРОВАТЬ ПО
    Продажи.Номенклатура

Правило простое: каждое поле в ВЫБРАТЬ либо стоит под агрегатной функцией, либо перечислено в СГРУППИРОВАТЬ ПО. Нарушите — конструктор или платформа выдадут ошибку о недопустимом поле в списке группировки.

Не путайте группировку с вкладкой Итоги. Итоги добавляют к детальным строкам отдельные итоговые строки по иерархии (ИТОГИ СУММА(…) ПО …) — они нужны отчётам, а не обычной выборке в коде.

Параметры запроса и виртуальные таблицы

Жёстко зашитые даты и значения в тексте запроса — плохая идея. Вместо них ставят параметры: имя со знаком &. В условии выберите поле, в правой части укажите &НачалоПериода, &КонецПериода и так далее.

ГДЕ
    Продажи.Дата МЕЖДУ &НачалоПериода И &КонецПериода

В коде значения передаются до выполнения:

Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(ДатаОтчёта));
Запрос.УстановитьПараметр("КонецПериода",  КонецДня(ДатаОтчёта));
Результат = Запрос.Выполнить();

Отдельная история — параметры виртуальных таблиц. У регистров есть виртуальные таблицы: Остатки, Обороты, ОстаткиИОбороты, СрезПоследних, СрезПервых. Когда вы перетаскиваете такую таблицу, на вкладке Таблицы и поля становится активной кнопка Параметры виртуальной таблицы. Период и условия отбора задавайте именно там — платформа применит их внутри, до расчёта итогов. Это быстрее, чем фильтровать результат в ГДЕ.

ВЫБРАТЬ
    Остатки.Номенклатура,
    Остатки.Склад,
    Остатки.КоличествоОстаток
ИЗ
    РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &Склад) КАК Остатки

&Период в виртуальной таблице остатков — это момент, НА который считается остаток. Для оборотов за интервал используйте таблицу Обороты с двумя границами периода.

Временные таблицы, пакеты и подзапросы

Для сложной логики один запрос разбивают на пакет. Включите режим пакетного запроса — в конструкторе появится область Пакет запросов сверху, где запросы добавляются по очереди. Результат любого из них можно положить во временную таблицу оператором ПОМЕСТИТЬ, а следующий запрос уже читает её.

ВЫБРАТЬ
    Товары.Номенклатура,
    Товары.Количество
ПОМЕСТИТЬ ВременныеТовары
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
    Товары.Ссылка.Проведён
;

ВЫБРАТЬ
    ВременныеТовары.Номенклатура,
    СУММА(ВременныеТовары.Количество) КАК Количество
ИЗ
    ВременныеТовары КАК ВременныеТовары
СГРУППИРОВАТЬ ПО
    ВременныеТовары.Номенклатура

Чтобы временные таблицы жили между запросами пакета, объекту Запрос назначают менеджер:

Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;

Рядом с временными таблицами работают подзапросы и объединения. Подзапрос — это запрос внутри секции ИЗ или ГДЕ, его тоже можно собрать конструктором (кнопка создания вложенного запроса в области таблиц). Объединение складывает результаты нескольких запросов: ОБЪЕДИНИТЬ ВСЕ оставляет все строки и работает быстрее, ОБЪЕДИНИТЬ дополнительно убирает дубли. Для больших выборок почти всегда нужен ОБЪЕДИНИТЬ ВСЕ.

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

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

Оптимизация запросов и типичные ошибки

У конструктора нет собственного окна с планом выполнения — его показывает СУБД. Чтобы увидеть, как запрос отработал на SQL Server, снимают план через профилировщик СУБД или анализируют замер в технологическом журнале. Внутри самой 1С ориентируются на время выполнения и на правила, которые почти всегда дают эффект.

Прежде чем встраивать запрос в код, прогоните его в консоли запросов на рабочей копии базы. Консоль показывает число полученных строк и время выполнения — этого достаточно, чтобы сравнить два варианта одного запроса и выбрать быстрый. Там же удобно подобрать значения параметров и убедиться, что отбор отсекает именно то, что нужно. Если строк вернулось заметно больше ожидаемого — почти всегда виновата кратность соединения.

Чего избегать:

  • ❌ Соединения с подзапросами и виртуальными таблицами. СУБД плохо оценивает их размер. Выносите промежуточный результат во временную таблицу и соединяйтесь с ней.
  • ❌ Получение данных через точку от ссылки (Док.Контрагент.ИНН). Каждая точка — скрытое левое соединение. На объёмах заменяйте явными соединениями.
  • ❌ Фильтр по вычисляемому полю в ГДЕ. Условие по выражению, а не по индексируемому полю, заставляет СУБД читать всю таблицу.
  • ❌ Отбор в ГДЕ вместо параметров виртуальной таблицы. Регистр сначала посчитает итоги по всем данным, и только потом вы их отфильтруете.
  • ❌ ВЫБРАТЬ * — в языке 1С звёздочки нет, но привычка тянуть все поля сохраняется. Берите только нужные колонки.
Проверьте себя
Какой оператор помещает результат запроса во временную таблицу?
Чем `ОБЪЕДИНИТЬ ВСЕ` отличается от `ОБЪЕДИНИТЬ`?
Что вернёт поле правой таблицы при левом соединении, если пары нет?

Ещё две ошибки, которые ломают уже не скорость, а результат. Первая — потерянные NULL после внешних соединений: без ЕСТЬNULL суммы занижаются, а условия = 0 не срабатывают. Вторая — неуникальная связь, когда одной строке слева соответствует несколько справа: строки задваиваются, и СУММА завышается в разы. Проверяйте кратность соединений до того, как доверитесь цифрам.

Частые вопросы

Можно ли редактировать текст запроса руками, а потом снова открыть конструктором?
Да. Конструктор разбирает корректный текст обратно по вкладкам. Если он отказывается открыть запрос — в тексте синтаксическая ошибка или конструкция, которую конструктор не поддерживает (например, часть возможностей языка доступна только вручную).
Чем конструктор запроса отличается от конструктора с обработкой результата?
Первый вставляет только текст запроса в кавычках. Второй дополнительно генерирует код: объект Запрос, установку параметров, Выполнить() и цикл обхода выборки. Второй удобен для быстрого каркаса, но сгенерированный цикл обычно приходится дорабатывать.
Почему в условиях нельзя писать конкретную дату, а нужен параметр?
Параметр &Дата подставляется до выполнения и позволяет переиспользовать запрос с разными значениями. Зашитая дата делает запрос одноразовым, а строковые даты в тексте ещё и приводят к ошибкам преобразования типов.
Как отобрать только первые N строк?
На вкладке Дополнительно укажите число в поле «Количество» (оператор ПЕРВЫЕ N). Чтобы результат был предсказуемым, обязательно задайте сортировку на вкладке Порядок — без неё «первые» строки произвольны.
В выборке задвоились строки — что проверить?
Соединение с таблицей, где ключ не уникален: одной строке слева соответствует несколько справа. Либо добавьте условие, делающее связь однозначной, либо сгруппируйте результат. Для устранения полных дублей поможет РАЗЛИЧНЫЕ на вкладке Дополнительно.