Кнопка динамического отбора в списке документов/справочнике

13.03.12

Разработка - Работа с интерфейсом

Меню отбора в один клик, заполняющееся возможными значениями из текущей колонки.

Скачать файлы

Наименование Файл Версия Размер
Обработка с примером динамического фильтра
.epf 24,43Kb
78
.epf 24,43Kb 78 Скачать

Мне давно хотелось иметь возможность не залезать в дебри отбора, а иметь возможность одним лёгким касанием установить отбор по реквизиту, с учетом только возможных вариантов.

Тоесть не лазить по всему справочнику контрагентов, а выбрать из перечня реально встречающихся в текущем списке документов, причем еще и желательно с учетом уже установленных  по прочим реквизитам этих документов.

Для этого нужно на форму добавить одно подменю, а в саму форму - немножечко кода, всего три процедуры, и назначить событию динамического списка ПриАктивизацииКолонки  обработчик кдоДокументСписокПриАктивизацииКолонки.

Код излагаю ниже, а в файле публикации - работающий пример, где фильтр реализован во внешней обработке с динамическим списком документов "Реализация товаров и услуг". (обработка для 8.2, но сам принцип реализуется в любой восьмерке).

UPD 2012-03-13: поправил код и обновил файл с примером. теперь, если мы стоим на колонке, по которой уже отфильтрован список, всё равно меню заполняется всеми значениями из этой колонки (с учетом других отборов). Вследствие этого, не будет "одиноких" меню из одного значения.

 

//будем использовать префикс кдо - "кнопки динамического отбора" для нашей подсистемы
Перем кдоМассивПунктовМеню;
Перем
кдоПодменю;
Перем
кдоДинамическийСписок;


Процедура
кдоДействияФормыИнициализация(Кнопка)
   
//__________________________________________________________________________________________________________________________
    //настройки подсистемки
    //__________________________________________________________________________________________________________________________
    //в принципе, их можно вынести в модуль формы
   
ПредставлениеПустогоЗначения="(не заполнено)";
   
ОграничениеКоличестваПунктовМеню=20;
   
кдоПодменю=ЭлементыФормы.ДействияФормы.Кнопки.Фильтр;

   
кдоЭлементФормыСписок=ЭлементыФормы.Список;
   
кдоДинамическийСписок=ДокументСписок;
   
//__________________________________________________________________________________________________________________________

   
Состояние();

   
кдоПодменю.Кнопки.Очистить();
   
кдоМассивПунктовМеню.Очистить();
   
Действие=Новый Действие("кдоНажатиеНаПунктМенюОтбора");


   
//добавим готовые, установленные уже отборы

   
ТекущаяКолонкаИмя=кдоЭлементФормыСписок.ТекущаяКолонка.Имя;
    Если
кдоДинамическийСписок.Отбор.Найти(ТекущаяКолонкаИмя)=Неопределено Тогда
       
Сообщить("такого отбора нет");
        Возврат;
    КонецЕсли;

   
СчетчикПунктовМеню=0;
   
ВремяНач=ТекущаяДата();
   
ИмяДокумента=кдоЭлементФормыСписок.ТекущаяСтрока.метаданные().Имя;
   
запрос=новый Запрос;

   
СоставнаяЧастьЗапросаОтбор=" ГДЕ     ";
    Для каждого
ЭлементОтбора Из  кдоДинамическийСписок.Отбор Цикл
        Если
ЭлементОтбора.Использование Тогда

            Если
ЭлементОтбора.ПутьКДанным <> ТекущаяКолонкаИмя Тогда
               
СоставнаяЧастьЗапросаОтбор=СоставнаяЧастьЗапросаОтбор+Символы.ПС+" ВыбраннаяТаблица."+ЭлементОтбора.ПутьКДанным +" В(&"+ЭлементОтбора.ПутьКДанным+") И";
            КонецЕсли;



            Если
ТипЗнч(ЭлементОтбора.Значение)<>Тип("СписокЗначений") Тогда
               
ПараметрСписокЗначений=Новый СписокЗначений;
               
ПараметрСписокЗначений.Добавить(ЭлементОтбора.Значение);
            Иначе
               
ПараметрСписокЗначений=ЭлементОтбора.Значение;
            КонецЕсли;

           
запрос.УстановитьПараметр(ЭлементОтбора.ПутьКДанным,ПараметрСписокЗначений);//ЭлементОтбора.Значение);


           
Если Ложь Тогда кдоМассивПунктовМеню=Новый  Массив;КонецЕсли;


           
СтруктураУправленияПунктаМеню=Новый Структура;
           
СтруктураУправленияПунктаМеню.Вставить("Действие","Сбросить");
           
СтруктураУправленияПунктаМеню.Вставить("ИмяОтбора",ЭлементОтбора.Имя);
           
СтруктураУправленияПунктаМеню.Вставить("Значение",Неопределено);
           
кдоМассивПунктовМеню.Добавить(СтруктураУправленияПунктаМеню);

           
СчетчикПунктовМеню=СчетчикПунктовМеню+1;

       
НоваяКнопка=кдоПодменю.Кнопки.Добавить(СчетчикПунктовМеню,ТипКнопкиКоманднойПанели.Действие,
        ?(
ЗначениеЗаполнено(ЭлементОтбора.Имя),строка(ЭлементОтбора.Имя),ПредставлениеПустогоЗначения)
        ,
Действие);
       
НоваяКнопка.Пометка=Истина;


           
//СтруктураЗначенийПунктовМеню;
            //СтруктураЗначенийПунктовМеню.Вставить("_"+Строка(СчетчикПунктовМеню),ТекСтрока[ТекущаяКолонкаИмя]);
        //      НоваяКнопка=Подменю.Кнопки.Добавить(СчетчикПунктовМеню,ТипКнопкиКоманднойПанели.Действие,
        //?(ЗначениеЗаполнено(ТекСтрока[ТекущаяКолонкаИмя]),строка(ТекСтрока[ТекущаяКолонкаИмя]),ПредставлениеПустогоЗначения)
        //,Действие);
       
КонецЕсли;
    КонецЦикла;

   
НоваяКнопка=кдоПодменю.Кнопки.Добавить(,ТипКнопкиКоманднойПанели.Разделитель,,);

    Если
Прав(СоставнаяЧастьЗапросаОтбор,1)="И" Тогда
       
СоставнаяЧастьЗапросаОтбор=Лев(СоставнаяЧастьЗапросаОтбор, СтрДлина(СоставнаяЧастьЗапросаОтбор)-1);
    КонецЕсли;
    Если
СтрДлина(СокрЛП(СоставнаяЧастьЗапросаОтбор))=3 Тогда
       
//небыло ни одного условия
       
СоставнаяЧастьЗапросаОтбор=" ";
    КонецЕсли;

   
Запрос.Текст=
   
"ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ "+ОграничениеКоличестваПунктовМеню+"
    |   ВыбраннаяТаблица."
+ТекущаяКолонкаИмя+"
    |ИЗ
    |   Документ."
+ИмяДокумента+" КАК ВыбраннаяТаблица
    |"
+СоставнаяЧастьЗапросаОтбор+"
    |УПОРЯДОЧИТЬ ПО
    |   "
+ТекущаяКолонкаИмя;

   
Таблица=запрос.Выполнить().Выгрузить();
   
ВремяКон=ТекущаяДата();
    Для каждого
ТекСтрока Из  Таблица Цикл
       
СчетчикПунктовМеню=СчетчикПунктовМеню+1;

       
НоваяКнопка=кдоПодменю.Кнопки.Добавить(СчетчикПунктовМеню,ТипКнопкиКоманднойПанели.Действие,
        ?(
ЗначениеЗаполнено(ТекСтрока[ТекущаяКолонкаИмя]),строка(ТекСтрока[ТекущаяКолонкаИмя]),ПредставлениеПустогоЗначения)
        ,
Действие);


        Если
ТипЗнч(Отбор[ТекущаяКолонкаИмя].Значение)=Тип("СписокЗначений") Тогда
            Если
Отбор[ТекущаяКолонкаИмя].Значение.найтиПоЗначению(ТекСтрока[ТекущаяКолонкаИмя])<>Неопределено Тогда
               
//такое значение есть в списке
               
НоваяКнопка.пометка=Истина;
            КонецЕсли;
        КонецЕсли;

        Если Ложь Тогда
кдоМассивПунктовМеню=Новый  Массив;КонецЕсли;

       
СтруктураУправленияПунктаМеню=Новый Структура;
       
СтруктураУправленияПунктаМеню.Вставить("Действие","Установить");
       
СтруктураУправленияПунктаМеню.Вставить("ИмяОтбора",ТекущаяКолонкаИмя);
       
СтруктураУправленияПунктаМеню.Вставить("Значение",ТекСтрока[ТекущаяКолонкаИмя]);

       
кдоМассивПунктовМеню.Добавить(СтруктураУправленияПунктаМеню);
    КонецЦикла;

КонецПроцедуры


Процедура
кдоНажатиеНаПунктМенюОтбора(Кнопка)

   
НомерЭлемента=Число(Кнопка.Имя)-1;
   
ЗначениеПунктаМеню  = кдоМассивПунктовМеню[НомерЭлемента].Значение;
   
ИмяОтбора           = кдоМассивПунктовМеню[НомерЭлемента].ИмяОтбора;
   
Действие            = кдоМассивПунктовМеню[НомерЭлемента].Действие;

    Если
Действие="Сбросить" Тогда
       
кдоДинамическийСписок.Отбор[ИмяОтбора].использование= ложь;
       
ЗначениеОтбора=кдоДинамическийСписок.Отбор[ИмяОтбора].Значение;
        Если
ТипЗнч(ЗначениеОтбора)=Тип("СписокЗначений") Тогда
           
кдоДинамическийСписок.Отбор[ИмяОтбора].Значение=Новый СписокЗначений;
        КонецЕсли;

       
кдоПодменю.Кнопки.удалить(Кнопка);

    ИначеЕсли
Действие="Установить" Тогда
       
ЗначениеОтбора=кдоДинамическийСписок.Отбор[ИмяОтбора].Значение;

       
кдоДинамическийСписок.Отбор[ИмяОтбора].видСравнения=ВидСравнения.ВСписке;
       
кдоДинамическийСписок.Отбор[ИмяОтбора].использование=Истина;

        Если
Кнопка.Пометка Тогда
           
//нужно удалять
           
Если ТипЗнч(ЗначениеОтбора)=Тип("СписокЗначений") Тогда

               
ИскомыйЭлемент=ЗначениеОтбора.найтиПоЗначению(ЗначениеПунктаМеню);
                Если
ИскомыйЭлемент<>Неопределено Тогда
                   
ЗначениеОтбора.удалить(ИскомыйЭлемент);

                    Если
ЗначениеОтбора.Количество()=0 Тогда
                       
кдоДинамическийСписок.Отбор[ИмяОтбора].использование=Ложь;
                    Иначе
                       
массив=ЗначениеОтбора.ВыгрузитьЗначения();
                       
ЗначениеОтбора.ЗагрузитьЗначения(массив);
                       
кдоДинамическийСписок.Отбор[ИмяОтбора].использование=Ложь;
                       
кдоДинамическийСписок.Отбор[ИмяОтбора].использование=Истина;
                    КонецЕсли;
                КонецЕсли;
            Иначе
               
кдоДинамическийСписок.Отбор[ИмяОтбора].Использование=Ложь;
            КонецЕсли;

        Иначе
            Если
ТипЗнч(ЗначениеОтбора)=Тип("СписокЗначений") Тогда
               
ЗначениеОтбора.Добавить(ЗначениеПунктаМеню);
            Иначе
               
СписокЗначений=Новый СписокЗначений;
               
СписокЗначений.Добавить(ЗначениеПунктаМеню);
               
кдоДинамическийСписок.Отбор[ИмяОтбора].Значение=СписокЗначений;
            КонецЕсли;

        КонецЕсли;

       
Состояние();

    КонецЕсли;
   
кдоДинамическийСписок.Отбор[ИмяОтбора].использование= не ДокументСписок.Отбор[ИмяОтбора].использование;
   
кдоДинамическийСписок.Отбор[ИмяОтбора].использование= не ДокументСписок.Отбор[ИмяОтбора].использование;


   
Кнопка.пометка=не Кнопка.пометка;

   
кдоДействияФормыИнициализация(Неопределено);
КонецПроцедуры


Процедура
кдоДокументСписокПриАктивизацииКолонки(Элемент)
   
кдоДействияФормыИнициализация(Неопределено);
КонецПроцедуры

//нам не нужен строковый идентификатор, поэтому используем массив
кдоМассивПунктовМеню=Новый Массив;

См. также

Богатый редактор картинок, хранимых в базе, с возможностью РИСОВАНИЯ. Редактор внешних файлов картинок. Объект, расширяющий возможности работы с картинками из встроенного языка (Три в одном) + Обработка «Стандартизация картинок»

Работа с интерфейсом Рабочее место Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Обработка предназначена для редактирования картинок в режиме «Предприятие», с возможностью РИСОВАТЬ на них. Поддерживается работа как в обычных формах (толстый клиент) так и на управляемых формах (тонкий клиент). Обработка позволяет редактировать как картинки, хранимые в базе, так и графические файлы с диска на файловой системе. Помимо базовых функций (изменение размеров, преобразование формата, обрезание картинки, повороты и т.п.) – редактор имеет богатый набор инструментов для рисования. Доступна функция вставки изображения из буфера обмена. Также обработка может быть использована из встроенного языка как объект для редактирования картинок. Объект может быть использован: на стороне клиента, на стороне сервера, из внешнего соединения. Данная обработка будет особенно полезна тем, кто вносит картинки в базу (изображения номенклатуры, фотографии физических лиц и т.п.). Функционал реализуется с использованием JavaScript и бесплатного ПО ImageMagick (без использования внешних компонент).

6000 руб.

16.01.2015    61797    43    59    

80

[Расширения] Динамическое управление видимостью и доступностью элементов форм (УФ) (8.3.6+)

Работа с интерфейсом Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Механизм «Динамическое управление доступом к элементам форм объектов 1С8» предназначен для обеспечения возможности оперативного управления видимостью и доступностью элементов форм документов и справочников продуктов фирмы «1С» «1С:Предприятие 8». Решение универсальное, встраивается в любую конфигурацию с минимальными доработками, что позволяет без проблем обновлять типовые решения.

5000 руб.

14.01.2016    54403    16    21    

42

Управление дашбордами

Работа с интерфейсом Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Обработка предназначена для создания и управления дашбордами.

2400 руб.

29.06.2020    16698    21    4    

35

Новогоднее оформление для 1С

Работа с интерфейсом Платформа 1С v8.3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 Бесплатно (free)

Добавьте новогоднего настроения! Расширение создает декорацию в виде гирлянды на некоторых формах объектов.

27.12.2023    10738    750    elcoan    45    

106

Конструктор HTML, CSS и javascript

Инструментарий разработчика Работа с интерфейсом Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

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

2 стартмани

10.04.2023    9615    151    acces969    31    

118

Модель состояния для MVC

Работа с интерфейсом Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

"MVC плохо применима в 1С" - познакомьтесь с моделью состояния и, возможно, ваше мнение поменяется! Представленное решение является эволюционным развитием идеи реализации MVC для 1С. В новой версии добавлены DSL для описания модели состояния, а также параметризация свойств параметров и элементов формы.

1 стартмани

05.07.2022    3666    kalyaka    2    

27

Табло очереди заказов на экран телевизора

WEB-интеграция Работа с интерфейсом Платформа 1С v8.3 1С:Розница 2 Платные (руб)

Связка из веб-приложения и расширения для 1С: Розница 2.3.

3600 руб.

29.04.2022    12082    1    5    

10
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. scape 282 29.02.12 01:18 Сейчас в теме
Хорошая идея! Но как всегда, сделаю все по своему... :D
7. chmod660 417 29.02.12 12:18 Сейчас в теме
(1), (2), (3) - спасибо за отзыв!
Переработка и использование приветствуется, особенно с фидбеком ))
Есть мнение, что на большом массиве данных заполнение дерева возможных вариантов отбора будет небыстрым.
Но, тем не менее, интересно будет посмотреть реализацию.


(4) Для управляемых небыло необходимости, но при возможности гляну.
2. ta44ik 57 29.02.12 04:28 Сейчас в теме
Идея хорошая) Но красивше было бы дерево сделать, так и сделаю) Ну типо конрагенты - подстроки соответственно значения, отмеченные - вверх, ну и все такое)
chmod660; +1 Ответить
3. andrei.k 29.02.12 08:13 Сейчас в теме
Отличная идея, спасибо. В любом случает все делается под себя. Спасибо.
4. milanse 38 29.02.12 08:44 Сейчас в теме
А для управляемых форм ?
5. OLEG4120 162 29.02.12 09:06 Сейчас в теме
У Вас есть небольшие ошибки в коде, приведенном в публикации.
Например отсутствие определения переменных
кдоПодменю;
кдоДинамическийСписок;
кдоМассивПунктовМеню;

массив вообще-то есть, но
Если Ложь Тогда кдоМассивПунктовМеню=Новый  Массив;КонецЕсли;

а так +
chmod660; +1 Ответить
8. chmod660 417 29.02.12 12:29 Сейчас в теме
(5) Благодарю!
Поправил публикацию. (в обработке эти определения есть)
Процитированный вами код - это уловка, чтобы конфигуратор видел нужный тип переменной и добавлял контекстную подсказку.
9. OLEG4120 162 29.02.12 14:04 Сейчас в теме
6. пользователь 29.02.12 10:31
Сообщение было скрыто модератором.
...
10. dkprim 5 29.02.12 16:47 Сейчас в теме
Идея очень хорошая! Буду адаптировать под свои потребности. Автору спасибо )
11. rus128 2 29.02.12 18:23 Сейчас в теме
Классная идея!
Странно, что это до сих пор не реализовано в платформе и в типовых...
12. yoyoman 01.03.12 05:35 Сейчас в теме
Ой и правда, юзабилити очень высокое)
13. YakshinAnd 01.03.12 10:00 Сейчас в теме
Начинаю пользоваться. Часто приходится тестить разные отборы, а тут такое счастье, которое облегчит жизнь и сэкономит много времени. Спасибо огромное)!
14. fomix 33 01.03.12 10:20 Сейчас в теме
Спасибо автору за идею и реализацию. Однако руки чешутся сделать подменю фильтра не выборочно для конкретного вида документа, а для всех списков...
15. chmod660 417 01.03.12 10:54 Сейчас в теме
всем спасибо за положительные отзывы, очень приятно.

(14) fomix, не знаю, как программно добавить менюшку прям сразу ко всем формам. всё равно править код придется. Процедуру инициализации меню можно доработать и вынести во внешний модуль (чтобы осталась одна), но код её вызова всё равно в форму надо добавлять.
А так - специально делал настраиваемым, чтобы для любой формы подходило, лишь правильно надо указать 3 (три) переменных. Ну и немножко доделаю, чтобы и для справочников работало.
16. fomix 33 01.03.12 11:41 Сейчас в теме
18. Boroda 90 05.03.12 00:35 Сейчас в теме
Судя по количеству положительных отзывов - очень неплохая вещица! Думаю, будет работать в любых конфигурациях. Спасибо за интересное решение.
19. krund 10.03.12 13:37 Сейчас в теме
Решение интересное. Жаль, что сделана под себя.
20. chmod660 417 12.03.12 13:16 Сейчас в теме
(19) krund, почему жаль?
Вроде пытался сделать универсальной, можно брать и пользоваться, а можно - дорабатывать.
21. pt_olga 61 12.03.12 22:11 Сейчас в теме
спасибо автору, быстро, удобно, красиво :)
22. Kamikadze 46 12.03.12 22:24 Сейчас в теме
23. Kamikadze 46 15.03.12 17:15 Сейчас в теме
В строке ИмяДокумента=кдоЭлементФормыСписок.ТекущаяСтрока.метаданные().Имя;

должно быть так: ИмяДокумента=кдоЭлементФормыСписок.ТекущаяСтрока.метаданные().Данные.

и строки неограниченой длинны фильтр не отрабатывает.
24. chmod660 417 15.03.12 18:01 Сейчас в теме
(23) Kamikadze, спасибо!
Я буду накапливать исправления, чтобы не изменять по чайной ложке и не нагружать модератора. Но все уведомления и предложения приветствуются.
25. Valerich 1633 27.03.12 16:19 Сейчас в теме
я бы предложил основной функционал сделать универсальным:
- добавление подменю на панель при открытии (в типовых такую процедуру можно вызывать из процедур, всегда отрабатывающих при открытии)
- формирование подменю (достаточно передавать правильный набор параметров, чтобы этой процедуре было "фиолетово" откуда ее вызвали.

тогда ценность публикации вырастет в разы

А вообще идея отличная, за что и + автору
26. unoDosTres 30.05.12 12:06 Сейчас в теме
когда слишком большой список в меню фильтра он весь не помещается, добавить бы полосу прокрутки внизу и вверху, и еще когда реквизит незаполнен, стоит добавить исключение, а то ошибка на доедает выскакивать )
а вообще идея отличная ПЛЮСУЮ
27. chmod660 417 30.05.12 12:48 Сейчас в теме
(26) unoDosTres, список ограничен параметром ОграничениеКоличестваПунктовМеню.
Можно переделать запрос (убрав "ПЕРВЫЕ "+ОграничениеКоличестваПунктовМеню+"), тогда 1С сама будет дорисовывать стрелки прокрутки. Мне это показалось неудобным, да и небыстрым.
про ошибку: не видел, напишите, как воспроизвести - исправим.
28. unoDosTres 31.05.12 10:38 Сейчас в теме
(27)
оказалось, что ошибка связана не с незаполненностью реквизита, я проверял на УТ, реквизит адрес доставки,а как сказал kamikadze в (23) строки неограниченной длинны фильтр не отрабатывает, так что оказалось что об этом вы уже знаете
29. Kamikadze 46 31.05.12 11:21 Сейчас в теме
я подсистему внедрил - пользователм понравилась, такая себе юзабилюшка, не особо важно, но приятно :)
30. пользователь 03.04.13 18:51
Сообщение было скрыто модератором.
...
31. пользователь 03.04.13 18:52
Сообщение было скрыто модератором.
...
32. Foxux 03.04.13 18:52 Сейчас в теме
глюк какой то в предыдущем посте, сорри
33. Inerren 02.03.12 11:49 Сейчас в теме
Огромное спасибо! Особенно за выложенный отдельно код. Будет интересно поковырять. =)
Оставьте свое сообщение