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

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

Базовая группировка с подсчетом количества строк

// Группировка таблицы с подсчетом количества записей в каждой группе
Процедура ГруппировкаСПодсчетомКоличества()

    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Категория");
    Таблица.Колонки.Добавить("Товар");
    Таблица.Колонки.Добавить("Цена", Новый ОписаниеТипов("Число"));
    
    Таблица.Добавить().Категория = "Электроника"; Таблица[0].Товар = "Ноутбук"; Таблица[0].Цена = 50000;
    Таблица.Добавить().Категория = "Электроника"; Таблица[1].Товар = "Телефон"; Таблица[1].Цена = 30000;
    Таблица.Добавить().Категория = "Электроника"; Таблица[2].Товар = "Планшет"; Таблица[2].Цена = 20000;
    Таблица.Добавить().Категория = "Мебель"; Таблица[3].Товар = "Стол"; Таблица[3].Цена = 10000;
    Таблица.Добавить().Категория = "Мебель"; Таблица[4].Товар = "Стул"; Таблица[4].Цена = 3000;
    Таблица.Добавить().Категория = "Одежда"; Таблица[5].Товар = "Куртка"; Таблица[5].Цена = 5000;
    
    // Группировка с подсчетом количества товаров в категории
    Группировка = Новый ТаблицаЗначений;
    Группировка.Колонки.Добавить("Категория");
    Группировка.Колонки.Добавить("КоличествоТоваров", Новый ОписаниеТипов("Число"));
    Группировка.Колонки.Добавить("МинимальнаяЦена", Новый ОписаниеТипов("Число"));
    Группировка.Колонки.Добавить("МаксимальнаяЦена", Новый ОписаниеТипов("Число"));
    
    // Формируем массив уникальных категорий
    УникальныеКатегории = Новый Массив;
    Для Каждого Строка Из Таблица Цикл
        Если УникальныеКатегории.Найти(Строка.Категория) = Неопределено Тогда
            УникальныеКатегории.Добавить(Строка.Категория);
        КонецЕсли;
    КонецЦикла;
    
    // Собираем статистику по каждой категории
    Для Каждого Категория Из УникальныеКатегории Цикл
        НоваяСтрока = Группировка.Добавить();
        НоваяСтрока.Категория = Категория;
        
        Количество = 0;
        МинЦена = 999999999;
        МаксЦена = 0;
        
        Для Каждого ИсходнаяСтрока Из Таблица Цикл
            Если ИсходнаяСтрока.Категория = Категория Тогда
                Количество = Количество + 1;
                
                Если ИсходнаяСтрока.Цена < МинЦена Тогда
                    МинЦена = ИсходнаяСтрока.Цена;
                КонецЕсли;
                
                Если ИсходнаяСтрока.Цена > МаксЦена Тогда
                    МаксЦена = ИсходнаяСтрока.Цена;
                КонецЕсли;
            КонецЕсли;
        КонецЦикла;
        
        НоваяСтрока.КоличествоТоваров = Количество;
        НоваяСтрока.МинимальнаяЦена = МинЦена;
        НоваяСтрока.МаксимальнаяЦена = МаксЦена;
    КонецЦикла;
    
    Сообщить("Группировка по категориям:");
    Для Каждого Строка Из Группировка Цикл
        Сообщить(Строка.Категория + " | Товаров: " + Строка.КоличествоТоваров +
                 " | Цены от " + Строка.МинимальнаяЦена + " до " + Строка.МаксимальнаяЦена);
    КонецЦикла;
    
КонецПроцедуры

Группировка с суммированием числовых показателей

// Группировка с вычислением суммы, среднего значения и других агрегатов
Процедура ГруппировкаССуммированием()

    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Менеджер");
    Таблица.Колонки.Добавить("СуммаПродаж", Новый ОписаниеТипов("Число"));
    Таблица.Колонки.Добавить("Комиссия", Новый ОписаниеТипов("Число"));
    
    Таблица.Добавить().Менеджер = "Иванов"; Таблица[0].СуммаПродаж = 100000; Таблица[0].Комиссия = 5000;
    Таблица.Добавить().Менеджер = "Иванов"; Таблица[1].СуммаПродаж = 150000; Таблица[1].Комиссия = 7500;
    Таблица.Добавить().Менеджер = "Петров"; Таблица[2].СуммаПродаж = 200000; Таблица[2].Комиссия = 10000;
    Таблица.Добавить().Менеджер = "Петров"; Таблица[3].СуммаПродаж = 80000; Таблица[3].Комиссия = 4000;
    Таблица.Добавить().Менеджер = "Иванов"; Таблица[4].СуммаПродаж = 50000; Таблица[4].Комиссия = 2500;
    Таблица.Добавить().Менеджер = "Сидоров"; Таблица[5].СуммаПродаж = 120000; Таблица[5].Комиссия = 6000;
    
    // Группировка с использованием встроенного метода Свернуть
    Группировка = Таблица.Свернуть("Менеджер", "СуммаПродаж, Комиссия");
    
    // Добавляем вычисляемые поля
    Группировка.Колонки.Добавить("СредняяКомиссия", Новый ОписаниеТипов("Число"));
    Группировка.Колонки.Добавить("ПроцентКомиссии", Новый ОписаниеТипов("Число"));
    
    Для Каждого Строка Из Группировка Цикл
        Строка.СредняяКомиссия = Строка.Комиссия / Строка.СуммаПродаж * 100;
        Строка.ПроцентКомиссии = (Строка.Комиссия / Строка.СуммаПродаж) * 100;
    КонецЦикла;
    
    // Сортируем по сумме продаж
    Группировка.Сортировать("СуммаПродаж УБЫВ");
    
    Сообщика("Группировка по менеджерам:");
    Для Каждого Строка Из Группировка Цикл
        Сообщить(Строка.Менеджер + " | Сумма продаж: " + Строка.СуммаПродаж +
                 " | Комиссия: " + Строка.Комиссия +
                 " | % комиссии: " + Формат(Строка.ПроцентКомиссии, "ЧЦ=2") + "%");
    КонецЦикла;
    
КонецПроцедуры

Группировка по нескольким полям

// Многомерная группировка по двум и более ключевым полям
Процедура ГруппировкаПоНесколькимПолям()

    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Год", Новый ОписаниеТипов("Число"));
    Таблица.Колонки.Добавить("Квартал", Новый ОписаниеТипов("Число"));
    Таблица.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
    
    Таблица.Добавить().Год = 2024; Таблица[0].Квартал = 1; Таблица[0].Сумма = 1000;
    Таблица.Добавить().Год = 2024; Таблица[1].Квартал = 1; Таблица[1].Сумма = 1500;
    Таблица.Добавить().Год = 2024; Таблица[2].Квартал = 2; Таблица[2].Сумма = 2000;
    Таблица.Добавить().Год = 2024; Таблица[3].Квартал = 2; Таблица[3].Сумма = 2500;
    Таблица.Добавить().Год = 2024; Таблица[4].Квартал = 3; Таблица[4].Сумма = 3000;
    Таблица.Добавить().Год = 2025; Таблица[5].Квартал = 1; Таблица[5].Сумма = 3500;
    Таблица.Добавить().Год = 2025; Таблица[6].Квартал = 1; Таблица[6].Сумма = 4000;
    Таблица.Добавить().Год = 2025; Таблица[7].Квартал = 2; Таблица[7].Сумма = 4500;
    
    // Группировка по году и кварталу
    Группировка = Таблица.Свернуть("Год, Квартал", "Сумма");
    
    // Формируем структурированный вывод
    Сообщить("Продажи по периодам:");
    
    Для Год = 2024 По 2025 Цикл
        Сообщить("=== " + Строка(Год) + " год ===");
        
        Для Квартал = 1 По 4 Цикл
            Найдено = Ложь;
            Для Каждого Строка Из Группировка Цикл
                Если Строка.Год = Год И Строка.Квартал = Квартал Тогда
                    Сообщить("  Квартал " + Строка(Квартал) + ": " + Строка.Сумма);
                    Найдено = Истина;
                    Прервать;
                КонецЕсли;
            КонецЦикла;
            
            Если Не Найдено И (Год = 2024 И Квартал = 4 ИЛИ Год = 2025 И Квартал > 2) И Квартал <= 4 Тогда
                Сообщить("  Квартал " + Строка(Квартал) + ": 0");
            КонецЕсли;
        КонецЦикла;
        
    КонецЦикла;
    
КонецПроцедуры

Группировка с накоплением (running totals)

// Группировка с вычислением накопительных итогов
Процедура ГруппировкаСНакоплением()

    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Месяц");
    Таблица.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
    
    Таблица.Добавить().Месяц = "Январь"; Таблица[0].Сумма = 10000;
    Таблица.Добавить().Месяц = "Февраль"; Таблица[1].Сумма = 12000;
    Таблица.Добавить().Месяц = "Март"; Таблица[2].Сумма = 15000;
    Таблица.Добавить().Месяц = "Апрель"; Таблица[3].Сумма = 13000;
    Таблица.Добавить().Месяц = "Май"; Таблица[4].Сумма = 18000;
    
    // Сортируем по месяцам в хронологическом порядке
    ПорядокМесяцев = Новый Массив;
    ПорядокМесяцев.Добавить("Январь");
    ПорядокМесяцев.Добавить("Февраль");
    ПорядокМесяцев.Добавить("Март");
    ПорядокМесяцев.Добавить("Апрель");
    ПорядокМесяцев.Добавить("Май");
    
    // Сортируем таблицу вручную
    СортированнаяТаблица = Новый ТаблицаЗначений;
    СортированнаяТаблица.Колонки.Добавить("Месяц");
    СортированнаяТаблица.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
    
    Для Каждого Месяц Из ПорядокМесяцев Цикл
        Для Каждого Строка Из Таблица Цикл
            Если Строка.Месяц = Месяц Тогда
                НоваяСтрока = СортированнаяТаблица.Добавить();
                НоваяСтрока.Месяц = Строка.Месяц;
                НоваяСтрока.Сумма = Строка.Сумма;
                Прервать;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    
    // Добавляем накопительный итог
    СортированнаяТаблица.Колонки.Добавить("НакопленныйИтог", Новый ОписаниеТипов("Число"));
    
    Накоплено = 0;
    Для Каждого Строка Из СортированнаяТаблица Цикл
        Накоплено = Накоплено + Строка.Сумма;
        Строка.НакопленныйИтог = Накоплено;
    КонецЦикла;
    
    Сообщить("Продажи с накопительным итогом:");
    Для Каждого Строка Из СортированнаяТаблица Цикл
        Сообщить(Строка.Месяц + " | Сумма: " + Строка.Сумма + 
                 " | Накоплено: " + Строка.НакопленныйИтог);
    КонецЦикла;
    
КонецПроцедуры

Группировка через запрос (для больших таблиц)

// Использование языка запросов для группировки таблицы значений
Процедура ГруппировкаЧерезЗапрос()

    // Создаем исходную таблицу
    ИсходнаяТаблица = Новый ТаблицаЗначений;
    ИсходнаяТаблица.Колонки.Добавить("Регион");
    ИсходнаяТаблица.Колонки.Добавить("Город");
    ИсходнаяТаблица.Колонки.Добавить("Продажи", Новый ОписаниеТипов("Число"));
    ИсходнаяТаблица.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
    
    // Заполняем данными
    ИсходнаяТаблица.Добавить().Регион = "Центр"; ИсходнаяТаблица[0].Город = "Москва"; ИсходнаяТаблица[0].Продажи = 5000; ИсходнаяТаблица[0].Количество = 10;
    ИсходнаяТаблица.Добавить().Регион = "Центр"; ИсходнаяТаблица[1].Город = "Москва"; ИсходнаяТаблица[1].Продажи = 3000; ИсходнаяТаблица[1].Количество = 6;
    ИсходнаяТаблица.Добавить().Регион = "Центр"; ИсходнаяТаблица[2].Город = "Тула"; ИсходнаяТаблица[2].Продажи = 2000; ИсходнаяТаблица[2].Количество = 5;
    ИсходнаяТаблица.Добавить().Регион = "Урал"; ИсходнаяТаблица[3].Город = "Екатеринбург"; ИсходнаяТаблица[3].Продажи = 4000; ИсходнаяТаблица[3].Количество = 8;
    ИсходнаяТаблица.Добавить().Регион = "Урал"; ИсходнаяТаблица[4].Город = "Челябинск"; ИсходнаяТаблица[4].Продажи = 2500; ИсходнаяТаблица[4].Количество = 5;
    
    // Создаем запрос к таблице значений
    Запрос = Новый Запрос;
    Запрос.Текст = "
    |ВЫБРАТЬ
    |   Исходные.Регион,
    |   СУММА(Исходные.Продажи) КАК ОбщиеПродажи,
    |   СУММА(Исходные.Количество) КАК ОбщееКоличество,
    |   СРЕДНЕЕ(Исходные.Продажи / Исходные.Количество) КАК СреднийЧек,
    |   МИНИМУМ(Исходные.Продажи) КАК МинПродажи,
    |   МАКСИМУМ(Исходные.Продажи) КАК МаксПродажи,
    |   КОЛИЧЕСТВО(Исходные.Город) КАК КоличествоГородов
    |ИЗ
    |   &ИсходнаяТаблица КАК Исходные
    |СГРУППИРОВАТЬ ПО
    |   Исходные.Регион
    |УПОРЯДОЧИТЬ ПО
    |   ОбщиеПродажи УБЫВ";
    
    Запрос.УстановитьПараметр("ИсходнаяТаблица", ИсходнаяТаблица);
    
    Результат = Запрос.Выполнить().Выгрузить();
    
    Сообщить("Группировка по регионам:");
    Для Каждого Строка Из Результат Цикл
        Сообщить(Строка.Регион + 
                 " | Продажи: " + Строка.ОбщиеПродажи +
                 " | Количество: " + Строка.ОбщееКоличество +
                 " | Средний чек: " + Формат(Строка.СреднийЧек, "ЧЦ=2") +
                 " | Городов: " + Строка.КоличествоГородов);
    КонецЦикла;
    
КонецПроцедуры

Группировка с фильтрацией внутри групп (HAVING)

// Группировка с отбором групп, удовлетворяющих условию
Процедура ГруппировкаСУсловиемНаГруппу()

    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Менеджер");
    Таблица.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
    Таблица.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата"));
    
    Таблица.Добавить().Менеджер = "Иванов"; Таблица[0].Сумма = 50000; Таблица[0].Дата = '20240115';
    Таблица.Добавить().Менеджер = "Иванов"; Таблица[1].Сумма = 30000; Таблица[1].Дата = '20240210';
    Таблица.Добавить().Менеджер = "Иванов"; Таблица[2].Сумма = 20000; Таблица[2].Дата = '20240305';
    Таблица.Добавить().Менеджер = "Петров"; Таблица[3].Сумма = 80000; Таблица[3].Дата = '20240120';
    Таблица.Добавить().Менеджер = "Петров"; Таблица[4].Сумма = 60000; Таблица[4].Дата = '20240215';
    Таблица.Добавить().Менеджер = "Сидоров"; Таблица[5].Сумма = 20000; Таблица[5].Дата = '20240125';
    Таблица.Добавить().Менеджер = "Сидоров"; Таблица[6].Сумма = 15000; Таблица[6].Дата = '20240220';
    Таблица.Добавить().Менеджер = "Кузнецов"; Таблица[7].Сумма = 10000; Таблица[7].Дата = '20240130';
    
    // Сначала группируем
    Группировка = Таблица.Свернуть("Менеджер", "Сумма");
    
    // Добавляем колонку для подсчета количества сделок
    Группировка.Колонки.Добавить("КоличествоСделок", Новый ОписаниеТипов("Число"));
    
    Для Каждого СтрокаГруппы Из Группировка Цикл
        Количество = 0;
        Для Каждого ИсходнаяСтрока Из Таблица Цикл
            Если ИсходнаяСтрока.Менеджер = СтрокаГруппы.Менеджер Тогда
                Количество = Количество + 1;
            КонецЕсли;
        КонецЦикла;
        СтрокаГруппы.КоличествоСделок = Количество;
    КонецЦикла;
    
    // Фильтруем группы: оставляем только менеджеров с суммой > 50000 и количеством сделок > 1
    Отфильтрованные = Новый ТаблицаЗначений;
    Отфильтрованные.Колонки.Добавить("Менеджер");
    Отфильтрованные.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
    Отфильтрованные.Колонки.Добавить("КоличествоСделок", Новый ОписаниеТипов("Число"));
    
    Для Каждого Строка Из Группировка Цикл
        Если Строка.Сумма > 50000 И Строка.КоличествоСделок > 1 Тогда
            НоваяСтрока = Отфильтрованные.Добавить();
            НоваяСтрока.Менеджер = Строка.Менеджер;
            НоваяСтрока.Сумма = Строка.Сумма;
            НоваяСтрока.КоличествоСделок = Строка.КоличествоСделок;
        КонецЕсли;
    КонецЦикла;
    
    Сообщить("Менеджеры с суммой продаж > 50000 и количеством сделок > 1:");
    Для Каждого Строка Из Отфильтрованные Цикл
        Сообщить(Строка.Менеджер + " | Сумма: " + Строка.Сумма + 
                 " | Сделок: " + Строка.КоличествоСделок);
    КонецЦикла;
    
КонецПроцедуры

Иерархическая группировка с промежуточными итогами

// Создание отчета с группировкой и подгруппами
Функция СформироватьИерархическийОтчет(Таблица, ПоляГруппировки, ПолеСуммы)

    Результат = Новый ТаблицаЗначений;
    Результат.Колонки.Добавить("Уровень", Новый ОписаниеТипов("Число"));
    Результат.Колонки.Добавить("Значение");
    Результат.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
    
    // Рекурсивная группировка
    СформироватьУровень(Таблица, ПоляГруппировки, ПолеСуммы, 0, Результат);
    
    Возврат Результат;
    
КонецФункции

Процедура СформироватьУровень(Таблица, ПоляГруппировки, ПолеСуммы, Уровень, Результат)
    
    Если ПоляГруппировки.Количество() <= Уровень Тогда
        Возврат;
    КонецЕсли;
    
    ТекущееПоле = ПоляГруппировки[Уровень];
    
    // Получаем уникальные значения текущего поля
    УникальныеЗначения = Новый Массив;
    Для Каждого Строка Из Таблица Цикл
        Значение = Строка[ТекущееПоле];
        Если УникальныеЗначения.Найти(Значение) = Неопределено Тогда
            УникальныеЗначения.Добавить(Значение);
        КонецЕсли;
    КонецЦикла;
    
    // Для каждого значения собираем подгруппу
    Для Каждого Знач Из УникальныеЗначения Цикл
        
        // Фильтруем таблицу по текущему значению
        ОтфильтрованнаяТаблица = Новый ТаблицаЗначений;
        ОтфильтрованнаяТаблица.Колонки.Добавить(ТекущееПоле);
        ОтфильтрованнаяТаблица.Колонки.Добавить(ПолеСуммы);
        
        СуммаПоГруппе = 0;
        Для Каждого Строка Из Таблица Цикл
            Если Строка[ТекущееПоле] = Знач Тогда
                СтрокаОтбора = ОтфильтрованнаяТаблица.Добавить();
                СтрокаОтбора[ТекущееПоле] = Строка[ТекущееПоле];
                СтрокаОтбора[ПолеСуммы] = Строка[ПолеСуммы];
                СуммаПоГруппе = СуммаПоГруппе + Строка[ПолеСуммы];
            КонецЕсли;
        КонецЦикла;
        
        // Добавляем строку с итогом по группе
        СтрокаРезультата = Результат.Добавить();
        СтрокаРезультата.Уровень = Уровень;
        СтрокаРезультата.Значение = Знач;
        СтрокаРезультата.Сумма = СуммаПоГруппе;
        
        // Рекурсивно обрабатываем следующий уровень
        СформироватьУровень(ОтфильтрованнаяТаблица, ПоляГруппировки, ПолеСуммы, Уровень + 1, Результат);
        
    КонецЦикла;
    
КонецПроцедуры

Процедура ТестИерархическойГруппировки()

    // Подготавливаем данные
    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Страна");
    Таблица.Колонки.Добавить("Город");
    Таблица.Колонки.Добавить("Район");
    Таблица.Колонки.Добавить("Продажи", Новый ОписаниеТипов("Число"));
    
    Таблица.Добавить().Страна = "Россия"; Таблица[0].Город = "Москва"; Таблица[0].Район = "ЦАО"; Таблица[0].Продажи = 1000;
    Таблица.Добавить().Страна = "Россия"; Таблица[1].Город = "Москва"; Таблица[1].Район = "САО"; Таблица[1].Продажи = 2000;
    Таблица.Добавить().Страна = "Россия"; Таблица[2].Город = "СПб"; Таблица[2].Район = "Центр"; Таблица[2].Продажи = 1500;
    Таблица.Добавить().Страна = "Беларусь"; Таблица[3].Город = "Минск"; Таблица[3].Район = "Центр"; Таблица[3].Продажи = 800;
    
    ПоляГруппировки = Новый Массив;
    ПоляГруппировки.Добавить("Страна");
    ПоляГруппировки.Добавить("Город");
    ПоляГруппировки.Добавить("Район");
    
    Отчет = СформироватьИерархическийОтчет(Таблица, ПоляГруппировки, "Продажи");
    
    Сообщить("Иерархический отчет:");
    Для Каждого Строка Из Отчет Цикл
        Отступ = "";
        Для Н = 1 По Строка.Уровень Цикл
            Отступ = Отступ + "  ";
        КонецЦикла;
        
        Сообщить(Отступ + Строка.Значение + ": " + Строка.Сумма);
    КонецЦикла;
    
КонецПроцедуры

Группировка с распределением по диапазонам

// Группировка числовых значений по диапазонам (корзинам)
Процедура ГруппировкаПоДиапазонам()

    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Товар");
    Таблица.Колонки.Добавить("Цена", Новый ОписаниеТипов("Число"));
    
    Таблица.Добавить().Товар = "Ноутбук"; Таблица[0].Цена = 50000;
    Таблица.Добавить().Товар = "Телефон"; Таблица[1].Цена = 30000;
    Таблица.Добавить().Товар = "Планшет"; Таблица[2].Цена = 15000;
    Таблица.Добавить().Товар = "Мышь"; Таблица[3].Цена = 1000;
    Таблица.Добавить().Товар = "Клавиатура"; Таблица[4].Цена = 2000;
    Таблица.Добавить().Товар = "Монитор"; Таблица[5].Цена = 20000;
    Таблица.Добавить().Товар = "Системный блок"; Таблица[6].Цена = 40000;
    Таблица.Добавить().Товар = "Наушники"; Таблица[7].Цена = 3000;
    Таблица.Добавить().Товар = "Внешний диск"; Таблица[8].Цена = 5000;
    
    // Определяем диапазоны цен
    Диапазоны = Новый Массив;
    Диапазоны.Добавить(Новый Структура("Название, Мин, Макс", "До 10000", 0, 10000));
    Диапазоны.Добавить(Новый Структура("Название, Мин, Макс", "10000-20000", 10000, 20000));
    Диапазоны.Добавить(Новый Структура("Название, Мин, Макс", "20000-35000", 20000, 35000));
    Диапазоны.Добавить(Новый Структура("Название, Мин, Макс", "Более 35000", 35000, 999999999));
    
    // Группируем по диапазонам
    Группировка = Новый ТаблицаЗначений;
    Группировка.Колонки.Добавить("Диапазон");
    Группировка.Колонки.Добавить("КоличествоТоваров", Новый ОписаниеТипов("Число"));
    Группировка.Колонки.Добавить("СписокТоваров");
    
    Для Каждого Диапазон Из Диапазоны Цикл
        НоваяСтрока = Группировка.Добавить();
        НоваяСтрока.Диапазон = Диапазон.Название;
        
        Количество = 0;
        Список = "";
        
        Для Каждого Товар Из Таблица Цикл
            Если Товар.Цена >= Диапазон.Мин И Товар.Цена < Диапазон.Макс Тогда
                Количество = Количество + 1;
                
                Если Список <> "" Тогда
                    Список = Список + ", ";
                КонецЕсли;
                Список = Список + Товар.Товар;
            КонецЕсли;
        КонецЦикла;
        
        НоваяСтрока.КоличествоТоваров = Количество;
        НоваяСтрока.СписокТоваров = Список;
    КонецЦикла;
    
    Сообщить("Распределение товаров по ценовым категориям:");
    Для Каждого Строка Из Группировка Цикл
        Сообщить(Строка.Диапазон + ": " + Строка.КоличествоТоваров + " товаров");
        Если НЕ ПустаяСтрока(Строка.СписокТоваров) Тогда
            Сообщить("  " + Строка.СписокТоваров);
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

Группировка с вычислением доли от общего итога

// Группировка с расчетом процентной доли каждой группы
Процедура ГруппировкаСРасчетомДоли()

    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Категория");
    Таблица.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
    
    Таблица.Добавить().Категория = "Продукты"; Таблица[0].Сумма = 15000;
    Таблица.Добавить().Категория = "Продукты"; Таблица[1].Сумма = 8000;
    Таблица.Добавить().Категория = "Электроника"; Таблица[2].Сумма = 50000;
    Таблица.Добавить().Категория = "Электроника"; Таблица[3].Сумма = 30000;
    Таблица.Добавить().Категория = "Электроника"; Таблица[4].Сумма = 20000;
    Таблица.Добавить().Категория = "Одежда"; Таблица[5].Сумма = 7000;
    Таблица.Добавить().Категория = "Одежда"; Таблица[6].Сумма = 5000;
    Таблица.Добавить().Категория = "Мебель"; Таблица[7].Сумма = 25000;
    
    // Сначала вычисляем общую сумму
    ОбщаяСумма = 0;
    Для Каждого Строка Из Таблица Цикл
        ОбщаяСумма = ОбщаяСумма + Строка.Сумма;
    КонецЦикла;
    
    // Группируем по категориям
    Группировка = Таблица.Свернуть("Категория", "Сумма");
    
    // Добавляем колонки для доли и накопительного итога
    Группировка.Колонки.Добавить("Доля", Новый ОписаниеТипов("Число"));
    Группировка.Колонки.Добавить("ДоляПроцент", Новый ОписаниеТипов("Строка"));
    
    // Сортируем по убыванию суммы
    Группировка.Сортировать("Сумма УБЫВ");
    
    // Вычисляем долю для каждой категории
    НакопленнаяДоля = 0;
    Для Каждого Строка Из Группировка Цикл
        Строка.Доля = Строка.Сумма / ОбщаяСумма;
        Строка.ДоляПроцент = Формат(Строка.Доля * 100, "ЧЦ=1") + "%";
        НакопленнаяДоля = НакопленнаяДоля + Строка.Доля;
    КонецЦикла;
    
    Сообщить("Общая сумма: " + ОбщаяСумма);
    Сообщить("Структура расходов по категориям:");
    Сообщить("----------------------------------------");
    
    Для Каждого Строка Из Группировка Цикл
        Сообщить(Строка.Категория + " | " + Строка.Сумма + 
                 " | Доля: " + Строка.ДоляПроцент);
    КонецЦикла;
    
    // Определяем категории по правилу Парето (80/20)
    Сообщить("----------------------------------------");
    Сообщить("Категории, составляющие 80% суммы:");
    
    Накоплено = 0;
    Для Каждого Строка Из Группировка Цикл
        Накоплено = Накоплено + Строка.Доля;
        Сообщить(Строка.Категория + " (" + Строка.ДоляПроцент + ")");
        Если Накоплено >= 0.8 Тогда
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

Примечания

// Важные особенности группировки данных в таблице значений:
// 1. Метод Свернуть() - самый простой способ группировки с суммированием
// 2. Для группировки без агрегации используйте создание уникальных ключей
// 3. Для сложной агрегации (среднее, медиана, стандартное отклонение) используйте ручную группировку
// 4. При больших объемах данных используйте запросы к таблице значений
// 5. Для иерархической группировки применяйте рекурсивные алгоритмы
// 6. Группировку по диапазонам удобно выполнять через предварительное определение корзин
// 7. Всегда учитывайте производительность при группировке больших таблиц
// 8. После группировки рекомендуется сортировать результаты для наглядности
// 9. Для расчета накопительных итогов группируйте данные предварительно
// 10. При использовании Свернуть() исходная таблица изменяется - создавайте копию при необходимости
// 11. Для группировки по составным ключам используйте составные ключи через конкатенацию
// 12. Для группировки с условиями (HAVING) отфильтровывайте группы после агрегации

Поделиться с друзьями
Smirnov code
Добавить комментарий