Как в 1С получить остатки «несвежих» товаров по дате партии в запросе?

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

При построении отчетов по срокам хранения или анализе «залежалого» товара разработчики часто сталкиваются с проблемой: при попытке отфильтровать остатки по дате закупки строки в отчете просто исчезают, либо цифры не соответствуют ожиданиям. Рассмотрим, как правильно реализовать задачу вывода остатков товаров, которые хранятся на складе более определенного количества дней (X дней), на примере конфигурации «Управление торговлей 10.3» и регистра ПартииТоваровНаСкладах.

Почему фильтрация в секции ГДЕ работает некорректно?

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

Важный нюанс: В типовых решениях (УТ 10.3, КА 1.1, УПП 1.3) при использовании метода ФИФО остатки в регистре партий распределяются по конкретным документам оприходования. Если товар был списан, он списывается из самых старых партий. Следовательно, текущий остаток в разрезе документа оприходования — это и есть то, что осталось от конкретной закупки.

Решение 1: Использование параметров виртуальной таблицы

Наиболее правильный и производительный способ — наложение фильтра непосредственно в параметрах виртуальной таблицы. Это позволяет платформе 1С отобрать нужные записи еще на этапе формирования итогов в базе данных. Для нашей задачи эффективнее использовать таблицу Остатки, а не ОстаткиИОбороты, если нам не нужны данные о приходах и расходах за период.

Проанализируем пример запроса:


ВЫБРАТЬ
    ПартииОстатки.Номенклатура КАК Номенклатура,
    ПартииОстатки.КоличествоОстаток КАК ОстатокНесвежегоТовара,
    ПартииОстатки.ДокументОприходования КАК ДокументПартии,
    ПартииОстатки.ДокументОприходования.Дата КАК ДатаЗакупки
ИЗ
    РегистрНакопления.ПартииТоваровНаСкладах.Остатки(
        &КонецПериода,
        ДокументОприходования.Дата < &ДатаГраницыСвежести
    ) КАК ПартииОстатки

В данном случае &ДатаГраницыСвежести рассчитывается как ТекущаяДата() - (Х * 86400). Обратите внимание, что условие ДокументОприходования.Дата < &ДатаГраницыСвежести находится внутри круглых скобок параметров виртуальной таблицы. Это гарантирует, что в выборку попадут только те остатки, которые образовались от «старых» документов.

Решение 2: Использование конструкции ВЫБОР КОГДА

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

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


ВЫБРАТЬ
    Партии.Номенклатура КАК Номенклатура,
    СУММА(Партии.КоличествоОстаток) КАК ОбщийОстаток,
    СУММА(ВЫБОР
            КОГДА Партии.ДокументОприходования.Дата < &ДатаГраницы
                ТОГДА Партии.КоличествоОстаток
            ИНАЧЕ 0
        КОНЕЦ) КАК ОстатокСтарый
ИЗ
    РегистрНакопления.ПартииТоваровНаСкладах.Остатки(&Период, ) КАК Партии

СГРУППИРОВАТЬ ПО
    Партии.Номенклатура

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

Оптимизация производительности (Временные таблицы)

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

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

  1. Создать Временную Таблицу, в которую выбрать все ссылки на документы оприходования, дата которых меньше нужной.
  2. Использовать эту временную таблицу в качестве фильтра в основном запросе через оператор В (ВЫБРАТЬ ... ИЗ ВТ_Партии).

Пример оптимизированного подхода:


// Шаг 1: Отбор нужных документов
ВЫБРАТЬ
    Партии.Ссылка КАК Документ
ПОМЕСТИТЬ ВТ_СтарыеПартии
ИЗ
    Документ.ПоступлениеТоваровУслуг КАК Партии
ГДЕ
    Партии.Дата < &ДатаГраницы
;

// Шаг 2: Получение остатков
ВЫБРАТЬ
    Остатки.Номенклатура,
    Остатки.КоличествоОстаток
ИЗ
    РегистрНакопления.ПартииТоваровНаСкладах.Остатки(&Период, ДокументОприходования В (ВЫБРАТЬ Документ ИЗ ВТ_СтарыеПартии)) КАК Остатки

Итоги

Для корректного построения отчета по «несвежим» товарам в 1С:

← На главную