Как настроить дополнение периодов в СКД и сохранить красивую сортировку без потери остатков?

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

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

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

Выясняем причину: почему пропадают остатки в пустых периодах?

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

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

Шаг 1. Настройка ролей полей в наборе данных

Прежде чем включать дополнение в настройках отчета, обязательно проверьте вкладку «Наборы данных» в конструкторе СКД. Без правильной разметки ролей дополнение работать не будет:

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

Шаг 2. Включение базового дополнения периодов

Перейдем к настройке структуры отчета на вкладке «Настройки»:

  1. Выберите группировку по вашему полю периода (например, ПериодМесяц).
  2. Внизу, в свойствах этой группировки, найдите вкладку «Дополнение» (в некоторых версиях интерфейса это доступно через детальные настройки выбранного поля группировки).
  3. Установите флаг использования дополнения.
  4. Выберите тип дополнения: ДвиженияИГраницыПериода. Это заставит систему дополнять периоды внутри интервала от первого до последнего движения.
  5. Для того чтобы дополнять периоды строго в границах выбранного пользователем диапазона дат отчета (даже если движений не было вообще во всем интервале), укажите в полях «Начало периода» и «Конец периода» параметры вашего отчета (например, &НачалоПериода и &КонецПериода).

После этого система начнет выводить пустые месяцы. Но тут мы сталкиваемся со следующей проблемой: поле дополнения имеет тип Дата (например, 01.02.2018 00:00:00). Выводить пользователю сухие даты начала месяца некрасиво. Нам нужно представление вида "Февраль 2018", а также сортировка по году и месяцу.

Если мы добавим в группировку строковое поле периода или поля года/месяца для сортировки, СКД выдаст ошибку:

Дополнение может быть выполнено только по одному полю или Нельзя в одной группировке использовать поле периода с другим полем.

Проанализируем три способа решения этой проблемы.

Решение 1. Использование встроенных свойств поля (Выражение представления и упорядочивания)

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

Перейдите на вкладку «Наборы данных», найдите ваше поле периода (например, ПериодМесяц) и настройте следующие параметры:

  1. Оформление (Формат): В колонке «Оформление» найдите параметр «Формат» и укажите строчку форматирования даты: ДФ='MMMM yyyy'. На выходе пользователь увидит понятное «Январь 2018», «Февраль 2018», при этом для системы поле останется полноценной датой.
  2. Выражение представления: Если форматирования недостаточно и вам нужна более сложная логика отображения, в колонке «Выражение представления» можно написать выражение на языке выражений СКД, например: Формат(ПериодМесяц, "ДФ='MMMM yyyy'").
  3. Выражение упорядочивания: Если вам нужна особая сортировка (например, вы хотите сортировать по какому-то специфическому алгоритму), пропишите выражение сортировки прямо в колонке «Выражение упорядочивания» для этого поля. В простейшем случае СКД отлично сортирует даты по возрастанию стандартным образом, поэтому если поле остается датой, дополнительно настраивать упорядочивание обычно не требуется — оно по умолчанию будет хронологическим.

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

Решение 2. Перенос логики форматирования в Вычисляемые поля

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

Рассмотрим, почему это помогает обойти ошибку дополнения:

Посмотрим на пример настройки вычисляемого поля:

  1. Перейдите на вкладку «Вычисляемые поля».
  2. Добавьте новое поле с именем ПредставлениеПериода.
  3. В колонку «Выражение» пропишите логику формирования строки, например: Формат(ПериодМесяц, "ДФ='MMMM yyyy'") или используйте более сложные функции работы с датами СКД.
  4. В настройках группировки используйте поле ПериодМесяц, а в выбранных полях или в качестве представления выводите ваше вычисляемое поле.

Решение 3. Связь двух наборов данных (Метод таблицы-календаря)

Бывают сложные случаи, когда стандартный механизм дополнения СКД по каким-то причинам не подходит или работает некорректно (например, при сложных объединениях или внешних наборах данных). В этом случае мы можем применить классический архитектурный паттерн — генерацию периодов через связь наборов данных.

Идея заключается в том, чтобы разделить получение периодов и получение самих данных на два разных запроса в СКД:

НаборДанных1 (Запрос-Календарь): Этот запрос должен возвращать нам исключительно список всех возможных периодов (месяцев) в выбранном интервале. Пример такого запроса на основе производственной закупки или регламентированного календаря (также можно сгенерировать периоды автоподбором из системных таблиц):


ВЫБРАТЬ РАЗЛИЧНЫЕ
    НАЧАЛОПЕРИОДА(РегламентированныйПроизводственныйКалендарь.Дата, МЕСЯЦ) КАК ПериодМесяц,
    ПредставлениеПериода КАК ИмяМесяца
ИЗ
    РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ГДЕ
    РегламентированныйПроизводственныйКалендарь.Дата МЕЖДУ &НачалоПериода И &КонецПериода

НаборДанных2 (Запрос-Данные): Это ваш основной запрос к виртуальной таблице остатков и оборотов регистра накопления. Он выбирает только реальные движения.

Теперь свяжем эти наборы на вкладке «Связи наборов данных»:

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

Важный нюанс: обработка NULL при детальных записях

Если вы выводите в дополненные периоды детальные записи (например, поле Регистратор), помните, что в тех месяцах, которые были добавлены искусственно механизмом дополнения, поле регистратора вернет значение NULL.

Это может привести к тому, что остатки поползут или строки начнут некрасиво двоиться. Чтобы этого избежать, обязательно найдите поле Регистратор на вкладке «Наборы данных» и в настройках его роли установите флаг «Игнорировать NULL». Это укажет процессору компоновки данных, что строки с пустыми регистраторами в дополненных периодах не нужно выделять в отдельные пустые записи, а следует корректно агрегировать их и переносить на них накопленный остаток предыдущих периодов.

Используя предложенные методы, вы сможете создавать профессиональные и визуально привлекательные отчёты со стабильным расчетом остатков по временной шкале без раздражающих пользователя пропусков данных.

← На главную