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

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

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

Метод 1: Использование регистра сведений (Профессиональный подход)

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

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

Теперь разберем, как правильно составить запрос в СКД, чтобы учесть иерархию. Нам нужно соединить основную таблицу товаров с этим регистром. Важным моментом здесь является использование оператора В ИЕРАРХИИ, однако в классическом левом соединении запроса это сделать напрямую сложно. Поэтому мы часто используем следующий алгоритм в запросе:


ВЫБРАТЬ
    Товары.Ссылка КАК Номенклатура,
    ЕСТЬNULL(Наценки.ПроцентНаценки, 0) КАК Процент
ИЗ
    Справочник.Номенклатура КАК Товары
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НаценкиНоменклатуры.СрезПоследних(&Период, ) КАК Наценки
    ПО Товары.Ссылка В ИЕРАРХИИ (Наценки.ОбъектНастройки)

Важное примечание: Использование В ИЕРАРХИИ в условии соединения может существенно замедлить отчет на больших справочниках. Если производительность критична, рекомендуется предварительно подготовить таблицу соответствий в коде или использовать дополнительные реквизиты.

Метод 2: Внешний набор данных (Таблица значений)

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

Рассмотрим по шагам, как это реализовать:

  1. Создадим в схеме СКД Набор данных - объект и назовем его ТаблицаНаценок.
  2. В коде модуля сформируем таблицу значений с колонками Номенклатура и ПроцентНаценки.
  3. Передадим эту таблицу в СКД.

Пример программного кода для инициализации компоновки:


// Подготовим таблицу данных
ТЗНаценок = Новый ТаблицаЗначений;
ТЗНаценок.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ТЗНаценок.Колонки.Добавить("ПроцентНаценки", Новый ОписаниеТипов("Число"));

// Логика заполнения таблицы (например, обход дерева групп)
// ... затычка для логики заполнения ...

ВнешниеНаборыДанных = Новый Структура;
ВнешниеНаборыДанных.Вставить("ТаблицаНаценок", ТЗНаценок);

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиКомпоновки, ДанныеРасшифровки);

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки);

Этот метод идеален, если у вас сложная иерархия и правила "перекрытия" наценок (когда у подгруппы одна наценка, а у родительской группы — другая).

Метод 3: Использование конструкции ВЫБОР в запросе

Если количество групп ограничено и они меняются редко, мы можем воспользоваться оператором ВЫБОР непосредственно в тексте запроса СКД. Это самый быстрый метод с точки зрения производительности СУБД.

Разберем пример такого запроса:


ВЫБРАТЬ
    Номенклатура.Ссылка,
    ВЫБОР
        КОГДА Номенклатура.Ссылка В ИЕРАРХИИ (&Группа_30) ТОГДА 30
        КОГДА Номенклатура.Ссылка В ИЕРАРХИИ (&Группа_20) ТОГДА 20
        КОГДА Номенклатура.Ссылка В ИЕРАРХИИ (&Группа_10) ТОГДА 10
        ИНАЧЕ 0
    КОНЕЦ КАК ПроцентНаценки
ИЗ
    Справочник.Номенклатура КАК Номенклатура

В данном случае &Группа_30, &Группа_20 и т.д. — это параметры СКД с типом Список значений или СправочникСсылка.Номенклатура. Система компоновки данных очень эффективно транслирует оператор В ИЕРАРХИИ в SQL-запрос, что обеспечивает высокую скорость выполнения.

Метод 4: Дополнительные реквизиты и характеристики

Современные конфигурации на базе БСП (Библиотеки стандартных подсистем) позволяют добавлять дополнительные реквизиты к объектам без изменения метаданных. Мы можем добавить реквизит Процент наценки прямо к элементам справочника Номенклатура.

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

Проблема приоритетов при наложении групп

Проанализируем ситуацию: что делать, если товар входит в группу "Электроника" (наценка 10%), которая в свою очередь входит в группу "Импорт" (наценка 5%)? Какой процент должен примениться?

При использовании метода с ВЫБОР в запросе, приоритет определяется порядком условий КОГДА. Первое сработавшее условие "выигрывает". Если мы хотим, чтобы приоритет имела максимально близкая к товару группа (самая глубокая в иерархии), нам необходимо:

  1. Либо проверять группы в порядке от самых специфичных к самым общим.
  2. Либо программно рассчитывать "уровень" вложенности каждой группы и выбирать ту, у которой уровень больше.

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

Подведение итогов

Мы рассмотрели различные способы реализации дифференцированных наценок. Для небольших задач отлично подойдет Метод 3 (ВЫБОР в запросе). Для серьезных систем автоматизации торговли наиболее правильным решением будет Метод 1 (Регистр сведений), так как он обеспечивает прозрачность для пользователя и гибкость настроек без участия программиста.

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

← На главную