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