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

09.05.18

Разработка - Работа с интерфейсом

Если с программным изменением управляемых форм 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

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

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

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

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

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

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

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

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

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

См. также

Работа с интерфейсом Программист Платформа 1С v8.3 Конфигурации 1cv8 1С:ERP Управление предприятием 2 Платные (руб)

Обработка предназначена для создания и управления дашбордами.

2400 руб.

29.06.2020    17609    24    6    

38

Работа с интерфейсом Программист Платформа 1С v8.3 Бесплатно (free)

Пример простого и симпатичного прогресс-бара в динамическом списке, без картинок, используя редактирование запроса.

27.05.2024    5343    smielka    37    

95

Работа с интерфейсом Платформа 1С v8.3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 Бесплатно (free)

Добавьте новогоднего настроения! Расширение создает декорацию в виде гирлянды на некоторых формах объектов.

27.12.2023    12349    785    elcoan    47    

110

Инструментарий разработчика Работа с интерфейсом Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

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

2 стартмани

10.04.2023    10612    158    acces969    31    

120

Работа с интерфейсом Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

"MVC плохо применима в 1С" - познакомьтесь с моделью состояния и, возможно, ваше мнение поменяется! Представленное решение является эволюционным развитием идеи реализации MVC для 1С. В новой версии добавлены DSL для описания модели состояния, а также параметризация свойств параметров и элементов формы.

1 стартмани

05.07.2022    4576    kalyaka    6    

32

Работа с интерфейсом Платформа 1С v8.3 Платные (руб)

Подсистема условного оформления элементов форм (далее подсистема) предназначена для настройки оформления элементов форм (видимость, доступность, цвет фона, цвет текста и прочее) в пользовательском режиме 1С. Также подсистему возможно использовать для ограничения доступа к реквизитам формы для определенных пользователей (или групп пользователей).

6000 руб.

18.01.2022    9343    1    2    

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

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

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

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


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

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

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

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


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

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


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

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

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

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


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

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

В каждом случае решение индивидуально - что выгоднее, то и надо делать. Только рассматривая выгоду, всегда нужно учитывать удобство дальнейшего обновления.
Уверен, что во многих случаях может быть выгоден вариант, указанный в (3).
7. ILM 241 08.10.19 18:35 Сейчас в теме
Так и хочется написать: - Господя, а ЭТО то тут зачем?
В УПП и КА 5 лет уже ничего не меняется. Куча форм переделаны на сто рядов и проблем с обновлением нет совсем никаких. А тут на тебе откровение свыше. Программное добавление элементов на форму. Я бы умер поддерживать такими "программными средствами" нашу УПП с доработками по ТОС, планированию спроса, управлению качеством, раздельным учетом, требованиями ГОЗ и т.д. в одно лицо
8. dima_home 245 27.10.19 14:10 Сейчас в теме
(7)
В УПП и КА 5 лет уже ничего не меняется.
-Мм, да вы батенька либо в упр. учете застряли или на производстве только табуретки из демо-версии собираете.


Не обижайтесь... но серьезно...
1. Посту уже больше года.
2. УПП будет поддерживаться еще до 2022 года, как и мы, многие производители до последнего будут отодвигать переход на ЕРП2, хоть его и приобрели.
3. А по поводу не меняется: наберите в гугле изменения налогового/трудового законодательства, акцизы табака (у нас), алкоголь, онлайн кассы, маркировка (будут изменения к декабрю).

А вообще каждый сам для себя решает, как вести изменения в 1С.
Я лишь делился опытом, который использовал ранее и использую сейчас.
user986734; acanta; +2 Ответить
9. ILM 241 27.10.19 18:10 Сейчас в теме
(8) У нас уникальное научно-техническое производство не имеющее аналогов в России. Таких заводов всего три в мире, а технологий всего две в Америке и в России - это к "табуреткам" если что. В УПП у нас считается налог на прибыль, и зачем нам эта ЕРП? Её дорабатывать придётся пару лет просто до уровня нашей УПП пятилетней давности.
Онлайн-кассы у нас две штуки в столовой стоит, а табак, алкоголь и т.д. это точно не к нам.
(7) Поддержка программных изменений форм и их доработка занимает в разы больше времени.
10. It-developer 25 03.03.21 13:19 Сейчас в теме
11. dima_home 245 22.03.21 18:41 Сейчас в теме
(10) Возможность расширений к сожалению появилось позже. Во всех новых проектах используем расширения конфигураций и центральный репозитарий.
Именно в УПП работаем без расширений.
Однако 99% изменений вынесли в отдельный общие модули, в стандартных объектах конфигурации добавляем только реквизиты.
Такой метод позволил сильно ускорить процесс накатки обновлений 1С для УПП.
Оставьте свое сообщение