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