При разработке отчетов на Системе компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда добавление нового поля (например, Партии) или группировки по Регистратору приводит к «рассыпанию» итогов. Начальный остаток перестает быть общим для товара и начинает дробиться по документам или, что еще хуже, рассчитываться как нарастающий итог внутри дня с ошибками. Рассмотрим подробно, почему это происходит и как настроить отчет, чтобы остатки отображались корректно.
Основная проблема заключается в том, как СКД интерпретирует записи при наличии дополнительных соединений в запросе. Когда мы используем виртуальную таблицу Остатки и обороты, система ожидает четкой иерархии периодов и измерений. Как только в запрос добавляется левое соединение с таблицей партий или другой аналитикой, количество строк может увеличиться (если одной записи регистра соответствует несколько записей в присоединенной таблице). Это приводит к тому, что СКД «теряется» и не понимает, к какому именно моменту времени и разрезу аналитики относится остаток.
Ситуация, описанная автором (когда по первому регистратору выдается остаток только по его партии, а не общий по товару), говорит о неправильной настройке ролей полей и отсутствии учета иерархии периодов. Выясним, как это исправить по шагам.
Первым делом проанализируем вкладку Наборы данных в схеме компоновки. Для корректного расчета остатков у каждого поля должна быть четко определена его роль. Если роли настроены неверно, Сумма(НачальныйОстаток) будет работать как обычный ресурс, просто складывая числа, вместо того чтобы учитывать временную ось.
Проверим следующие настройки для полей:
Измерение.Измерение. Если это просто дополнительный реквизит, убедитесь, что он не мешает расчету итогов.Период с порядковым номером (например, 1).Период, но с более высоким порядковым номером (например, 2). В поле Дополнительно для регистратора часто указывается, что он является уточнением периода.Для ресурсов (полей остатков) в колонке Роль необходимо нажать на кнопку выбора и заполнить параметры:
КоличествоНачальныйОстаток) или Конечный.Количество).ПериодСекунда).Многие разработчики совершают ошибку, используя в группировках только Регистратор. Однако в системе 1С регистратор сам по себе не гарантирует уникальности во времени — в одну секунду может быть проведено несколько документов. Без поля ПериодСекунда СКД не может построить правильную последовательность записей.
Проанализируем ситуацию: чтобы остаток на начало Регистратора2 был равен остатку на конец Регистратора1, система должна четко знать их порядок. Рассмотрим пример настройки запроса:
ВЫБРАТЬ
РегистрНакопления.Номенклатура,
РегистрНакопления.Партия,
РегистрНакопления.ПериодСекунда,
РегистрНакопления.Регистратор,
РегистрНакопления.КоличествоНачальныйОстаток,
РегистрНакопления.КоличествоПриход,
РегистрНакопления.КоличествоРасход,
РегистрНакопления.КоличествоКонечныйОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Авто, , ) КАК РегистрНакопления
В настройках группировки отчета следует использовать иерархию: Номенклатура -> ПериодСекунда -> Регистратор. Если вы хотите видеть только регистратор, можно добавить ПериодСекунда в группировку вместе с ним (в одну строку), но оно обязательно должно присутствовать в выборке и иметь роль периода.
Если после присоединения таблицы по Партии данные начали удваиваться или остатки стали некорректными, это признак того, что соединение (JOIN) в запросе нарушает целостность виртуальной таблицы. Рассмотрим более надежный способ получения данных — Связи наборов данных.
Вместо того чтобы писать сложный запрос с ЛЕВОЕ СОЕДИНЕНИЕ, попробуйте следующее:
Номенклатура и Партия.Этот метод позволяет СКД сначала получить чистые остатки по регистру, а затем «подтянуть» к ним аналитику партий, не искажая математические итоги.
Автор темы пытался использовать сложную конструкцию с ВычислитьВыражениеСГруппировкойМассив. Зачастую это избыточно для простых ведомостей. Если роли периодов настроены верно, стандартный ресурс Сумма(КоличествоНачальныйОстаток) будет работать правильно.
Однако, если стоит задача вывести в строке каждого регистратора именно «входной» остаток по всей номенклатуре на начало периода отчета, можно использовать возможности языка выражений СКД. Посмотрим на пример корректного выражения ресурса:
ВычислитьВыражение("Сумма(КоличествоНачальныйОстаток)", "Номенклатура", "ОбщийИтог", "Первая", "Первая")
Это выражение вернет значение из первой строки группировки по Номенклатуре для всех вложенных записей (регистраторов). Но будьте осторожны: это полезно для визуализации, но может сбить с толку, если вы пытаетесь построить классический «нарастающий итог».
Для исправления проблемы с остатками по регистратору выполните проверку по чек-листу:
ГРУППИРОВАТЬ ПО в подзапросах или связи наборов данных).Соблюдение этих правил гарантирует, что ваш отчет будет строиться по классической логике 1С: когда начальный остаток по первому документу равен начальному остатку по товару в целом, а каждый последующий документ корректно «подхватывает» результат предыдущего.