gifts2017

Hot-keys для дополнительных свойств справочников и документов.

Опубликовал Renat Sitdikov (renmy) в раздел Программирование - Работа с интерфейсом

Способ создания hot-keys для дополнительных свойств справочников и документов в обычном интерфейсе.

Ктото может скажет: Чего тут сложного, добавить скрытую кнопку на форму и приязать к ней действие.

А если нам нужно добавить на все формы объектов у которых есть дополнительные свойства? А что делать с формами списков?

Обработка события от элементов формы должна находится в модуле формы, придеться вставлять процедуры во все формы.

Представляю способ не затрагивающий модули форм, в результате которого получает 3 вставки по 2 строчки каждый в типовой код, и две процедуры.  Процедуры можно разместить в свой общий модуль или , если его у вас нет, в типовой, например: РаботаСДиалогами.

Приступим.

 

Функция вызывается при открытии формы на которой есть кнопка дополнительные свойства.

Вставка № 1


Процедура ИзменитьПредставлениеКнопкиВыбораСвойств(ФормаОбъекта, ОписаниеЗначенийСвойств) Экспорт

    Если
ПустаяСтрока(ОписаниеЗначенийСвойств) ИЛИ ОписаниеЗначенийСвойств = "Дополнительные реквизиты" Тогда
       
КартинкаКнопки = БиблиотекаКартинок.ДополнительныеРеквизитыНеУстановлены;
    Иначе
       
КартинкаКнопки = БиблиотекаКартинок.ДополнительныеРеквизитыУстановлены;
    КонецЕсли;

    Для Каждого
ЭлементФормы Из ФормаОбъекта.ЭлементыФормы Цикл
        Если
ТипЗнч(ЭлементФормы) = Тип("КоманднаяПанель") Тогда
           
Кнопка = ЭлементФормы.Кнопки.Найти("ДействиеСвойства");
            Если
Кнопка <> Неопределено Тогда
               
РаботаСДополнительнымиХарактеристикамиОбъектов.СоздатьКнопкиУстановкиДополнительныхРеквизитов(ФормаОбъекта, ЭлементФормы);
               
Кнопка.Подсказка = ОписаниеЗначенийСвойств;
               
Кнопка.Картинка  = КартинкаКнопки;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;

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

 

Т.к. мы не можем разместить процедуру обрабатывающую событие в в общем модуле, будем использовать "чужую", котораю уже есть в форме. Вставки 2 и 3 вызываются при нажатии на кнопку дополнительные свойства. Первая при нажатии кнопки на форме элемента, вторая на форме списка. 

Вставка № 2

Процедура ОткрытьСвойстваДокумента(ДокументОбъект, ФормаДокумента) Экспорт

    Если
ДокументОбъект.ЭтоНовый() Тогда
       
Вопрос = "Перед началом работы со свойствами необходимо записать документ. Записать?";
       
Ответ  = Вопрос(Вопрос, РежимДиалогаВопрос.ОКОтмена);
        Если
Ответ = КодВозвратаДиалога.ОК Тогда
           
ФормаДокумента.ЗаписатьВФорме();
        Иначе
            Возврат;
        КонецЕсли;
    КонецЕсли;

   
ЗначениеУстановленно = РаботаСДополнительнымиХарактеристикамиОбъектов.УстановитьЗначениеСвойстваОбъекта(ДокументОбъект, ФормаДокумента);
   
Если ЗначениеУстановленно Тогда Возврат; КонецЕсли;


   
Форма = Обработки.ЗначенияСвойствОбъекта.ПолучитьФорму("ЗначенияСвойствОбъекта", ФормаДокумента, ДокументОбъект.Ссылка);
   
Форма.НазначениеСвойств      = ОбщегоНазначения.ПолучитьСписокНазначенийСвойствКатегорийОбъектовПоСсылке(ДокументОбъект.Ссылка);
   
Форма.ОбъектОтбораЗначений   = ДокументОбъект.Ссылка;
   
Форма.ОбъектОтбораНазначений = ДокументОбъект.Ссылка;
   
Форма.ПрочитатьЗаполнитьСвойстваИЗначения();
   
Форма.Открыть
();

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


Вставка № 3


Процедура ОткрытьСвойстваИзСписка(Объект, ФормаОбъекта) Экспорт

    Если
Объект = неопределено Тогда
        Возврат;
    КонецЕсли;

   
ЗначениеУстановленно = РаботаСДополнительнымиХарактеристикамиОбъектов.УстановитьЗначениеСвойстваОбъекта(Объект, ФормаОбъекта);
   
Если ЗначениеУстановленно Тогда Возврат; КонецЕсли;


   
Форма = Обработки.ЗначенияСвойствОбъекта.ПолучитьФорму("ЗначенияСвойствОбъекта", ФормаОбъекта);
   
Форма.ОбъектОтбораЗначений   = Объект;
   
Форма.ОбъектОтбораНазначений = Объект;
   
Форма.ПрочитатьЗаполнитьСвойстваИЗначения();
   
Форма.Открыть
();

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


Со вставками разобрались, приступим к процедуре создания наших кнопок.

Процедура создает кнопки на текущей форме и устанавливает на нее действие. (Если у кнопки убрать видимость, не отрабатывает нажатие по hot-key поэтому пришлось сделать "микро" кнопки). Сделаем ограничение на количество кнопок, 10 шт.


Процедура СоздатьКнопкиУстановкиДополнительныхРеквизитов(ФормаОбъекта, ЭлементФормы)

   
Перем ТипЗначенияРеквизита;

   
СписокКодовСвойствДокументов = "004,006,009,010,012,013,014,015"; //не больше 10 !
   
СписокКодовСвойствСправочников = "001,002,003,005,007,009,011,016,017"; // не больше 10 !

   
МассивВсехКодов = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(СписокКодовСвойствДокументов+","+СписокКодовСвойствСправочников);

    Для Каждого
Код Из МассивВсехКодов Цикл
       
Кнопка = ФормаОбъекта.ЭлементыФормы.Найти("О_"+Код);
        Если НЕ
Кнопка = Неопределено Тогда Возврат; КонецЕсли;
    

       
Кнопка = ФормаОбъекта.ЭлементыФормы.Найти("С_"+Код);
        Если НЕ
Кнопка = Неопределено Тогда Возврат; КонецЕсли;
    КонецЦикла;

   
//список возможных способов получения типов

    Попытка
       
ТипЗначенияРеквизита = ТипЗнч(ФормаОбъекта.Ссылка); //Тип
       
ПрфиксКода = "О_";
    Исключение
        Попытка
           
ТипЗначенияРеквизита = ТипЗнч(ФормаОбъекта.СправочникСписок.Отбор.Ссылка.Значение); //Тип
           
ПрфиксКода = "С_";
        Исключение
            Попытка
               
ТипЗначенияРеквизита = ТипЗнч(ФормаОбъекта.ДокументСписок.Отбор.Ссылка.Значение); //Тип
               
ПрфиксКода = "С_";
            Исключение
                Попытка
                   
ТипЗначенияРеквизита = ФормаОбъекта.ЖурналДокументовСписок.Отбор.Ссылка.ТипЗначения; // ОписаниеТипов
                   
ПрфиксКода = "С_";
                Исключение
                    Попытка
                       
ТипЗначенияРеквизита = ТипЗнч(ФормаОбъекта.Список.Отбор.Ссылка.Значение); //Тип
                       
ПрфиксКода = "С_";
                    Исключение
                        Возврат;
                    КонецПопытки;
                КонецПопытки;
            КонецПопытки;
        КонецПопытки;
    КонецПопытки;

   
// Получим списки свойств объектов
   
Запрос = Новый Запрос("ВЫБРАТЬ
    |   СвойстваОбъектов.Ссылка,
    |   СвойстваОбъектов.Код КАК Код,
    |   СвойстваОбъектов.Наименование,
    |   СвойстваОбъектов.ТипЗначения,
    |   Представление(СвойстваОбъектов.НазначениеСвойства) КАК НазначениеСвойства,
    |   НазначенияСвойствКатегорийОбъектов.ТипЗначения КАК НазначениеСвойстваТипЗначения
    |ИЗ
    |   ПланВидовХарактеристик.СвойстваОбъектов КАК СвойстваОбъектов
    |       ЛЕВОЕ СОЕДИНЕНИЕ ПланВидовХарактеристик.НазначенияСвойствКатегорийОбъектов КАК НазначенияСвойствКатегорийОбъектов
    |       ПО СвойстваОбъектов.НазначениеСвойства = НазначенияСвойствКатегорийОбъектов.Ссылка
    |ГДЕ
    |   СвойстваОбъектов.Код В(&Коды)
    |   И СвойстваОбъектов.ПометкаУдаления = ЛОЖЬ
    |
    |УПОРЯДОЧИТЬ ПО
    |   Код"
);

   
Запрос.УстановитьПараметр("Коды",МассивВсехКодов);
   
РезультатЗапроса = Запрос.Выполнить();
    Если
РезультатЗапроса.Пустой() Тогда Возврат; КонецЕсли;
   
ТаблицаСвойстваОбъектов = РезультатЗапроса.Выгрузить();

   
//проверим если тип ОбъектаФормы в ТаблицаСвойстваОбъектов

   
Для Каждого Строка Из ТаблицаСвойстваОбъектов Цикл
        Если
ТипЗнч(ТипЗначенияРеквизита) = Тип("ОписаниеТипов") Тогда
           
НашлиТипДокумента = Ложь;
            Для каждого
ТипДокумента Из ТипЗначенияРеквизита.Типы() Цикл
                Если
Строка.НазначениеСвойстваТипЗначения.СодержитТип(ТипДокумента) Тогда
                   
НашлиТипДокумента = Истина;
                    Прервать;
                КонецЕсли;
            КонецЦикла;
            Если
НашлиТипДокумента Тогда
                Продолжить;
            КонецЕсли;
        ИначеЕсли
ТипЗнч(ТипЗначенияРеквизита) = Тип("Тип") Тогда
            Если
Строка.НазначениеСвойстваТипЗначения.СодержитТип(ТипЗначенияРеквизита) Тогда Продолжить; КонецЕсли;
        КонецЕсли;
       
Строка.ТипЗначения = Неопределено; // Назначим чтобы не создавать на них кнопки
   
КонецЦикла;

   
СчетчикКнопок = 0;
    Для Каждого
Строка Из ТаблицаСвойстваОбъектов Цикл
        Если
СчетчикКнопок = 10 Тогда Прервать; КонецЕсли;
        Если
Строка.ТипЗначения = Неопределено Тогда Продолжить; КонецЕсли;
        Если НЕ
МассивВсехКодов.Найти(Строка.Код) = Неопределено Тогда
           
ИмяКнопки = ПрфиксКода+Строка.Код;
        Иначе
            Продолжить;
        КонецЕсли;

       
ТекщаяКлавиша = Клавиша.Нет;
        Если
СчетчикКнопок = 0 Тогда
           
ТекщаяКлавиша = Клавиша.Num0;
        ИначеЕсли
СчетчикКнопок = 1 Тогда
           
ТекщаяКлавиша = Клавиша.Num1;
        ИначеЕсли
СчетчикКнопок = 2 Тогда
           
ТекщаяКлавиша = Клавиша.Num2;
        ИначеЕсли
СчетчикКнопок = 3 Тогда
           
ТекщаяКлавиша = Клавиша.Num3;
        ИначеЕсли
СчетчикКнопок = 4 Тогда
           
ТекщаяКлавиша = Клавиша.Num4;
        ИначеЕсли
СчетчикКнопок = 5 Тогда
           
ТекщаяКлавиша = Клавиша.Num5;
        ИначеЕсли
СчетчикКнопок = 6 Тогда
           
ТекщаяКлавиша = Клавиша.Num6;
        ИначеЕсли
СчетчикКнопок = 7 Тогда
           
ТекщаяКлавиша = Клавиша.Num7;
        ИначеЕсли
СчетчикКнопок = 8 Тогда
           
ТекщаяКлавиша = Клавиша.Num8;
        ИначеЕсли
СчетчикКнопок = 9 Тогда
           
ТекщаяКлавиша = Клавиша.Num9;
        КонецЕсли;

       
КнопкаДействия = ЭлементФормы.Кнопки.Найти("ДействиеСвойства");
       
ОбработкаНажатия = КнопкаДействия.Действие;

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

    КонецЦикла;

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

 

 Ну и последняя функция обрабатывет событие от наших кнопок. При нажатии на hot-key наша кнопка становится текущей, это и будем проверять. Если тип значения у свойства Булево, то функция меняет с Истины на Ложь или наобром, если другой тип, то вызывается Окно ввода значения. 

 

Функция УстановитьЗначениеСвойстваОбъекта(Объект, ФормаДокумента)

   
Перем ВыбранЗнач;
   
ИмяКнопки = "";
   
СвойствоУстановленно = Ложь;
   
ЗаписьЗаписать = Ложь;

    Если
ТипЗнч(ФормаДокумента.ТекущийЭлемент) = Тип("Кнопка") Тогда
       
ИмяКнопки = ФормаДокумента.ТекущийЭлемент.Имя;
       
ЕстьПрефикс = Ложь;
       
ПрефиксИмени = Лев(ИмяКнопки,2);
        Если
ПрефиксИмени = "О_" Тогда
           
ЕстьПрефикс = Истина;
        ИначеЕсли
ПрефиксИмени = "С_" Тогда
           
ЕстьПрефикс = Истина;
        КонецЕсли;
        Если НЕ
ЕстьПрефикс Тогда Возврат СвойствоУстановленно; КонецЕсли;
    Иначе
        Возврат
СвойствоУстановленно;
    КонецЕсли;

   
Запрос = Новый Запрос("ВЫБРАТЬ
    |   СвойстваОбъектов.Ссылка,
    |   СвойстваОбъектов.Код КАК Код,
    |   СвойстваОбъектов.Наименование,
    |   СвойстваОбъектов.ТипЗначения
    |ИЗ
    |   ПланВидовХарактеристик.СвойстваОбъектов КАК СвойстваОбъектов
    |ГДЕ
    |   СвойстваОбъектов.Код = &Код
    |   И СвойстваОбъектов.ПометкаУдаления = ЛОЖЬ"
);

   
Запрос.УстановитьПараметр("Код",Сред(ИмяКнопки,3));
   
РезультатЗапроса = Запрос.Выполнить();
    Если
РезультатЗапроса.Пустой() Тогда Возврат СвойствоУстановленно; КонецЕсли;
   
Выборка = РезультатЗапроса.Выбрать();
   
Выборка.Следующий();

    Если 
ПрефиксИмени = "О_" Тогда
       
СсылкаОбъекта = Объект.Ссылка;
    ИначеЕсли
ПрефиксИмени = "С_" Тогда
       
СсылкаОбъекта = Объект;
    КонецЕсли;

   
Запись = РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьМенеджерЗаписи();
   
Запись.Объект = СсылкаОбъекта;
   
Запись.Свойство = Выборка.Ссылка;
   
Запись.Прочитать();

    Если
Выборка.ТипЗначения.СодержитТип(Тип("Булево")) Тогда
        Если
Запись.Выбран() Тогда
           
Запись.Объект = СсылкаОбъекта;
           
Запись.Свойство = Выборка.Ссылка;
           
Запись.Значение = Не(Запись.Значение);
           
ЗаписьЗаписать = Истина;
        Иначе
           
Запись.Объект = СсылкаОбъекта;
           
Запись.Свойство = Выборка.Ссылка;
           
Запись.Значение = Истина;
           
ЗаписьЗаписать = Истина;
        КонецЕсли;
    Иначе
        Если
ВвестиЗначение(ВыбранЗнач,Выборка.Наименование,Выборка.ТипЗначения) Тогда
           
Запись.Объект = СсылкаОбъекта;
           
Запись.Свойство = Выборка.Ссылка;
           
Запись.Значение = ВыбранЗнач;
           
ЗаписьЗаписать = Истина;
        Иначе
           
СвойствоУстановленно = Истина;
        КонецЕсли;
    КонецЕсли;

    Если
ЗаписьЗаписать Тогда
        Попытка
           
Запись.Записать(Истина);
           
СвойствоУстановленно = Истина;
        Исключение
           
Сообщить(ОписаниеОшибки());
        КонецПопытки;
    КонецЕсли;

   
// установим текущий элемент не на наши кнопки
   
Для Каждого ЭлементФормы Из ФормаДокумента.ЭлементыФормы Цикл
       
ТипЗначенияЭлемента  = ТипЗнч(ЭлементФормы);
        Если
ТипЗначенияЭлемента = Тип("ТабличноеПоле") ИЛИ ТипЗначенияЭлемента = Тип("ПолеВвода") ИЛИ ТипЗначенияЭлемента = Тип("ПолеВыбора") Тогда
           
ФормаДокумента.ТекущийЭлемент = ЭлементФормы;
            Прервать;
        КонецЕсли;
    КонецЦикла;

   
// изменим представление кнопки дополнительные свойства
   
РаботаСДиалогами.ИзменитьПредставлениеКнопкиВыбораСвойств(ФормаДокумента, РаботаСДиалогами.ПолучитьОписаниеЗначенийСвойствОбъекта(СсылкаОбъекта));

    Возврат
СвойствоУстановленно;

КонецФункции

 

Вот вобщем и все.

В результате получаем hot-keys на любой форме, где есть кнопка "Дополнительные свойства" с минимальными вставками в типовой код.

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Ruslan (rus128) 27.02.13 13:06
Я правильно понимаю, что hot-keys фактически не назначаются (выбираются) пользователем/администратором, а в качестве hot-keys используются клавиши NumPad0..9?
Если да - вряд ли пользователи будут запоминать, какому реквизиту какая цифра соответствует.
2. Renat Sitdikov (renmy) 04.03.13 15:38
Все время горячие клавиши назначались программистом, представьте если этим будут заниматься пользователи.
3. andrey dyak (dyak84) 09.04.13 01:17
Вообще если по сути разобраться автор описал не просто работу с горячими клавишами, а по сути справку с примерами програмной работи с свойствами материал на Инфостарте хоть и есть на в очень скудном размере. Хотя направление по работе с свойствами считаю очень перспективным.Автору огромное спасибо так держать
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа