Как в СКД 1С создать отчет с колонками разной длительности (кварталы, годы, бесконечность)?

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

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

Решение 1: Объединение запросов через ОБЪЕДИНИТЬ ВСЕ

Это самый прямой и надежный способ, предложенный на форуме. Суть метода заключается в создании одного набора данных-запроса в СКД, который состоит из нескольких подзапросов, соединенных с помощью оператора ОБЪЕДИНИТЬ ВСЕ. Каждый подзапрос отвечает за свой тип интервала.

Проанализируем структуру такого запроса. Нам нужно получить данные (например, суммы по договорам) и для каждой записи определить, в какой из наших кастомных периодов она попадает.

  1. Подготовка данных. Сначала получим исходные данные во временную таблицу. Это могут быть обороты по регистру накопления, записи регистра сведений и т.д. Главное, чтобы в таблице была дата и нужный показатель.
    
    ВЫБРАТЬ
        ФинансовыеГрафики.Ссылка КАК Договор,
        ФинансовыеГрафики.Период КАК Период,
        ФинансовыеГрафики.Сумма КАК Сумма
    ПОМЕСТИТЬ ВТ_ИсходныеДанные
    ИЗ
        РегистрСведений.ФинансовыеГрафики КАК ФинансовыеГрафики
    
  2. Формирование периодов. Теперь создадим основной запрос, который будет объединять данные по разным правилам группировки.

    Часть 1: Кварталы (с 01.01.2026 по 31.12.2028).

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

    
    ВЫБРАТЬ
        Данные.Договор,
        Данные.Сумма,
        // Формируем представление периода, например, "I квартал 2026 г."
        ПРЕДСТАВЛЕНИЕПЕРИОДА(НАЧАЛОПЕРИОДА(Данные.Период, КВАРТАЛ), "'кв.' q 'г.' yyyy") КАК ПредставлениеПериода,
        // Создаем поле для правильной сортировки
        ГОД(Данные.Период) * 100 + КВАРТАЛ(Данные.Период) КАК ПорядокСортировки
    ИЗ
        ВТ_ИсходныеДанные КАК Данные
    ГДЕ
        Данные.Период МЕЖДУ ДАТАВРЕМЯ(2026, 1, 1) И ДАТАВРЕМЯ(2028, 12, 31)
    

    Часть 2: Годы (с 01.01.2029 по 31.12.2033).

    Аналогично первому, но группируем по годам.

    
    ОБЪЕДИНИТЬ ВСЕ
    
    ВЫБРАТЬ
        Данные.Договор,
        Данные.Сумма,
        ПРЕДСТАВЛЕНИЕПЕРИОДА(НАЧАЛОПЕРИОДА(Данные.Период, ГОД), "'г.' yyyy") КАК ПредставлениеПериода,
        ГОД(Данные.Период) * 100 КАК ПорядокСортировки // Квартал равен 0 для годов
    ИЗ
        ВТ_ИсходныеДанные КАК Данные
    ГДЕ
        Данные.Период МЕЖДУ ДАТАВРЕМЯ(2029, 1, 1) И ДАТАВРЕМЯ(2033, 12, 31)
    

    Часть 3: "Бесконечность" (с 01.01.2034).

    Здесь все оставшиеся данные группируются в один период.

    
    ОБЪЕДИНИТЬ ВСЕ
    
    ВЫБРАТЬ
        Данные.Договор,
        Данные.Сумма,
        "с 2034 года" КАК ПредставлениеПериода,
        203400 КАК ПорядокСортировки
    ИЗ
        ВТ_ИсходныеДанные КАК Данные
    ГДЕ
        Данные.Период >= ДАТАВРЕМЯ(2034, 1, 1)
    
  3. Настройка структуры отчета и сортировки.

    После создания такого запроса у вас появятся поля: Договор, Сумма, ПредставлениеПериода и ПорядокСортировки.

    В настройках структуры отчета:

    • В строки добавьте группировку по полю Договор.
    • В колонки добавьте группировку по полю ПредставлениеПериода.
    • В ресурсы добавьте Сумма(Сумма).

    Критически важный шаг — настройка сортировки колонок. По умолчанию СКД отсортирует текстовое поле ПредставлениеПериода по алфавиту, что нарушит хронологию. Чтобы это исправить:

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

    Этот прием заставит СКД расположить колонки в правильном хронологическом порядке.

Решение 2: Связь наборов данных

Этот подход более структурирован и гибок, так как он разделяет логику формирования периодов и логику получения данных.

  1. Создаем набор данных "Периоды". Его задача — сгенерировать таблицу с нашими интервалами. Это можно сделать через запрос или даже через набор данных-объект, заполняемый программно.
    
    ВЫБРАТЬ ДАТАВРЕМЯ(2026, 1, 1) КАК НачалоИнтервала, ДАТАВРЕМЯ(2026, 3, 31) КАК КонецИнтервала, "1 кв. 2026" КАК НаименованиеИнтервала, 202601 КАК ПорядокСортировки
    ОБЪЕДИНИТЬ ВСЕ
    ВЫБРАТЬ ДАТАВРЕМЯ(2026, 4, 1), ДАТАВРЕМЯ(2026, 6, 30), "2 кв. 2026", 202602
    // ... и так далее для всех кварталов ...
    ОБЪЕДИНИТЬ ВСЕ
    ВЫБРАТЬ ДАТАВРЕМЯ(2029, 1, 1), ДАТАВРЕМЯ(2029, 12, 31), "2029 год", 202900
    // ... и так далее для всех годов ...
    ОБЪЕДИНИТЬ ВСЕ
    ВЫБРАТЬ ДАТАВРЕМЯ(2034, 1, 1), ДАТАВРЕМЯ(3999, 12, 31), "с 2034", 203400
    
  2. Создаем набор данных "Данные". Это ваш основной запрос, который извлекает финансовые показатели (аналогично ВТ_ИсходныеДанные из первого решения).
    
    ВЫБРАТЬ
        ФинансовыеГрафики.Ссылка КАК Договор,
        ФинансовыеГрафики.Период КАК Период,
        ФинансовыеГрафики.Сумма КАК Сумма
    ИЗ
        РегистрСведений.ФинансовыеГрафики КАК ФинансовыеГрафики
    
  3. Настраиваем связь наборов данных.

    Перейдите на вкладку "Связи наборов данных" в конструкторе схемы.

    • Источник связи: "Данные".
    • Приемник связи: "Периоды".
    • Выражение источника: Период.
    • Выражение приемника: НачалоИнтервала.
    • Условие связи: Вместо равенства (=) выберите условие "Больше или равно" (>=).
    • Добавьте еще одно условие связи: Период из источника и КонецИнтервала из приемника с условием "Меньше или равно" (<=).

    Таким образом, вы установите связь по попаданию даты из набора "Данные" в интервал из набора "Периоды". Настройка структуры отчета и сортировки выполняется аналогично первому решению, используя поля НаименованиеИнтервала и ПорядокСортировки из набора "Периоды".

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

Решение 3: Программная модификация запроса (продвинутый)

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

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

Посмотрим на примерный код. Допустим, в схеме СКД есть набор данных-запрос с текстом:


ВЫБРАТЬ
    NULL КАК НачалоИнтервала,
    NULL КАК КонецИнтервала
ПОМЕСТИТЬ ВТ_Интервалы
ГДЕ
    ЛОЖЬ
;
// ...Далее основной запрос, использующий ВТ_Интервалы

В обработчике ПриКомпоновкеРезультата пишем код:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;

    // Получаем настройки и текст запроса
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);
    
    ТекстЗапроса = МакетКомпоновки.НаборыДанных[0].Запрос;
    
    // Формируем текст для замены
    ТекстИнтервалов = "";
    Для Каждого СтрокаИнтервала Из ЭтаФорма.ТаблицаИнтервалов Цикл
        ТекстИнтервалов = ТекстИнтервалов + ?(ПустаяСтрока(ТекстИнтервалов), "", " ОБЪЕДИНИТЬ ВСЕ ") + "
        |ВЫБРАТЬ ДАТАВРЕМЯ(" + Формат(СтрокаИнтервала.НачалоИнтервала, "ДФ=yyyy,M,d") + ") КАК НачалоИнтервала, " +
                       "ДАТАВРЕМЯ(" + Формат(СтрокаИнтервала.КонецИнтервала, "ДФ=yyyy,M,d") + ") КАК КонецИнтервала";
    КонецЦикла;
    
    // Подменяем заглушку в запросе
    ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ВЫБРАТЬ NULL КАК НачалоИнтервала, NULL КАК КонецИнтервала ПОМЕСТИТЬ ВТ_Интервалы ГДЕ ЛОЖЬ", ТекстИнтервалов + " ПОМЕСТИТЬ ВТ_Интервалы");
    
    // Выполняем компоновку с измененным запросом
    // ... код выполнения и вывода результата ...
    
КонецПроцедуры

Этот метод сложен в реализации, но незаменим, когда требуется полная динамика в определении периодов отчета.

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

← На главную