Программное управление обычными формами документов и справочников в УПП/КА
Если с программным изменением управляемых форм 1С все более или менее понятно, то с программированием обычных форм примеров не так уж много в сети. А уж примеров готовых решений совсем не видно.
В данной статье я покажу, как можно реализовать аналог «управляемых» форм в своих конфигурациях с обычными формами и забыть о сложностях обновлений форм.
- Описание
- Подробнее
Описание
Часть 1
Чтобы не снимать с поддержки все формы конфигурации и не вставлять свои обработчики в процедуры «ПриОткрытии», будем искать такую процедуру, которая вызывается во всех формах документах и справочников.
Для форм документов — это функция общего модуля «РаботаСДиалогами.АктивизироватьРеквизитВФорме». Она как раз вызывается из процедуры форм документов «При открытии» и двойное бинго — в конце процедуры, после стандартных процедур по изменению формы.
И так, снимаем с поддержки общий модуль «РаботаСДиалогами».
Находим функцию «АктивизироватьРеквизитВФорме» и сразу после объявления функции добавляем строку вызова нашей процедуры:
Функция АктивизироватьРеквизитВФорме(Объект, ФормаОбъекта, СтруктураРеквизитов = Неопределено, ТабличнаяЧасть = неопределено, СтраницыСТабЧастями = неопределено) Экспорт
ИТ_РаботаСДиалогами.ДополнитьФормуДокумента(Объект, ФормаОбъекта);//Вызов нашей будущей процедуры
//...
КонецФункции// АктивизироватьРеквизитВФорме()Для форм справочников — это процедура общего модуля «МеханизмНумерацииОбъектов.УстановитьДоступностьПоляВводаНомера».
Находим модуль «МеханизмНумерацииОбъектов", в процедуре «УстановитьДоступностьПоляВводаНомера», сразу после ее объявления, добавляем строку вызова нашей процедуры:
Процедура УстановитьДоступностьПоляВводаНомера(МетаданныеОбъекта, ФормаОбъекта, ПодменюДействия, ПолеВводаНомера) Экспорт
ИТ_РаботаСДиалогами.ДополнитьФормуСправочника(МетаданныеОбъекта,ФормаОбъекта);//Вызов нашей будущей процедуры
// Обратите внимание на то, что в этом случае мы передаем метаданные, а не объект. Учитывайте это при работе с параметрами.
//...
КонецПроцедуры // УстановитьДоступностьПоляВводаНомера()
Все. Отделались снятием с поддержки двух модуле с добавлением в них двух строк. Обновлять будет легко.
Часть 2
Теперь самое главное.
Добавляем в конфигурацию общий модуль «ИТ_РаботаСДиалогами». В свойствах ставим галочки на использование в клиенте.
В модуль помещаем вызываемые функции.
//*******************************************************************************************
//*В ЭТОМ МОДУЛЕ ПРОЦЕДУРЫ И ФУНКЦИИ, СВЯЗАННЫЕ С ДИНАМИЧЕСКИМ ФОРМИРОВАНИЕМ ФОРМ ДОКУМЕНТОВ*
//*******************************************************************************************
//******************* ЗАПОЛНЕНИЕ ФОРМ ДОКУМЕНТОВ ****************************
//Вызывается из процедуры РаботаСДиалогами.АктивизироватьРеквизитВФорме
//В свою очередь процедура "АктивизироватьРеквизитВФорме" вызывается в каждой форме документа при открытии
Процедура ДополнитьФормуДокумента(ДокументОбъект, ФормаДокумента) Экспорт
//Пример вызова процедуры для изменения формы документа
Если ТипЗнч(ДокументОбъект) = Тип("ДокументОбъект.УвольнениеИзОрганизаций") тогда
ПриОткрытии_УвольнениеИзОрганизаций(ДокументОбъект, ФормаДокумента);
КонецЕсли;
КонецПроцедуры
//******************* ЗАПОЛНЕНИЕ ФОРМ СПРАВОЧНИКОВ ****************************
//Вызывается из процедуры МеханизмНумерацииОбъектов.УстановитьДоступностьПоляВводаНомера
//В свою очередь процедура "УстановитьДоступностьПоляВводаНомера" вызывается почти в каждой форме справочника при открытии.
Процедура ДополнитьФормуСправочника(ОбъектМетоданных, ФормаСправочника) Экспорт
//!ВНИМАНИЕ! Процедура вызывается и при открытии формы элемента справочника, и при открытии формы списка справочника. Отличить место вызова процедуры можно по имени формы, но имя формы у них приходится получать по разному.
Попытка
ИмяФормы = ФормаСправочника.Имя;
Исключение
ИмяФормы = ФормаСправочника.Заголовок;
КонецПопытки;
//Примеры вызова процедур для изменения формы элемента справочника.
Если ОбъектМетоданных.ПолноеИмя()="Справочник.Склады"
И ИмяФормы="Склады (места хранения)" Тогда
ПриОткрытии_Склады(ОбъектМетоданных, ФормаСправочника);
ИначеЕсли ОбъектМетоданных.ПолноеИмя()="Справочник.СтатьиДвиженияДенежныхСредств"
И ИмяФормы="Статьи движения денежных средств" Тогда
ПриОткрытии_СтатьиДвиженияДенежныхСредств(ОбъектМетоданных, ФормаСправочника);
КонецЕсли;
КонецПроцедуры
Обратите внимание, что работа с формами справочника имеет особенности. Поскольку процедура "МеханизмНумерацииОбъектов.УстановитьДоступностьПоляВводаНомера" вызывается как из формы списка справочника, так и из формы самого элемента справочника. Различить можно только по составу передаваемых метаданных или просто по имени формы.
Часть 3
Поскольку мы не хотим каждый раз писать кучу кода при размещении реквизитов на форму, мы напишем заранее разного рода функции и процедуры, которые и будем в дальнейшем использовать.
— Функция добавления поля ввода на форму (одна из ранних наших функций).
Эта функция позволяет разместить на форму реквизит данный как поле ввода и его заголовок как надпись.
Есть некоторые особенности использования этой функции:
— При наличии заголовка в параметрах, он отображается как надпись на форме слева от поля ввода, если поле ввода имеет флаг РастягиватьПоВысоте=Истина, то заголовок выводится слева-сверху от поля ввода.
— В параметр "ДействиеПриИзменении" можно указать название процедуры, вызываемый при изменении реквизита, добавленного на форму. !ВАЖНО! указываемая процедура должна быть размещена в модуле формы, где добавляется реквизит.
//****************** ФУНКЦИИ РИСОВАНИЯ ОБЪЕКТОВ НА ФОРМЕ *******************
Функция ДобавитьПолеВводаНаФорму(ФормаОбъекта,Заголовок="",ИмяДанных,ИмяЭлементаПривязки="",ИндексЭлемента=0,РастягиватьПоШирине=Ложь,РастягиватьПоВысоте=Ложь,ШиринаЗаголовка = 88, ДействиеПриИзменении="")
СдвигВПраво = 0;
ЭлементыФормы = ФормаОбъекта.ЭлементыФормы;
МинимальнаяВысотаФормы = 5 + (ИндексЭлемента * 20)+ 19+5+ЭлементыФормы.ОсновныеДействияФормы.Высота;
//Увеличение высоты формы и смещение нижних кнопок при недостаточности высоты формы.
Если ФормаОбъекта.Высота < МинимальнаяВысотаФормы Тогда
РазницаВВысоте = МинимальнаяВысотаФормы - ФормаОбъекта.Высота;
ФормаОбъекта.Высота = ФормаОбъекта.Высота + РазницаВВысоте+2;
ШиринаВерхКнопок = ЭлементыФормы.ОсновныеДействияФормы.ширина;
НовыйВерхКнопок = ЭлементыФормы.ОсновныеДействияФормы.Верх + РазницаВВысоте;
ЭлементыФормы.ОсновныеДействияФормы.Верх=НовыйВерхКнопок;
Shell = Новый COMОбъект("WScript.Shell");
Shell.SendKeys("%+R"); // вызов Alt+Shift+R
КонецЕсли;
//Имя панели, на которую выводится новое поле ввода.
Если ПустаяСтрока(ИмяЭлементаПривязки) Тогда
ЭлементПривязки=ФормаОбъекта.ТекущийЭлемент;
Ширина = ФормаОбъекта.Ширина;
Высота = ФормаОбъекта.Высота;
Иначе
ЭлементПривязки = ЭлементыФормы[ИмяЭлементаПривязки];
Ширина = ЭлементПривязки.Ширина;
Высота = ЭлементПривязки.Высота;
КонецЕсли;
//Выводим заголовок поля на форме как надпись.
Если Не ПустаяСтрока(Заголовок) Тогда
НоваяНадпись = ЭлементыФормы.Добавить(Тип("Надпись"),"Надпись"+ИмяДанных,,ЭлементПривязки);
НоваяНадпись.Заголовок = Заголовок;
НоваяНадпись.Верх = 5 + (ИндексЭлемента * 20);
НоваяНадпись.Лево = 5;
НоваяНадпись.Ширина = ШиринаЗаголовка;
НоваяНадпись.Высота = 19;
НоваяНадпись.УстановитьПривязку(ГраницаЭлементаУправления.Верх,ЭлементПривязки,ГраницаЭлементаУправления.Верх);
НоваяНадпись.УстановитьПривязку(ГраницаЭлементаУправления.Лево,ЭлементПривязки,ГраницаЭлементаУправления.Лево);
ЗаголовокСверху = (РастягиватьПоВысоте И РастягиватьПоШирине);
Если ЗаголовокСверху Тогда
НоваяНадпись.Ширина = Ширина-10;
НоваяНадпись.УстановитьПривязку(ГраницаЭлементаУправления.Право,ЭлементПривязки,ГраницаЭлементаУправления.Право);
ИндексЭлемента = ИндексЭлемента + 1;
Иначе
СдвигВПраво = ШиринаЗаголовка;
КонецЕсли;
КонецЕсли;
//Добавление самого поля ввода (вашего реквизита) на форму
НовоеПолеВвода = ЭлементыФормы.Добавить(Тип("ПолеВвода"),ИмяДанных,,ЭлементПривязки);
НовоеПолеВвода.Данные = ИмяДанных;
ЭтоСправочник = Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(НовоеПолеВвода.Значение));
ЭтоДокумент = Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(НовоеПолеВвода.Значение));
НовоеПолеВвода.КнопкаОткрытия = ЭтоСправочник ИЛИ ЭтоДокумент;
НовоеПолеВвода.Верх = 5+(ИндексЭлемента*20);
НовоеПолеВвода.Лево = 5+СдвигВПраво;
НовоеПолеВвода.Ширина = ?(РастягиватьПоШирине,Ширина-15-СдвигВПраво,220);
НовоеПолеВвода.Высота = ?(РастягиватьПоВысоте,Высота-15-(ИндексЭлемента*20),19);
;
НовоеПолеВвода.Подсказка = Заголовок;
//НовоеПолеВвода.МногострочныйРежим = Истина;
НовоеПолеВвода.УстановитьПривязку(ГраницаЭлементаУправления.Верх,ЭлементПривязки,ГраницаЭлементаУправления.Верх);
НовоеПолеВвода.УстановитьПривязку(ГраницаЭлементаУправления.Лево,ЭлементПривязки,ГраницаЭлементаУправления.Лево);
Если РастягиватьПоВысоте Тогда
НовоеПолеВвода.УстановитьПривязку(ГраницаЭлементаУправления.Низ,ЭлементПривязки,ГраницаЭлементаУправления.Низ);
Иначе
НовоеПолеВвода.УстановитьПривязку(ГраницаЭлементаУправления.Низ,ЭлементПривязки,ГраницаЭлементаУправления.Верх);
КонецЕсли;
Если РастягиватьПоШирине Тогда
НовоеПолеВвода.УстановитьПривязку(ГраницаЭлементаУправления.Право,ЭлементПривязки,ГраницаЭлементаУправления.Право);
Иначе
НовоеПолеВвода.УстановитьПривязку(ГраницаЭлементаУправления.Право,ЭлементПривязки,ГраницаЭлементаУправления.Лево);
КонецЕсли;
//Добавление события при изменении.
Если НЕ ПустаяСтрока(ДействиеПриИзменении) Тогда
НовоеПолеВвода.УстановитьДействие("ПриИзменении",Новый Действие(ДействиеПриИзменении));
КонецЕсли;
Возврат НовоеПолеВвода;
КонецФункции
— Функция добавления флажка на форму.
Эта функция позволяет разместить на форму флажок (булево).
Правила использования такие же как у предыдущей функции. Фактически это копия предыдущей функции, только для флажка.
Код этой функции почти идентичны предыдущим, по этому убран под спойлер.

