Как исправить некорректное распределение регистраторов по периодам в отчете СКД?

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

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

Проанализируем причины такого поведения платформы и разберем эффективные способы решения этой задачи.

Причины некорректной группировки периодов в СКД

Выясним, почему СКД связывает регистраторы и даты по неверной логике:

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

Способ 1. Настройка ролей полей в схеме компоновки данных

Самый простой и правильный способ решения проблемы без переработки запроса — корректная настройка ролей полей на вкладке Наборы данных в конструкторе СКД.

Рассмотрим настройку ролей по шагам:

  1. Перейдем на вкладку Наборы данных и найдем колонку Роль для полей отчета.
  2. Для поля ПериодСекунда (или Период) укажем роль Период, порядковый номер 1, тип Основное.
  3. Для поля ПериодДень укажем роль Период, порядковый номер 2, тип Дополнительно.
  4. Для поля Регистратор укажем роль Период, номер 1 и обязательно установим флаг Игнорировать NULL.
  5. Для измерений регистра (например, Партнер, Номенклатура) убедимся, что в колонке Роль явно указано Измерение.

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

Способ 2. Ограничение расчета ресурсов остатков

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

  1. Перейдем на вкладку Ресурсы.
  2. Для полей КоличествоНачальныйОстаток и КоличествоКонечныйОстаток в колонке Рассчитывать по... ограничим список группировок.
  3. Укажем расчет остатков только для верхних уровней (например, для группировок ПериодДень и Партнер), исключив расчет остатков по детальным записям и полю Регистратор.

Способ 3. Изменение структуры запроса и жесткое связывание

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

Рассмотрим пример запроса с временной таблицей, где период и регистратор жестко связываются:


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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ВТ.ПериодДень КАК ПериодДень,
	Регистр.ПериодСекунда КАК ПериодСекунда,
	Регистр.Партнер КАК Партнер,
	Регистр.Номенклатура КАК Номенклатура,
	Регистр.Регистратор КАК Регистратор,
	Регистр.КоличествоПриход КАК КоличествоПриход,
	Регистр.КоличествоРасход КАК КоличествоРасход
ИЗ
	ВТ_ПериодыДокументов КАК ВТ
	ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Авто, , ) КАК Регистр
		ПО ВТ.Регистратор = Регистр.Регистратор

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

← На главную