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

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

Как узнать результат запроса в 1С

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

Результат запроса в 1С — это объект типа «РезультатЗапроса», который возвращает метод Выполнить() после обращения к базе данных. Сам по себе этот объект не показывает данные на экране: чтобы узнать, что вернул запрос, нужно либо выгрузить результат в таблицу значений, либо обойти его выборкой, либо проверить его на пустоту. Какой способ выбрать — зависит от задачи: быстрая проверка, циклическая обработка строк или передача данных дальше.

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

Отдельный случай — работа не в модуле, а в Консоли запросов или в конструкторе запроса, где результат виден сразу в табличном виде. Это самый быстрый способ проверить, что запрос написан правильно, до того как код попадёт в конфигурацию.

Как выполнить запрос и получить объект результата

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

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

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

"ВЫБРАТЬ

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

| Номенклатура.Наименование КАК Наименование

|ИЗ

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

|ГДЕ

| Номенклатура.Родитель = &Группа";

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

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

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

Если метод Выполнить() завершился исключением, причина обычно в ошибке текста запроса, неустановленном параметре или отсутствии прав на объект. Текст исключения платформа выводит достаточно подробный — по нему почти всегда можно локализовать проблемное место.

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

Метод Пустой() возвращает Истина, если запрос не нашёл ни одной записи. Это самый дешёвый по ресурсам способ ответить на вопрос «есть ли данные», когда сами данные не нужны.

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

Если РезультатЗапроса.Пустой() Тогда

Сообщить("По условию ничего не найдено");

Иначе

// обработка данных

КонецЕсли;

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

Если требуется только факт наличия записи, хорошей практикой считается добавить в текст запроса конструкцию ВЫБРАТЬ ПЕРВЫЕ 1 — серверу не придётся формировать полный набор строк, который всё равно не будет использоваться.

Как обойти результат через выборку

Метод Выбрать() возвращает объект «ВыборкаИзРезультатаЗапроса», который обходится в цикле Пока Выборка.Следующий() Цикл. Это основной способ построчной обработки: записи читаются последовательно, память расходуется экономно, поля доступны по именам из текста запроса.

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

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

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

КонецЦикла;

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

Чтобы узнать количество строк без полного обхода, у выборки есть метод Количество(). Однако учтите: для некоторых типов обхода платформа может сама выполнить обход для подсчёта, поэтому на больших результатах дешевле получить количество отдельным запросом с функцией КОЛИЧЕСТВО() или через выгруженную таблицу.

Порядок действий при обходе выборки
  1. 1
    Выполните запрос методом Выполнить() и сохраните результат в переменную
  2. 2
    Проверьте РезультатЗапроса.Пустой(), чтобы не обходить пустой набор
  3. 3
    Получите выборку: Выборка = РезультатЗапроса.Выбрать()
  4. 4
    Организуйте цикл Пока Выборка.Следующий() Цикл
  5. 5
    Обращайтесь к полям по именам из текста запроса: Выборка.ИмяПоля
  6. 6
    После цикла убедитесь, что обработано ожидаемое число строк

Как выгрузить результат в таблицу значений

Метод Выгрузить() превращает результат в таблицу значений — универсальную структуру, которую можно сортировать, фильтровать, сворачивать, искать по ней методом Найти() и НайтиСтроки(), передавать в табличное поле формы или в построитель отчёта.

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

Для Каждого Строка Из ТаблицаРезультата Цикл

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

КонецЦикла;

Сообщить("Всего строк: " + ТаблицаРезультата.Количество());

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

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

Выбор способа получения данных

Пустой()

Нужно только узнать, есть ли записи. Самый быстрый вариант, данные не извлекаются.

Выбрать()

Построчная обработка большого результата, экономия памяти, обход итогов и иерархии.

Выгрузить()

Нужны поиск, сортировка, повторные обходы, передача в форму или отчёт. Требует больше памяти.

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

Во время разработки удобнее всего смотреть результат визуально, а не через сообщения. Основной инструмент — Консоль запросов (внешняя обработка или встроенная в конфигурации на БСП): вставьте текст запроса, заполните параметры в списке параметров и нажмите «Выполнить» — данные отобразятся в таблице сразу.

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

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

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

Как узнать результат пакетного запроса

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

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

// результаты промежуточных запросов и помещения во временные таблицы

РезультатОсновной = МассивРезультатов[МассивРезультатов.Количество() - 1];

Выборка = РезультатОсновной.Выбрать();

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

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

Типичные ошибки
01
Обращение к Выборка.Следующий() без проверки Пустой() — лишний код и путаница при отладке, хотя ошибкой это не является
02
Забытый УстановитьПараметр() — запрос падает с ошибкой либо возвращает не те данные, если параметр не объявлен
03
Выгрузка огромного результата в таблицу значений ради одной строки — расход памяти и времени
04
Обращение к полю выборки по имени, которого нет в тексте запроса, — исключение 'Поле не найдено'
05
Использование Выполнить() для пакетного запроса и попытка читать промежуточный результат

Частые проблемы и как их диагностировать

Ситуация «запрос выполняется, но данных нет» чаще всего объясняется параметрами. Проверьте, что параметр установлен до вызова Выполнить(), что тип значения совпадает с типом поля в условии (например, ссылка, а не строка с наименованием) и что в условии нет лишнего отбора, отсекающего все записи.

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

Ошибки вида «Поле не найдено» при обращении к выборке означают, что имя в коде не совпадает с именем (псевдонимом) поля в тексте запроса. Псевдонимы задаются конструкцией КАК ИмяПоля, и обращаться нужно именно к ним, а не к именам реквизитов объекта метаданных.

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

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

Наличие данных
Норма

Пустой() возвращает Ложь, выборка заходит в цикл

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

Пустой() = Истина — проверяйте параметры и условия отбора

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

Совпадает с ожидаемым по логике задачи

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

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

Доступ к полям
Норма

Выборка.ИмяПоля возвращает значение без исключения

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

Ошибка 'Поле не найдено' — сверьте псевдонимы в тексте запроса

Часто задаваемые вопросы

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

Три способа: вызвать Выборка.Количество() после Выбрать(), выгрузить результат и взять Таблица.Количество(), либо написать отдельный запрос с агрегатной функцией КОЛИЧЕСТВО(*). Последний вариант самый быстрый, если сами данные не нужны.

Можно ли посмотреть результат запроса без программирования?

Да. Консоль запросов (встроенная в конфигурации на базе БСП или внешняя обработка) выполняет произвольный запрос и показывает результат в таблице. Достаточно вставить текст, заполнить параметры и нажать «Выполнить».

Почему запрос в консоли возвращает данные, а в коде — пустой результат?

Почти всегда причина в параметрах: в коде параметр не установлен, имеет другой тип (строка вместо ссылки) или другое значение. Сравните значения параметров в консоли и в отладчике в момент вызова Выполнить().

Что вернёт Выполнить(), если запрос содержит ошибку?

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

Чем отличается Выбрать() от Выгрузить() по скорости?

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

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

Используйте ВыполнитьПакетСПромежуточнымиДанными() — он вернёт массив таблиц значений по каждому запросу пакета. Либо добавьте в конец пакета отдельный запрос ВЫБРАТЬ * ИЗ ИмяВременнойТаблицы и прочитайте последний элемент массива ВыполнитьПакет().

Итог

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

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