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

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

Как создать запросы в 1С: пошаговое руководство

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

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

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

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

Что такое запрос в 1С и когда он нужен

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

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

Способы создания запроса: конструктор и ручное написание

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

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

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

Способы создания запроса

Конструктор запроса

Подходит новичкам и для сложных соединений; минус — перегенерация текста может затереть ручные правки

Ручное написание

Быстрее для коротких запросов и точных правок; требует знания синтаксиса

Консоль запросов

Идеальна для отладки на реальных данных; не является частью конфигурации, результат нужно переносить в код

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

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

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

Обратите внимание на закладку «Связи»: при добавлении второй таблицы конструктор обычно предлагает связь автоматически, но тип соединения (левое, внутреннее) нужно проверить вручную. Для подборки «справочник + цены» почти всегда нужно левое соединение, иначе товары без цены выпадут из выборки.

После вставки текста допишите код выполнения: создайте объект Запрос, присвойте текст, установите параметры и вызовите Выполнить().

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

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

Пример полного фрагмента кода:

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

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

"ВЫБРАТЬ

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

| Товары.Наименование КАК Наименование

|ИЗ

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

|ГДЕ

| Товары.ЭтоГруппа = ЛОЖЬ

| И Товары.Родитель = &Группа

|

|УПОРЯДОЧИТЬ ПО

| Наименование";

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

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

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

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

Сообщить(Выборка.Наименование);

КонецЦикла;

Ключевые моменты: параметры в тексте обозначаются символом & и обязательно устанавливаются через УстановитьПараметр() до выполнения. Псевдонимы полей (КАК Наименование) определяют имена колонок в результате — именно по ним вы обращаетесь к данным в цикле обхода.

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

bsl
Запрос = Новый Запрос("ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ГДЕ ПометкаУдаления = ЛОЖЬ");
Таблица = Запрос.Выполнить().Выгрузить();

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

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

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

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

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

Перед использованием результата проверьте, не пуст ли он: Если Результат.Пустой() Тогда .... Обращение к полям пустой выборки не вызовет ошибки напрямую, но логика обработки молча сработает неправильно.

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

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

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

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

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

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

Значения итоговых полей
Норма

Суммы совпадают с типовым отчётом по тем же данным

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

Суммы завышены кратно — дублирование строк при соединении «один ко многим»

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

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

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

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

Типичные ошибки при создании запросов
01
Соединение без учёта «один ко многим»: строки основной таблицы дублируются, итоги завышаются
02
Условие на виртуальную таблицу в ГДЕ вместо параметров — резкое падение производительности
03
Подстановка значений в текст запроса конкатенацией вместо параметров — ошибки на датах и строках
04
Обращение к результату без проверки Пустой() — скрытые логические ошибки
05
Левое соединение вместо внутреннего (или наоборот) — лишние пустые строки или потерянные записи

Ещё одна частая проблема — задвоение при соединении табличных частей. Если вы соединяете табличную часть «Товары» документа с табличной частью «Серии», каждая строка товаров перемножится на каждую строку серий. Решение — соединять по составному ключу (номенклатура + ключ связи) или агрегировать одну из таблиц перед соединением.

Отладка и оптимизация запросов

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

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

Простые правила оптимизации: выбирайте только нужные поля, накладывайте отбор как можно раньше (в параметрах виртуальных таблиц и ГДЕ), соединяйте по ссылкам, а не по строковым реквизитам, избегайте В ИЕРАРХИИ по большим справочникам без необходимости.

Маршрут решения

Как выбрать подход

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

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

Чем запрос отличается от отбора динамического списка?

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

Можно ли писать запрос на английском синтаксисе?

Да, язык запросов поддерживает оба варианта: SELECT ... FROM ... WHERE работает наравне с ВЫБРАТЬ ... ИЗ ... ГДЕ. Смешивать русские и английские ключевые слова в одном запросе тоже допустимо, но в типовых конфигурациях принят русский синтаксис.

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

Добавьте условие на поле Дата: ГДЕ Документ.Дата МЕЖДУ &НачалоПериода И &КонецПериода. Для границы конца периода удобно использовать объект Граница с видом «Включая», чтобы попали документы на конец дня, или передавать конец дня через КонецДня(Период).

Почему запрос возвращает дубли строк?

Почти всегда причина в соединении таблиц, находящихся в отношении «один ко многим», без агрегации. Проверьте, нет ли в правой таблице нескольких строк на одну строку левой. Решения: сгруппировать правую таблицу, соединять по более точному ключу или использовать РАЗЛИЧНЫЕ, если дубли полностью идентичны.

Как передать в запрос список значений или таблицу?

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

Нужно ли изучать SQL, чтобы писать запросы в 1С?

Не обязательно, но знание основ SQL (соединения, группировки, подзапросы) сильно помогает: концепции языка запросов 1С заимствованы из SQL. Различия касаются работы с метаданными, виртуальными таблицами и специфических конструкций вроде ИТОГИ и В ИЕРАРХИИ.

Итог

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

Запрос создаётся конструктором или вручную, выполняется через объект Запрос с параметрами. Условия на виртуальные таблицы задавайте в их параметрах, значения передавайте только через УстановитьПараметр, результат проверяйте на пустоту и задвоения. Отлаживайте сложные запросы в консоли на копии базы.