Группировка списка по текущей колонке

22.06.15

Разработка - Универсальные функции

Встать на некую ячейку списка, нажать кнопку, сгруппировать список по значениям этой колонки.

Во-первых, залезать в "настройку списка" бывает долго и неудобно.  Это ж догадаться надо, что есть кнопка "Ещё", да и не всегда она есть. Во-вторых, часть колонок может вообще настраиваться динамически, прямо в Предприятии, кодом или профилем или ещё чем-нибудь. И бывают они не просто данными "первого уровня", а разыменованиями через 2-3 точки, вот и поди догадайся, по чему делать группировку.

Поступим проще - у нас есть поле, т.е. текущая колонка, иногда есть её путь к данным и уж точно всегда есть имя. Разберёмся, каким должен быть путь группировки, да и сделаем её по нажатию на одну кнопку. Например, так:

// Функция разбирает путь к данным, известный для элемента, или имя элемента (если оно добавлено динамически),

// возвращает массив путей, соответствующих типам значений фигурирующих полей (обычно из 1 элемента).
// При ошибке возвращает Неопределено.
//
// Параметры:
// аргИмя - имя колонки как элемента формы;
// аргПуть - имя элемента списка, где расположена колонка;
// аргМетаданные - используется при внутренних рекурсивных вызовах, при внешнем вызове не нужен.
//
// Ограничения:
// Многотипное поле, объявленное в конфигураторе или предприятии, не может иметь дальнейшее разыменование;
// Любое дополнительное поле, объявленное в предприятии, не может иметь разыменование более чем на 1 шаг.
//
&НаСервере
Функция ПолучитьПутиКДанным(аргИмя,аргПуть,аргМетаданные=Неопределено)
    Попытка
        мПутей=Новый Массив;

        Если аргМетаданные=Неопределено Тогда // это первый шаг
            #Область ПервыйШаг
                рИмяЭлемента=аргИмя;
                рИмяСписка=аргПуть;
                //
                элСписок=Элементы.Найти(рИмяСписка);
                Если элСписок=Неопределено Тогда Возврат Неопределено КонецЕсли;
                //
                эл=Элементы.Найти(рИмяЭлемента);
                Если эл=Неопределено Тогда // это динамически добавленная колонка
                    рПутьСписка=элСписок.ПутьКДанным;
                    Для каждого элспис Из элСписок.ПодчиненныеЭлементы Цикл
                        Если ТипЗнч(элспис)<>Тип("ПолеФормы") Тогда Продолжить КонецЕсли;
                        Если Лев(рИмяЭлемента,СтрДлина(элспис.Имя))<>элспис.Имя Тогда Продолжить КонецЕсли;
                        // источником является именно это поле, рассмотрим его путь к данным и от него разыменуем
                        рПуть=СтрЗаменить(элспис.ПутьКДанным,рПутьСписка+".","");
                        // разбираем
                        мрек=ЭтаФорма.ПолучитьРеквизиты(рПутьСписка);
                        Для каждого рек Из мрек Цикл
                            Если Лев(рПуть,СтрДлина(рек.Имя))<>рек.Имя Тогда Продолжить КонецЕсли;
                            // рассматриваем по типам найденного реквизита формы
                            метадан=Неопределено;
                            Для каждого рТип Из рек.ТипЗначения.Типы() Цикл
                                метадан=Метаданные.НайтиПоТипу(рТип);
                                Если метадан=Неопределено Тогда Продолжить КонецЕсли; // разыменования глубже всё равно нет
                                рИмяКРазбору=СтрЗаменить(рИмяЭлемента,элспис.Имя,"");
                                Если Лев(рИмяКРазбору,1)="_" Тогда // это был "_", вставленный СКД, а не часть имени реквизита
                                    рИмяКРазбору=Сред(рИмяКРазбору,2); // далее там уже могут быть и свои "_", входящие в имена
                                КонецЕсли;
                                мПутейРек=ПолучитьПутиКДанным(рИмяКРазбору,рПуть,метадан);
                                Если ТипЗнч(мПутейРек)=Тип("Массив") Тогда
                                    Для каждого знч Из мПутейРек Цикл мПутей.Добавить(знч) КонецЦикла;
                                КонецЕсли;
                            КонецЦикла; // по типам найденного реквизита формы
                        КонецЦикла; // по реквизитам формы, подчинённым реквизиту списка
                        // уже всё нашли
                        Прервать;
                    КонецЦикла; // по подчинённым элементам списка
                    //
                Иначе
                    // простой случай, это штатное поле или его статично заданное разыменование
                    мПутей.Добавить(СтрЗаменить(эл.ПутьКДанным,рИмяСписка+".",""));
                КонецЕсли;
            #КонецОбласти
        Иначе
            #Область РекурсивныйШаг
                рИмяКРазбору=аргИмя;
                мПутей=Новый Массив;
                // ищем среди стандартных и обычных реквизитов левую часть; если находим - откусываем и двигаемся дальше
                метарек=Неопределено;
                Для каждого мтрк Из аргМетаданные.Реквизиты Цикл
                    Если Лев(рИмяКРазбору,СтрДлина(мтрк.Имя))=мтрк.Имя Тогда метарек=мтрк; Прервать КонецЕсли;
                КонецЦикла;
                Если метарек=Неопределено Тогда // обычно это случай стандартного реквизита
                    //В списках фигурируют как Code, Description, DeletionMark, Predefined, Owner, Parent, IsFolder, Date, Number, Posted
                    мПутей.Добавить(аргПуть+"."+рИмяКРазбору);
                Иначе
                    рПутьДальше=аргПуть+"."+метарек.Имя;
                    рИмяДальше=СтрЗаменить(рИмяКРазбору,метарек.Имя,"");
                    Если Лев(рИмяДальше,1)="_" Тогда // это был "_", вставленный СКД, а не часть имени реквизита
                        рИмяДальше=Сред(рИмяДальше,2); // далее там уже могут быть и свои "_", входящие в имена
                    КонецЕсли;
                    Если не ПустаяСтрока(рИмяДальше) Тогда
                        Для каждого рТип Из метарек.Тип.Типы() Цикл
                            метаданДальше=Метаданные.НайтиПоТипу(рТип);
                            Если метаданДальше=Неопределено Тогда Продолжить КонецЕсли; // разыменования глубже всё равно нет
                            мПутейРек=ПолучитьПутиКДанным(рИмяДальше,рПутьДальше,метаданДальше);
                            Если ТипЗнч(мПутейРек)=Тип("Массив") Тогда
                                Для каждого знч Из мПутейРек Цикл мПутей.Добавить(знч) КонецЦикла;
                            КонецЕсли;
                        КонецЦикла;
                    Иначе
                        мПутей.Добавить(рПутьДальше);
                    КонецЕсли;
                КонецЕсли;
            #КонецОбласти
        КонецЕсли;

        Возврат мПутей;
    Исключение
        Сообщить("ПолучитьПутиКДанным, ошибка: "+ОписаниеОшибки(),СтатусСообщения.ОченьВажное);
        Возврат Неопределено;
    КонецПопытки;
КонецФункции

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

Нажатие одной кнопки - и список сгруппирован по значениям текущей колонки)

p.s. Допускаю, что я просмотрел какой-то хитрый случай разыменования для добавленных вручную колонок. Если что, сообщайте, довинтим)

группировка списка;динамический список;значение ячейки списка

См. также

GUID в 1С 8.3 - как с ними быть

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    4341    atdonya    22    

41

Переоткрытие внешних обработок

Универсальные функции Платформа 1С v8.3 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    3886    ke.92@mail.ru    16    

60

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

28.08.2023    8567    YA_418728146    6    

139

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2023    21    progmaster    7    

3

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    16018    131    sapervodichka    112    

129

Система контроля ведения учета [БСП]

Универсальные функции Механизмы типовых конфигураций БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данном материале рассмотрим типовой алгоритм подсистемы контроля учета БСП в конфигурациях на примерах.

18.07.2022    7201    quazare    8    

108
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. TMV 14 22.06.15 21:50 Сейчас в теме
Проблемы со шрифтом в листинге мне причудились? А то глаза болят.
2. Bukaska 140 23.06.15 10:45 Сейчас в теме
3. TMV 14 23.06.15 13:40 Сейчас в теме
(2) Bukaska, так отлично, спасибо.
4. TreeDogNight 22 28.06.15 10:27 Сейчас в теме
Из приведенного кода понятно, что первый язык авторы был вовсе не 1С =)
5. Yashazz 4707 28.06.15 10:44 Сейчас в теме
(4) TreeDogNight, первым был Pascal 5.0, а что навело на эту мысль?
Оставьте свое сообщение