Как в 1С:УТ 11.4 программно получить список скидок, в которых участвует определенная номенклатура?

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

В конфигурации 1С:Управление торговлей 11.4 (УТ 11.4) механизм автоматических скидок и наценок является крайне гибким, но в то же время технически сложным. Часто перед разработчиком встает задача: быстро определить, в каких именно правилах ценообразования задействована конкретная позиция номенклатуры. Проблема заключается в том, что условия применения скидок могут храниться в разных структурах данных в зависимости от выбранного пользователем способа настройки.

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

Анализ структуры хранения скидок в справочнике

Для начала проанализируем, где именно хранятся условия. В справочнике СкидкиНаценки существует несколько вариантов настройки того, на какие товары распространяется скидка. За это отвечает реквизит ВариантОтбораНоменклатуры. Рассмотрим основные варианты:

  1. Список номенклатуры: Самый простой вариант, когда пользователь вручную подбирает товары в таблицу.
  2. Сегмент номенклатуры: Скидка действует на товары, входящие в определенный сегмент.
  3. Отбор компоновки данных: Самый мощный и сложный инструмент, позволяющий задавать произвольные условия (например, "Весь товар бренда Apple, кроме аксессуаров").

Рассмотрим ситуацию, когда условия хранятся в поле ХранилищеНастроекКомпоновкиДанных. При вызове метода Получить() мы получаем структуру, содержащую НастройкиКомпоновкиДанных. Прямой перебор этих настроек вручную — путь тупиковый, так как условия могут содержать вложенные группы "И", "ИЛИ", "НЕ", а также использовать иерархию папок номенклатуры.

Решение 1: Использование регистра «Действие скидок (наценок) по номенклатуре»

Прежде чем писать сложный программный код, проверим наличие данных в специализированном регистре. В УТ 11.4 существует регистр сведений ДействиеСкидокНаценокПоНоменклатуре. Выясним, как он заполняется:

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

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

Решение 2: Программная проверка через механизм СКД

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

Разберем алгоритм действий по шагам:

  1. Создаем временную таблицу в памяти, содержащую одну строку с нашей номенклатурой.
  2. Загружаем схему компоновки из скидки.
  3. Применяем настройки отбора из скидки к нашему набору данных.
  4. Выполняем компоновку. Если результат не пустой — значит, номенклатура подходит под условия скидки.

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


// Примерный алгоритм проверки вхождения номенклатуры в отбор СКД
Функция НоменклатураВходитВОтборСкидки(СсылкаНаСкидку, ИскомаяНоменклатура) Экспорт
    
    НастройкиСтруктура = СсылкаНаСкидку.ХранилищеНастроекКомпоновкиДанных.Получить();
    Если НастройкиСтруктура = Неопределено Тогда
        Возврат Ложь;
    КонецЕсли;
    
    Настройки = НастройкиСтруктура.ОтборПоНоменклатуре; // Тип: НастройкиКомпоновкиДанных
    
    // Используем штатный компоновщик для проверки
    Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
    // Загружаем настройки из скидки в компоновщик
    Компоновщик.ЗагрузитьНастройки(Настройки);
    
    // Далее необходимо применить эти настройки к запросу или таблице значений
    // содержащей текущую номенклатуру.
    // Если результат выполнения запроса с данными фильтрами содержит записи,
    // значит скидка применима.
    
КонецФункции

Решение 3: Использование сегментов как посредника

Проанализируем ситуацию: если ваша задача — обеспечить высокую скорость получения списка скидок в интерфейсе, использование произвольных отборов СКД будет существенно замедлять работу системы при большом количестве действующих скидок. Для ускорения типовых механизмов можно использовать расширение для оптимизации расчета скидок.

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

В этом случае поиск скидок сводится к двум быстрым шагам:

  1. Находим все сегменты, в которые входит искомая номенклатура (запрос к НоменклатураСегмента).
  2. Находим все скидки, у которых в качестве условия указаны эти сегменты.

Решение 4: Обращение к API типового решения

В конфигурациях на базе ERP и УТ 11 существуют мощные инструменты в общих модулях. Рассмотрим модули СкидкиНаценкиСервер и ЦенообразованиеВызовСервера. В них реализованы процедуры расчета скидок для документов (Заказ клиента, Реализация).

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

Для поиска механизмов сбора данных рекомендуем изучить код обработки ПечатьСкидокНаценок. Там реализован алгоритм обхода всех доступных скидок и проверки их условий для текущего контекста продажи.

Особенности работы с иерархией и характеристиками

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

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

← На главную