Как в 1С вывести в одном отчете данные по продажам, а также клиентов и товары без продаж?

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

В управленческом учете часто возникает задача проанализировать «пустые» зоны: понять, какие клиенты перестали совершать покупки или какие товары из ассортимента лежат мертвым грузом. Стандартные отчеты по продажам обычно строятся по регистру ВыручкаИСебестоимостьПродаж и показывают только те записи, где движение уже произошло. Если продажи не было — записи в регистре нет, и строка в отчет не попадает.

Разберем подробно, как спроектировать запрос, который позволит вывести полную картину: и реальные продажи, и тех контрагентов или товары, по которым движений за период не зафиксировано.

Метод 1: Декартово произведение для создания полной матрицы «Клиент-Товар»

Проанализируем ситуацию: менеджеру нужно видеть отчет, где по строкам идут все клиенты, по колонкам — все ключевые товары, а на пересечении — количество продаж. Если мы просто сделаем ЛЕВОЕ СОЕДИНЕНИЕ справочника Партнеры с регистром продаж, мы увидим всех клиентов, но только по тем товарам, которые они купили.

Чтобы увидеть, что клиент не купил конкретный товар (например, арбузы), нам нужно сначала создать «сетку» из всех возможных комбинаций клиентов и товаров. В языке запросов 1С это достигается соединением двух справочников без указания условия связи (декартово произведение).

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


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

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

Метод 2: Соединение матрицы с данными о продажах

После того как мы получили временную таблицу ВТ_ПолнаяМатрица, мы можем соединить её с реальными данными из регистра. Выясним причину отсутствия данных с помощью функции ЕСТЬNULL.

Проанализируем следующий запрос:


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

В данном случае, если продажи не было, поле Количество примет значение 0, и запись не исчезнет из отчета. Это позволит менеджеру увидеть наглядный список: Клиент «А» — Товар «Арбуз» — 0 штук.

Метод 3: Использование Системы компоновки данных (СКД)

Если задача стоит шире и нужно просто дополнить отчет данными о тех, кто не покупал (без жесткой привязки к каждому товару), мы можем воспользоваться возможностями СКД. Рассмотрим вариант с объединением двух наборов данных.

  1. Создадим Набор данных - запрос 1: выбираем все продажи из регистра ВыручкаИСебестоимостьПродаж.
  2. Создадим Набор данных - запрос 2: выбираем всех партнеров из справочника Партнеры.
  3. На закладке Связи наборов данных укажем связь от Справочника к Продажам по полю Партнер.
  4. Установим параметр «Обязательное» для поля связи со стороны справочника.

Такой подход позволит системе автоматически выводить всех партнеров, даже если по ним нет записей в первом наборе данных (продажах). В настройках отчета достаточно будет установить отбор Количество ЕСТЬ NULL или Количество = 0, чтобы получить список «молчунов».

Оптимизация производительности: как не «положить» базу

Как мы уже выяснили, декартово произведение N * M — это опасная операция. Рассмотрим, как профессиональные разработчики оптимизируют такие задачи:

Посмотрим на пример оптимизированного выбора партнеров:


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

Бизнес-аналитика: зачем это нужно?

Помимо простого вывода нулей, такие отчеты являются базой для RFM-анализа (Recency, Frequency, Monetary). Рассмотрим подробнее: строя отчет по клиентам, которые не покупали, вы фактически анализируете показатель Recency (давность сделки). Если клиент не покупал более 30 дней, он попадает в зону риска.

Также подобные запросы незаменимы для контроля Матрицы ассортимента. Например, в торговой сети магазины определенного формата обязаны продавать 50 видов хлеба. Отчет «все товары — все магазины» с левым соединением продаж сразу покажет, в каких торговых точках нарушена товарная матрица.

Подводя итог, можно сказать, что решение задачи «продаж с нулевыми остатками» — это всегда баланс между полнотой данных и производительностью системы. Используйте ЛЕВОЕ СОЕДИНЕНИЕ от справочников к регистрам и не забывайте про фильтрацию данных во временных таблицах.

← На главную