Рассмотрим частую задачу, с которой сталкиваются разработчики при создании управленческих отчетов — классификацию номенклатуры, клиентов или менеджеров по методу АВС-анализа. Суть метода заключается в разделении объектов на три группы (A, B и C) в зависимости от их вклада в общий результат (например, выручку). Классический пример распределения: группа А приносит 70-80% результата, группа В — 15-20%, группа С — оставшиеся 5-10%.
Проанализируем ситуацию, в которой у нас уже есть таблица значений с колонками: Товар, Количество, Доля каждого товара в % и Совокупный (накопительный) вклад в %. Наша задача — отнести каждую строку к нужной группе. Разберем по шагам, как это можно запрограммировать, какие подводные камни нас ожидают и какие более современные методы существуют.
Часто разработчики пытаются решить задачу "в лоб" с помощью простого перебора строк в цикле. Посмотрим на типичный алгоритм:
Для Каждого ТекСтр Из Таб Цикл
Если ТекСтр.СовокупныйПроцент <= АВС_А Тогда
// относим к группе А
ИначеЕсли (ТекСтр.СовокупныйПроцент > АВС_А) И (ТекСтр.СовокупныйПроцент <= (АВС_А + АВС_В)) Тогда
// относим к группе В
Иначе
// относим к группе С
КонецЕсли;
КонецЦикла;
На больших объемах данных такой код может работать сносно, но разработчики часто замечают, что алгоритм "ломается", если в таблице всего две строки (например, с долями 90% и 10%) или одна строка (100%). Причина кроется в самой математической и бизнес-модели АВС-анализа, который базируется на законе Парето. Этот метод требует статистически значимой выборки. Если ассортимент состоит из 1-3 товаров, классифицировать их бессмысленно — они все важны.
Правильным архитектурным решением в коде будет добавить предварительную проверку. Выясним причину ошибки: не нужно пытаться распределить 2 товара по трем группам. Если количество строк меньше определенного порога, программа должна прерывать выполнение с сообщением пользователю, либо автоматически присваивать всем позициям высший класс А.
Если мы все же пишем обработку таблицы значений кодом, и выборка достаточна, обратим внимание на совет опытных разработчиков: чтобы избежать путаницы с граничными процентами, двигайтесь в обратном порядке.
Рассмотрим доработанный пример цикла:
Для Каждого ТекСтр Из Таб Цикл
// Сначала проверяем группу С
Если ТекСтр.СовокупныйПроцент > (100 - АВС_С) Тогда
НЗ = ТабС.Добавить();
НЗ.Номенклатура = ТекСтр.Номенклатура;
// Затем проверяем группу В
ИначеЕсли ТекСтр.СовокупныйПроцент > АВС_А Тогда
НЗ = ТабВ.Добавить();
НЗ.Номенклатура = ТекСтр.Номенклатура;
// Все остальное - это группа А
Иначе
НЗ = ТабА.Добавить();
НЗ.Номенклатура = ТекСтр.Номенклатура;
КонецЕсли;
КонецЦикла;
Такой подход делает логику более прозрачной и гарантирует, что ни одна строка не "потеряется" между условиями.
Зададимся вопросом: зачем писать сложные циклы, если платформа 1С предоставляет мощные инструменты для аналитики? Оптимальным способом построения таких отчетов является использование СКД. В этом случае нарастающий итог вычисляется динамически прямо на этапе вывода отчета.
Разберем, как это настроить:
ВычислитьВыражение("Сумма(Доля)", , , "Первая", "Текущая"). Эта формула берет показатель и суммирует его от первой строки отчета до текущей.КлассАВС, где используем конструкцию языка выражений СКД: ВЫБОР КОГДА НарастающийИтог <= 80 ТОГДА "A" КОГДА НарастающийИтог <= 95 ТОГДА "B" ИНАЧЕ "C" КОНЕЦ.В результате классы распределятся автоматически при формировании отчета, без единой строки программного кода. Для изучения похожих приемов настройки вычислений можно посмотреть примеры построения отчетов в СКД со сложными выражениями.
Иногда результат АВС-анализа нужен не для отчета, а для дальнейшей программной обработки. Перебирать тысячи строк в цикле — плохая практика. Вычисления эффективнее выполнять на уровне базы данных.
Посмотрим на два подхода к реализации в запросе:
СУММА(Доля) ОВЕР (ПОРЯДОК ПО Доля УБЫВ). После этого классы назначаются через простой оператор ВЫБОР прямо в запросе.Прежде чем писать свой алгоритм с нуля, проанализируем конфигурацию, в которой мы работаем. В современных решениях (Управление торговлей, ERP, Комплексная автоматизация) механизм АВС-анализа уже встроен "из коробки". Он не только рассчитывает классы, но и записывает результаты в специальные регистры сведений, чтобы сохранять историю перемещения товаров между классами.
Логичным шагом по улучшению такого инструмента является добавление XYZ-анализа (расчет коэффициента вариации по периодам, который оценивает стабильность спроса). В результате объединения каждый товар получит две буквы, например AX (высокие стабильные продажи) или CZ (низкие случайные продажи). Это позволит бизнесу принимать гораздо более точные управленческие решения. В дополнение к матрице классификации также пригодится алгоритм расчета показателей оборачиваемости товаров.