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

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

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

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

Причина возникновения дублей

Разберем ситуацию на примере. Допустим, на складе числится Товар1 в количестве 10 штук. У этого товара есть две цены: 500 рублей и 700 рублей. После выполнения запроса с соединением таблиц остатков и цен система получит следующие строки:

  1. Товар1 — 10 шт — 500 руб.
  2. Товар1 — 10 шт — 700 руб.

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

Способ 1. Использование функции ВычислитьВыражениеСГруппировкойМассив

Этот метод позволяет агрегировать данные внутри группировки по определенным правилам, игнорируя дублирующиеся строки. Рассмотрим, как правильно настроить выражение ресурса. Вместо простого суммирования в поле «Выражение» на вкладке «Ресурсы» необходимо прописать специальную конструкцию.

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

Итоговое выражение будет выглядеть следующим образом:


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

Разберем по шагам, как работает эта формула:

  1. ВычислитьВыражениеСГруппировкойМассив — функция создает массив значений, предварительно сгруппировав их по указанному полю.
  2. "Максимум(Остаток)" — это первый параметр. Он указывает, что внутри каждой группы (в нашем случае внутри каждой номенклатуры) нужно взять максимальное значение остатка. Поскольку остаток в дублях одинаковый, максимум из 10 и 10 даст нам 10.
  3. "Номенклатура" — второй параметр. Это измерение, по которому происходит сворачивание дублей. Мы говорим системе: «Сначала разберись с остатками внутри каждой номенклатуры, а потом отдай результат выше».
  4. Сумма(...) — внешняя функция, которая складывает все полученные уникальные значения из массива для расчета итогов по папкам или всему отчету.

Важный нюанс: при использовании этого метода важно правильно указывать поле группировки. Если считать не по полю Номенклатура, а по самому полю Остаток, система может пропустить разные товары с одинаковыми остатками, что приведет к занижению итогов.

Способ 2. Связь наборов данных в СКД

Еще один эффективный и зачастую более «чистый» с точки зрения архитектуры способ — разделение данных на разные наборы. Вместо одного сложного запроса с ЛЕВОЕ СОЕДИНЕНИЕ, мы создаем два отдельных набора данных:

  1. НаборДанныхОстатки: запрос, который получает только номенклатуру и ее количество.
  2. НаборДанныхЦены: запрос, который получает номенклатуру, тип цены и само значение цены.

Связь между ними настраивается на вкладке «Связи наборов данных». В качестве источника связи выступает набор с остатками, приемником — набор с ценами. Условие связи — Номенклатура.

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

Сравнение методов и рекомендации

Выясним, какой метод лучше использовать в различных ситуациях:

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

← На главную