Как составить запрос для поиска неликвидных товаров в программе «Штрих-М: Торговое предприятие»?

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

Контроль неликвидных товаров — одна из ключевых задач любого торгового предприятия. Избыточные запасы, которые мертвым грузом лежат на складе, замораживают оборотные средства и снижают общую рентабельность бизнеса. В линейке решений «Штрих-М: Торговое предприятие» (версий 5 и 7) партионный учет и структура данных имеют свои особенности, из-за чего стандартные подходы к разработке аналитических отчетов могут вызывать трудности у начинающих программистов 1С.

В рамках данной статьи мы подробно разберем, как решить задачу поиска залежавшегося товара. Мы изучим штатные возможности конфигурации, проанализируем типичные ошибки при написании запросов к регистрам накопления, разберем проблему «отсечения новинок» и построим оптимальный, быстродействующий запрос на языке 1С для вывода реальных неликвидов.

Штатные инструменты для поиска неликвидов в «Штрих-М»

Прежде чем приступать к написанию собственного программного кода, давайте выясним, действительно ли в системе нет готового решения. Довольно часто пользователи и даже товароведы не знают обо всех возможностях программы. В конфигурациях «Штрих-М: Торговое предприятие» заложены базовые механизмы для подобного анализа:

  1. Встроенный отчет «Неликвидные товары». Найти его можно в группе аналитических отчетов (в зависимости от релиза он может располагаться в меню «Все розничные отчеты» либо в блоке складских отчетов). Данный отчет сопоставляет текущие складские остатки с частотой и объемами продаж за выбранный период.
  2. Универсальный отчет «Анализ номенклатуры». Он находится в меню Отчеты -> Номенклатура. В его настройках на вкладке «Общие» присутствует важный параметр «Вид отчета». По умолчанию там выбрано значение «Лидеры продаж» (ABC-анализ), однако, если переключить его на «Неликвидные товары», конфигурация автоматически перестроит схему компоновки данных и выведет товары по возрастанию их оборачиваемости.

Если штатный функционал по каким-то причинам вас не устраивает (например, требуется специфическое оформление или интеграция в сторонний АРМ), перейдем к разработке собственного запроса.

Разбор ошибок в логике запроса к регистрам накопления

Рассмотрим попытку построения запроса, с которой часто сталкиваются разработчики. Идея проста: получить остатки товаров, получить продажи за период, а затем соединить эти две таблицы левым соединением. Если продаж не было (значение равно NULL), то товар считается неликвидным.

Посмотрим на пример ошибочного кода, который часто приводят на форумах:


ВЫБРАТЬ
    ОстаткиНоменклатурыОстаткиИОбороты.Номенклатура,
    ОстаткиНоменклатурыОстаткиИОбороты.КоличествоНачальныйОстаток КАК Остатки
ПОМЕСТИТЬ ВТОстатки
ИЗ
    РегистрНакопления.ОстаткиНоменклатуры.ОстаткиИОбороты(&Начало, &Конец, МЕСЯЦ, , ) КАК ОстаткиНоменклатурыОстаткиИОбороты
ГДЕ
    ОстаткиНоменклатурыОстаткиИОбороты.КоличествоНачальныйОстаток > 0    
;
 ////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ОстаткиНоменклатурыОстаткиИОбороты.Номенклатура,
    ОстаткиНоменклатурыОстаткиИОбороты.КоличествоОборот = 0 КАК Продажи
ПОМЕСТИТЬ ВТПродажи
ИЗ
    РегистрНакопления.ОстаткиНоменклатуры.ОстаткиИОбороты(&Начало, &Конец, МЕСЯЦ, , ) КАК ОстаткиНоменклатурыОстаткиИОбороты
;
 ////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
    ВТОстатки.Номенклатура,
    ВТОстатки.Остатки КАК Остатки,
    ВТПродажи.Номенклатура КАК Номенклатура1,
    ВТПродажи.Продажи КАК Продажи
ИЗ
    ВТОстатки КАК ВТОстатки
        ЛЕВОЕ СОЕДИНЕНИЕ ВТПродажи КАК ВТПродажи
        ПО ВТОстатки.Номенклатура = ВТПродажи.Номенклатура
ГДЕ 
    ВТПродажи.Номенклатура = NULL // Ошибка!

Проанализируем две критические ошибки, из-за которых данный запрос возвращает либо пустой результат, либо некорректные данные.

Ошибка первая: сравнение с NULL через знак равенства. В теории реляционных баз данных и в языке запросов 1С значение NULL означает отсутствие данных. Оно не равно ничему, даже самому себе. Выражение ВТПродажи.Номенклатура = NULL всегда будет вычисляться как ЛОЖЬ. Для проверки отсутствия записи во второй таблице при левом соединении необходимо использовать специальный оператор ЕСТЬ NULL (в SQL — IS NULL).

Ошибка вторая: булево выражение в поле выборки. В таблице ВТПродажи поле Продажи формируется как КоличествоОборот = 0 КАК Продажи. Это логическое выражение, которое вернет либо ИСТИНА (если оборотов не было), либо ЛОЖЬ (если обороты были). При левом соединении, даже если продаж не было вовсе, строка из таблицы ВТОстатки соединится с записью из ВТПродажи, и поле примет конкретное булево значение, а не ожидаемый NULL. Проверять на отсутствие данных нужно строго ключевое поле связки — саму номенклатуру из правой таблицы.

Проблема «новинок»: как не спутать новый товар с неликвидом

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

Выясним, как решить эту проблему. Нам необходимо применить так называемый «период охлаждения» или отсечь свежие поступления. Для этого мы должны получить список товаров, по которым были приходы (движения с видом «Приход» по регистру накопления ОстаткиНоменклатуры) за определенный период (например, за последние 14–30 дней). Исключив эти новые товары из итоговой выборки, мы получим только честный, залежавшийся неликвид.

Пошаговое построение правильного запроса

Разберем по шагам логику построения эффективного запроса для поиска неликвидных товаров:

  1. Получаем текущие остатки. Нам нужны только те товары, которые физически присутствуют на складах на текущий момент (конечный остаток больше нуля).
  2. Получаем продажи за анализируемый период. Выбираем номенклатуру, по которой зафиксирован расход (продажа) за указанный пользователем интервал (например, 2-3 месяца).
  3. Получаем новые поступления. Собираем товары, которые впервые поступили на склад за последний месяц, чтобы исключить ложные срабатывания по новинкам.
  4. Соединяем таблицы. Применяем левое соединение остатков с таблицами продаж и приходов. В секции фильтрации ГДЕ оставляем только те строки, у которых в таблицах продаж и новинок образовался NULL.

Рассмотрим пример готового запроса, который можно использовать в консоли отчетов или при разработке собственного отчета:


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

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

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

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

Как работает этот запрос и как его настроить?

Рассмотрим подробнее параметры, которые передаются в разработанный нами запрос:

Использование временных таблиц (конструкция ПОМЕСТИТЬ) позволяет оптимизировать нагрузку на СУБД. Программа сначала подготавливает небольшие плоские таблицы в оперативной памяти, а затем быстро производит левое соединение по индексированным полям. Это обеспечивает высокую скорость работы отчета даже на базах данных с большим количеством номенклатурных позиций и интенсивным товарооборотом.

← На главную