При проведении инвентаризации, оптимизации складских запасов или аудите номенклатурного справочника часто возникает задача выявить позиции, по которым не было никаких движений (поступлений, перемещений, списаний или продаж) за длительный срок — например, за последний год. Разберем основные способы решения этой задачи с помощью языка запросов 1С и в схеме компоновки данных (СКД).
Чтобы найти элементы справочника Номенклатура, по которым отсутствовали движения, необходимо выполнить следующие шаги:
&ДатаНачала и &ДатаКонца).Номенклатура с полученным списком движений.ЕСТЬ NULL).С точки зрения производительности реляционных СУБД (MS SQL Server, PostgreSQL) оптимальным подходом является предварительная выборка уникальных позиций с движениями во временную таблицу с индексацией, а затем левое соединение со справочником. Рассмотрим пример такого запроса:
ВЫБРАТЬ РАЗЛИЧНЫЕ
ТоварыНаСкладахОбороты.Номенклатура КАК Номенклатура
ПОМЕСТИТЬ ВТ_НоменклатураСДвижениями
ИЗ
РегистрНакопления.ТоварыНаСкладах.Обороты(&ДатаНачала, &ДатаКонца, , ) КАК ТоварыНаСкладахОбороты
ИНДЕКСИРОВАТЬ ПО
Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
СпрНоменклатура.Ссылка КАК Номенклатура,
СпрНоменклатура.Артикул КАК Артикул,
СпрНоменклатура.Код КАК Код
ИЗ
Справочник.Номенклатура КАК СпрНоменклатура
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_НоменклатураСДвижениями КАК ВТ_Движения
ПО СпрНоменклатура.Ссылка = ВТ_Движения.Номенклатура
ГДЕ
НЕ СпрНоменклатура.ЭтоГруппа
И НЕ СпрНоменклатура.ПометкаУдаления
И НЕ СпрНоменклатура.Услуга
И ВТ_Движения.Номенклатура ЕСТЬ NULL
УПОРЯДОЧИТЬ ПО
СпрНоменклатура.Наименование
Проанализируем ключевые моменты этого запроса:
ТоварыНаСкладах.Обороты обязательно передаются границы периода &ДатаНачала и &ДатаКонца. Это позволяет платформе 1С читать только нужные итоги и записи, а не всю историю базы.ИНДЕКСИРОВАТЬ ПО ускоряет последующее левое соединение на больших объемах данных.ВТ_Движения.Номенклатура ЕСТЬ NULL отсекает все товары, которые попали во временную таблицу (то есть имели хотя бы один оборот за период).НЕ СпрНоменклатура.ЭтоГруппа, НЕ СпрНоменклатура.ПометкаУдаления и НЕ СпрНоменклатура.Услуга исключают служебные и неактуальные строки.Посмотрим на более компактный вариант запроса, где проверка оборотов вынесена в подзапрос. Такой синтаксис часто используется для быстрых выборок в консоли запросов:
ВЫБРАТЬ
СпрНоменклатура.Ссылка КАК Номенклатура,
СпрНоменклатура.Код КАК Код
ИЗ
Справочник.Номенклатура КАК СпрНоменклатура
ГДЕ
НЕ СпрНоменклатура.ЭтоГруппа
И НЕ СпрНоменклатура.ПометкаУдаления
И НЕ СпрНоменклатура.Ссылка В
(ВЫБРАТЬ РАЗЛИЧНЫЕ
Обороты.Номенклатура
ИЗ
РегистрНакопления.ТоварыНаСкладах.Обороты(&ДатаНачала, &ДатаКонца, , ) КАК Обороты)
УПОРЯДОЧИТЬ ПО
СпрНоменклатура.Наименование
Обратите внимание: на сверхбольших справочниках (сотни тысяч элементов) конструкция с НЕ ... В (ВЫБРАТЬ ...) может уступать по скорости варианту с временной таблицей и левым соединением из-за особенностей построения плана запроса в СУБД.
Выясним, какой регистр накопления следует использовать в качестве источника данных:
Если отчет строится в СКД, нет необходимости жестко прописывать отбор в тексте запроса. Разберем порядок настройки:
Номенклатура и виртуальную таблицу Обороты через ЛЕВОЕ СОЕДИНЕНИЕ.&НачалоПериода и &КонецПериода.КоличествоОборот Не Заполнено (или КоличествоОборот Равно 0).