Как настроить скидку на товары, не входящие в сегмент (инверсия сегмента), в 1С:Розница 2.2?

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

При работе в крупных торговых сетях с распределенными информационными базами (РИБ) администраторы и разработчики часто сталкиваются с проблемой производительности. Типичная ситуация: необходимо назначить скидку на весь ассортимент (например, 40 000 позиций), за исключением небольшой группы товаров (например, 1 000 позиций). Если создавать стандартный сегмент на 39 000 товаров, то регистр СоставСегментовНоменклатуры раздувается до огромных размеров, и его миграция по 50 узлам РИБ превращается в «ад», как выразился автор темы. Рассмотрим, как решить эту задачу изящно, используя «инверсный» подход: когда мы создаем сегмент исключений и заставляем скидку работать «от противного».

Проблема передачи сегментов в РИБ

Прежде чем мы перейдем к решениям, разберем, почему стандартный подход не всегда эффективен. В программе 1С:Розница сегменты номенклатуры могут быть статическими или динамическими. Состав статического сегмента хранится в физической таблице. При каждом изменении состава или создании нового сегмента сотни тысяч записей должны улететь в каждый магазин. Это забивает каналы связи, раздувает объем баз на точках и замедляет расчеты в РМК. Инверсия сегмента позволяет нам передавать только 1 000 товаров-исключений вместо 39 000 основных, что сокращает трафик в десятки раз.

Решение 1: Использование внешних условий предоставления скидок

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

Рассмотрим алгоритм реализации:

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

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


// Пример логики проверки вхождения в сегмент "от обратного"
Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	1
|ИЗ
|	РегистрСведений.НоменклатураСегмента КАК НомСегмента
|ГДЕ
|	НомСегмента.Номенклатура = &Номенклатура
|	И НомСегмента.Сегмент = &СегментИсключение";

Запрос.УстановитьПараметр("Номенклатура", ТекущийТовар);
Запрос.УстановитьПараметр("СегментИсключение", СсылкаНаСегментИсключений);

Результат = Запрос.Выполнить();
// Если результат пустой, значит товара НЕТ в сегменте исключений - СКИДКА ПОЛОЖЕНА
Если Результат.Пустой() Тогда
    Возврат Истина;
Иначе
    Возврат Ложь;
КонецЕсли;

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

Решение 2: Механизм «Вытеснения» (без программирования)

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

Разберем этот метод по шагам:

  1. Создаем группу скидок с типом совместного применения Вытеснение.
  2. В эту группу добавляем две скидки:
    • Скидка №1 (Приоритет 100 — высокий): Скидка 0%. В условиях предоставления указываем наш сегмент «Исключения».
    • Скидка №2 (Приоритет 50 — низкий): Наша основная скидка (например, 15%). Условий по сегменту не ставим (скидка на всё).

Как это работает в РМК? Программа сначала проверяет скидки с самым высоким приоритетом. Если товар входит в сегмент исключений, срабатывает Скидка №1 (0%). Поскольку группа работает в режиме Вытеснения, поиск других скидок для этой строки чека прекращается. Если же товара нет в исключениях, система переходит к Скидке №2 и успешно применяет 15%. Результат достигнут: сегмент в базе маленький, а логика работает корректно.

Решение 3: Использование ценовых групп

Проанализируем альтернативный вариант, который еще легче для обмена данными, чем сегменты. Если товары-исключения можно сгруппировать по смыслу, используйте ЦеновыеГруппы. Информация о ценовой группе хранится непосредственно в реквизите справочника Номенклатура.

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

Риски при правке типовых запросов

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

Итоги и рекомендации

Для решения задачи инверсии сегмента в 1С:Розница 2.2 мы рекомендуем придерживаться следующей иерархии решений:

  1. Вариант с «Вытеснением» — если нужно быстро и без кода. Это штатное поведение системы, понятное любому консультанту.
  2. Внешняя обработка условий — если логика исключений сложнее, чем просто один сегмент (например, нужно проверять остатки или специфические реквизиты).
  3. Инверсный сегмент через расширение — если вы все же решили дорабатывать систему, лучше добавьте признак Инверсия в расширение к справочнику СкидкиНаценки и аккуратно внедрите его в механизм расчета, не трогая основную конфигурацию.

Помните, что главная цель — минимизировать объем данных, передаваемых через РИБ. Использование сегмента исключений на 1 000 позиций вместо основного сегмента на 35 000 — это правильный архитектурный ход, который сэкономит ресурсы серверов и нервы системных администраторов.

← На главную