Как исправить удвоение и умножение итогов остатков в отчетах СКД при выводе цен

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

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

Почему происходит «размножение» данных

Проанализируем ситуацию с точки зрения теории баз данных. Когда мы объединяем таблицу остатков с таблицей цен в одном запросе, система выполняет левое или внутреннее соединение. Если на одну запись из таблицы остатков (например, Товар №1 — 83 шт.) приходится несколько записей из таблицы цен (Оптовая, Розничная, Закупочная), в итоговой выборке запроса мы получим три строки. В каждой из этих строк будет значиться число 83. Для системы компоновки данных, если не заданы специальные настройки, это три разных числа, которые она добросовестно складывает в итогах, получая 249 вместо 83.

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

Одним из самых надежных и архитектурно правильных методов является разделение запроса на два независимых набора данных. Рассмотрим, как это реализовать:

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

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

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

Если мы предпочитаем использовать один запрос, нам необходимо «объяснить» системе компоновки, что поле Остаток является особенным. Выясним, как это сделать через механизм ролей:

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

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

Способ 3. Сложные выражения ресурсов

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

Рассмотрим пример использования функции Максимум или Среднее. Если в рамках одной номенклатуры остаток всегда одинаков во всех строках (различаются только цены), то формула Максимум(Остаток) в итогах по номенклатуре даст верное число (83). Однако для общих итогов по всему отчету просто Максимум не подойдет, так как он выберет максимальный остаток среди всех товаров.

Для корректного расчета общих итогов по всем товарам используем более сложную конструкцию:


Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(Остаток)", "Номенклатура"))

Разберем, что делает эта формула:

Способ 4. Организация колонок через вычисляемые поля

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

  1. На вкладке Вычисляемые поля добавим поле, например, ЗаголовокЦен с выражением "Цены номенклатуры".
  2. В настройках отчета добавим группировку колонок по этому полю.
  3. Внутрь этой группировки поместим ресурс Цена.
  4. Поля Остаток и Стоимость оставим в основных колонках или в другой группе.

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

Резюме и рекомендации

Для решения проблемы с «двоением» остатков в СКД рекомендуем придерживаться следующего алгоритма:

Во-первых, проверьте настройки ролей полей. Это самый быстрый способ, предусмотренный платформой. Во-вторых, если роли не помогают или отчет сложный, разделите получение остатков и получение цен на два разных набора данных (запроса), связав их по ключевым полям. В-третьих, используйте продвинутые агрегатные функции в ресурсах, такие как ВычислитьВыражениеСГруппировкойМассив, если вам нужно специфическое поведение итогов.

Помните, что СКД — это мощный инструмент, и понимание того, как он обрабатывает выборку данных (SQL-результат запроса), является ключом к созданию точных и профессиональных отчетов.

← На главную