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

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

Задача поиска позиций номенклатуры без движений часто возникает при оптимизации базы данных, очистке справочников от неиспользуемых элементов, а также при решении бизнес-задач по анализу залежалых остатков (неликвидов). В зависимости от конкретных требований бизнеса подходы к написанию запроса на платформе 1С:Предприятие будут существенно различаться.

Разберем основные сценарии решения этой задачи, выясним причину частых ошибок и рассмотрим примеры эффективных запросов.

Сценарий 1. Поиск номенклатуры, по которой никогда не было движений

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

Рассмотрим, как правильно построить запрос с использованием конструкции ЛЕВОЕ СОЕДИНЕНИЕ (паттерн Anti-Join). Соединение справочника с физической таблицей регистра без использования виртуальных таблиц работает максимально быстро, так как СУБД не тратит ресурсы на расчет итогов:


ВЫБРАТЬ
	СпрНоменклатура.Ссылка КАК Номенклатура
ИЗ
	Справочник.Номенклатура КАК СпрНоменклатура
	ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
		ПО СпрНоменклатура.Ссылка = ТоварыНаСкладах.Номенклатура
ГДЕ
	ТоварыНаСкладах.Номенклатура ЕСТЬ NULL
	И НЕ СпрНоменклатура.ЭтоГруппа
	И НЕ СпрНоменклатура.ПометкаУдаления

Разберем важные детали этого запроса:

  1. Исключение групп: Обязательно добавляем условие НЕ СпрНоменклатура.ЭтоГруппа, чтобы в результат не попадали папки иерархического справочника.
  2. Проверка на NULL: Условие ТоварыНаСкладах.Номенклатура ЕСТЬ NULL отсекает все позиции, которые присутствуют хотя бы в одной строке регистра.
  3. Псевдонимы таблиц: Для справочника задан явный псевдоним СпрНоменклатура. Это исключает распространенную ошибку платформы «Неоднозначное поле», когда имя таблицы совпадает с именем реквизита или измерения.

Сценарий 2. Отбор товаров без движений за определенный период (через временную таблицу)

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


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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	СпрНоменклатура.Ссылка КАК Ссылка,
	СпрНоменклатура.Наименование КАК Наименование
ИЗ
	Справочник.Номенклатура КАК СпрНоменклатура
	ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ДвиженияЗаПериод КАК ВТ_ДвиженияЗаПериод
		ПО СпрНоменклатура.Ссылка = ВТ_ДвиженияЗаПериод.Номенклатура
ГДЕ
	ВТ_ДвиженияЗаПериод.Номенклатура ЕСТЬ NULL
	И НЕ СпрНоменклатура.ЭтоГруппа

Использование инструкции ИНДЕКСИРОВАТЬ ПО ускоряет последующее левое соединение временной таблицы со справочником в СУБД.

Сценарий 3. Поиск неликвидов (товар есть на остатке, но нет расхода)

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

Посмотрим на пример отбора неликвидных товаров:


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

В этом запросе мы отбираем только те позиции, которые физически присутствуют на остатке на конец периода (КоличествоКонечныйОстаток > 0), но при этом за весь интервал не имели расхода (КоличествоРасход = 0).

Практические рекомендации при разработке

  1. Учет дополнительных разрезов: Если на складах ведется учет по характеристикам или сериям, анализируйте необходимость группировки до уровня номенклатуры или проверки комбинации полей (Номенклатура, Характеристика).
  2. Проверка ссылочной целостности: Если цель отбора — очистка базы и удаление неиспользуемых элементов, перед непосредственным удалением используйте метод НайтиСсылкиНаОбъект(). Он гарантирует, что на позицию нет ссылок в других документах, реквизитах справочников и периодических регистрах сведений.
  3. Исключение служебных движений: Если перемещение между складами не должно считаться движением (продажей), предпочтительно использовать регистры подсистемы продаж (например, ВыручкаИСебестоимостьПродаж или Продажи) вместо складских регистров остатков.
← На главную