Книга знаний

1С:Предприятие / v8 / Приемы программирования / Формы

v8: Настройка формы по макету

В случае, если вам необходимо изменить что то в диалоге типовой формы, не торопитесь изменять его. Ведь можно использовать динамическую модификацию формы перед открытием.Автор статьи: TormozIT | Редакторы: Гений 1С,
Последняя редакция №2 от 13.08.06 | История
URL: http://kb.mista.ru/article.php?id=327

Ключевые слова: макет, форма, настройка, динамическая


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

Но есть и еще вариант. Нужно создать копию формы в конфигураторе, дав ей имя <Префикс>+<ОригинальноеИмя>+<Макет> и сделать там все необходимые изменения диалога в конфигураторе.
В разделе основной программы макета нужно заполнить список произведенных настроек.
НастройкиМакета = ЛксСоздатьРеквизитНастройкиМакета(ЭтаФорма);
НастройкиМакета.Добавить(<ДобавленныйЭлемент>);
НастройкиМакета.Добавить(<ЭлементСИзмененнойПозицией>, "Позиция");
НастройкиМакета.Добавить(<ЭлементСИзмененнымиРазмеромИПривязкой>, "Размер_Привязка");
НастройкиМакета.Добавить(<КоманднаяПанельСДобавленнойКнопкой>, "Внутри");

В обработчике ПередОткрытием рабочей(типовой) формы нужно вызвать процедуру настройки формы по макету.
Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)

    ЛксНастроитьФормуПоМакету(ЭтаФорма);

КонецПроцедуры // ПередОткрытием()

Либо с применением моего метода Книга знаний: v8: Методика переопределения и вызова обработчиков событий формы
// Процедура - обработчик события "ПередОткрытием" элемента формы "".
//
Процедура ЛксПередОткрытием(Отказ, СтандартнаяОбработка)

    ЛксНастроитьФормуПоМакету(ЭтаФорма);
      Выполнить(ЛксПолучитьСтароеДействиеФормы(ЭтаФорма, "ПередОткрытием", ""));    

КонецПроцедуры // ЛксПередОткрытием()

ЛксУстановитьДействиеФормы(ЭтаФорма, "ПередОткрытием", "");




Необходимые функции и процедуры общего модуля.


// Создает невидимый реквизит макета формы.
// В этот реквизит потом будет помещен список настроек макета.
// Вызывается в самом начале основной программы модуля макета формы.
//
// Параметры:
//  пФорма       – Форма – макета формы.
//
// Возвращаемое значение:
//               - СписокЗначений – список выбора созданного элемента формы.
//
Функция ЛксСоздатьРеквизитНастройкиМакета(пФорма) Экспорт

    Возврат пФорма.ЭлементыФормы.Добавить(Тип("ПолеВвода"), "общНастройкиМакетаФормы").СписокВыбора;

КонецФункции // ЛксПолучитьРеквизитНастройкиМакета()

// Заполняет форму по ее макету. Используется для динамического добавления элементов
// в типовые формы, чтобы облегчить их обновление. Макет формы, если явно не указан,
// ищется среди форм объекта метаданных формы по имени "Лкс"+<ИмяФормы>+"Макет".
// Список настраиваемых элементов формы берется из свойства СписокВыбора предварительно
// программно добавленного элемента формы общНастройкиМакетаФормы.
// Для измененных элементов формы при внесеннии в список добавляется
// представление в соответствии с изменениями, содержащее ключевые слова с разделителем "_":
// "Привязка", "Размер", "Позиция", "Внутри" (для коллекций).
// Следует вызывать в обработчике ПередОткрытием формы.
//   Ограничения.
// 1. Нельзя добавлять элементы в панели и поля табличного документа, т.к. у элемента нельзя
// определить родителя.
// 3. Нельзя, чтобы формы были разной высоты. Обрабатываеся.
// 4. Нельзя добавлять и изменять элементы, привязанные косвенно к низу формы.
// 5. Иногда элементы, привязанные косвенно к правой границе формы неверно располагаются.
//
// Параметры:
//  пФорма       – Форма – которую настраиваем;
//  *пМакет      – Форма - макет, по которому настраиваем.
//
Процедура ЛксНастроитьФормуПоМакетуСНастройками(пФорма, пМакетФормы = Неопределено) Экспорт

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

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика