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

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

Что возвращает запрос в 1С: разбор результата выполнения

Разбираем, что возвращает запрос в 1С: объект РезультатЗапроса, выборка, таблица значений. Методы Выполнить, Выбрать, Выгрузить с примерами кода.

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

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

Объект РезультатЗапроса: что именно возвращает метод Выполнить

Метод Выполнить() объекта Запрос возвращает значение типа РезультатЗапроса. Это не сами данные, а объект-обёртка, содержащий ссылку на выборку данных на стороне сервера и метаданные результата — например, коллекцию колонок с именами и типами полей.

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

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

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

"ВЫБРАТЬ

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

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

|ИЗ

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

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

// РезультатЗапроса — объект типа РезультатЗапроса

Проверка результата: метод Пустой() и состав колонок

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

Коллекция РезультатЗапроса.Колонки позволяет программно определить, какие поля присутствуют в результате. Обращение к несуществующему полю выборки вызывает ошибку времени выполнения, поэтому в универсальных механизмах состав колонок проверяют заранее.

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

Сообщить("По запросу данных не найдено");

Иначе

Для Каждого Колонка Из РезультатЗапроса.Колонки Цикл

Сообщить(Колонка.Имя + " : " + Колонка.ТипЗначения);

КонецЦикла;

КонецЕсли;

Выборка из результата запроса: построчный обход

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

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

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

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

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

КонецЦикла;

Обход по группировкам и итогам

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

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

Выгрузка результата: таблица значений и дерево значений

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

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

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

// Поиск по колонке

СтрокаТовара = ТаблицаТоваров.Найти(НужнаяСсылка, "Товар");

// Дерево значений для иерархического запроса

Дерево = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);

Выборка или таблица значений

Выборка (Выбрать)

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

Таблица значений (Выгрузить)

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

Дерево значений (Выгрузить с иерархией)

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

Пакетные запросы: что возвращает ВыполнитьПакет

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

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

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

// Последний элемент — итоговый результат

ИтоговыйРезультат = МассивРезультатов[МассивРезультатов.ВГраница()];

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

Что возвращает запрос в СКД и консоли запросов

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

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

Типичные ошибки
01
Попытка обратиться к РезультатЗапроса как к таблице: Результат[0].Поле — у РезультатЗапроса нет индексированного доступа, сначала нужен Выбрать() или Выгрузить()
02
Обход выборки без проверки Пустой() с последующей логикой, которая ломается на пустом результате
03
Выгрузка миллионов строк в таблицу значений ради одного поиска — расход памяти и падение производительности, лучше ограничить запрос условием ГДЕ
04
Использование результата пакетного запроса по неверному индексу массива — получение пустого результата от создания временной таблицы
05
Обращение к полю выборки по имени реквизита вместо псевдонима, заданного через КАК в тексте запроса

Проверка корректности полученных данных

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

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

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

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

РезультатЗапроса.Пустой() = Ложь, выборка содержит строки

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

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

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

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

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

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

Типы полей
Норма

Колонки имеют ожидаемые типы (ссылка, число, дата)

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

Поле содержит NULL или составной тип из-за левого соединения

Значения итогов
Норма

Итоговые суммы сходятся с контрольными данными

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

Итоги завышены — проверьте группировки и дубли строк

FAQ: частые вопросы о результате запроса

Можно ли узнать количество строк результата без полного обхода?

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

Что вернёт запрос, если данных нет?

Метод Выполнить() всё равно вернёт корректный объект РезультатЗапроса — не NULL и не Неопределено. У него метод Пустой() вернёт Истина, выборка не выполнит ни одной итерации, а Выгрузить() вернёт пустую таблицу значений с заданными колонками.

Чем выборка отличается от таблицы значений по скорости?

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

Почему обращение Выборка.Количество() вызывает ошибку?

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

Что возвращает запрос с итогами при обычном Выбрать()?

Без параметра метод Выбрать() вернёт только детальные записи, строки итогов будут пропущены. Чтобы обойти итоги, передайте ОбходРезультатаЗапроса.ПоГруппировкам и укажите имя группировки вторым параметром, либо используйте Прямой обход с проверкой ТипЗаписи().

Можно ли передать результат запроса между сервером и клиентом?

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

Итог

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

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