К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как выгрузить запрос в массив в 1С

Как выгрузить результат запроса 1С в массив: ВыгрузитьКолонку, обход выборки, различия для обычных и управляемых форм. Примеры кода, ошибки и проверка результата.

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

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

Ниже разобраны рабочие примеры кода для каждого сценария, типичные ошибки, из-за которых массив оказывается пустым или содержит не те данные, и способы проверить результат до передачи его дальше по алгоритму.

Как устроен результат запроса и почему массива в нём нет

После выполнения метода Запрос.Выполнить() вы получаете объект «РезультатЗапроса». Из него данные извлекаются двумя способами: методом Выбрать(), который возвращает выборку для последовательного обхода, и методом Выгрузить(), который материализует весь результат в таблицу значений (по умолчанию) или в дерево значений (при указании типа обхода «ПоГруппировкамСИерархией»).

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

Способ 1. Выгрузить одну колонку в массив

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Ссылка

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| НЕ Номенклатура.ПометкаУдаления";

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

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

МассивСсылок = ТаблицаРезультата.ВыгрузитьКолонку("Ссылка");

Имя колонки в ВыгрузитьКолонку() должно совпадать с псевдонимом поля в тексте запроса. Если в запросе поле не имеет явного псевдонима, платформа назначит имя автоматически, и надёжнее всегда задавать псевдоним через КАК. Ошибка в имени колонки приведёт к исключению времени выполнения, которое в толстом клиенте отладить просто, а в серверном коде без журнала регистрации — заметно сложнее.

Учтите, что в массив попадут все строки, включая возможные дубли и значения NULL, если поле составного типа или в выборке есть левое соединение. Если нужны только уникальные значения, добавьте в текст запроса РАЗЛИЧНЫЕ — это дешевле, чем сворачивать массив потом вручную.

bsl
МассивСсылок = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");

Способ 2. Обход выборки с заполнением массива структур

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Товары.Номенклатура КАК Номенклатура,

| Товары.Количество КАК Количество,

| Товары.Сумма КАК Сумма

|ИЗ

| Документ.РеализацияТоваровУслуг.Товары КАК Товары

|ГДЕ

| Товары.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", ДокументСсылка);

МассивСтрок = Новый Массив;

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

СтрокаДанных = Новый Структура("Номенклатура, Количество, Сумма");

ЗаполнитьЗначенияСвойств(СтрокаДанных, Выборка);

МассивСтрок.Добавить(СтрокаДанных);

КонецЦикла;

Метод ЗаполнитьЗначенияСвойств() копирует значения из текущей строки выборки в структуру по совпадающим именам, поэтому ключи структуры должны точно совпадать с псевдонимами полей запроса. Если имя в запросе отличается или содержит точку (например, при выборке через разыменование), заполнение такого свойства молча пропустится — это одна из самых коварных причин «пустых» полей в итоговом массиве.

При большом объёме данных заранее оцените размер выборки. Массив из сотен тысяч структур расходует заметно больше памяти, чем таблица значений с теми же данными, потому что каждая структура хранит имена ключей. Если данные нужны только для серверной обработки, таблица значений часто оказывается рациональнее.

Порядок действий для массива структур
  1. 1
    Сформируйте запрос и задайте псевдонимы всем полям через КАК
  2. 2
    Выполните запрос и получите выборку методом Выбрать()
  3. 3
    Создайте пустой массив перед циклом
  4. 4
    В цикле Пока Выборка.Следующий() создавайте структуру и заполняйте её через ЗаполнитьЗначенияСвойств
  5. 5
    Добавляйте структуру в массив и после цикла проверьте Массив.Количество()

Способ 3. Передача результата запроса на клиент в управляемой форме

В управляемом приложении таблица значений недоступна на клиенте, и попытка вернуть её из серверной процедуры приведёт к ошибке сериализации. Стандартное решение — вернуть массив структур, собранный на сервере, либо использовать реквизит формы типа «ДинамическийСписок» или «ТаблицаЗначений» через механизм данных формы.

&НаСервереБезКонтекста

Функция ПолучитьДанныеНаСервере(ОтборСсылка)

// ... запрос и обход выборки ...

Возврат МассивСтрок;

КонецФункции

&НаКлиенте

Процедура ЗагрузитьДанные(Команда)

Данные = ПолучитьДанныеНаСервере(ТекущийДокумент);

Для Каждого СтрокаДанных Из Данные Цикл

// обработка на клиенте

КонецЦикла;

КонецПроцедуры

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

Сравнение способов и условия выбора

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

Сравнение вариантов

ВыгрузитьКолонку()

Подходит для списка значений одного поля. Минимум кода, но требует полной выгрузки результата в таблицу значений.

Обход выборки в массив структур

Единственный способ передать несколько полей на клиент в управляемой форме. Больше кода и выше расход памяти на больших объёмах.

Таблица значений через Выгрузить()

Лучший вариант для серверной логики: поиск, сортировка, итоги. Недоступна на клиенте управляемого приложения.

Прямая обработка выборки без массива

Если данные нужны один раз и последовательно, массив вообще не нужен — обрабатывайте строки в цикле выборки и экономьте память.

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

Маршрут решения

Как выбрать действие

Нужен список ссылок для параметра запроса или отбораИспользуйте Выгрузить().ВыгрузитьКолонку() с псевдонимом поля
Нужно вернуть данные с сервера на клиент управляемой формыСоберите массив структур обходом выборки на сервере
Нужны поиск, сортировка и итоги на сервереОставьте результат в таблице значений, массив не создавайте
Результат потенциально содержит сотни тысяч строкОбрабатывайте выборку в цикле без промежуточных коллекций

Проверка результата и типичные ошибки

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

Контрольные точки

Как проверить результат

Результат запроса
Норма

РезультатЗапроса.Пустой() = Ложь

Тревожный признак

Пустой результат — проверяйте параметры и условия запроса

Заполненность массива
Норма

Массив.Количество() больше нуля и совпадает с числом строк выборки

Тревожный признак

Массив пуст или строк меньше, чем вернул запрос

Тип значений
Норма

Элементы массива имеют ожидаемый тип (ссылка, число, строка)

Тревожный признак

В массиве NULL или значения другого типа из-за составного поля

Совпадение имён
Норма

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

Тревожный признак

Свойства структуры не заполняются из-за расхождения имён

Типичные ошибки
01
Обращение к ВыгрузитьКолонку() по имени поля без псевдонима — имя колонки не совпадает, возникает исключение. Всегда задавайте КАК в тексте запроса.
02
Попытка вернуть таблицу значений с сервера на клиент в управляемой форме — ошибка сериализации. Возвращайте массив структур.
03
Отсутствие РАЗЛИЧНЫЕ при выгрузке колонки — массив содержит дубли, которые потом искажают отборы и циклы.
04
Игнорирование NULL в левых соединениях — в массиве появляются неопределённые значения, ломающие дальнейшую логику.
05
Выгрузка результата без отбора из большой таблицы — переполнение памяти и падение рабочего процесса.

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

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

FAQ: частые вопросы о выгрузке запроса в массив

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

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

Чем массив структур отличается от таблицы значений при работе с запросом?

Таблица значений поддерживает поиск, сортировку, свёртку и итоги, но недоступна на клиенте в управляемом приложении. Массив структур свободно передаётся между клиентом и сервером, но не имеет встроенных методов поиска и сортировки и расходует больше памяти на больших объёмах.

Почему после ВыгрузитьКолонку массив пустой, хотя запрос возвращает данные?

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

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

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

Есть ли ограничение на размер массива в 1С?

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

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

Да. Установите параметр через Запрос.УстановитьПараметр("Список", МассивСсылок) и используйте в тексте условие ГДЕ Поле В (&Список). Платформа автоматически разворачивает массив в список значений. Пустой массив при этом даст условие, которому не удовлетворяет ни одна строка.

Итог

Что важно запомнить

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