Можно ли получить список значений или массив прямо в запросе 1С

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

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

Ограничения языка запросов 1С

Проанализируем технические особенности работы платформы 1С. Чистый язык запросов 1С не позволяет возвращать сложные коллекции данных (такие как Массив, СписокЗначений или ТаблицаЗначений) в качестве значений колонок выборки.

Результатом выполнения запроса всегда является РезультатЗапроса, колонки которого могут содержать только примитивные типы (число, строка, дата, булево), ссылки на объекты базы данных, значение NULL или Неопределено. В языке запросов также отсутствуют стандартные агрегатные функции для конкатенации строк (аналоги SQL-функций GROUP_CONCAT или STRING_AGG).

Таким образом, выполнить команду вида Запрос.Выполнить().Выгрузить() и сразу получить заполненную колонку с типом СписокЗначений или Массив средствами одного только запроса невозможно.

Способ 1. Использование Системы компоновки данных (СКД)

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

Разберем, как настроить агрегацию в СКД:

  1. В схеме компоновки данных создадим набор данных — запрос, выбирающий детальные записи (например, номенклатуру, документ и сумму).
  2. Перейдем на вкладку Ресурсы.
  3. Для поля Ссылка (или Документ) укажем выражение агрегации: СоединитьСтроки(Массив(Различные Ссылка), ", ") Или, если требуется сформировать именно коллекцию: Массив(Различные Ссылка)
  4. В настройках отчета добавим группировку по полю Номенклатура.

При вычислении итогов СКД автоматически объединит все документы по каждой номенклатуре в одну строку через запятую или сформирует массив ссылок. Результат работы СКД можно вывести в отчет или программно выгрузить в ТаблицуЗначений.

Способ 2. Программная обработка результата запроса в BSL

Если применение СКД невозможно или требуется получить результат в виде обычной ТаблицыЗначений с колонкой типа СписокЗначений, используем двухуровневый запрос и программный обход результатов на языке 1С (BSL).

Рассмотрим пример запроса с секцией ИТОГИ ПО:


ВЫБРАТЬ
    ТЧ.Номенклатура КАК Номенклатура,
    ТЧ.Ссылка КАК Ссылка,
    СУММА(ТЧ.Сумма) КАК Сумма
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК ТЧ
ГДЕ
    ТЧ.Ссылка.Проведен = ИСТИНА
СГРУППИРОВАТЬ ПО
    ТЧ.Номенклатура,
    ТЧ.Ссылка
ИТОГИ
    СУММА(Сумма)
ПО
    Номенклатура

Далее выполним программную обработку полученного результата для формирования итоговой таблицы со списками значений:


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

ТЗРезультат = Новый ТаблицаЗначений;
ТЗРезультат.Колонки.Добавить("Номенклатура");
ТЗРезультат.Колонки.Добавить("Документы", Новый ОписаниеТипов("СписокЗначений"));
ТЗРезультат.Колонки.Добавить("Сумма");

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

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

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


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

СписокДокументов = Новый СписокЗначений;
СписокДокументов.ЗагрузитьЗначения(МассивДокументов);

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

← На главную