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

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

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

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

Почему стандартный СрезПоследних не подходит?

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

Реализация через пакетный запрос: пошаговая инструкция

Для решения этой задачи мы будем использовать конструкцию пакетного запроса. Весь процесс можно разделить на четыре этапа:

  1. Получение первичных данных. Сначала сформируем запрос к регистру бухгалтерии, который выведет все необходимые поля (Номенклатура, Склад, Регистратор, ДатаРегистратора и т.д.). Важно на этом этапе не пытаться привязывать цены, просто подготовим выборку документов.
  2. Соединение с физической таблицей регистра. Мы обращаемся не к виртуальной таблице, а к физической — РегистрСведений.ЦеныНоменклатуры. Мы выполняем соединение с результатом первого пакета по условию Номенклатура = Номенклатура и ДатаРегистратора >= ПериодЦена. Это позволит нам отобрать все цены, которые были установлены до момента проведения каждого конкретного документа.
  3. Определение последней актуальной даты. Теперь, когда у нас есть список всех цен, действовавших на момент документа, нам нужно выбрать самую близкую к дате документа. Для этого группируем результат второго пакета по полям Номенклатура и ДатаРегистратора, вычисляя максимум: МАКСИМУМ(Период). Это даст нам точную дату установки цены, актуальной на момент документа.
  4. Финал: соединение с максимумами. Используем внутреннее соединение между результатом второго и третьего пакетов по условию совпадения Номенклатуры, ДатаРегистратора и ПериодаЦена. В итоге мы получим набор данных, где каждой записи регистратора соответствует единственная актуальная цена.

Пример структуры пакетного запроса

Рассмотрим, как примерно выглядит этот алгоритм в консоли запросов:


// Пакет 1: Получаем регистраторы
ВЫБРАТЬ
    Хозрасчетный.Субконто1 КАК Номенклатура,
    Хозрасчетный.Регистратор,
    Хозрасчетный.Период КАК ДатаРегистратора
ПОМЕСТИТЬ ВТ_Документы
ИЗ РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный;

// Пакет 2: Соединяем с физической таблицей цен
ВЫБРАТЬ
    Док.Номенклатура,
    Док.ДатаРегистратора,
    Цены.Период КАК ПериодЦена,
    Цены.Цена
ПОМЕСТИТЬ ВТ_ВсеЦены
ИЗ ВТ_Документы КАК Док
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК Цены
ПО Док.Номенклатура = Цены.Номенклатура
ГДЕ Док.ДатаРегистратора >= Цены.Период;

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

// Пакет 4: Итоговое получение цен
ВЫБРАТЬ
    ВТ_ВсеЦены.Номенклатура,
    ВТ_ВсеЦены.ДатаРегистратора,
    ВТ_ВсеЦены.Цена
ИЗ ВТ_ВсеЦены КАК ВТ_ВсеЦены
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_МаксДаты КАК Макс
ПО ВТ_ВсеЦены.Номенклатура = Макс.Номенклатура
    И ВТ_ВсеЦены.ДатаРегистратора = Макс.ДатаРегистратора
    И ВТ_ВсеЦены.ПериодЦена = Макс.МаксПериод;

Важные рекомендации по производительности

Работа с физическими таблицами может быть требовательной к ресурсам сервера, особенно при больших объемах данных. Обратите внимание на следующие моменты:

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

← На главную