Как в одном отчете СКД сравнить данные за два разных периода?

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

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

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

---

Проблема: два периода — две разные таблицы?

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

Для решения этой задачи в СКД мы можем использовать два основных архитектурных сценария.

---

Сценарий А: Кросс-таблица через ОБЪЕДИНИТЬ ВСЕ (Рекомендуемый способ)

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

Разберем этот метод по шагам:

  1. Проектируем запрос СКД. Мы пишем два запроса, объединенных оператором ОБЪЕДИНИТЬ ВСЕ. В каждом запросе мы используем свои уникальные параметры для связи с виртуальными таблицами и добавляем искусственное текстовое поле ПериодДляСравнения.

Рассмотрим пример такого запроса:


ВЫБРАТЬ
    Продажи.Номенклатура КАК Номенклатура,
    Продажи.КоличествоОборот КАК Количество,
    Продажи.СуммаОборот КАК Сумма,
    "Текущий период" КАК ПериодДляСравнения
ИЗ
    РегистрНакопления.ВыручкаИПродажи.Обороты(&НачалоПериода1, &КонецПериода1, , ) КАК Продажи

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    Продажи.Номенклатура,
    Продажи.КоличествоОборот,
    Продажи.СуммаОборот,
    "Период для сравнения"
ИЗ
    РегистрНакопления.ВыручкаИПродажи.Обороты(&НачалоПериода2, &КонецПериода2, , ) КАК Продажи
  1. Настраиваем ресурсы. На вкладке «Ресурсы» определяем наши показатели: Количество и Сумма (рассчитываются по функции СУММА).
  2. Настраиваем структуру отчета. Переходим на вкладку «Настройки». Вместо обычной группировки создаем структуру типа «Таблица»:
    • В Строки добавляем группировку по полю Номенклатура.
    • В Колонки добавляем группировку по нашему системному полю ПериодДляСравнения.
    • В Выбранные поля перетаскиваем ресурсы Количество и Сумма.

Проанализируем результат: СКД автоматически сгруппирует все товары по строкам, а по колонкам выведет два блока — «Текущий период» и «Период для сравнения». Если товар продавался в обоих периодах, он займет одну строчку, а цифры распределятся по соответствующим столбцам. При необходимости настроить вывод конкретных показателей только в определенных колонках кросс-таблицы можно использовать способ вывода ресурса в СКД только в одной колонке без изменения запроса.

---

Сценарий Б: Полное соединение в пакете запросов (Для жесткой структуры)

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

Рассмотрим, как правильно составить такой запрос:

  1. Создаем первую временную таблицу. Собираем данные за первый период во временную таблицу ВТ_ТекущийПериод.
  2. Создаем вторую временную таблицу. Собираем данные за второй период во временную таблицу ВТ_ПрошлыйПериод.
  3. Соединяем таблицы. В финальном запросе выполняем ПОЛНОЕ СОЕДИНЕНИЕ этих таблиц. Важно использовать именно полное соединение, так как товар мог продаваться в прошлом периоде, но не продаваться в текущем, и наоборот. При этом обязательно обрабатываем возможные значения NULL с помощью функции ЕСТЬNULL.

Посмотрим на пример реализации финального запроса пакета:


ВЫБРАТЬ
    ЕСТЬNULL(Текущий.Номенклатура, Прошлый.Номенклатура) КАК Номенклатура,
    ЕСТЬNULL(Текущий.СуммаОборот, 0) КАК СуммаТекущая,
    ЕСТЬNULL(Прошлый.СуммаОборот, 0) КАК СуммаПрошлая,
    ЕСТЬNULL(Текущий.СуммаОборот, 0) - ЕСТЬNULL(Прошлый.СуммаОборот, 0) КАК ОтклонениеСумма
ИЗ
    ВТ_ТекущийПериод КАК Текущий
        ПОЛНОЕ СОЕДИНЕНИЕ ВТ_ПрошлыйПериод КАК Прошлый
        ПО Текущий.Номенклатура = Прошлый.Номенклатура

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

---

Важный подводный камень: почему данные в колонках становятся одинаковыми?

Частая ошибка при разработке подобных отчетов — вывод абсолютно идентичных данных в колонках обоих периодов. Выясним причину этого поведения.

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

Как решить эту проблему:

  1. Перейдите на вкладку «Параметры» в схеме компоновки данных.
  2. Для стандартных параметров НачалоПериода и КонецПериода установите галочку «Ограничение доступности».
  3. В свойствах вашего набора данных (на вкладке «Наборы данных») убедитесь, что вы не используете фигурные скобки автозаполнения периодов {} внутри текста запроса, так как они отдают управление периодами на откуп СКД. Используйте прямые параметры виртуальных таблиц, как показано в примерах выше.

---

Реализация галочки «Сравнивать с периодом» (динамическое управление колонками)

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

Решить эту задачу можно двумя путями: через условное оформление или программно в модуле объекта отчета.

Способ 1: Скрытие через Условное оформление (Без кода)

Этот способ позволяет решить задачу исключительно настройками компоновщика:

  1. Добавьте в параметры СКД новый параметр с типом Булево и именем СравниватьСПрошлымПериодом. Выведите его на пользовательскую форму.
  2. Перейдите на вкладку «Настройки» -> «Условное оформление».
  3. Добавьте новое правило оформления:
    • Оформление: Установите свойства МаксимальнаяШирина = 0.1 и МинимальнаяШирина = 0 (это визуально сожмет и скроет колонки).
    • Условие: ПараметрыДанных.СравниватьСПрошлымПериодом Равно Ложь.
    • Оформляемые поля: Выберите поля ресурсов, относящиеся ко второму периоду (например, СуммаПрошлая и ОтклонениеСумма).

Способ 2: Программное управление в модуле отчета (Максимально надежный)

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


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Получаем значение флага из параметров компоновщика
    ПараметрСравнение = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("СравниватьСПрошлымПериодом"));
    
    Если ПараметрСравнение <> Неопределено И ПараметрСравнение.Использование Тогда
        Если Не ПараметрСравнение.Значение Тогда
            // Если галочка снята, отключаем использование полей сравнения
            Для Каждого ВыбранноеПоле Из КомпоновщикНастроек.Настройки.Выбор.Элементы Цикл
                Если Строка(ВыбранноеПоле.Поле) = "СуммаПрошлая" Или Строка(ВыбранноеПоле.Поле) = "ОтклонениеСумма" Тогда
                    ВыбранноеПоле.Использование = Ложь;
                КонецЕсли;
            КонецЦикла;
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

---

Решение проблемы: Почему список «Выбор варианта отчета» пуст в режиме Предприятия?

В сообщении №9 пользователь столкнулся с тем, что созданные им в конфигураторе варианты отчета не отображаются при нажатии кнопки «Выбор варианта отчета» в режиме Предприятия.

Разберем, почему так происходит. Современные конфигурации на базе БСП (Библиотеки стандартных подсистем) хранят информацию о доступных вариантах отчетов в специальном справочнике Справочник.ВариантыОтчетов. Если вы просто добавили новый вариант в конфигураторе или открыли отчет как внешний, БСП еще не зарегистрировала его в своей базе данных.

Для исправления этой ситуации выполните следующие действия:

  1. Для внешнего отчета: Подключите ваш отчет через справочник «Дополнительные отчеты и обработки» (Администрирование -> Печатные формы, отчеты и обработки). БСП автоматически считает структуру схемы СКД и добавит все доступные варианты в справочник.
  2. Для встроенного отчета: Если отчет встроен в конфигурацию, необходимо инициировать обновление справочника вариантов. Для этого запустите базу с параметром запуска ЗапуститьОбновлениеИнформационнойБазы или выполните в консоли кода вызов метода обновления БСП:

Справочники.ВариантыОтчетов.ОбновитьСоставВариантовПоОписаниюВКонфигурации();

Также обязательно проверьте настройки самой схемы компоновки данных в конфигураторе: убедитесь, что у каждого варианта отчета на вкладке «Варианты» заполнено свойство «Представление» и снят флаг «Ограничить доступность».

Используя предложенные методики, мы можем создавать быстрые, удобные и интерактивные отчета сравнения периодов в СКД, которые не перегружают сервер СУБД и выводят информацию в удобном для конечного пользователя виде.

← На главную