Как убрать пустые столбцы и настроить ABC-анализ в отчете 1С по месяцам

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

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

Разбираемся с причиной появления пустого первого столбца

Лишний пустой столбец в начале таблицы отчета чаще всего свидетельствует о наличии записей со значением NULL или пустой ссылкой в полях, которые используются в группировках колонок. Рассмотрим подробнее, почему это происходит и как это исправить.

Проанализируем ситуацию: когда мы выполняем ЛЕВОЕ СОЕДИНЕНИЕ в запросе (как это показано в Сообщении 3), система берет все записи из левой таблицы (например, втНоменклатура) и пытается найти соответствия в правой (ПродажиОбороты). Если продаж за конкретный месяц не было, поля правой таблицы примут значение NULL. Если это поле (например, ВариантИсполнения) выбрано в качестве группировки колонок, СКД создаст отдельный столбец для значения «Пусто».

Способы решения:

  1. Фильтрация на уровне запроса: В секции ГДЕ или в параметрах виртуальных таблиц следует отсекать пустые значения. Однако более гибким методом является использование функции ЕСТЬNULL.
  2. Замена NULL на пустую ссылку: В тексте запроса вместо простого выбора поля используйте конструкцию ЕСТЬNULL(ВариантИсполнения, ЗНАЧЕНИЕ(Справочник.ВариантыИсполнения.ПустаяСсылка)). Это позволит системе сгруппировать «пустые» записи с явно заданными пустыми ссылками, избегая дублирования столбцов.
  3. Настройка «Игнорировать NULL»: В самой СКД на закладке «Наборы данных» для соответствующих полей можно установить флаг «Игнорировать значения NULL». Это заставит систему пропускать такие строки при формировании группировок.

Анализ запроса для ABC-отчета

Рассмотрим структуру запроса, используемую для получения данных. Она состоит из нескольких временных таблиц, что является хорошей практикой для оптимизации.

Первым шагом мы подготавливаем полный список номенклатуры и ее вариантов:


ВЫБРАТЬ 
    Номенклатура.Ссылка КАК Номенклатура, 
    ВариантыИсполнения.Ссылка КАК ВариантИсполнения 
ПОМЕСТИТЬ втНоменклатура 
ИЗ Справочник.Номенклатура КАК Номенклатура 
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ВариантыИсполнения КАК ВариантыИсполнения 
    ПО Номенклатура.Ссылка = ВариантыИсполнения.Владелец

Затем мы получаем данные о продажах, используя параметры &НачПериода_1 и &КонПериода_1. Обратите внимание, что в запросе из примера используется группировка по периодам (месяц и год). Это критически важно для отчета «по месяцам».

Проблема в исходном коде заключалась в том, что при добавлении таблицы в структуру отчета расчет ABC мог «отвалиться», так как логика классификации часто привязана к итогам. Если мы хотим видеть ABC-статус в динамике по месяцам, нам нужно решить: считается ли категория один раз за весь период или индивидуально для каждого месяца.

Программная обработка ABC-классификации в модуле объекта

Иногда возможностей простого запроса СКД недостаточно, и требуется программное вмешательство в процесс компоновки. Рассмотрим, как правильно перехватить данные отчета через процедуру ПриКомпоновкеРезультата в модуле объекта.

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


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    
    // 1. Инициализируем схему и настройки
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки, ДанныеРасшифровки);
    
    // 2. Создаем процессор компоновки
    ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных);
    
    // 3. Выводим результат в таблицу значений для обработки
    ТаблицаРезультат = Новый ТаблицаЗначений;
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТаблицуЗначений;
    ПроцессорВывода.УстановитьОбъект(ТаблицаРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
    
    // 4. Анализируем полученные данные
    Для Каждого _Строка Из ТаблицаРезультат Цикл
        // Проверяем заполнение ключевых полей, например АБЦ_Маржа или АБЦ_Кол
        Если Не ЗначениеЗаполнено(_Строка.АБЦ_Маржа) Тогда 
            Продолжить; 
        КонецЕсли;
        
        // Логика присвоения символьных категорий
        Если _Строка.АБЦ_Маржа = 1 Тогда
            Статус = "A";
        ИначеЕсли _Строка.АБЦ_Маржа = 2 Тогда
            Статус = "B";
        Иначе
            Статус = "C";
        КонецЕсли;
        
        // Здесь можно вызвать процедуру записи результата в справочник
    КонецЦикла;
    
    // 5. Не забудьте в конце вывести финальный результат в ДокументРезультат
    // чтобы пользователь увидел отчет на экране
КонецПроцедуры

Важные нюансы и типичные ошибки

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

Также обратите внимание на работу с группами номенклатуры. При расчете ABC-анализа иерархия может искажать проценты. Рекомендуется использовать условие Если _Строка.Номенклатура.ЭтоГруппа Тогда Продолжить; КонецЕсли;, чтобы расчет производился только по конечным элементам (товарам).

Современный подход: Встроенная функция ABCКлассификация

Выясним, как упростить задачу в актуальных версиях платформы 1С 8.3. В СКД на закладке «Вычисляемые поля» или непосредственно в ресурсах можно использовать встроенную функцию ABCКлассификация.

Синтаксис выглядит так: ABCКлассификация(СуммаОборот, 3, 80, 15). Где:

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

Резюме: Чтобы ваш ABC-отчет по месяцам был чистым и информативным, всегда проверяйте левые соединения на NULL, используйте ЕСТЬNULL для полей группировок и старайтесь использовать штатные функции классификации СКД, обращаясь к программному коду в модуле объекта только для специфических задач (например, для записи результатов анализа обратно в базу данных).

← На главную