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

13.03.12

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

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

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Обработка с примером динамического фильтра
.epf 24,43Kb
78
78 Скачать (1 SM) Купить за 1 850 руб.

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

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

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

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

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

 

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


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

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

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

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


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

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

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

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

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



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

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


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


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

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

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


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

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

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

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

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

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


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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

        КонецЕсли;

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

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


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

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


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

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

См. также

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

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

6000 руб.

16.01.2015    63011    44    59    

82

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

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

2400 руб.

29.06.2020    18879    26    6    

41

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

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

1500 руб.

06.10.2020    10253    7    7    

10

Работа с интерфейсом Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Это инструкция по дизайну форм в среде 1С. Гайд охватывает рекомендации и стандарты для оптимизации пользовательского интерфейса. В гайде содержатся указания по использованию элементов интерфейса, включая как основные, так и продвинутые аспекты. Предоставляются также примеры и антипримеры для наглядного понимания принципов дизайна

20.08.2024    17036    mrXoxot    43    

121

Работа с интерфейсом Программист Платформа 1С v8.3 Бесплатно (free)

Пример простого и симпатичного прогресс-бара в динамическом списке, без картинок, используя редактирование запроса.

27.05.2024    7523    smielka    37    

100

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

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

27.12.2023    14882    922    elcoan    47    

117

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

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

2 стартмани

10.04.2023    11939    162    acces969    31    

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


(4) Для управляемых небыло необходимости, но при возможности гляну.
2. ta44ik 58 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 165 29.02.12 09:06 Сейчас в теме
У Вас есть небольшие ошибки в коде, приведенном в публикации.
Например отсутствие определения переменных
кдоПодменю;
кдоДинамическийСписок;
кдоМассивПунктовМеню;

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

а так +
chmod660; +1 Ответить
8. chmod660 417 29.02.12 12:29 Сейчас в теме
(5) Благодарю!
Поправил публикацию. (в обработке эти определения есть)
Процитированный вами код - это уловка, чтобы конфигуратор видел нужный тип переменной и добавлял контекстную подсказку.
9. OLEG4120 165 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 1636 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 Сейчас в теме
Огромное спасибо! Особенно за выложенный отдельно код. Будет интересно поковырять. =)
Оставьте свое сообщение