Как свернуть таблицу значений в коде, но получить не сумму, а максимум

FastCode 1530 12 22 67

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

Дано.Сортировать("Поле1, Поле2");

Для ё = 1 По Дано.Количество() - 1 Цикл
    Если Дано[ё].Поле1 = Дано[ё - 1].Поле1 И Дано[ё].Поле2 = Дано[ё - 1].Поле2 Тогда
        Дано[ё].Поле3 = МИН(Дано[ё].Поле3, Дано[ё - 1].Поле3); // = МАКС(Дано[ё].Поле3, Дано[ё - 1].Поле3);
        Дано[ё - 1].Поле3 = 0
    КонецЕсли 
КонецЦикла;

Дано.Свернуть("Поле1, Поле2", "Поле3");

Здесь Поле1, Поле2 - поля группировки, а Поле3 - поле, в котором ищется минимум в группировках.

Заменив функцию МИН на функцию МАКС, получим агрегатную функцию максимум, если убрать первый оператор в цикле, то будут выбираться все последние записи в группировках, а если в цикле оставить только оператор

Дано[ё].Поле3 = 0

то будут выбираться первые значения в группировках.

В обсуждении http://www.forum.mista.ru/topic.php?id=766103 родился еще более короткий вариант:

Дано.Сортировать("Поле1, Поле2, Поле3 Убыв"); //для МАКС, Дано.Сортировать("Поле1, Поле2, Поле3"); //для МИН
Для ё = 1 По Дано.Количество() - 1 Цикл
    Если Дано[ё].Поле1 = Дано[ё - 1].Поле1 И Дано[ё].Поле2 = Дано[ё - 1].Поле2 Тогда
        Дано[ё].Поле3 = 0
    КонецЕсли 
КонецЦикла;
Дано.Свернуть("Поле1, Поле2", "Поле3");

Чтобы не записывать каждый раз конкретные названия полей группировки, можно обобщить приведенный выше фрагмент, задавая строку имен полей группировок:

Дано.Сортировать(ИменаПолейГруппировки);

Для ё = 1 По Дано.Количество() - 1 Цикл
    Повтор = Истина;
    Для каждого Элемент Из Новый Структура(ИменаПолейГруппировки) Цикл
        Повтор = Повтор И (Дано[ё][Элемент.Ключ] = Дано[ё - 1][Элемент.Ключ])  
    КонецЦикла; 
    Если Повтор Тогда 
        Дано[ё][Ресурс] = МИН(Дано[ё][Ресурс], Дано[ё - 1][Ресурс]);
        Дано[ё - 1][Ресурс] = 0
    КонецЕсли 
КонецЦикла;

Дано.Свернуть(ИменаПолейГруппировки, Ресурс);

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

Сток = Новый Соответствие;

Для каждого Строка Из Дано Цикл 
    Ключ = Строка[ПолеГруппировки];
    Если Сток[Ключ] = Неопределено Тогда 
        Сток[Ключ] = Строка
    Иначе 
        Сток[Ключ][Ресурс] = МИН(Сток[Ключ][Ресурс], Строка[Ресурс]);
        Строка[Ресурс] = 0
    КонецЕсли 
КонецЦикла;

Дано.Свернуть(ПолеГруппировки, Ресурс);

Автор: ildarovich

0

См. также

Связывание таблиц значений по ФИФО

Свернуть строки в таблице значений конкатенацией

СвернутьМассив (БСП)

Заполнить таблицу значений на основе строки

Получить выделенные строки списка (с сохранением выделения)

ТаблицаЗначенийВТаблицуХТМЛ

Транспонировать таблицу значений

Сохранение таблицы значений в XML

Получить данные временной таблицы

Модератору