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