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

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

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

Разберем различные подходы к построению такого запроса в платформе 1С:Предприятие, проанализируем их плюсы, минусы и особенности производительности.

Вариант 1. Использование группировки и конструкции ИМЕЮЩИЕ

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

Посмотрим на пример текста запроса:


ВЫБРАТЬ
    РТУ.Контрагент КАК Контрагент
ИЗ
    Документ.РеализацияТоваровУслуг КАК РТУ
ГДЕ
    РТУ.Проведен = ИСТИНА
СГРУППИРОВАТЬ ПО
    РТУ.Контрагент
ИМЕЮЩИЕ
    МИНИМУМ(РТУ.Дата) МЕЖДУ &ДатаНачала И &ДатаОкончания

Разберем особенности этого метода:

  1. Условие МИНИМУМ(РТУ.Дата) МЕЖДУ &ДатаНачала И &ДатаОкончания гарантирует, что самый ранний проведенный документ клиента попадает именно в выбранный интервал. Если у контрагента был документ до даты &ДатаНачала, минимум будет меньше, и строка будет отсечена.
  2. Если клиент начал покупать только после даты &ДатаОкончания, он также не попадет в выборку.
  3. Важный нюанс: при таком подходе происходит полное сканирование таблицы документов за всю историю базы данных, если по полю Контрагент нет соответствующего покрывающего индекса в СУБД. В больших базах данных это может выполняться медленно.

Вариант 2. Левое соединение текущих отгрузок с историческими данными

Проанализируем классический двухэтапный алгоритм через временные таблицы. Этот способ удобен, когда на выходе требуется получить не просто контрагентов, а сами строки документов отгрузки за период.

Разберем реализацию по шагам:

  1. Помещаем во временную таблицу ВТ_ДокументыПериода все реализации за интересующий интервал.
  2. Помещаем во временную таблицу ВТ_КонтрагентыРанее список контрагентов, у которых были движения строго до даты начала периода.
  3. Выполняем левое соединение первой таблицы со второй по полю контрагента и отбираем записи, где правая таблица пуста (ЕСТЬNULL(..., NULL) IS NULL).

Посмотрим на пример текста запроса:


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

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

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

Обратим внимание на условие во второй временной таблице: РТУ.Контрагент В (ВЫБРАТЬ ВТ_ДокументыПериода.Контрагент...). Это ограничивает выборку исторических данных только теми клиентами, которые фактически покупали что-то в текущем периоде, что существенно снижает нагрузку на СУБД.

Вариант 3. Использование виртуальных таблиц регистров накопления (на примере УТ 11, КА, ERP)

В типовых конфигурациях линейки 1С:Управление торговлей 11, 1С:Комплексная автоматизация 2 и 1С:ERP обращение напрямую к документам не всегда оптимально, так как продажи могут фиксироваться разными документами (РеализацияТоваровУслуг, АктВыполненныхРабот, ОтчетОРозничныхПродажах). Кроме того, учет ведется в разрезе партнеров.

Для ускорения расчетов эффективнее использовать виртуальную таблицу регистра ВыручкаИСебестоимостьПродаж.Обороты. Платформа рассчитывает итоги регистров быстрее, чем сканирует физические таблицы документов.

Посмотрим на пример запроса для прикладных конфигураций:


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

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

Важные практические рекомендации

При построении запросов на проверку первых документов обязательно учитываем следующие моменты:

  1. Статус проведения: При обращении к физическим таблицам документов всегда необходимо указывать ГДЕ Документ.Проведен = ИСТИНА, иначе непроведенные или помеченные на удаление черновики могут ошибочно исключить нового клиента из отчета.
  2. Границы периодов: Параметры виртуальных таблиц оборотов включают указанную граничную дату. Чтобы прошлая история не захватила начало первого дня периода, в качестве параметра &ГраницаНачала рекомендуется передавать объект Новый Граница(&ДатаНачала, ВидГраницы.Исключая) или дату, уменьшенную на 1 секунду.
  3. Разделение «Партнер» и «Контрагент»: Если клиент изменил юридическое лицо (ИНН/КПП), но остался тем же партнером, проверка только по справочнику Контрагенты может посчитать его новым клиентом. В управленческих отчетах отбор надежнее строить по партнерам.
← На главную