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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки на платформе «1С:Предприятие 8» одной из самых частотных задач является получение данных из базы с их последующей обработкой в оперативной памяти. Наиболее удобным контейнером для такой работы является объект ТаблицаЗначений. В этой статье мы подробно разберем, как правильно перенести данные из результата запроса в таблицу, какие параметры при этом можно использовать и на что следует обратить внимание, чтобы избежать ошибок и проблем с производительностью.

Базовый метод выгрузки данных

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

Проанализируем пример простейшего кода:


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

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

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

Управление структурой колонок и типизация

Важно понимать, что метод Выгрузить() автоматически типизирует колонки создаваемой таблицы. Платформа анализирует описание типов полей в запросе и переносит эти типы в объект ТаблицаЗначений. Это критически важно для дальнейшей работы: если колонка типизирована как Число, вы сможете корректно вычислять итоги по ней или выполнять сортировку. Если же тип не определен (например, если поле запроса может принимать значения разных типов), в колонке таблицы значений будет установлен составной тип данных.

Рассмотрим ситуацию с именованием. Если мы забудем указать оператор КАК в запросе, платформа сформирует имя колонки автоматически (например, Поле1). Мы настоятельно рекомендуем всегда назначать осмысленные псевдонимы в тексте запроса. Это делает код читаемым и предотвращает ошибки при обращении к колонкам через конструкцию СтрокаТЗ.ИмяКолонки.

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

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

Выясним, какие варианты обхода существуют:

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

Пример получения дерева значений:


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

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

Производительность и работа с памятью

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

Проанализируем риски:

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

Ограничения контекста (Клиент-Сервер)

Важно помнить, что объект ТаблицаЗначений является серверным. Если вы вызываете запрос в контексте &НаСервере, вы без проблем получите таблицу. Однако передать этот объект напрямую на клиент (в процедуру &НаКлиенте) невозможно — это вызовет ошибку передачи данных между слоями системы.

Как мы можем решить эту проблему, если данные нужно отобразить в таблице на форме?

  1. Использовать метод ЗначениеВРеквизитФормы(ТаблицаРезультатов, "ИмяРеквизитаФормы"). Это заполнит таблицу, привязанную к интерфейсу.
  2. Преобразовать таблицу в Массив структур. Массивы и структуры являются универсальными типами и могут передаваться между клиентом и сервером.

Выгрузка в существующую таблицу

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

В этом случае мы рекомендуем следующий алгоритм:

  1. Выгрузите результат запроса во временную таблицу значений.
  2. Используйте цикл для обхода временной таблицы и добавления строк в основную таблицу методом Добавить().
  3. Или воспользуйтесь методом ЗагрузитьКолонку(), если типы и количество строк позволяют выполнить прямое копирование данных.

Использование для поиска и расчетов

Зачем вообще выгружать данные в таблицу, если есть запросы? Рассмотрим преимущества. Таблица значений позволяет выполнять операции, которые недоступны или сложны в языке запросов SQL:

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

← На главную