Динамическое создание форм как универсальный инструмент

05.06.26

Разработка - Механизмы платформы 1С

В статье будет описано, где можно применить динамическое создание.

Введение


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

Задача звучит так: "Необходимо сделать внешнюю обработку, которая будет запускаться во всех конфигурациях  независимо от того, что это за конфигурация (Бухгалтерия, Зарплата и управление, ЕРП), и отображать на форме любой из выбранных объектов. То есть все реквизиты, которые есть в этом объекте, должны быть отображены на форме. При этом не должно быть привязки к конкретному объекту конфигурации, которое делается с помощью статичного формирования пользовательского интерфейса (UI или форма)."

Интересная задача, не правда ли? Но тут возникает еще один вопрос: Задача-то интересная, но как ее выполнить?

И тут нам с вами может помочь то самое динамическое формирование элементов на форме.


Что такое динамическое формирование элементов на форме 


Динамическое формирование элементов на форме - это формирование элементов формы не при создании формы изначально заданных на форме элементов, а формирование элементов в момент, определенный самим программистом с помощью кода.

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


Пример формирования динамической формы


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

Таблица на форме:

 

Реквизиты, элементы которых уже есть на форме: ДанныеССсылкиОбъекта, ОбменДаннымиЗагрузка, ОтключитьДатыЗапрета, СсылкаНаОбъект, ТабличнаяЧасть, ТабличнаяЧастьОбъекта

Ниже представлен листинг кода, который по ссылке на объект (справочник, документ) формирует реквизиты на форме.

Процедура ТабличнаяЧастьПриИзмененииНаСервере() 
	

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

	ТаблицаОбъекта = СсылкаНаОбъект[ТабличнаяЧасть];
	//Добавить строки
	Для каждого СтрокаТЧСсылки Из ТаблицаОбъекта Цикл
		
		СтрокаДанных 			= 	ТЧО.Добавить();
		
		ЗаполнитьЗначенияСвойств(СтрокаДанных, СтрокаТЧСсылки);
		
	КонецЦикла; 
	
	ТабличнаяЧастьОбъекта.Загрузить(ТЧО);   

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

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

Метаданные объекта, если говорить в контексте ООП - это свойства заданного объекта, если говорить в контексте 1С - это реквизиты объекта.

Первым условием мы проверяем, есть ли создаваемый нами элемент. Если его нет, мы создаем его с помощью кода:

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

Если он есть, необходимо его найти и использовать. 

С помощью метода "Очистить()", удаляем данные элемента (это нужно на случай, если он уже был использован).

После очистки данных таблицы на форме собираем метаданные табличной части объекта по ссылке, выбранной на форме.  По этим данным "НайденнаяПоСсылкеТЧ" мы будем формировать колонки таблицы.

Теперь также, если элемент уже был использован, нам необходимо очистить пути данных (реквизиты, к которым привязаны элементы колонок) его колонок от предыдущего объекта и заполнить реквизиты и элементы колонок нынешнего, то есть выбранного объекта. 

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

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

Вторым циклом мы собираем массив элементов, которые нужно добавить добавить на форму, также обозначаем путь к данным, иначе элементы будут отображать пустые данные.

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

ИзменитьРеквизиты(КолонкиДляДобавления, КолонкиДляУдаления);

Этот метод работает не только для замены реквизитов, его можно использовать без второго параметра "КолонкиДляУдаления". В таком случае он не будет ничего удалять, а лишь добавит новый массив реквизитов на форму. 

После выполнения изменения реквизитов нужно отобразить данные на форме и отобразить элементы.

Создаем колонки на форме:

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

Подведем итоги


В данной статье мы рассмотрели практическую задачу, которая хоть и не часто, но если возникает, то бывает сложно впервые с ней разобраться. При разработке в среде 1С: Предприятие бывает необходимостью - создания универсальной внешней обработки, работающей с любыми объектами любых конфигураций (Бухгалтерия, ЗУП, ЕРП и т.д.) без статической привязки.

Ключевые выводы:

  1. Универсальность через динамику — динамическое формирование элементов формы позволяет создавать интерфейс под любой объект, получая его структуру через метаданные. Это решает главную задачу: обработка не зависит от того, какой именно справочник или документ выбран.

  2. Баланс преимуществ и недостатков:

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

    • Минусы: сложность поддержки, менее наглядная разработка.

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

Наконец, универсальная обработка — отличный пример для понимания внутреннего устройства платформы 1С. Освоив динамическое создание формы, можно легко реализовывать собственные инструменты, без привязки к конкретной конфигурации. Это расширяет границы типовой разработки и даёт свободу для нестандартных задач.

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

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

Таким образом, динамическое формирование формы — это мощный, хотя и требующий аккуратности, инструмент, который позволяет выйти за рамки статического UI и создавать по-настоящему универсальные решения в экосистеме 1С.

Вступайте в нашу телеграмм-группу Инфостарт

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Механизмы платформы 1С Программист Бесплатно (free)

Разберем 15 мифов о работе платформы «1С:Предприятие 8» – как распространенных, так и малоизвестных. Начнем с классики: «Код, написанный в одну строку, работает быстрее, чем многострочный». Так ли это на самом деле?

16.07.2025    33502    TitanLuchs    108    

149

Механизмы платформы 1С Работа с интерфейсом Программист Стажер 1С:Предприятие 8 Бесплатно (free)

Про ООП в 1С и о том, как сделать свой код более кратким и выразительным при помощи использования текучего интерфейса (fluent interface).

03.02.2025    18308    bayselonarrend    127    

68

Механизмы платформы 1С Программист 1С:Предприятие 8 Бесплатно (free)

В этой статье подробно рассматривается работа с JSON в XDTO в 1С:Предприятие. Вы узнаете, как сериализовать и десериализовать объекты XDTO в JSON, интегрировать 1С с веб-сервисами и API, а также корректно обрабатывать данные при обмене. Разбираются особенности работы с коллекциями, использование функций восстановления и частые ошибки при работе с JSON и XDTO.

30.01.2025    23291    user2122906    9    

66

Механизмы платформы 1С Файловый обмен (TXT, XML, DBF), FTP Программист 1С:Предприятие 8 Бесплатно (free)

Этот материал познакомит вас с механизмом XDTO (XML Data Transfer Objects) в 1С и научит эффективно использовать его возможности. Мы разберёмся, как работать с XML-схемами, создавать модели данных, манипулировать объектами XDTO, а также сериализовать и десериализовать их в XML. Вы узнаете, как использовать XDTO для интеграции с внешними системами, избегать типичных ошибок и оптимизировать код. К концу вы будете уверенно применять XDTO для решения сложных задач обмена данными и автоматизации процессов.

17.01.2025    40875    user2122906    12    

62

Механизмы платформы 1С WEB-интеграция Программист 1С:Предприятие 8 Бесплатно (free)

В платформе 8.3.27 появилась возможность использовать WebSocket-клиент. Давайте посмотрим, как это все устроено и чем оно нам полезно.

14.01.2025    34314    dsdred    106    

149

Механизмы платформы 1С Программист Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

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

23.06.2024    29939    bayselonarrend    22    

178

Механизмы платформы 1С Программист Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    16098    dsdred    22    

88
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. ksnik 695 05.06.26 10:21 Сейчас в теме
Статья отлично раскрывает кейс с разными конфигурациями. Хочу добавить ещё один, не менее важный — работа внутри одной типовой конфигурации, но с частыми обновлениями от поставщика. Данный подход полезен особенно в контексте работы с расширениями, возникает упрощение обновления типовых конфигураций.

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

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

Обновление становится автоматическим: Новая версия формы от поставщика применяется без каких-либо ручных доработок, так как наши изменения не "зашиты" в её статическую структуру.

Снижение стоимости владения: В долгосрочной перспективе затраты на поддержку такого решения кратно ниже. Один раз написанный код программного добавления элемента будет работать на любой будущей версии конфигурации, если только не изменится сам "скелет" (имя реквизита, к которому мы обращаемся) .

Таким образом, динамическое создание форм полезно не только для межконфигурационной универсальности (как в статье), но и для защиты доработок внутри одной конфигурации от разрушения при обновлениях — особенно в связке с расширениями. Сочетание "расширение + динамическое создание элементов формы" — это золотой стандарт для доработки типовых конфигураций. Это дает и гибкость (через код), и "безопасность" при обновлениях (через расширение), и прозрачность разработки (поскольку все изменения собраны в одном месте и видны в коде, а не разбросаны по свойствам десятков форм).
Для отправки сообщения требуется регистрация/авторизация