Как в СКД получить срез последних только по одному измерению регистра сведений

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

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

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

Причина поведения платформы 1С

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

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

Способ 1. Изменение структуры регистра сведений

Проанализируем архитектуру данных. Если бизнес-логика системы не требует хранить независимые срезы цен в разрезе каждого контрагента, оптимальным решением станет изменение состава объектов регистра сведений:

  1. Перенесите поле Контрагент из состава Измерений в Реквизиты регистра сведений.
  2. В этом случае уникальным ключом записи станет только измерение Номенклатура.
  3. Виртуальная таблица СрезПоследних начнет автоматически возвращать ровно одну актуальную запись на позицию номенклатуры, а контрагент будет выводиться как дополнительный справочный реквизит.

Способ 2. Построение «ручного» среза через физическую таблицу регистра

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

Разберем по шагам создание такого запроса:

  1. Выбираем из физической таблицы регистра Номенклатуру и максимальную дату записи МАКСИМУМ(Период) с группировкой по номенклатуре и помещаем результат во временную таблицу.
  2. Соединяем временную таблицу с физической таблицей регистра по полям Номенклатура и Период для получения значений ресурсов (цены).

Пример текста запроса в конструкторе СКД:


ВЫБРАТЬ
    Цены.Номенклатура КАК Номенклатура,
    МАКСИМУМ(Цены.Период) КАК Период
ПОМЕСТИТЬ ВТ_ПоследниеДаты
ИЗ
    РегистрСведений.ЦеныНоменклатуры КАК Цены
ГДЕ
    Цены.Период <= &Период
ГРУППИРОВАТЬ ПО
    Цены.Номенклатура
;

ВЫБРАТЬ
    ВТ.Номенклатура КАК Номенклатура,
    МАКСИМУМ(Цены.ЦенаОптовая) КАК ЦенаОптовая
ИЗ
    ВТ_ПоследниеДаты КАК ВТ
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК Цены
        ПО ВТ.Номенклатура = Цены.Номенклатура
        И ВТ.Период = Цены.Период
ГРУППИРОВАТЬ ПО
    ВТ.Номенклатура

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

Способ 3. Схлопывание записей на уровне ресурсов СКД

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

  1. Перейдите на вкладку Ресурсы в схеме компоновки данных.
  2. Задайте для поля ЦенаОптовая выражение агрегации Максимум(ЦенаОптовая) или используйте функцию СКД для получения цены по последней дате.
  3. В настройках структуры отчета оставьте только группировку по полю Номенклатура. В этом случае СКД автоматически объединит записи по товару и выведет одно итоговое значение.
← На главную