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

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

Как работать с запросом в 1С

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

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

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

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

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

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

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

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

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

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

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

Порядок создания запроса
  1. 1
    Откройте модуль и вызовите конструктор запроса через контекстное меню
  2. 2
    Выберите таблицу-источник и перенесите нужные поля в список выборки
  3. 3
    Добавьте условия отбора через параметры (например, Контрагент = &Контрагент)
  4. 4
    При необходимости настройте группировку, соединения и сортировку
  5. 5
    Нажмите ОК и проверьте сгенерированный текст запроса
  6. 6
    Выполните запрос в консоли запросов на тестовых данных

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

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

Параметры и отборы: как фильтровать данные

Параметры в тексте запроса начинаются со знака «&» и заполняются методом УстановитьПараметр() до выполнения. Через параметры передают даты, ссылки на объекты, списки значений. Это единственный правильный способ подставлять значения: склеивать текст запроса строками с подстановкой переменных нельзя — это источник ошибок и потенциальных уязвимостей.

Типовые условия: равенство (Поле = &Значение), диапазон дат (Дата МЕЖДУ &Начало И &Конец), проверка вхождения в список (Поле В (&Список)), отбор по иерархии (Поле В ИЕРАРХИИ (&Группа)). Для строк доступен оператор ПОДОБНО с шаблоном, например ПОДОБНО &Поиск, где в параметр передают значение с символами «%».

При отборе по списку в параметр передают массив или список значений. Условие «Поле В (&Список)» сработает корректно только если список не пуст: пустой список отфильтрует все строки. Если пустой список должен означать «без отбора», условие дописывают динамически или используют приём с проверкой количества элементов в параметре.

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

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

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

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

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

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

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

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

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

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

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

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

Совпадает с ожидаемым числом объектов выборки

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

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

Суммы по ключевым показателям
Норма

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

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

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

Позиции без движений
Норма

Присутствуют с NULL или нулём, если использовано левое соединение

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

Пропали — применено внутреннее соединение или лишний отбор

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

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

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

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

Отладка запроса и проверка результата

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

Полезный приём — разбивать сложный запрос на временные таблицы с помощью конструкции «ПОМЕСТИТЬ ИмяТаблицы». Каждый промежуточный этап можно выполнить в консоли отдельно и проверить, где именно данные начинают расходиться с ожиданиями. В коде пакет временных таблиц выполняется через менеджер временных таблиц.

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

Частые ошибки и альтернативы запросам

Кроме уже упомянутых задвоений и отборов вне виртуальных таблиц, распространены: сравнение даты документа без приведения границ периода (документ в конце дня выпадает из выборки), использование ПОДОБНО без экранирования спецсимволов, обращение к реквизитам через точку от поля-составного типа (платформа разворачивает это в соединения по всем возможным таблицам). Ещё одна ошибка — выгрузка результата в таблицу значений там, где достаточно обхода выборки: лишний расход памяти на больших выборках.

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

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

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

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

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

Итог

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

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

Частые вопросы о работе с запросами в 1С

Чем запрос в 1С отличается от SQL?

Язык запросов 1С похож на SQL по синтаксису, но оперирует объектами метаданных (справочниками, документами, регистрами), а не физическими таблицами СУБД. Платформа сама транслирует запрос в команды базы данных. Прямой доступ к СУБД в обход платформы не поддерживается и нарушает лицензионные требования.

Как посмотреть, почему запрос работает медленно?

Сначала проверьте, передаются ли отборы в параметры виртуальных таблиц, а не в секцию ГДЕ. Затем убедитесь, что в условиях соединений используются индексируемые поля (измерения, ссылки, даты). На клиент-серверной базе план выполнения можно проанализировать средствами СУБД или через технологический журнал с замером времени.

Можно ли изменить данные базы запросом?

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

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

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

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

Через параметр: сформируйте массив или список значений, передайте его методом УстановитьПараметр, а в тексте используйте условие «Поле В (&Список)». Учтите, что пустой список отфильтрует все строки — если это нежелательно, условие добавляют в текст запроса динамически.

Что выбрать для отчёта: запрос в коде или СКД?

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