Программное управление обычными формами документов и справочников в УПП/КА

Программирование - Работа с интерфейсом

Обычные формы программирование форм вывод полей на форму вывод колонки на форму

26
Если с программным изменением управляемых форм 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); 
;
	НовоеПолеВвода.Подсказка = Заголовок;
	//НовоеПолеВвода.МногострочныйРежим  = Истина;
	НовоеПолеВвода.УстановитьПривязку(ГраницаЭлементаУправления.Верх,ЭлементПривязки,ГраницаЭлементаУправления.Верх); 
	НовоеПолеВвода.УстановитьПривязку(ГраницаЭлементаУправления.Лево,ЭлементПривязки,ГраницаЭлементаУправления.Лево); 
	Если РастягиватьПоВысоте Тогда
		НовоеПолеВвода.УстановитьПривязку(ГраницаЭлементаУправления.Низ,ЭлементПривязки,ГраницаЭлементаУправления.Низ); 
	Иначе
		НовоеПолеВвода.УстановитьПривязку(ГраницаЭлементаУправления.Низ,ЭлементПривязки,ГраницаЭлементаУправления.Верх); 
	КонецЕсли;			
	Если РастягиватьПоШирине Тогда
		НовоеПолеВвода.УстановитьПривязку(ГраницаЭлементаУправления.Право,ЭлементПривязки,ГраницаЭлементаУправления.Право); 
	Иначе
		НовоеПолеВвода.УстановитьПривязку(ГраницаЭлементаУправления.Право,ЭлементПривязки,ГраницаЭлементаУправления.Лево); 
	КонецЕсли;

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

 - Функция добавления флажка на форму.

Эта функция позволяет разместить на форму флажок (булево).
Правила использования такие же как у предыдущей функции. Фактически это копия предыдущей функции, только для флажка.

Код этой функции почти идентичны предыдущим, по этому убран под спойлер.

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

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

 

 

- Функция добавления надписи на форму.

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

Код убран под спойлер

 

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

 

 

- Универсальное добавление поля на форму.  (это другой подход добавления элементов на форму, гораздо более универсальный).
Используем эту процедуру гораздо чаще тех, что указал выше.

Эта более универсальная процедура. Появилась в нашем арсенале гораздо позже. Основное ее преимущество в том, что она может автоматически копировать оформление и привязку с других элементов на форме.
Так же можно назначить выполнение любого события, а не только "При изменении". Работает через структуру в параметрах.
Обязательные поля структуре  - "ТипПоля,ИмяПоля,Данные,ЭлементЭталон,Подсказка,ПолеСдвига". Не забывайте их заполнять при вызове этой процедуры.

//Универсальная функция добавления элементов на форму
//Параметры:
//ДокументОбъект, ФормаДокумента 
//СтруктураЗаполнения = Новый Структура("ТипПоля,ИмяПоля,Данные,ЭлементЭталон,Подсказка,ПолеСдвига") - обязательные поля в структуре.
//СтруктураЗаполнения.Вставить("Доступность",Ложь),СтруктураЗаполнения.Вставить("Видимость",истина") - не обязательные поля в структуре
// ИмяСобытие, ИмяДействия - заполняются в паре.
// Имя элемента привязки - копирует свойства с данного элемента формы
// РазмерОтступа - это отступ вниз от элемента привязки для нового элемента.
// ИмяПоляВладельца - это имя элемента владельца для подчиненных справочников.

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

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

 

- Процедура добавления колонки в табличную часть формы.
Это универсальная процедура добавления колонки на форму.
Обязательные поля структуреколонки  - "Имя,Данные,КолонкаЭталон,Подсказка". Не забывайте их заполнять при вызове этой процедуры. Остальные свойства для новой колонки будут скопированы с колонки эталон, указанной в структуре.

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

 

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

Процедура УдалитьКолонкуТабличнойЧасти(ФормаДокумента, ИмяТабЧасти, ПризнакКолонки)
    Для каждого Элемент из ФормаДокумента.ЭлементыФормы[ИмяТабЧасти].Колонки Цикл 
		Если Найти(Элемент.Имя,ПризнакКолонки ) > 0 тогда 
			 ФормаДокумента.ЭлементыФормы[ИмяТабЧасти].Колонки.Удалить(Элемент);
			 УдалитьКолонкуТабличнойЧасти(ФормаДокумента,"Товары", ПризнакКолонки);
		КонецЕсли;
	КонецЦикла;

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

- Процедура удаления элемента формы.
 

Процедура УдалитьЭлемент(ФормаДокумента, ПризнакЭлемента) 
	
   Для каждого Элемент из ФормаДокумента.ЭлементыФормы Цикл 
		Если Найти(Элемент.Имя,ПризнакЭлемента ) > 0 тогда 
			 ФормаДокумента.ЭлементыФормы.Удалить(Элемент);
			 УдалитьЭлемент(ФормаДокумента,ПризнакЭлемента);
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

 

Часть 4

Думаю надо показать несколько примеров, как мы добавляем новые реквизиты на форму.
Примеры добавления колонки на форме:

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

Пример добавления колонки на форму

Еще пример с добавлением полей в отдельной закладке:


Процедура ПриОтккрытии_РеализацияТоваровУслуг(ДокументОбъект, ФормаДокумента)		
	Если ДокументОбъект.Метаданные().Реквизиты.Найти("Автомобиль") = Неопределено Тогда 
		Возврат;
	КонецЕсли;	
	ЭлементыФормы=ФормаДокумента.ЭлементыФормы;
	СтараяСтраница = ЭлементыФормы.ОсновнаяПанель.ТекущаяСтраница;
	СтраницаТТН = ЭлементыФормы.ОсновнаяПанель.Страницы.Найти("ТТН");
	Если СтраницаТТН=Неопределено Тогда
		СтраницаТТН = ЭлементыФормы.ОсновнаяПанель.Страницы.Добавить("ТТН","ТТН",,);
		ЭлементыФормы.ОсновнаяПанель.ТекущаяСтраница=СтраницаТТН;
		НовоеПолеВвода = ДобавитьПолеВводаНаФорму(ФормаДокумента,"Автомобиль:","Автомобиль","ОсновнаяПанель",0,Истина,Ложь,120,"АвтомобильПриИзменении");
		НовоеПолеВвода = ДобавитьПолеВводаНаФорму(ФормаДокумента,"Водитель:","Водитель","ОсновнаяПанель",1,Истина,Ложь,120);
		НовоеПолеВвода = ДобавитьПолеВводаНаФорму(ФормаДокумента,"Транспортная компания:","ТрансКомпания","ОсновнаяПанель",2,Истина,Ложь,120);
		
		НовоеПолеВвода = ДобавитьПолеВводаНаФорму(ФормаДокумента,"Менеджер:","Менеджер","ОсновнаяПанель",4,Истина,Ложь,120);
		
	КонецЕсли;
	ЭлементыФормы.ОсновнаяПанель.ТекущаяСтраница=СтараяСтраница;
	
КонецПроцедуры	

Пример добавления реквизитов на отдельную закладку

Еще пример работы с формой справочника.


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

Пример работы с формой справочника

Часть 5

Доработки по совместимости и универсальности.

Желательно весь код модуля "ИТ_РаботаСДиалогами" обрамить в клиента
 

#Если Клиент Тогда
//…..
#КонецЕсли

В процедурах, прежде чем добавлять реквизиты на форму, убедитесь, что такой реквизит существует.
Например так:

Если ДокументОбъект.Метаданные().Реквизиты.Найти("ВидОперации") = Неопределено Тогда 
		 Возврат;
КонецЕсли;

Поскольку вызов функции может происходить многократно в одной форме, всегда проверяйте, выведен ли уже реквизит на форму.
Например так:

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

Такие проверки позволят вам копировать общий модуль «ИТ_РаботаСДиалогами» во все ваши конфигурации УПП/КА и не бояться вызова исключений.

26

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. Batman 136 10.05.18 09:54 Сейчас в теме
Доброго времени суток
Дополню своими наблюдениями
Пошел аналогичным путем, через "точку входа" - МеханизмНумерацииОбъектов.УстановитьДоступностьПоляВводаНомера

1а. Для формы списка вызываю другую процедуру, в таком виде

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

1б. и процедурой обрабатываю каждый тип
Процедура ТабличноеПолеПриОткрытии(мТабличноеПоле, мТип, ЭлементыФормы)
	
	Если мТип = Тип("ДокументСписок.РеализацияТоваровУслуг") Тогда 
		ДокументСписок_РеализацияТоваровУслуг(мТабличноеПоле, ЭлементыФормы);


1в. Если по колонке, добавленно программным способом. требуется будет устанавливать отбор - предусматриваем такую возможность

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

2а. Для формы объектов, не забываем проверять, если это справочник и элемент является группой, то программное создание реквизитов для него вызовет ошибку

мОбъект = ЭтаФорма.ЭтотОбъект;
	
	ЭтоСправочник = Метаданные.Справочники.Содержит(мОбъект.Метаданные());
	
	Если ЭтоСправочник И мОбъект.ЭтоГруппа Тогда
		Возврат;
	КонецЕсли;


2в. После обработки формы возвращаемся (активизируем) текущую страницу панели формы

ЭлементыФормы = ЭтаФорма.ЭлементыФормы;
	
	Если ТипЗнч(мОбъект) = Тип("ДокументОбъект.ПоступлениеТоваровУслуг") Тогда				
		мТекущаяСтраница = ЭлементыФормы.ОсновнаяПанель.ТекущаяСтраница;		
		ПоступлениеТоваровУслуг(ЭлементыФормы, ЭтаФорма, мОбъект);		
		ЭлементыФормы.ОсновнаяПанель.ТекущаяСтраница = мТекущаяСтраница;


P.S. Кстати, некоторое время назад от уважаемой Евгения Карук (ekaruk) была интересная статья о программном восстановлении расположения колонок в табличных частях управляемых форм, в случае, если пользователь скрыл колонки путем настройки списка
https://infostart.ru/public/259747/
dima_home; +1 Ответить
2. dima_home 99 10.05.18 18:26 Сейчас в теме
Спасибо за дополнение. Хорошо, когда можно собрать все сведения о программировании форм в одном месте.
3. script 196 10.05.18 23:55 Сейчас в теме
Все это интересно до того момента когда новому элементу, размещенному на форме программно, нужно назначить обработчик одного из событий. Вот тут все и заканчивается, потому что процедуру-обработчик нужно полюбому разместить в модуле формы. И тогда становится понятным, что самым удобным способом является подмена стандартных обработчиков событий формы на свои. Эта методика подробно описана в статье: Методика переопределения и вызова обработчиков событий формы в 1С 8 и показала свою незаменимость
dima_home; +1 Ответить
4. dima_home 99 11.05.18 11:35 Сейчас в теме
(3)
Вот тут все и заканчивается, потому что процедуру-обработчик нужно полюбому разместить в модуле формы. И тогда становится понятным, что самым удобным способом является подмена стандартных обработчиков событий формы на свои

Ну я тут с вами не могу согласиться.

Исходя из личной практики:
Более 50% добавленных реквизитов на формы документов и справочников во всех используемых нами конфигураций, это просто недостающие дополнительные реквизиты объекта, не требующие моментальной реакции формы на их изменение. По-этому снимать форму с поддержки по таким случаям не нужно, и прикреплять какие либо события тоже.
Более того, незначительная часть событий "ПриИзменении" можно привязать к стандартным процедурам, вызываемым из других стандартных реквизитов на форме, когда там и так выполняются те действия, которые вам надо проделать ( например "ПриИзмененииТабличнойЧасти")

Если все таки реакция формы на изменение программно добавленного реквизита нужна незамедлительно и вам не удалось свести реакцию на вызов уже имеющихся процедур в форме, то на мой взгляд, для обновления, легче добавить в конец модуля объявление процедуры:
Процедура ПриИзмененииНовогоРеквизита(Элемент)
ИТ_РаботаСФормой.ПриИзмененииНовогоРеквизита(Элемент, ЭлементыФормы);
КонецПроцедуры


чем городить предложенную методологию.
Хотя, как говориться, на вкус и цвет...

Тоже касается, когда приходится добавлять на форму новые кнопки.
5. pm74 130 11.05.18 11:54 Сейчас в теме
(3) можно по принципу "чтобы купить что-то полезное нужно продать нужно продать что-то бесполезное " , другими словами в типовых любят делать вызовы общих модулей на команды формы , которые можно слегка подправить
6. dima_home 99 11.05.18 12:52 Сейчас в теме
(5)
которые можно слегка подправить

В каждом случае решение индивидуально - что выгоднее, то и надо делать. Только рассматривая выгоду, всегда нужно учитывать удобство дальнейшего обновления.
Уверен, что во многих случаях может быть выгоден вариант, указанный в (3).
Оставьте свое сообщение