Как в 1С:Комплексная автоматизация 2 найти товары, которые ранее не продавались конкретному клиенту

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

В управленческом учете часто возникает задача проанализировать эффективность работы отдела продаж по расширению ассортимента у действующих клиентов. Одной из ключевых метрик является отчет по «новым» товарам — это те позиции, которые клиент никогда не покупал до определенной даты, но начал закупать в текущем периоде. В конфигурациях на базе ERP-платформы, таких как 1С:Комплексная автоматизация 2 (КА 2), эта задача имеет свои технические нюансы, связанные с архитектурой регистров и особенностями языка запросов.

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

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

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

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

Проанализируем типичную ошибку в условии фильтрации. Часто программисты пишут: ГДЕ ТаблицаСтарыхПродаж.Номенклатура = NULL. С точки зрения логики это кажется верным, но в языке запросов 1С сравнение с NULL через знак равенства всегда возвращает «Ложь». Чтобы отобрать записи, необходимо использовать специальный оператор ЕСТЬ NULL.

Способ №1: Классическое левое соединение виртуальных таблиц

Рассмотрим пошагово, как реализовать этот метод. Мы будем использовать регистр накопления ВыручкаИСебестоимостьПродаж, так как именно он в КА 2 содержит наиболее полные данные об отгрузках.

Шаг 1. Получаем текущие продажи. Нам необходимо выбрать обороты за интересующий нас период. Важно помнить, что в КА 2 номенклатура и партнеры хранятся в ключах аналитики.

Шаг 2. Получаем историю продаж. Нам нужны данные за все время до начала текущего периода. Границей будет выступать параметр &НачалоПериода.

Шаг 3. Соединяем данные. Реализуем запрос, который объединит эти данные и отфильтрует лишнее.


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

Важный нюанс: Обратите внимание на условие соединения. Если в вашей базе ведется учет по характеристикам, их обязательно нужно добавить в условие ПО, иначе система может ошибочно посчитать продажу новой характеристики старого товара как уже совершенную ранее.

Способ №2: Метод минимальной даты (наиболее производительный)

Если база данных имеет огромный объем, левое соединение двух виртуальных таблиц «Обороты» может выполняться медленно. Разберем более изящный способ — поиск первой даты продажи для каждой пары «Клиент-Товар».

Проанализируем алгоритм:

  1. Выбираем вообще все продажи по регистру без ограничения по начальной дате (до &КонецПериода).
  2. Группируем результат по Номенклатуре и Партнеру.
  3. Для каждой группы находим МИНИМУМ(Период).
  4. Устанавливаем условие: эта минимальная дата должна входить в наш текущий интервал (от &НачалоПериода до &КонецПериода).

Если самая первая отгрузка товара клиенту произошла в текущем месяце — значит, это и есть наш «новый» товар. Рассмотрим пример кода для этого метода:


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

Этот метод работает быстрее, так как требует только одного прохода по данным регистра и исключает операцию соединения больших таблиц.

Особенности работы с ключами аналитики в КА 2

Выясним причину, почему работа с регистром ВыручкаИСебестоимостьПродаж может быть сложнее, чем кажется. В отличие от старых версий 1С (например, УТ 10.3), здесь измерениями являются не сами объекты (Номенклатура, Склад, Заказ), а ссылки на специальные справочники-ключи: Ключи аналитики учета номенклатуры и Ключи аналитики учета по партнерам.

Рассмотрим рекомендации по оптимизации запроса:

Использование консоли запросов для отладки

При поиске ошибок, как в ситуации, когда «все поля заполнены, и нет NULL», обязательно используйте консоль запросов. Разберем по шагам процесс отладки:

  1. Сначала выполните запрос только к таблице «Старых продаж». Убедитесь, что там есть данные по конкретному клиенту.
  2. Затем выполните запрос только к «Текущим продажам».
  3. Выведите результат левого соединения БЕЗ фильтра ГДЕ. Посмотрите на колонки из правой таблицы. Если они заполнены там, где вы ожидали пустоту, значит, товар уже продавался ранее.
  4. Проверьте типы данных. Иногда NULL может не возникать, если таблицы соединены неправильно (например, по ссылке на один объект, а в условии указан другой).

Таким образом, мы выяснили, что для решения задачи поиска новых продаж необходимо либо аккуратно использовать ЛЕВОЕ СОЕДИНЕНИЕ с обязательной проверкой ЕСТЬ NULL, либо использовать группировку по минимальной дате периода. Оба способа являются рабочими и зависят от ваших требований к производительности и сложности отчета.

← На главную