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

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

Как написать запрос в 1С 8.3: руководство с примерами

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

Язык запросов — основной способ получения данных в 1С 8.3: через него строятся отчёты, обработки, динамические списки и проверки внутри проведения документов. Синтаксис напоминает SQL, но оперирует объектами конфигурации — справочниками, документами, регистрами, — а не физическими таблицами базы данных. Это снимает с разработчика заботу о структуре хранения, но требует понимания виртуальных таблиц и типовых конструкций платформы.

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

Где пишутся запросы и как устроен объект Запрос

Текст запроса размещается в модуле — документа, обработки, отчёта или общем модуле. Сам по себе текст — просто строка; выполняет его объект встроенного языка Запрос. Минимальный порядок работы: создать объект, присвоить свойству Текст строку с запросом, установить параметры через УстановитьПараметр(), вызвать Выполнить() и обработать результат через Выбрать() или Выгрузить().

Результат запроса можно получить в трёх формах: выборка (последовательный обход через Выборка.Следующий()), таблица значений (Выгрузить()) или дерево (Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам)). Выборка экономит память на больших объёмах, таблица значений удобнее, когда данные нужно сортировать, искать и выводить на форму.

bsl
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Товар,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Родитель = &Группа";
Запрос.УстановитьПараметр("Группа", ГруппаТоваров);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
 Сообщить(Выборка.Наименование);
КонецЦикла;

Как собрать запрос конструктором

Конструктор запроса — встроенный визуальный инструмент конфигуратора. Он избавляет от необходимости помнить точные имена таблиц и полей и снижает количество синтаксических ошибок. Чтобы открыть его, установите курсор внутрь строки с текстом запроса (или в пустое место модуля), нажмите правую кнопку мыши и выберите «Конструктор запроса».

Порядок действий в конструкторе
  1. 1
    Откройте модуль, поставьте курсор в нужное место, вызовите конструктор запроса через контекстное меню
  2. 2
    На закладке «Таблицы и поля» выберите источник данных слева и перенесите нужные поля в список полей
  3. 3
    На закладке «Условия» задайте отбор, используя параметры вида &ИмяПараметра
  4. 4
    При необходимости настройте закладки «Связи», «Группировка», «Порядок», «Итоги»
  5. 5
    Нажмите «ОК» — конструктор вставит готовый текст запроса в модуль
  6. 6
    Запустите отладку (F5) и проверьте результат на тестовых данных

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

Базовый синтаксис: ВЫБРАТЬ, ИЗ, ГДЕ

Минимальный запрос состоит из секции ВЫБРАТЬ со списком полей и секции ИЗ с указанием источника. Источник записывается через тип объекта и имя: Справочник.Номенклатура, Документ.РеализацияТоваровУслуг, РегистрНакопления.ОстаткиТоваров. После имени таблицы принято указывать псевдоним через КАК — это делает текст читаемым и обязательно при соединениях.

Условия задаются в секции ГДЕ. Операторы сравнения стандартные: =, <>, >, <, а также В для списков и ПОДОБНО для поиска по шаблону строки. Логика объединяется через И, ИЛИ, НЕ. Порядок строк определяет секция УПОРЯДОЧИТЬ ПО, ограничение количества — ВЫБРАТЬ ПЕРВЫЕ 100.

Для проверки заполненности ссылочных полей используйте сравнение со значением ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка). Проверка на NULL уместна только после соединений: Поле ЕСТЬ NULL.

Параметры запроса: зачем нужны и как передавать

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

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

Виртуальные таблицы регистров

Остатки и обороты получают не из физических таблиц регистров, а из виртуальных: РегистрНакопления.ТоварыНаСкладах.Остатки, РегистрНакопления.Продажи.Обороты, РегистрСведений.ЦеныНоменклатуры.СрезПоследних. Виртуальная таблица принимает параметры в скобках — период и условия, например: Остатки(&Дата, Склад = &Склад).

Ключевое правило производительности: условия на измерения передавайте в параметры виртуальной таблицы, а не в секцию ГДЕ всего запроса. Фильтр в параметрах отсекает данные на этапе расчёта виртуальной таблицы; фильтр в ГДЕ заставляет платформу сначала вычислить остатки по всей базе, а потом отбрасывать лишнее — на больших регистрах разница по времени многократная.

Соединения и объединения таблиц

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

Условие связи пишется в секции ПО: ПО Товары.Номенклатура = Цены.Номенклатура. Отсутствие или неполнота условия связи — классическая причина «дублирования» строк: декартово произведение перемножает каждую строку левой таблицы на каждую строку правой.

Объединение наборов строк выполняется через ОБЪЕДИНИТЬ ВСЕ (сохраняет дубли, работает быстрее) или ОБЪЕДИНИТЬ (убирает дубли, требует дополнительной обработки). Количество и типы полей во всех объединяемых запросах должны совпадать.

Типичные ошибки
01
Условие на измерения в ГДЕ вместо параметров виртуальной таблицы — запрос обсчитывает весь регистр и работает в разы медленнее
02
Соединение без полного ключа — строки задваиваются, суммы в отчёте завышаются
03
Получение данных через точку от ссылки (Товар.Наименование вместо соединения) — платформа генерирует скрытые соединения, запрос деградирует
04
Обход результата и вызов запросов внутри цикла — сотни обращений к СУБД вместо одного
05
Сравнение составного поля с конкретным типом без ВЫРАЗИТЬ — условие не срабатывает или падает с ошибкой

Группировки, итоги и проверка результата

Агрегирование выполняется функциями СУММА, КОЛИЧЕСТВО, СРЕДНЕЕ, МАКСИМУМ, МИНИМУМ вместе с секцией СГРУППИРОВАТЬ ПО. Правило: все поля в списке выборки либо входят в группировку, либо обёрнуты агрегатной функцией. Условие на агрегаты задаётся через ИМЕЮЩИЕ, а не ГДЕ.

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

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

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

Количество строк результата
Норма

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

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

Строк больше из-за дублей соединения или меньше из-за лишнего отбора

Суммы по группам
Норма

Сходятся с типовым отчётом конфигурации за тот же период

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

Расхождения — проверьте параметры виртуальной таблицы и период

Время выполнения
Норма

Запрос с отборами отрабатывает быстро на реальном объёме данных

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

Заметная пауза — условия не в параметрах виртуальной таблицы или нет индекса по полю связи

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

Итог

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

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

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

Чем запрос отличается от СКД?

Запрос — это текст на языке запросов, который выбирает данные. СКД (система компоновки данных) — надстройка, которая использует запрос как источник и добавляет настройки отбора, группировок и оформления без изменения кода. Для отчётов, которые будут настраивать пользователи, выбирайте СКД; для программной выборки внутри алгоритма достаточно объекта Запрос.

Как выбрать данные за период?

Для документов добавьте условие ГДЕ Документ.Дата МЕЖДУ &Начало И &Конец, передав границы параметрами. Для регистров накопления используйте виртуальную таблицу Обороты с параметрами периода: Обороты(&Начало, &Конец, , ) — так платформа рассчитает только нужный интервал.

Почему запрос возвращает NULL и как это обработать?

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

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

Да, через ОБЪЕДИНИТЬ ВСЕ, но состав и порядок полей во всех частях должны совпадать. Недостающие поля дополняйте константами или NULL с приведением типа через ВЫРАЗИТЬ(NULL КАК Число(15,2)), иначе получите ошибку несовместимости типов.

Где смотреть текст запроса, который платформа строит для динамического списка?

Текст динамического списка задаётся в свойстве «Произвольный запрос» в настройках списка на форме. Если флаг снят, платформа строит запрос автоматически по основной таблице. Для отладки скопируйте текст в консоль запросов и выполните с теми же параметрами отбора.

Что делать, если запрос работает медленно?

Сначала проверьте, что условия по измерениям регистров стоят в параметрах виртуальных таблиц, а не в секции ГДЕ. Затем уберите обращения через точку к полям ссылок и замените их соединениями. Если этого недостаточно, разбейте запрос на этапы с временными таблицами через менеджер временных таблиц — это упрощает план выполнения на сложных выборках.