Язык запросов 1С

Результат запроса в таблицу значений в 1С: метод Выгрузить()

Коротко

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

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

Выгрузить результат запроса в таблицу значений 1С

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

Запрос = Новый Запрос;
Запрос.Текст =
    "ВЫБРАТЬ
    |   Номенклатура.Ссылка КАК Ссылка,
    |   Номенклатура.Наименование КАК Наименование,
    |   Номенклатура.Артикул КАК Артикул
    |ИЗ
    |   Справочник.Номенклатура КАК Номенклатура";

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

Сообщить("Строк выгружено: " + ТаблицаЗначений.Количество());
Для Каждого Строка Из ТаблицаЗначений Цикл
    Сообщить(Строка.Наименование + " / " + Строка.Артикул);
КонецЦикла;
Выгрузить
ТипОбходаОбходРезультатаЗапроса: Прямой (по умолчанию) или ПоГруппировкам
ТаблицаЗначений / ДеревоЗначений

Колонки таблицы значений создаются автоматически по псевдонимам полей запроса (после КАК). Поэтому имена в секции ВЫБРАТЬ и обращения к Строка.Наименование должны совпадать. Полученная таблица — обычная ТаблицаЗначений: её можно сортировать, сворачивать, накладывать отбор и присваивать реквизиту формы с типом «Таблица значений».

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

Ключевой выбор при работе с результатом запроса в 1С — Выгрузить() или Выбрать(). Оба метода вызываются у одного и того же РезультатЗапроса, но работают принципиально по-разному:

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

// Вариант 1: вся выборка сразу в память
ТаблицаЗначений = РезультатЗапроса.Выгрузить();

// Вариант 2: построчный обход без загрузки всего в память
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
    Сообщить(Выборка.Наименование);
КонецЦикла;
Выбрать
ТипОбходаПрямой или ПоГруппировкам
Группировкиимена полей группировок при обходе ПоГруппировкам
ГруппировкиДляЗначенийГруппировокдетализация значений группировок
ВыборкаИзРезультатаЗапроса

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

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

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

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

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

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

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

Выгрузить результат запроса в дерево значений

Метод Выгрузить() возвращает не только таблицу значений: при обходе по группировкам из запроса с ИТОГИ он отдаёт ДеревоЗначений с сохранением иерархии группировок. Это удобно для отчётов с раскрывающимися уровнями:

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

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

// Верхний уровень — склады, вложенные строки — номенклатура
Для Каждого СтрокаСклада Из ДеревоЗначений.Строки Цикл
    Сообщить(СтрокаСклада.Склад + ": " + СтрокаСклада.Количество);
КонецЦикла;

Тип возвращаемого значения зависит именно от ТипОбхода и структуры запроса: прямой обход и запрос без итогов дают плоскую ТаблицаЗначений, а обход по группировкам запроса с ИТОГИДеревоЗначений.

Колонки и количество строк таблицы значений

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

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

Сообщить("Количество строк: " + ТаблицаЗначений.Количество());

Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
    Сообщить("Колонка: " + Колонка.Имя);
КонецЦикла;

// Быстрая проверка «есть ли данные» без выгрузки — у самого результата:
Если Запрос.Выполнить().Пустой() Тогда
    Сообщить("Запрос не вернул строк");
КонецЕсли;

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

Когда выборка эффективнее выгрузки

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

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

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

Частые ошибки при выгрузке результата запроса в таблицу значений

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

Частые вопросы о выгрузке результата запроса в 1С

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

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

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

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

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

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