Как исправить неверные остатки на начало периода при группировке по Регистратору в СКД

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

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

Разберем причину возникновения ошибки

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

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

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

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

Проверим следующие настройки для полей:

  1. Номенклатура: должна иметь роль Измерение.
  2. Партия: если вы присоединяете её из регистра, она также должна быть помечена как Измерение. Если это просто дополнительный реквизит, убедитесь, что он не мешает расчету итогов.
  3. ПериодСекунда: это поле критически важно. Ему нужно назначить роль Период с порядковым номером (например, 1).
  4. Регистратор: ему также назначается роль Период, но с более высоким порядковым номером (например, 2). В поле Дополнительно для регистратора часто указывается, что он является уточнением периода.

Для ресурсов (полей остатков) в колонке Роль необходимо нажать на кнопку выбора и заполнить параметры:

Шаг 2. Обязательное использование поля ПериодСекунда

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

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


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

В настройках группировки отчета следует использовать иерархию: Номенклатура -> ПериодСекунда -> Регистратор. Если вы хотите видеть только регистратор, можно добавить ПериодСекунда в группировку вместе с ним (в одну строку), но оно обязательно должно присутствовать в выборке и иметь роль периода.

Шаг 3. Решение проблемы «размножения» остатков при соединении

Если после присоединения таблицы по Партии данные начали удваиваться или остатки стали некорректными, это признак того, что соединение (JOIN) в запросе нарушает целостность виртуальной таблицы. Рассмотрим более надежный способ получения данных — Связи наборов данных.

Вместо того чтобы писать сложный запрос с ЛЕВОЕ СОЕДИНЕНИЕ, попробуйте следующее:

  1. Создайте первый набор данных (запрос) только по виртуальной таблице остатков и оборотов.
  2. Создайте второй набор данных (запрос или объект), который выбирает информацию по партиям.
  3. Перейдите на вкладку Связи наборов данных.
  4. Свяжите наборы по полям Номенклатура и Партия.

Этот метод позволяет СКД сначала получить чистые остатки по регистру, а затем «подтянуть» к ним аналитику партий, не искажая математические итоги.

Шаг 4. Настройка ресурсов и функции ВычислитьВыражение

Автор темы пытался использовать сложную конструкцию с ВычислитьВыражениеСГруппировкойМассив. Зачастую это избыточно для простых ведомостей. Если роли периодов настроены верно, стандартный ресурс Сумма(КоличествоНачальныйОстаток) будет работать правильно.

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


ВычислитьВыражение("Сумма(КоличествоНачальныйОстаток)", "Номенклатура", "ОбщийИтог", "Первая", "Первая")

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

Подведем итоги

Для исправления проблемы с остатками по регистратору выполните проверку по чек-листу:

Соблюдение этих правил гарантирует, что ваш отчет будет строиться по классической логике 1С: когда начальный остаток по первому документу равен начальному остатку по товару в целом, а каждый последующий документ корректно «подхватывает» результат предыдущего.

← На главную