Разработка и Конфигурация · 12 мин
Как сформировать запрос в 1С: пошаговое руководство
Как сформировать запрос в 1С: конструктор запросов, язык запросов, примеры кода, типичные ошибки и проверка результата. Практическое руководство для новичков.
Запрос в 1С — основной инструмент для получения данных из информационной базы: остатков по складу, оборотов по счетам, списков документов и справочников. Без запросов не обходится ни один отчёт, ни одна обработка и практически ни один модуль конфигурации. При этом синтаксис языка запросов 1С похож на SQL, но имеет собственные особенности: виртуальные таблицы, параметризацию, разделы итогов и обращение к реквизитам через точку.
Сформировать запрос можно двумя способами: визуально через встроенный конструктор запросов или вручную, написав текст на языке запросов. Первый вариант подходит новичкам и помогает избежать синтаксических ошибок, второй даёт полный контроль и нужен для сложных выборок. Ниже разобраны оба подхода, структура текста запроса, работа с параметрами и типичные ошибки, из-за которых запрос возвращает пустой или неверный результат.
Где и как создаётся запрос в 1С
Запрос создаётся программно — в модуле объекта, формы, общем модуле или внешней обработке. Для этого используется встроенный объект Запрос. Минимальный сценарий выглядит так: создать объект, присвоить текст запроса, установить параметры, выполнить и обработать результат.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Товар,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ПометкаУдаления";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Наименование);
КонецЦикла;
Обратите внимание: текст запроса в модуле обрамляется вертикальными чертами | в начале каждой строки — это особенность литеральных строк в 1С. Если текст написан без них, платформа выдаст синтаксическую ошибку ещё до выполнения.
Как сформировать запрос через конструктор
Конструктор запросов — самый быстрый способ собрать корректный текст без знания синтаксиса наизусть. Он доступен в конфигураторе и вызывается из любого модуля.
- 1В модуле напишите Запрос.Текст = ""; и поставьте курсор между кавычками
- 2Нажмите правую кнопку мыши и выберите «Конструктор запроса»
- 3На закладке «Таблицы и поля» перенесите нужные таблицы и поля в выборку
- 4На закладке «Условия» задайте отборы, на закладке «Объединения/Псевдонимы» — имена полей
- 5Нажмите «ОК» — конструктор вставит готовый текст запроса в модуль
- 6Проверьте синтаксис модуля (Ctrl+F7) и выполните запрос в отладке
Конструктор особенно полезен при работе с виртуальными таблицами регистров: он сам подставит правильные параметры виртуальной таблицы — например, периодичность для РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты или условие отбора по измерениям. Вручную эти параметры часто указывают с ошибками.
Ограничение конструктора: он не умеет всё. Некоторые конструкции — например, сложные вложенные запросы с нестандартной логикой или обращение к табличным частям с хитрыми условиями — проще написать вручную. Поэтому конструктор стоит рассматривать как генератор основы, которую затем дорабатывают текстом.
Структура текста запроса: что обязательно указать
Текст запроса состоит из секций, часть из которых обязательна, а часть добавляется по необходимости.
- ВЫБРАТЬ — перечень полей выборки. Единственная обязательная секция вместе с ИЗ.
- ИЗ — источник данных: таблица справочника, документа, регистра или виртуальная таблица.
- ГДЕ — условия отбора. Именно здесь чаще всего используются параметры.
- СГРУППИРОВАТЬ ПО — группировка при использовании агрегатных функций СУММА, КОЛИЧЕСТВО, МИНИМУМ, МАКСИМУМ.
- УПОРЯДОЧИТЬ ПО — сортировка результата.
- ИТОГИ ПО — иерархические итоги, удобные для отчётов с группировками.
- АВТОУПОРЯДОЧИВАНИЕ — сортировка по умолчанию для ссылочных полей.
Псевдонимы полей задаются ключевым словом КАК и важны: именно по псевдониму вы обращаетесь к полю выборки в коде (Выборка.Наименование). Если псевдоним не задан, платформа возьмёт имя поля, но при соединениях таблиц с одинаковыми именами полей это приведёт к неоднозначности.
Работа с параметрами и виртуальными таблицами
Параметры — это значения, которые передаются в запрос извне: дата отчёта, конкретный склад, список номенклатуры. В тексте запроса параметр обозначается амперсандом: &Период, &Склад. Перед выполнением каждый параметр нужно установить:
Запрос.УстановитьПараметр("Период", КонецДня(ДатаОтчета));
Запрос.УстановитьПараметр("Склад", ВыбранныйСклад);
Если параметр используется в тексте, но не установлен, при выполнении возникнет ошибка «Переменная не определена». Это одна из самых частых причин «неработающего» запроса у новичков.
Виртуальные таблицы регистров — Остатки, Обороты, ОстаткиИОбороты, СрезПоследних, СрезПервых — принимают параметры в скобках сразу после имени таблицы:
ВЫБРАТЬ
Остатки.Номенклатура КАК Товар,
Остатки.КоличествоОстаток КАК Остаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &Склад) КАК Остатки
Условия на измерения правильно помещать в параметры виртуальной таблицы, а не в секцию ГДЕ. Это уменьшает объём вычисляемых данных: платформа сначала отфильтрует записи, а потом посчитает остатки, а не наоборот.
Если запрос с виртуальной таблицей работает медленно, первым делом проверьте, не вынесены ли условия по измерениям в секцию ГДЕ. Перенос отбора в параметры виртуальной таблицы часто ускоряет выполнение в разы без изменения логики.
Соединения таблиц и объединения запросов
Когда данные лежат в разных таблицах — например, остатки в регистре, а артикул товара в справочнике — используются соединения. В 1С доступны ЛЕВОЕ СОЕДИНЕНИЕ, ПРАВОЕ СОЕДИНЕНИЕ, ВНУТРЕННЕЕ СОЕДИНЕНИЕ и ПОЛНОЕ СОЕДИНЕНИЕ.
| Тип соединения | Что возвращает | Когда применять |
|---|---|---|
| ВНУТРЕННЕЕ | Только строки, есть совпадения в обеих таблицах | Когда нужны только связанные данные, например документы с существующими контрагентами |
| ЛЕВОЕ | Все строки левой таблицы, плюс совпадения справа (или NULL) | Остатки по всей номенклатуре, включая товары без движений |
| ПОЛНОЕ | Все строки обеих таблиц | Сверка двух источников, где пропуски возможны с любой стороны |
Частая задача — показать все товары, включая те, по которым нет остатков. Здесь левой таблицей должен быть справочник номенклатуры, а правой — виртуальная таблица остатков. Если поменять их местами, товары без остатков пропадут из результата.
Для склейки нескольких однотипных выборок применяется ОБЪЕДИНИТЬ ВСЕ (сохраняет дубли) или ОБЪЕДИНИТЬ (удаляет дубли, но работает медленнее). Количество и типы полей во всех объединяемых запросах должны совпадать.
Как получить и обработать результат запроса
После Запрос.Выполнить() результат можно получить двумя основными способами, и выбор между ними влияет на производительность.
Способы обработки результата
Подходит для последовательной обработки строк, заполнения табличных частей, вывода в макет. Не загружает весь результат в память сразу.
Подходит, когда данные нужны целиком: для поиска, сортировки, свёртки, передачи в СКД или на форму. Требует больше памяти на больших выборках.
Возвращает дерево значений по секции ИТОГИ. Применяется для иерархических отчётов.
Перед обходом полезно проверить, не пуст ли результат: Если РезультатЗапроса.Пустой() Тогда ... КонецЕсли;. Это позволяет корректно обработать ситуацию «данных нет» вместо молчаливого пропуска логики.
Для временного хранения промежуточных результатов в сложных запросах используются пакетные запросы и временные таблицы: сначала данные помещаются во временную таблицу (ПОМЕСТИТЬ ВТ_Остатки), затем из неё делается итоговая выборка. Это упрощает отладку — каждый пакет можно проверить отдельно.
Типичные ошибки и как проверить результат
Проверять запрос удобнее всего вне модуля. Для этого существуют внешние обработки «Консоль запросов» (есть в типовых поставках БСП и в свободном доступе от сообщества): вставляете текст, задаёте параметры, выполняете и сразу видите таблицу результата. Это быстрее, чем каждый раз запускать отладку всей обработки.
Как проверить результат запроса
Совпадает с ожидаемым числом документов или записей
Строк в разы больше — вероятно задвоение из-за соединения
Сходятся с типовым отчётом (например, оборотно-сальдовой ведомостью)
Суммы завышены кратно — проверьте уникальность ключей соединения
Запрос выполняется за приемлемое время на рабочей базе
Выполнение занимает десятки секунд — проверьте отборы в параметрах виртуальных таблиц
Отладка запроса и оптимизация
Стандартный приём отладки — декомпозиция. Разбейте сложный запрос на пакеты с временными таблицами и выполняйте их по одному в консоли запросов: так видно, на каком этапе данные теряются или задваиваются. Проверяйте промежуточные таблицы сверху вниз, пока не найдёте пакет, где результат перестаёт совпадать с ожиданием.
Для анализа производительности в 1С есть технологический журнал и замеры производительности в конфигураторе (Отладка → Замер производительности). Они показывают, какой запрос и сколько раз выполняется. Часто оказывается, что запрос вызывается в цикле — тогда правильное решение: вынести его из цикла, выбрать все данные одним запросом и искать нужные строки уже в таблице значений.
Что важно запомнить
Запрос формируется через конструктор или вручную, выполняется объектом «Запрос» с обязательной установкой параметров. Условия по измерениям размещайте в параметрах виртуальных таблиц, проверяйте результат в консоли запросов и следите за задвоением строк при соединениях. Тяжёлые запросы отлаживайте на копии базы.
Частые вопросы
Можно ли сформировать запрос в 1С без программирования?
Да, частично. Пользовательские отчёты на СКД (система компоновки данных) позволяют менять отборы, группировки и поля без изменения кода. Но сам текст запроса в схеме компоновки всё равно пишется разработчиком. Полностью без знания языка запросов можно обойтись только типовыми отчётами и универсальным отчётом.
Чем отличается ОБЪЕДИНИТЬ от ОБЪЕДИНИТЬ ВСЕ?
ОБЪЕДИНИТЬ удаляет дублирующиеся строки из итогового результата, ОБЪЕДИНИТЬ ВСЕ сохраняет их. Второй вариант работает быстрее, так как платформе не нужно проверять строки на совпадение. Если дубли заведомо невозможны, используйте ОБЪЕДИНИТЬ ВСЕ.
Почему запрос возвращает NULL в поле соединённой таблицы?
При левом соединении для строк, которым не нашлось пары в правой таблице, все её поля равны NULL. Чтобы вместо NULL выводить ноль или пустую строку, используйте функцию ЕСТЬNULL(Поле, 0) в списке выборки.
Как передать в запрос список значений или массив?
Установите параметр со значением типа Массив или СписокЗначений, а в тексте запроса используйте условие с оператором В: Номенклатура В (&СписокТоваров). Для иерархических отборов применяется В ИЕРАРХИИ(&Группа).
Что делать, если запрос в консоли работает, а в модуле — нет?
Чаще всего в модуле не установлен один из параметров или параметр имеет другой тип (например, дата без времени вместо границы). Также проверьте контекст: на клиенте в обычных формах объект «Запрос» недоступен, запрос выполняется только на сервере.
Как получить остатки на конкретную дату включительно?
Передайте в виртуальную таблицу Остатки параметр типа Граница: Новый Граница(КонецДня(Дата), ВидГраницы.Включая). Если передать просто дату начала дня, движения за сам день не попадут в остатки, и данные будут расходиться с типовыми отчётами.