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