Почему СКД «двоит» данные в отчетах по остаткам и оборотам и как это исправить

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

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

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

Основная причина «двоения» данных кроется в механизме работы виртуальных таблиц. Когда мы выбираем периодичность, отличную от «Период», система формирует записи для каждой точки изменения остатка в выбранном интервале. Проанализируем ситуацию: если в параметрах виртуальной таблицы указана периодичность Запись, 1С вернет остатки на момент каждого документа-регистратора. Если мы не выводим Регистратор в группировку, СКД пытается «схлопнуть» эти записи. Без специальных указаний система просто суммирует все значения остатков, которые она нашла для каждой записи, что и приводит к кратному увеличению итога.

Шаг 1. Настройка периодичности виртуальной таблицы

Первым делом обратим внимание на параметры виртуальной таблицы в тексте запроса. Рассмотрим пример стандартного запроса к регистру бухгалтерии:


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

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

Шаг 2. Использование обязательных служебных полей

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

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

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

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

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

  1. Найдите поле СуммаНачальныйОстаток. В колонке «Роль» откройте редактор.
  2. Установите флаг Остаток.
  3. В поле Имя укажите общее имя для пары остатков, например, Сумма.
  4. В поле Тип выберите Начальный.
  5. В поле Поле периода укажите ПериодСекунда (или ПериодДень, если это минимальный период в вашем запросе).
  6. Для поля СуммаКонечныйОстаток проделайте то же самое, но выберите тип Конечный.

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

Шаг 4. Настройка ресурсов и функции «Рассчитывать по...»

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


Сумма(СуммаНачальныйОстаток)
Сумма(СуммаКонечныйОстаток)
Сумма(СуммаОборот)

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

Шаг 5. Особенности использования выражений Субконто

В бухгалтерских отчетах часто используется конструкция ВЫРАЗИТЬ(Субконто КАК ...). Рассмотрим пример:


ВЫРАЗИТЬ(ХозрасчетныйОстаткиИОбороты.Субконто1 КАК Справочник.Контрагенты) КАК Контрагент

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

Шаг 6. Исключение влияния соединений

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

Резюме для проверки отчета

Если ваш отчет продолжает «двоить» данные, пройдитесь по этому чек-листу:

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

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

← На главную