Почему в отчете СКД появляются несуществующие будущие месяцы и как правильно настроить параметры периода

Программист 1С v8.3 (Обычные формы)
← На главную

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

В чем причина появления «лишних» периодов в отчете СКД

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

Выясним причину этого явления. Главная ошибка заключается в неверном выборе типа виртуальной таблицы регистра накопления и способе передачи условий периода:

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

Шаг 1. Выбор правильной виртуальной таблицы

Проанализируем задачу: если в отчете требуется вывести помесячную динамику расходов, продаж или иных движений за выбранный период без учета переходящих входящих и исходящих остатков, использовать таблицу ОстаткиИОбороты категорически не рекомендуется.

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

Сравним структуру запросов к двум таблицам:

Неправильно (использование таблицы остатков и оборотов для анализа движения):


ВЫБРАТЬ
	ПотолкиОстаткиИОбороты.Контрагент КАК Контрагент,
	ПотолкиОстаткиИОбороты.ПериодМесяц КАК ПериодМесяц,
	ПотолкиОстаткиИОбороты.ПлощадьОборот КАК ПлощадьОборот
ИЗ
	РегистрНакопления.Потолки.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Авто, , ) КАК ПотолкиОстаткиИОбороты

Правильно (использование виртуальной таблицы оборотов):


ВЫБРАТЬ
	ПотолкиОбороты.Контрагент КАК Контрагент,
	ПотолкиОбороты.ПериодМесяц КАК ПериодМесяц,
	ПотолкиОбороты.ПлощадьОборот КАК ПлощадьОборот
ИЗ
	РегистрНакопления.Потолки.Обороты(&НачалоПериода, &КонецПериода, Авто, ) КАК ПотолкиОбороты

Шаг 2. Настройка параметров виртуальной таблицы в СКД

Параметры периода виртуальной таблицы должны передаваться непосредственно в конструкторе запроса на вкладке «Таблицы и поля» в окне параметров виртуальной таблицы. В поля Начало периода и Конец периода следует вписать имена параметров со знаком &:

  1. Начало периода: &НачалоПериода
  2. Конец периода: &КонецПериода

Ни в коем случае не следует использовать конструкции вида Период >= &ДатаНачала И Период <= &ДатаОкончания в секции ГДЕ основного запроса.

Шаг 3. Связка с объектом СтандартныйПериод

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

  1. Создадим новый параметр ПериодОтчета с типом СтандартныйПериод.
  2. Для системных параметров НачалоПериода и КонецПериода настроим выражения связи:

    Для параметра НачалоПериода в поле «Выражение» укажем:

    &ПериодОтчета.ДатаНачала

    Для параметра КонецПериода в поле «Выражение» укажем:

    &ПериодОтчета.ДатаОкончания

  3. Установим флаг «Ограничение доступности» для параметров НачалоПериода и КонецПериода. Это скроет их от пользователя, оставив на форме только один удобный элемент выбора периода ПериодОтчета.

Платформа автоматически позаботится о том, чтобы дата окончания интервала содержала точное время конца дня (23:59:59), что исключит стандартные ошибки границы периода.

Шаг 4. Обработка периода в коде формы (для обычных форм / толстого клиента)

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

Посмотрим на пример правильной обработки события выбора периода на форме:


Процедура ВыбПериодНажатие(Элемент)

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

КонецПроцедуры

Шаг 5. Работа со спецификой СКД: парные ресурсы и дополнение периодов

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

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

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

← На главную