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