Как в запросе 1С отобрать материалы без движения за 90 дней и более одного года?

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

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

В чем заключается логика анализа неликвидов

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

  1. Полное отсутствие движений — за выбранный период не зафиксировано ни поступлений (прихода), ни списаний (расхода).
  2. Отсутствие расхода — товар мог поступить на склад, но с момента последней партии не перемещался и не списывался в производство или на продажу.

Проанализируем практические подходы к решению поставленной задачи в языке запросов 1С: от условий на обороты до расчета интервала неподвижности через специализированные функции работы с датами.

Способ 1. Использование виртуальной таблицы «ОстаткиИОбороты» с условием на нулевые обороты

Рассмотрим вариант, когда интервал анализа задается непосредственно границами периода в виртуальной таблице регистра (например, РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты или соответствующего регистра накопления). Чтобы получить позиции без движения за 90 дней, в качестве начала периода виртуальной таблицы указывается дата со смещением назад на 90 дней от точки анализа, а в условии отбора накладывается фильтр на отсутствие оборотов.

Посмотрим на пример запроса к регистру бухгалтерии:


ВЫБРАТЬ
    ХозрасчетныйОстаткиИОбороты.Субконто1 КАК Номенклатура,
    ХозрасчетныйОстаткиИОбороты.Субконто2 КАК Склад,
    ХозрасчетныйОстаткиИОбороты.КоличествоКонечныйОстаток КАК Остаток,
    ХозрасчетныйОстаткиИОбороты.СуммаКонечныйОстаток КАК СуммаОстатка
ИЗ
    РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(
            ДОБАВИТЬКДАТЕ(&КонецПериода, ДЕНЬ, -90),
            &КонецПериода,
            Авто,
            ,
            Счет В ИЕРАРХИИ (&Счета10),
            &СубконтоНоменклатураСклады,
            Организация = &Организация
                И Субконто2 = &Склад) КАК ХозрасчетныйОстаткиИОбороты
ГДЕ
    ХозрасчетныйОстаткиИОбороты.КоличествоКонечныйОстаток > 0
    И ХозрасчетныйОстаткиИОбороты.КоличествоОборотДт = 0
    И ХозрасчетныйОстаткиИОбороты.КоличествоОборотКт = 0

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

  1. Параметр начала периода рассчитывается с помощью функции ДОБАВИТЬКДАТЕ(&КонецПериода, ДЕНЬ, -90), которая возвращает дату ровно за 90 дней до указанной границы.
  2. В секции ГДЕ проверяется, что конечный остаток strictly больше нуля (КоличествоКонечныйОстаток > 0), чтобы исключить полностью списанные ранее позиции.
  3. Условия КоличествоОборотДт = 0 и КоличествоОборотКт = 0 отсекают любые приходные и расходные операции. Если требуется проверять только отсутствие расхода, условие на КоличествоОборотДт убирается.

Способ 2. Вычисление даты последнего движения и разности дней

Если в одном отчете требуется вывести одновременно позиции без движения за 90 дней и позиции без движения более 1 года (365 дней) с разделением по колонкам или категоризацией, более гибким подходом является нахождение даты самого последнего движения и вычисление разницы между ней и расчетной датой с помощью функции РАЗНОСТЬДАТ.

Рассмотрим структуру запроса, вычисляющего точное количество дней неподвижности и распределяющего номенклатуру по группам:


ВЫБРАТЬ
    Остатки.Субконто1 КАК Номенклатура,
    Остатки.Субконто2 КАК Склад,
    Остатки.КоличествоОстаток КАК Количество,
    Остатки.СуммаОстаток КАК Сумма,
    ЕСТЬNULL(Движения.МаксПериод, ДАТАВРЕМЯ(1, 1, 1)) КАК ДатаПоследнегоДвижения,
    РАЗНОСТЬДАТ(ЕСТЬNULL(Движения.МаксПериод, &КонецПериода), &КонецПериода, ДЕНЬ) КАК ДнейБезДвижения,
    ВЫБОР
        КОГДА Движения.МаксПериод ЕСТЬ NULL
            ТОГДА "Движений не было вообще"
        КОГДА РАЗНОСТЬДАТ(Движения.МаксПериод, &КонецПериода, ДЕНЬ) >= 365
            ТОГДА "Более 1 года"
        КОГДА РАЗНОСТЬДАТ(Движения.МаксПериод, &КонецПериода, ДЕНЬ) >= 90
            ТОГДА "От 90 дней до года"
        ИНАЧЕ "Менее 90 дней"
    КОНЕЦ КАК КатегорияНеподвижности
ИЗ
    РегистрБухгалтерии.Хозрасчетный.Остатки(
            &КонецПериода,
            Счет В ИЕРАРХИИ (&Счета10),
            &СубконтоНоменклатураСклады,
            Организация = &Организация
                И Субконто2 = &Склад) КАК Остатки
        ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
            ДвиженияРегистра.Субконто1 КАК Номенклатура,
            ДвиженияРегистра.Субконто2 КАК Склад,
            МАКСИМУМ(ДвиженияРегистра.Период) КАК МаксПериод
        ИЗ
            РегистрБухгалтерии.Хозрасчетный КАК ДвиженияРегистра
        ГДЕ
            ДвиженияРегистра.Период <= &КонецПериода
            И ДвиженияРегистра.Счет В ИЕРАРХИИ (&Счета10)
            И ДвиженияРегистра.Организация = &Организация
            И ДвиженияРегистра.Субконто2 = &Склад
        СГРУППИРОВАТЬ ПО
            ДвиженияРегистра.Субконто1,
            ДвиженияРегистра.Субконто2) КАК Движения
        ПО Остатки.Субконто1 = Движения.Номенклатура
            И Остатки.Субконто2 = Движения.Склад
ГДЕ
    РАЗНОСТЬДАТ(ЕСТЬNULL(Движения.МаксПериод, ДАТАВРЕМЯ(1, 1, 1)), &КонецПериода, ДЕНЬ) >= 90

Важные нюансы и рекомендации

Проанализируем технические детали, которые необходимо учитывать при модификации существующих отчетов:

  1. Выбор виртуальной таблицы: если необходимо получить только остаток на дату, всегда используйте таблицу .Остатки вместо .ОстаткиИОбороты. Задание периодичности Период и режима ДвиженияИГраницыПериода в таблице ОстаткиИОбороты без строгой группировки дробит строки по каждой операции, что приводит к некорректным результатам.
  2. Ограничение подзапроса сверху: при получении даты максимального движения (МАКСИМУМ(Период)) из физической таблицы регистра обязательно ограничивайте выборку условием Период <= &КонецПериода, чтобы документы, введенные будущей датой, не искажали расчет.
  3. Обработка отсутствующих значений: если позиция была внесена вводом остатков или движений по ней в базе не было, левое соединение возвратит NULL. Обязательно оборачивайте результирующие поля в функцию ЕСТЬNULL.
← На главную