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

FastCode 1535 13 21 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

Модератору