Как вывести сторно-записи в отчет СКД и сохранить корректные остатки

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

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

Выясним причину: почему «плывут» остатки

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

Поскольку остаток — это значение на определенный момент времени, а регистратор — это событие, система пытается сопоставить начальный остаток конкретной записи регистратора. Так как на момент начала периода регистратор еще не совершил движение, возникают дубли или обнуление итогов. Чтобы избежать этого, нам нужно либо правильно настроить роли периодов, либо изменить структуру получения данных.

Способ 1. Использование двух наборов данных (Объединение)

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

Шаг 1. Создаем первый набор данных (Запрос к виртуальной таблице).

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


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

Шаг 2. Создаем второй набор данных (Запрос к физической таблице).

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


ВЫБРАТЬ
    Взаиморасчеты.Контрагент КАК Контрагент,
    Взаиморасчеты.Регистратор КАК Регистратор,
    Взаиморасчеты.Период КАК Период,
    Взаиморасчеты.Сумма КАК СуммаОборот
ИЗ
    РегистрНакопления.РасчетыСКлиентами КАК Взаиморасчеты
ГДЕ
    Взаиморасчеты.Период МЕЖДУ &НачалоПериода И &КонецПериода

Шаг 3. Настройка связей наборов данных.

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

Способ 2. Правильная настройка ролей полей периода

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

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

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

Способ 3. Работа с детализацией до записей регистра

Проанализируем ситуацию, когда сторно-записи пропадают из-за того, что итоговый оборот за период равен нулю. Например, приход составил 500 рублей, и в этот же день был оформлен возврат (сторно) на 500 рублей.

Чтобы такие записи отображались в отчете, выполним следующие настройки:

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

Важные нюансы при работе со сторно

Разберем специфику сторно в регистрах накопления. Сторно может быть реализовано двумя способами: записью с отрицательным числом или изменением свойства Активность = Ложь.

Если вы используете виртуальные таблицы оборотов, помните, что они учитывают только записи с Активность = Истина. Если ваше сторно — это просто отрицательная сумма при активной записи, она попадет в обороты стандартно. Если же сторно выполняется путем выключения активности записи, то в стандартных виртуальных таблицах вы ее не увидите. В этом случае поможет только прямой запрос к физической таблице регистра с условием по полю Активность.

Подведем итог: для корректного вывода сторно-записей при сохранении целостности остатков рекомендуется использовать метод двух наборов данных или тонкую настройку иерархии ролей периодов (ПериодСекунда — 1, Регистратор — 10). Это гарантирует, что каждая копейка, даже если она «ушла в ноль», будет видна пользователю в ведомости.

← На главную