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