Результат запроса в таблицу значений в 1С: метод Выгрузить()
Чтобы получить результат запроса в таблицу значений в 1С, вызовите
Запрос.Выполнить().Выгрузить() — метод Выгрузить() объекта
РезультатЗапроса возвращает ТаблицаЗначений со всеми строками
и колонками выборки за один проход.
Альтернатива — Выбрать(): он не грузит всё в память, а даёт
Выборку для построчного обхода через Следующий(). Правило простое:
Выгрузить() — когда нужна таблица целиком (отбор, сортировка, загрузка в реквизит формы);
Выбрать() — когда строк много и достаточно пройти их по одной.
Выгрузить результат запроса в таблицу значений 1С
Базовый способ получить результат запроса в таблицу значений — метод Выгрузить().
Он вызывается у объекта РезультатЗапроса, который возвращает
Запрос.Выполнить(), и отдаёт готовую ТаблицаЗначений:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование,
| Номенклатура.Артикул КАК Артикул
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";
ТаблицаЗначений = Запрос.Выполнить().Выгрузить();
Сообщить("Строк выгружено: " + ТаблицаЗначений.Количество());
Для Каждого Строка Из ТаблицаЗначений Цикл
Сообщить(Строка.Наименование + " / " + Строка.Артикул);
КонецЦикла;
Колонки таблицы значений создаются автоматически по псевдонимам полей запроса
(после КАК). Поэтому имена в секции ВЫБРАТЬ и обращения к
Строка.Наименование должны совпадать. Полученная таблица — обычная
ТаблицаЗначений: её можно сортировать, сворачивать, накладывать отбор и
присваивать реквизиту формы с типом «Таблица значений».
Выгрузить или Выбрать: обход выборки против таблицы значений
Ключевой выбор при работе с результатом запроса в 1С — Выгрузить() или
Выбрать(). Оба метода вызываются у одного и того же РезультатЗапроса,
но работают принципиально по-разному:
РезультатЗапроса = Запрос.Выполнить();
// Вариант 1: вся выборка сразу в память
ТаблицаЗначений = РезультатЗапроса.Выгрузить();
// Вариант 2: построчный обход без загрузки всего в память
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Наименование);
КонецЦикла;
Выгрузить() материализует всю выборку в
ТаблицаЗначений — удобно, когда данные нужны целиком как коллекция:
отобрать, отсортировать, свернуть, передать в реквизит формы или в другой метод.
Выбрать() возвращает ВыборкаИзРезультатаЗапроса
и отдаёт строки по одной через Следующий(), не удерживая всю выборку в памяти —
это эффективнее на больших объёмах.
Выгрузить результат запроса по группировкам
Если запрос содержит ИТОГИ ... ПО, результат запроса можно выгрузить не «плоско»,
а по группировкам — тогда в таблицу значений попадут только строки верхнего уровня итогов.
Управляет этим параметр ТипОбхода:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Продажи.Номенклатура КАК Номенклатура,
| Продажи.Количество КАК Количество
|ИЗ
| РегистрНакопления.Продажи КАК Продажи
|ИТОГИ
| СУММА(Количество)
|ПО
| Номенклатура";
Результат = Запрос.Выполнить();
// Только итоговые строки по группировке Номенклатура
ТаблицаИтогов = Результат.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам);
При ОбходРезультатаЗапроса.Прямой (значение по умолчанию) в таблицу попадают все
детальные строки, а строки итогов пропускаются. При ПоГруппировкам — наоборот:
только строки-итоги. Для многоуровневых итогов удобнее выгрузка в дерево значений (см. ниже),
где вложенность группировок сохраняется.
Выгрузить результат запроса в дерево значений
Метод Выгрузить() возвращает не только таблицу значений: при обходе по группировкам
из запроса с ИТОГИ он отдаёт ДеревоЗначений с сохранением иерархии
группировок. Это удобно для отчётов с раскрывающимися уровнями:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Продажи.Склад КАК Склад,
| Продажи.Номенклатура КАК Номенклатура,
| Продажи.Количество КАК Количество
|ИЗ
| РегистрНакопления.Продажи КАК Продажи
|ИТОГИ
| СУММА(Количество)
|ПО
| Склад,
| Номенклатура";
ДеревоЗначений = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам);
// Верхний уровень — склады, вложенные строки — номенклатура
Для Каждого СтрокаСклада Из ДеревоЗначений.Строки Цикл
Сообщить(СтрокаСклада.Склад + ": " + СтрокаСклада.Количество);
КонецЦикла;
Тип возвращаемого значения зависит именно от ТипОбхода и структуры запроса:
прямой обход и запрос без итогов дают плоскую ТаблицаЗначений, а обход по
группировкам запроса с ИТОГИ — ДеревоЗначений.
Колонки и количество строк таблицы значений
После выгрузки результата запроса в таблицу значений часто нужно узнать состав колонок и
число строк. Количество строк даёт метод Количество() самой таблицы значений,
а состав колонок — коллекция Колонки:
ТаблицаЗначений = Запрос.Выполнить().Выгрузить();
Сообщить("Количество строк: " + ТаблицаЗначений.Количество());
Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
Сообщить("Колонка: " + Колонка.Имя);
КонецЦикла;
// Быстрая проверка «есть ли данные» без выгрузки — у самого результата:
Если Запрос.Выполнить().Пустой() Тогда
Сообщить("Запрос не вернул строк");
КонецЕсли;
Обратите внимание: у ТаблицаЗначений число строк — это Количество(),
а не «КоличествоСтрок». Проверить, вернул ли запрос данные, можно и без выгрузки — методом
Пустой() у РезультатЗапроса: это дешевле, чем выгружать всю выборку
ради подсчёта строк.
Когда выборка эффективнее выгрузки
Выгрузить результат запроса в таблицу значений удобно, но не всегда правильно. Ориентируйтесь так:
- Выгрузить() — нужна коллекция целиком: сортировка, свёртка, отбор, загрузка в реквизит формы, передача в другой метод.
- Выбрать() — строк много (десятки и сотни тысяч), и достаточно пройти их построчно: обход не держит всю выборку в памяти.
- ПоГруппировкам — нужны итоги и иерархия: выгрузка в дерево значений или обход выборки по группировкам.
На больших объёмах выгрузка в таблицу значений увеличивает потребление памяти пропорционально
числу строк, тогда как построчный обход Выбрать() расходует память экономно.
Если результат запроса всё равно обрабатывается по одной строке — предпочтите выборку.
Частые ошибки при выгрузке результата запроса в таблицу значений
-
Выгружают всё в ТЗ на огромных выборках.
Выгрузить()на сотнях тысяч строк съедает память. Если строки обрабатываются по одной — используйтеВыбрать()и обход черезСледующий(). -
Путают Таблицу значений и Выборку.
Выгрузить()возвращаетТаблицаЗначений(обход черезДля Каждого), аВыбрать()—ВыборкаИзРезультатаЗапроса(обход черезПока Выборка.Следующий()). Это разные объекты с разными способами обхода. -
Обращение к колонке по неверному псевдониму. Имена колонок таблицы значений
берутся из псевдонимов запроса после
КАК.Строка.Наименованиесработает, только если в запросе есть... КАК Наименование. -
Ожидают ТаблицаЗначений при обходе по группировкам.
Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам)для запроса сИТОГИвозвращаетДеревоЗначений, а не плоскую таблицу — обход у него через.Строки. -
Считают строки через полную выгрузку. Чтобы узнать «есть ли данные»,
не нужно выгружать всё — используйте
Пустой()у результата запроса.
Частые вопросы о выгрузке результата запроса в 1С
Как получить результат запроса в таблицу значений в 1С?
Вызовите Запрос.Выполнить().Выгрузить(). Метод Выгрузить() объекта
РезультатЗапроса возвращает ТаблицаЗначений со всеми строками и
колонками выборки; колонки создаются по псевдонимам полей запроса.
Чем отличается Выгрузить() от Выбрать()?
Выгрузить() загружает всю выборку в таблицу значений сразу, а Выбрать()
возвращает выборку для построчного обхода через Следующий() без удержания всех
данных в памяти. На больших объёмах экономнее Выбрать().
Как выгрузить результат запроса по группировкам или в дерево значений?
Для запроса с секцией ИТОГИ вызовите
Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам) — метод вернёт
ДеревоЗначений с сохранением иерархии группировок. При обходе Прямой
(по умолчанию) получится плоская ТаблицаЗначений.