Как в СКД отобрать клиентов, посещавших клуб хотя бы раз в месяц в течение полугода?

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

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

Основная сложность здесь заключается в том, что простого условия по общему количеству визитов недостаточно: клиент мог прийти 10 раз за один месяц, а остальные пять месяцев отсутствовать. Разберем по шагам, как правильно спроектировать запрос и настроить схему компоновки данных (СКД) для решения этой задачи при регламентном фоновом расчете сегментов.

Анализ логики выборки данных

Проанализируем структуру хранения информации. Все визиты регистрируются в регистре накопления Посещения. Чтобы определить факт посещения в рамках каждого конкретного месяца, нам не требуется детальная таблица движений — достаточно обратиться к виртуальной таблице оборотов РегистрНакопления.Посещения.Обороты.

Для решения задачи выполним следующие преобразования:

  1. Зададим виртуальной таблице оборотов периодичность Месяц. В этом случае система автоматически сгруппирует все движения одного клиента внутри каждого календарного месяца в одну сводную запись.
  2. Ограничим анализируемый интервал ровно шестью полными месяцами.
  3. Сгруппируем данные по контрагентам и посчитаем количество различных месяцев, в которых зафиксирован оборот.
  4. Оставим только тех клиентов, у которых полученное количество периодов строго равно 6 (или больше либо равно 6).

Составление запроса к виртуальной таблице

Посмотрим на пример запроса. Чтобы система компоновки данных работала оптимально и не передавала лишние строки в память сервера, отсечение клиентов с недостаточным числом месяцев визитов лучше выполнять сразу на уровне СУБД с помощью конструкции ИМЕЮЩИЕ.


ВЫБРАТЬ
    ПосещенияОбороты.Контрагент КАК Контрагент,
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ПосещенияОбороты.Период) КАК КоличествоМесяцев
ИЗ
    РегистрНакопления.Посещения.Обороты(&НачалоПериода, &КонецПериода, Месяц, ) КАК ПосещенияОбороты
ГДЕ
    ПосещенияОбороты.КоличествоОборот > 0
СГРУППИРОВАТЬ ПО
    ПосещенияОбороты.Контрагент
ИМЕЮЩИЕ
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ПосещенияОбороты.Период) >= 6

Обратим внимание на важную деталь: поле ПосещенияОбороты.Период в виртуальной таблице с периодичностью Месяц возвращает дату начала соответствующего месяца. Функция агрегации КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ...) подсчитывает, сколько уникальных месяцев клиент посещал занятия.

Корректная настройка параметров периода в СКД

Выясним причину частой ошибки при настройке вычисляемых дат. Если попытаться записать в поле «Выражение» на вкладке «Параметры» СКД формулу вида ТекущаяДата() - 15552000, система выдаст синтаксическую ошибку. Язык выражений компоновки данных не поддерживает прямое вычитание секунд через математический оператор «минус», в отличие от встроенного языка 1С.

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

Для корректного смещения дат в выражениях СКД используем встроенную функцию ДобавитьКДате(). На вкладке «Параметры» схемы компоновки данных настроим параметры для анализа шести предшествующих закрытых календарных месяцев:

  1. Для параметра НачалоПериода в колонке «Выражение» укажем: НачалоПериода(ДобавитьКДате(ТекущаяДата(), "Месяц", -6), "Месяц")
  2. Для параметра КонецПериода в колонке «Выражение» зададим: КонецПериода(ДобавитьКДате(ТекущаяДата(), "Месяц", -1), "Месяц")
  3. Снимем флажки «Ограничение доступности» и убедимся, что параметры не дублируются на вкладках схемы.

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

Особенности работы запроса в динамических сегментах

Рассмотрим специфику механизма сегментов клиентов. Сегменты часто пересчитываются регламентным заданием в фоновом режиме. Фоновое задание не открывает пользовательских форм и не применяет интерактивные настройки отчета.

Если в тексте запроса заключить параметры виртуальной таблицы в фигурные скобки — {(&НачалоПериода)}, {(&КонецПериода)} — СКД сочтет их необязательными. Если модуль формирования сегмента не передаст эти параметры явно в структуру настроек, виртуальная таблица прочитает весь регистр за все время его существования. В результате отбор перестанет работать по датам и выдаст клиентов, набравших 6 визитов за несколько лет.

Именно поэтому параметры виртуальной таблицы в тексте запроса для сегментов следует указывать жестко без фигурных скобок: (&НачалоПериода, &КонецПериода, Месяц, ). В этом случае СКД обязательно подставит значения, рассчитанные в выражениях параметров схемы.

Настройка структуры отчета

Для завершения настройки выполним следующие действия в схеме компоновки данных:

  1. Перейдем на вкладку «Наборы данных». У поля КоличествоМесяцев проверим свойства: у него не должно быть роли Период, так как это агрегированное числовое значение.
  2. На вкладке «Настройки» создадим группировку «Детальные записи» или сгруппируем по полю Контрагент.
  3. В выбранные поля добавим только поле Контрагент (поле КоличествоМесяцев можно оставить на время отладки, но для итогового правила сегмента требуется только ссылка на объект).

В результате созданное правило динамического сегмента будет стабильно и без участия пользователя отбирать постоянных клиентов клуба при каждом регламентном пересчете.

← На главную