Как правильно добавить и настроить единый параметр периода в СКД при объединении наборов данных

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

При разработке отчетов на схеме компоновки данных (СКД) разработчики часто сталкиваются с необходимостью объединения информации из разных источников. Типичный пример — вывод в одном отчете данных по выработке транспортных средств (из путевых листов) и затрат на их обслуживание (из ремонтных листов). Для реализации этой задачи используется механизм «Набор данных - объединение».

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

Шаг 1. Оптимизация запросов и правильное обращение к датам документов

Разберем типичную ошибку, с которой столкнулся автор темы. При попытке наложить условие на дату документа через табличную часть (например, уатРемонтныйЛистМатериалы.Ссылка.Дата), система может выдать ошибку отсутствия поля или существенно снизить производительность отчета.

Обращение к реквизитам шапки документа через точку от табличной части (Материалы.Ссылка.Дата) в секции ГДЕ заставляет СУБД выполнять неявное левое соединение (LEFT JOIN). На базах с большим объемом данных это приводит к катастрофическому падению скорости генерации отчета. Чтобы этого избежать, мы применим явное внутреннее соединение табличной части с шапкой документа.

Рассмотрим правильную структуру первого запроса (выработка ТС):


ВЫБРАТЬ
    уатПутевойЛистЗадание.КоличествоЧасов КАК КоличествоЧасов,
    уатПутевойЛистЗадание.Ссылка.ТранспортноеСредство КАК ТС,
    уатПутевойЛистЗадание.ОбъектСтроительства КАК ОбъектСтроительства,
    уатПутевойЛист.Дата КАК Дата
ИЗ
    Документ.уатПутевойЛист.Задание КАК уатПутевойЛистЗадание
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.уатПутевойЛист КАК уатПутевойЛист
        ПО уатПутевойЛистЗадание.Ссылка = уатПутевойЛист.Ссылка
ГДЕ
    уатПутевойЛист.Дата МЕЖДУ &НачалоПериода И &КонецПериода

Теперь проанализируем второй запрос (затраты на ремонт) и построим его по аналогичному производительному принципу:


ВЫБРАТЬ
    уатРемонтныйЛистМатериалы.Сумма КАК Сумма,
    уатРемонтныйЛистМатериалы.Ссылка.ТС КАК ТС,
    уатРемонтныйЛист.Дата КАК Дата
ИЗ
    Документ.уатРемонтныйЛист.Материалы КАК уатРемонтныйЛистМатериалы
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.уатРемонтныйЛист КАК уатРемонтныйЛист
        ПО уатРемонтныйЛистМатериалы.Ссылка = uatРемонтныйЛист.Ссылка
ГДЕ
    уатРемонтныйЛист.Дата МЕЖДУ &НачалоПериода И &КонецПериода

Шаг 2. Объединение дублирующихся параметров

Выясним причину, почему в СКД изначально появляется 4 параметра вместо 2. Если в первом запросе написать &НачПериода и &КонПериода, а во втором — &ДатаНачала и &ДатаОкончания, компоновщик данных воспримет их как абсолютно разные сущности. На форме отчета пользователю придется заполнять четыре поля дат.

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

Шаг 3. Делаем выбор периода необязательным (Расширение языка запросов)

Если пользователь захочет сформировать отчет за все время, не указывая период, стандартный запрос с оператором МЕЖДУ выдаст ошибку или пустой результат. Чтобы сделать параметры гибкими, мы используем конструкцию расширения языка запросов СКД с фигурными скобками {}.

Перепишем условия фильтрации в наших запросах:


// Для первого запроса:
{ГДЕ (уатПутевойЛист.Дата >= &НачалоПериода), (уатПутевойЛист.Дата <= &КонецПериода)}

// Для второго запроса:
{ГДЕ (уатРемонтныйЛист.Дата >= &НачалоПериода), (уатРемонтныйЛист.Дата <= &КонецПериода)}

Если параметры периода не заполнены, СКД просто проигнорирует эти строки при построении итогового SQL-запроса к базе данных.

Шаг 4. Настройка дружелюбного интерфейса через «Стандартный период»

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

  1. Перейдем на вкладку «Параметры» в схеме компоновки данных.
  2. Добавим новый параметр, нажав на кнопку «Добавить» (плюс). Назовем его ПериодОтчета. Установим для него понятный заголовок — «Период».
  3. В колонке «Тип» для нового параметра выберем тип данных СтандартныйПериод.
  4. Для наших служебных параметров НачалоПериода и КонецПериода установим флажок в колонке «Ограничение доступности». Это скроет их от пользователя на форме настроек, чтобы избежать путаницы.
  5. В колонке «Выражение» для параметра НачалоПериода пропишем связь: &ПериодОтчета.ДатаНачала.
  6. В колонке «Выражение» для параметра КонецПериода укажем: КонецПериода(&ПериодОтчета.ДатаОкончания, "ДЕНЬ").

Важное примечание: использование функции КонецПериода крайне важно! Если пользователь выберет период, например, по сегодняшний день, то без этой функции граница установится на 00:00:00 начала дня. Все документы, проведенные в течение сегодняшнего дня, просто не попадут в отчет. Указание параметра "ДЕНЬ" сдвигает время границы на 23:59:59.

Шаг 5. Как профессионально убрать пустые строки (NULL) в объединениях

При объединении наборов данных из разных документов часто возникает проблема «рваных» строк. Например, в одной строке выводится транспортное средство и его выработка, а сумма ремонта пустая. В следующей строке — то же транспортное средство, пустая выработка, но заполнена сумма ремонта. Использование условного оформления (скрытие строк по условию видимости) является «костылем», который не решает проблему расхода памяти и некорректного расчета итогов.

Рассмотрим правильные архитектурные способы борьбы с этой проблемой:

  1. Синхронизация путей к данным. Убедитесь, что на вкладке «Наборы данных» связующее поле в обоих запросах имеет абсолютно одинаковый путь. Например, в обоих запросах это поле должно называться ТС. Если в одном наборе оно называется ТС, а в другом — ТранспортноеСредство, СКД не сможет их связать и разведет по разным колонкам и строкам.
  2. Отказ от детальных записей в структуре. Если в настройках отчета на вкладке «Настройки» добавить группировку «Детальные записи», система попытается вывести каждую физическую запись из документов. Поскольку путевой лист и ремонтный лист — разные объекты, они никогда не объединятся в одну детальную строку. Вместо этого удалите детальные записи, добавьте группировку по полю ТС, а числовые поля (КоличествоЧасов, Сумма) добавьте на вкладку «Ресурсы» с функцией Сумма(...). Компоновщик автоматически «схлопнет» данные по каждому автомобилю в одну красивую строку.
  3. Использование роли «Игнорировать NULL». На вкладке «Наборы данных» для вашего ключевого поля связи (например, ТС) откройте настройки в колонке «Роль». Установите флажок «Игнорировать NULL». Это заставит систему игнорировать группировочные записи, не имеющие ссылочной целостности по данному полю.

Применяя данные подходы, вы получите быстро работающий, визуально чистый и понятный для пользователей отчет, построенный на базе объединения разнородных данных.

← На главную