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