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

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

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

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

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

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

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

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

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

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

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

Как создать запрос через конструктор

Конструктор запроса — встроенный инструмент конфигуратора. Чтобы открыть его, поставьте курсор в модуль, нажмите правую кнопку мыши и выберите «Конструктор запроса». Если текст запроса уже написан, конструктор разберёт его и покажет в визуальном виде; если нет — предложит создать новый.

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

Конструктор особенно полезен на этапе изучения: он не допускает синтаксических ошибок и показывает все доступные поля объекта, включая реквизиты и табличные части. Для табличной части документа источник указывается через точку: Документ.РеализацияТоваровУслуг.Товары.

Ограничение конструктора — он не всегда генерирует оптимальный текст. Соединения, вложенные запросы и выражения с ВЫБОР часто удобнее дорабатывать вручную после того, как каркас готов.

Выполнение запроса из встроенного языка

Чтобы запрос заработал в коде, создают объект встроенного языка, присваивают текст, передают параметры и выполняют. Типовой шаблон выглядит так:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Товар,

| Номенклатура.Артикул КАК Артикул

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| Номенклатура.Родитель = &Группа

| И НЕ Номенклатура.ПометкаУдаления";

Запрос.УстановитьПараметр("Группа", ГруппаТоваров);

Результат = Запрос.Выполнить();

Выборка = Результат.Выбрать();

Пока Выборка.Следующий() Цикл

Сообщить(Выборка.Товар);

КонецЦикла;

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

Отборы, параметры и работа со списками

Секция ГДЕ фильтрует строки результата. Условия объединяют операторами И, ИЛИ, НЕ, сравнивают значения знаками =, <>, >, <, а для строк используют ПОДОБНО с шаблоном: Наименование ПОДОБНО "%кабель%".

Для отбора по списку значений применяют конструкцию В (&СписокЗначений), а в параметр передают массив или список значений. Для проверки вхождения в иерархию справочника используют оператор В ИЕРАРХИИ — например, Товар В ИЕРАРХИИ (&Группа) выберет элементы группы и всех её подгрупп.

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

Соединения, группировки и итоги

Когда данные лежат в разных объектах, таблицы соединяют. ЛЕВОЕ СОЕДИНЕНИЕ возвращает все строки левой таблицы, подставляя NULL, если пары нет; ВНУТРЕННЕЕ — только совпадающие строки. Условие связи пишут в секции ПО: Реализация.Контрагент = Контрагенты.Ссылка.

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

Секция ИТОГИ ПО строит иерархические итоги без группировки детальных строк: запрос вернёт и сами записи, и промежуточные суммы по указанным полям. Это удобно для отчётов вида «менеджер — его документы — сумма по менеджеру». Общий итог добавляется фразой ОБЩИЕ.

Выбор способа обхода результата

Выбрать() — выборка

Подходит для последовательной обработки больших объёмов: не загружает всё в память, но доступ только вперёд по строкам

Выгрузить() — таблица значений

Удобна для сортировки, поиска и многократного обхода, но весь результат загружается в память

Выгрузить по группировкам — дерево

Нужна при секции ИТОГИ: сохраняет иерархию итоговых строк для вывода в отчёт

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

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

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

Несколько запросов можно объединить в пакет через точку с запятой. Промежуточные результаты помещают во временные таблицы ключевым словом ПОМЕСТИТЬ, а затем используют в следующих запросах пакета. Это основной приём оптимизации: сначала отбирают узкий набор данных во временную таблицу с индексацией, потом соединяют её с большими таблицами.

Типичные ошибки и как проверить результат

Самая частая ошибка — соединение с виртуальной таблицей без параметров отбора, из-за чего запрос обрабатывает весь регистр. Вторая — использование соединений вместо параметров там, где достаточно условия ГДЕ. Третья — обращение к полям через точку от ссылки («разыменование») в условиях: это порождает неявные соединения и замедляет выполнение.

Типичные ошибки
01
Условия на виртуальную таблицу в секции ГДЕ вместо параметров — запрос сканирует весь регистр
02
Подстановка значений в текст запроса конкатенацией вместо параметров — ошибки типов и риск некорректных данных
03
Отсутствие проверки на NULL после левого соединения — сравнение с NULL всегда даёт ложь
04
Использование Выгрузить() для миллионов строк — переполнение памяти вместо потоковой выборки
05
Отсутствие индексации временной таблицы — медленные соединения в пакетном запросе

Проверять результат удобно в консоли запросов: выполните текст с теми же параметрами, что и в коде, и сравните количество строк и итоговые суммы с данными стандартных отчётов. Для поиска проблем производительности используйте технологический журнал и замеры производительности в конфигураторе (Отладка — Замер производительности).

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

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

Количество строк выборки
Норма

Совпадает с ожидаемым числом записей по отбору

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

Строк больше — вероятно, дубли из-за соединения без уникального ключа

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

Сходятся с типовым отчётом за тот же период

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

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

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

Запрос отрабатывает за секунды на рабочем объёме данных

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

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

Частые вопросы о запросах в 1С

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

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

Как вывести только первые N строк результата?

Используйте конструкцию ПЕРВЫЕ после слова ВЫБРАТЬ: ВЫБРАТЬ ПЕРВЫЕ 10. Обычно её сочетают с УПОРЯДОЧИТЬ ПО, чтобы получить осмысленную выборку — например, десять последних документов по дате.

Как объединить результаты двух запросов?

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

Почему в поле соединения приходит NULL и как это обработать?

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

Можно ли выполнить запрос без прав на объект?

Нет: в обычном режиме платформа применяет права доступа, и запрос по недоступному объекту вызовет ошибку. Обход возможен только в привилегированном режиме (УстановитьПривилегированныйРежим), который следует использовать осознанно и только в серверном коде.

Где хранить текст запроса: в коде или в макете?

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

Итог

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

Запрос в 1С выполняется через объект Запрос: текст, параметры, Выполнить(). Каркас удобно собирать конструктором, условия на виртуальные таблицы задавать в их параметрах, значения передавать только через параметры, а результат проверять в консоли запросов на копии базы.