Как реализовать алгоритм АВС-анализа в 1С: от циклов до СКД и запросов

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

Рассмотрим частую задачу, с которой сталкиваются разработчики при создании управленческих отчетов — классификацию номенклатуры, клиентов или менеджеров по методу АВС-анализа. Суть метода заключается в разделении объектов на три группы (A, B и C) в зависимости от их вклада в общий результат (например, выручку). Классический пример распределения: группа А приносит 70-80% результата, группа В — 15-20%, группа С — оставшиеся 5-10%.

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

Проблема малых выборок при программном обходе

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


Для Каждого ТекСтр Из Таб Цикл
    Если ТекСтр.СовокупныйПроцент <= АВС_А Тогда 
        // относим к группе А
    ИначеЕсли (ТекСтр.СовокупныйПроцент > АВС_А) И (ТекСтр.СовокупныйПроцент <= (АВС_А + АВС_В)) Тогда 
        // относим к группе В
    Иначе
        // относим к группе С
    КонецЕсли;
КонецЦикла;

На больших объемах данных такой код может работать сносно, но разработчики часто замечают, что алгоритм "ломается", если в таблице всего две строки (например, с долями 90% и 10%) или одна строка (100%). Причина кроется в самой математической и бизнес-модели АВС-анализа, который базируется на законе Парето. Этот метод требует статистически значимой выборки. Если ассортимент состоит из 1-3 товаров, классифицировать их бессмысленно — они все важны.

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

Решение 1: Правильный программный алгоритм (от обратного)

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

Рассмотрим доработанный пример цикла:


Для Каждого ТекСтр Из Таб Цикл
    // Сначала проверяем группу С
    Если ТекСтр.СовокупныйПроцент > (100 - АВС_С) Тогда 
        НЗ = ТабС.Добавить();
        НЗ.Номенклатура = ТекСтр.Номенклатура;
    // Затем проверяем группу В
    ИначеЕсли ТекСтр.СовокупныйПроцент > АВС_А Тогда
        НЗ = ТабВ.Добавить();
        НЗ.Номенклатура = ТекСтр.Номенклатура;
    // Все остальное - это группа А
    Иначе
        НЗ = ТабА.Добавить();
        НЗ.Номенклатура = ТекСтр.Номенклатура;
    КонецЕсли;
КонецЦикла;

Такой подход делает логику более прозрачной и гарантирует, что ни одна строка не "потеряется" между условиями.

Решение 2: АВС-анализ средствами СКД (Системы компоновки данных)

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

Разберем, как это настроить:

  1. Создаем базовый запрос в СКД, который получает продажи по номенклатуре и рассчитывает долю продаж в процентах.
  2. На закладке "Вычисляемые поля" или "Ресурсы" добавляем расчет нарастающего итога. Для этого используем специальную функцию СКД: ВычислитьВыражение("Сумма(Доля)", , , "Первая", "Текущая"). Эта формула берет показатель и суммирует его от первой строки отчета до текущей.
  3. После получения нарастающего итога добавляем еще одно вычисляемое поле, например КлассАВС, где используем конструкцию языка выражений СКД:
    ВЫБОР КОГДА НарастающийИтог <= 80 ТОГДА "A" КОГДА НарастающийИтог <= 95 ТОГДА "B" ИНАЧЕ "C" КОНЕЦ.

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

Решение 3: Реализация нарастающего итога в запросе 1С

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

Посмотрим на два подхода к реализации в запросе:

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

Типовые механизмы и развитие до ABC/XYZ-анализа

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

Логичным шагом по улучшению такого инструмента является добавление XYZ-анализа (расчет коэффициента вариации по периодам, который оценивает стабильность спроса). В результате объединения каждый товар получит две буквы, например AX (высокие стабильные продажи) или CZ (низкие случайные продажи). Это позволит бизнесу принимать гораздо более точные управленческие решения. В дополнение к матрице классификации также пригодится алгоритм расчета показателей оборачиваемости товаров.

← На главную