Ктото может скажет: Чего тут сложного, добавить скрытую кнопку на форму и приязать к ней действие.
А если нам нужно добавить на все формы объектов у которых есть дополнительные свойства? А что делать с формами списков?
Обработка события от элементов формы должна находится в модуле формы, придеться вставлять процедуры во все формы.
Представляю способ не затрагивающий модули форм, в результате которого получает 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 на любой форме, где есть кнопка "Дополнительные свойства" с минимальными вставками в типовой код.