Каталог решений - Примитивное оглавление по колонке таблицы

Примитивное оглавление по колонке таблицы

Примитивное оглавление по колонке таблицы

В наличии

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

Категория:

Описание

Это, честно говоря, фрагмент одной большой задачи, но сделанный для себя, просто для удобства работы с большим объёмом данных.

Что умеет: индексирует указанную колонку коллекции, беря первые символы, и потом по ним устанавливает отбор строк. Символы рассматривает любые, т.к. ориентируется на переданное «оглавление» — строку тех символов, по которым будут сделаны листы оглавления. Если символа в оглавлении нет, он попадёт в раздел «Все». Если символ есть, он попадёт в один из блоков оглавления. Размер блока регулируется. Можно многократно пересоздавать, можно задавать несколько оглавлений (русское и английское, например).

Создаётся выпадающее подменю, состоящее из блоков. При щелчке выполняется отбор всех строк, у которых первый символ входит в блок. Имеющиеся другие отборы строк по возможности оставляются без изменений.

Недостатки: индексация (т.е. заполнение колонки отбора) может занимать длительное время сообразно размерам коллекции. Почему не запрос? Потому что в коллекции могут содержаться значения таких типов, которые запрос не обрабатывает — картинки, допустим. Поэтому инициализацию оглавления лучше делать тогда, когда содержание коллекции уже стабильно.

Исходный код:

// Анализирует оглавление и подключает его использование к полю коллекции (желательно вызывать при инициализации
// или перезаполнении обрабатываемой коллекции), заполняет/перезаполняет список блоков оглавления.
//
// Параметры:
//    рИмяКоллекции - имя реквизита формы типа ДанныеФормыКоллекция, имеющего одноимённый элемент формы "таблица";
//    рИмяПоля - имя реквизита (колонки) коллекции; подразумевается, что есть элемент формы, чьё имя составлено по общим правилам;
//    рВсеОглавления - строка со списком "заглавных" символов, разделённых при необходимости знаком "|", например, буквы алфавита;
//    рРазмерБлока - число, размер фрагмента оглавления; например, при 4 будет А-Г, Д-Ж итд); по умолчанию равен 4.
//
&НаКлиенте
Процедура ДобавитьОглавлениеПоля(рИмяКоллекции,рИмяПоля,рВсеОглавления,рРазмерБлока=0)
    мОглавлений=СтрРазделить(рВсеОглавления,"|");
    //
    рРазмерБлока=?(рРазмерБлока=0,4,рРазмерБлока);
    //
    мБлоков=Новый Массив;
    соотПервыхСимволов=Новый Соответствие;
    //
    Для ыыы=0 По мОглавлений.Количество()-1 Цикл
        рОглавление=мОглавлений.Получить(ыыы);
        рДлина=СтрДлина(рОглавление);
        пози=1; 
        Пока Истина Цикл
            ОбработкаПрерыванияПользователя();
            рБлок=Сред(рОглавление,пози,рРазмерБлока);
            пози=пози+рРазмерБлока;
            рПервыйСимвол=Лев(рБлок,1);
            Для й=2 По рРазмерБлока Цикл
                соотПервыхСимволов.Вставить(Сред(рБлок,й,1),рПервыйСимвол);
            КонецЦикла;
            мБлоков.Добавить(Новый Структура("НомерОглавления,Блок",ыыы,рБлок));
            Если пози>=рДлина Тогда Прервать КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    //
    ДобавитьИндексноеПолеОглавленияИМеню(рИмяКоллекции,рИмяПоля,соотПервыхСимволов,мБлоков);
КонецПроцедуры    
// Добавляет колонку с индексом (первым символом) для отборов оглавления, и элементы формы для его меню;
// является вспомогательной для ДобавитьОглавлениеПоля и не рассчитана на самостоятельный вызов.
&НаСервере
Процедура ДобавитьИндексноеПолеОглавленияИМеню(рИмяКоллекции,рИмяПоля,соотПервыхСимволов,мБлоков)
    Попытка
        мрек=Новый Массив;
        мрек.Добавить(Новый РеквизитФормы(рИмяПоля+"_ИПО",Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(1)),рИмяКоллекции));
        ИзменитьРеквизиты(мрек);
    Исключение
    КонецПопытки;
    //
    рКоллекция=ЭтаФорма[рИмяКоллекции];
    Для каждого стро Из рКоллекция Цикл
        сим=Лев(стро[рИмяПоля],1);
        соотсим=соотПервыхСимволов.Получить(сим);
        Если соотсим=Неопределено Тогда соотсим=сим КонецЕсли;
        стро[рИмяПоля+"_ИПО"]=соотсим;
    КонецЦикла;
    
    заг=Элементы[рИмяКоллекции+рИмяПоля].Заголовок;
    преф="ИПО_"+рИмяКоллекции+"_"+рИмяПоля+"_";
    грэл=Элементы.Найти("ИПО_Вызовы_"+рИмяКоллекции);
    Если грэл=Неопределено Тогда
        грэл=Элементы.Добавить("ИПО_Вызовы_"+рИмяКоллекции,Тип("ГруппаФормы"),Элементы[рИмяКоллекции+"КоманднаяПанель"]);
        грэл.Вид=ВидГруппыФормы.Подменю;
        грэл.Заголовок="Оглавление"+?(ПустаяСтрока(заг),""," ("+заг+")");
    КонецЕсли;        
    //
    ком=ЭтаФорма.Команды.Найти(преф);
    Если ком=Неопределено Тогда
        ком=ЭтаФорма.Команды.Добавить(преф);
        ком.Действие="ОтобратьБлокПоОглавлению";
        ком.Отображение=ОтображениеКнопки.Текст;
    КонецЕсли;
    эл=Элементы.Найти(ком.Имя);
    Если эл=Неопределено Тогда
        эл=Элементы.Добавить(ком.Имя,Тип("КнопкаФормы"),грэл);
        эл.Вид=ВидКнопкиФормы.КнопкаКоманднойПанели;
        эл.ИмяКоманды=ком.Имя;
        эл.Заголовок="Все";
        эл.Пометка=Истина;
    КонецЕсли;    
    //
    Для каждого рБлок Из мБлоков Цикл
        Попытка
            рПервыйСимвол=Лев(рБлок.Блок,1);
            ком=ЭтаФорма.Команды.Добавить(преф+СокрЛП(рБлок.НомерОглавления)+"_"+рПервыйСимвол);
            ком.Действие="ОтобратьБлокПоОглавлению";
            ком.Отображение=ОтображениеКнопки.Текст;
            эл=Элементы.Добавить(ком.Имя,Тип("КнопкаФормы"),грэл);
            эл.Вид=ВидКнопкиФормы.КнопкаКоманднойПанели;
            эл.ИмяКоманды=ком.Имя;
            эл.Заголовок=рПервыйСимвол+" - "+Прав(рБлок.Блок,1);
        Исключение
        КонецПопытки;        
    КонецЦикла;
КонецПроцедуры
// Вызывается командами, созданными для каждого пункта меню оглавления, выполняет установку и снятие отбора
&НаКлиенте
Процедура ОтобратьБлокПоОглавлению(Команда)
    мстро=СтрРазделить(Команда.Имя,"_");
    рИмяКоллекции=мстро.Получить(1);
    рИмяПоля=мстро.Получить(2);
    Если мстро.Количество()=4 Тогда
        сим="";
    Иначе
        сим=мстро.Получить(4); // третьим идёт номер оглавления
    КонецЕсли;
    
    грэл=Элементы.Найти("ИПО_Вызовы_"+рИмяКоллекции);
    Для каждого эл Из грэл.ПодчиненныеЭлементы Цикл
        Если ТипЗнч(эл)=Тип("КнопкаФормы") Тогда эл.Пометка=Ложь КонецЕсли;
    КонецЦикла;
    
    отб=Новый Структура;
    отбСтарый=Элементы[рИмяКоллекции].ОтборСтрок;
    Если ТипЗнч(отбСтарый)<>Тип("ФиксированнаяСтруктура") Тогда отбСтарый=Новый Структура КонецЕсли;
    Для каждого киз Из отбСтарый Цикл отб.Вставить(киз.Ключ,киз.Значение) КонецЦикла;
    Если ПустаяСтрока(сим) Тогда // все пункты
        Попытка отб.Удалить(рИмяПоля+"_ИПО") Исключение КонецПопытки;
    Иначе
        отб.Вставить(рИмяПоля+"_ИПО",сим);
    КонецЕсли;
    Элементы[рИмяКоллекции].ОтборСтрок=Новый ФиксированнаяСтруктура(отб);
    
    Элементы[Команда.Имя].Пометка=Истина;
КонецПроцедуры

 

Пример вызова:

Оглавления="abcdefghijklmnopqrstuvwxyz|ABCDEFGHIJKLMNOPQRSTUVWXYZ";
ДобавитьОглавлениеПоля("ТаблицаПроизводителей", "Название", Оглавления);
has been added to your cart:
Оформление заказа