Разработка и Конфигурация · 11 мин
Как создавать запросы в 1С: пошаговое руководство
Практическое руководство по созданию запросов в 1С: конструктор запроса, синтаксис языка, параметры, виртуальные таблицы, типичные ошибки и проверка результата.
Запрос в 1С — основной способ получить данные из информационной базы для отчётов, обработок и программной логики. В отличие от прямого обращения к таблицам, запрос работает на языке, похожем на SQL, но адаптированном под объекты конфигурации: справочники, документы, регистры накопления и сведений. Платформа сама преобразует текст запроса в команды СУБД, поэтому разработчику не нужно знать структуру физических таблиц.
Создать запрос можно двумя путями: визуально — через конструктор запроса в конфигураторе, либо вручную — написав текст на встроенном языке запросов. Оба подхода дают одинаковый результат, разница только в скорости работы и уровне контроля над деталями. Ниже разобраны оба способа, синтаксис языка, работа с параметрами и виртуальными таблицами, а также типичные ошибки, из-за которых запрос возвращает пустой или неверный результат.
Где создаются запросы и какой инструмент выбрать
Текст запроса встречается в нескольких местах конфигурации: в модулях объектов и форм (объект «Запрос»), в схеме компоновки данных для отчётов на СКД, в динамических списках и в обработках. Во всех случаях синтаксис один и тот же, отличается только способ выполнения: программно через Запрос.Выполнить() или автоматически платформой при открытии отчёта.
Для начинающих оптимален конструктор запроса: он открывается из контекстного меню модуля («Конструктор запроса») и позволяет собрать выборку мышью, не запоминая синтаксис. Опытные разработчики чаще пишут текст вручную, а конструктор используют для сложных соединений и проверки себя. Для отладки готового запроса с реальными данными удобна консоль запросов — внешняя обработка, которая выполняет текст и показывает результат без написания программного кода.
Чем создавать запрос
Подходит новичкам и для сложных соединений нескольких таблиц. Ограничение: не поддерживает некоторые тонкие настройки, иногда генерирует избыточный текст.
Полный контроль над текстом, быстрее для простых выборок. Требует знания синтаксиса и структуры метаданных.
Инструмент отладки на реальных данных, а не способ создания. Позволяет подобрать параметры и проверить результат до переноса в модуль.
Создание запроса через конструктор: пошагово
Конструктор вызывается из конфигуратора: откройте модуль, поставьте курсор в нужное место, нажмите правую кнопку мыши и выберите «Конструктор запроса». Если текст запроса уже существует, конструктор загрузит его для редактирования; если нет — предложит создать новый.
Работа строится по вкладкам. На вкладке «Таблицы и поля» в левом списке выберите объект метаданных (например, «Справочник.Номенклатура»), перенесите его в список таблиц, затем отметьте нужные поля. На вкладке «Связи» настройте соединения, если таблиц несколько. Вкладка «Условия» задаёт отбор, «Объединения/Псевдонимы» — имена полей в результате, «Итоги» — группировку и агрегатные функции. После нажатия «ОК» конструктор вставит готовый текст в модуль.
- 1Откройте модуль, вызовите контекстное меню и выберите «Конструктор запроса»
- 2На вкладке «Таблицы и поля» добавьте нужную таблицу и отметьте поля выборки
- 3На вкладке «Условия» задайте отбор, например Поле = &Параметр
- 4При необходимости настройте связи, группировку и итоги на соответствующих вкладках
- 5Нажмите «ОК» и проверьте сгенерированный текст запроса в модуле
- 6Выполните запрос в консоли запросов с тестовыми параметрами и сверьте результат
Синтаксис языка запросов: минимальный набор
Язык запросов 1С напоминает SQL, но ключевые слова пишутся на русском. Минимальный запрос состоит из секций ВЫБРАТЬ и ИЗ. Секция ГДЕ задаёт отбор, УПОРЯДОЧИТЬ ПО — сортировку, СГРУППИРОВАТЬ ПО с агрегатными функциями СУММА, КОЛИЧЕСТВО, МАКСИМУМ — группировку. Допускается и английский синтаксис (SELECT, FROM, WHERE), платформа понимает оба варианта.
Пример простого запроса к справочнику с отбором по параметру:
ВЫБРАТЬ
Номенклатура.Ссылка,
Номенклатура.Наименование,
Номенклатура.Артикул
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Родитель = &Группа
И НЕ Номенклатура.ПометкаУдаления
УПОРЯДОЧИТЬ ПО
Номенклатура.Наименование
Обратите внимание на псевдоним таблицы после КАК: он упрощает чтение и обязателен при соединении нескольких таблиц. Оператор «НЕ» исключает помеченные на удаление элементы — частый источник ошибок, когда в отчёт попадают «мёртвые» записи. В условиях доступны сравнения, В (список), МЕЖДУ, ПОДОБНО для поиска по шаблону и проверка ЕСТЬ NULL.
Параметры запроса и их установка
Параметр — это именованное значение, которое подставляется в запрос при выполнении. В тексте параметр обозначается символом амперсанда: &Группа, &ДатаНачала. Прямая подстановка значений конкатенацией строк — грубая ошибка: она ломает план запроса, мешает кэшированию и открывает путь к ошибкам при специальных символах в данных.
Перед выполнением каждый параметр нужно явно установить методом УстановитьПараметр. Если параметр задан в тексте, но не установлен в коде, платформа выдаст ошибку «Параметр не определен». Для отбора по списку значений передайте массив или список значений и используйте оператор В (&СписокГрупп).
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ..."; // текст из примера выше
Запрос.УстановитьПараметр("Группа", ВыбраннаяГруппа);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
// обработка строки выборки
КонецЦикла;
Соединения таблиц и виртуальные таблицы регистров
Когда данные лежат в разных объектах, таблицы соединяют в секции ИЗ. Левое соединение (ЛЕВОЕ СОЕДИНЕНИЕ) возвращает все строки левой таблицы и совпадения из правой — это основной тип связи в учётных задачах. Внутреннее соединение оставляет только пары, где есть совпадение с обеих сторон. Условие связи пишется после ПО, например по полю «Ссылка».
Для регистров накопления и сведений платформа предлагает виртуальные таблицы: Остатки, Обороты, ОстаткиИОбороты, СрезПоследних, СрезПервых. Они не хранятся физически, а вычисляются на лету с учётом переданных параметров — периода и отбора. Параметры виртуальной таблицы указываются в скобках после её имени, и это важно: фильтр внутри виртуальной таблицы работает быстрее, чем тот же фильтр в секции ГДЕ по итоговой выборке.
ВЫБРАТЬ
Остатки.Номенклатура,
Остатки.КоличествоОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&ДатаОстатков, Склад = &Склад) КАК Остатки
Обработка результата: выборка, выгрузка, проверка
Метод Выполнить() возвращает объект «РезультатЗапроса». Из него данные получают двумя способами: метод Выбрать() даёт выборку для построчного обхода в цикле, а Выгрузить() — таблицу значений целиком. Выборка экономит память на больших объёмах, таблица значений удобнее, когда нужен произвольный доступ к строкам, сортировка или передача данных в форму.
Перед обходом полезно проверить Результат.Пустой, чтобы не выполнять лишнюю работу при пустом ответе. Если запрос с группировкой, в выборке доступны итоги: метод Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам) позволяет обойти иерархию итогов и детальных записей.
Как проверить результат
Совпадает с ожиданием по контрольному примеру или отчёту за тот же период
Пусто при наличии данных — проверьте параметры и отбор по пометке удаления
Сходятся с типовым отчётом по тому же регистру
Суммы завышены кратно — вероятно, дублирование строк из-за соединения без достаточного условия связи
Заполнены там, где связь существует, NULL там, где её нет
NULL во всех строках — неверное условие соединения
Типичные ошибки и ограничения
Самая частая проблема — пустой результат при корректном тексте. Причины обычно такие: параметр не установлен или установлен с неверным типом (например, строка вместо ссылки), отсутствует отбор по пометке удаления, период виртуальной таблицы не включает нужные данные. Вторая группа ошибок — логические: соединение по неполному условию порождает декартово произведение, и суммы «раздуваются» в разы.
Есть и ограничения платформы. Запрос не может изменять данные — только читать. В запросе нельзя вызывать произвольные функции встроенного языка, доступны только операции языка запросов. Обращение к реквизитам через точку от ссылки («разыменование») допустимо, но злоупотребление им в больших выборках замедляет выполнение — лучше соединить таблицы явно.
Как выбрать подход под конкретную задачу
Для разовой выборки в модуле документа достаточно простого запроса с параметрами. Для отчёта, который пользователь будет настраивать сам, правильнее схема компоновки данных: запрос пишется один раз, а отборы, группировки и поля пользователь меняет в настройках без программирования. Для списков на форме используйте динамический список с произвольным запросом — он сам обрабатывает сортировку и отбор.
Как выбрать действие
Что важно запомнить
Запрос в 1С создаётся конструктором или вручную на языке с секциями ВЫБРАТЬ, ИЗ, ГДЕ. Все переменные значения передавайте параметрами, остатки и обороты берите из виртуальных таблиц с отбором внутри, результат проверяйте в консоли запросов до переноса в модуль. Тяжёлые запросы отлаживайте на копии базы.
Частые вопросы
Чем запрос отличается от обхода справочника через Выбрать()?
Метод Выбрать() перебирает объекты по одному и при каждом обращении к реквизиту может инициировать обращение к базе. Запрос забирает нужные поля одним обращением к СУБД, что на больших объёмах быстрее в разы. Обход объектов оправдан только когда нужно менять данные, а не читать их.
Можно ли в запросе отобрать по нескольким значениям одного поля?
Да. Передайте в параметр массив или список значений и используйте оператор В: ГДЕ Номенклатура.Родитель В (&СписокГрупп). Платформа корректно развернёт список в условие на стороне СУБД.
Почему запрос с виртуальной таблицей возвращает пустой результат?
Чаще всего дело в параметрах виртуальной таблицы: дата остатков раньше первых движений, отбор по складу или организации не совпадает с данными, либо регистр вообще не заполнен. Проверьте те же данные типовым отчётом по регистру — если и там пусто, проблема в данных, а не в запросе.
Как вывести результат запроса в табличный документ или на форму?
Для табличного документа используйте макет с областями и построчный вывод из выборки. Для формы выгрузите результат методом Выгрузить() в таблицу значений и привяжите её к реквизиту формы типа «ТаблицаЗначений». Для отчётов предпочтительна СКД — она выводит результат без ручного кода.
Работает ли язык запросов одинаково на разных СУБД?
Да, это одно из назначений языка запросов: платформа транслирует один и тот же текст в диалекты MS SQL Server, PostgreSQL, Oracle и IBM Db2. Однако планы выполнения на разных СУБД могут отличаться, поэтому тяжёлые запросы стоит проверять на той СУБД, которая используется в рабочей базе.