Вести разработку в таком режиме получается немного дольше, чем прямое изменение формы. Но это хорошо компенсируется в дальнейшем при поддержке и обновлении системы 1С. На самом деле ничего сложного в этом нет, просто нужно привыкнуть.
Рассмотрим на примерах, как делать доработку управляемых форм кодом в 1С.
Чтобы упростить разработку изменений формы, можно воспользоваться небольшой хитростью. Все изменения можно сначала внести на форму через конфигурирование и отладить доработку формы. После преобразовать программные изменения в код. Изменения, которые нужны в форме изначально, стоит вносить в процедуре «ПриСозданииНаСервере». Для внесения изменений лучше сделать отдельную процедуру (например, «ДополнитьФормуПрограммно») и вызывать ее в штатной процедуре «ПриСозданииНаСервере», тогда изменение типовой формы 1С будет выглядеть одной строчкой.
Согласитесь, обновить доработанную таким образом форму значительно проще, чем вручную сравнивать и вносить все изменения формы при каждом обновлении. Конечно при сильном изменении типовой формы, могут потребоваться правки в процедуре программного дополнения формы, но такие случаи довольно редкие. Если в ходе разработки изменилась типовая структура объекта, то добавлять новые реквизиты на форму нет необходимости. Эти реквизиты будут доступны по пути «Объект.НовыйРеквизит».
Но иногда нужно добавить реквизит формы. Например, «Статус документа», который будет заполняться из специального регистра при открытии формы. Добавить новые реквизиты можно, открыв в 1С табличный документ, управляемая форма изменяется через команду ИзменитьРеквизиты(«ДобавляемыеРеквизиты», «УдаляемыеРеквизиты»).
«ДобавляемыеРеквизиты» и «УдаляемыеРеквизиты» – это массивы с элементами типа «РеквизитФормы». Тут все просто – «Добавляемые» добавляются, «Удаляемые» – удаляются.
Функция РеквизитФормы («ИмяРеквизита», «ТипРеквизита», «Путь», «Заголовок») создает объект типа «РеквизитФормы».
Тут важно понимать, что «ИмяРеквизита» содержит имя без точек. То есть имя без пути реквизита. Если нужно добавить реквизит, например, табличной части объекта, то уже в реквизите «Путь» указать путь к ТЧ реквизита – «Объект.Товары». «ТипРеквизита» задается через объект «ОписаниеТипов». После программного добавления реквизитов на форму нужно добавить элементы на форму или изменить свойства текущих. Для добавления новых элементов на форму есть два метода:
-Элементы.Добавить(«ИмяЭлемента», «ТипЭлемента», «Родитель»).
-Элементы.Вставить(«ИмяЭлемента», «ТипЭлемента», «Родитель», «Элемент»).
«ИмяЭлемента» должно быть уникальным в рамках элементов формы. Лучше добавить какой-то префикс, чтобы не возникло пересечений с типовыми элементами формы.
«ТипЭлемента» имеет не так уж много вариантов. Это «ПолеФормы», «ГруппаФормы», «ДекорацияФормы», «КнопкаФормы» и «ТаблицаФормы». Все остальные свойства назначаются через «Вид» создаваемого элемента. Например, поле с типом булево лучше сделать «флажком», установив вид элементу «ВидПоляФормы.ПолеФлажка».
В свойстве «Родитель» нужно указать группу или таблицу формы, в которую будет входить новый элемент. Также можно добавить элемент непосредственно на управляемую форму без подчинения другим элементам. Для функции вставить дополнительно указывается «Элемент», перед которым будет вставлен новый создаваемый элемент формы. Ну и конечно же, мало просто добавить элементы на форму. Система должна реагировать на действия пользователя с формой.
Для установки событий элементам нужно использовать процедуру УстановитьДействие («ИмяСобытия», «Действие»).
«ИмяСобытия» — имя события, которое нужно отработать. Например, «ПриИзменении», «Очистка», «ОбработкаВыбора» и т.п.
«Действие» — процедура отработки события. Самое главное процедура должна содержать параметры необходимые для выполняемого события. Например, процедура «ПриИзменении» должна иметь параметр «Элемент». Также программно можно задавать прочие доступные свойства новых элементов формы. Например, установить видимость кнопки очистки:
НовыйЭлемент.КнопкаОчистки = Истина;
Получилась вот такая процедура программного заполнения управляемой формы:
Код для копирования:
&НаСервере
Процедура КЛ_ДополнитьФормуПрограммно()
МассивРеквизитовФормы = Новый Массив;
//Новый реквизит Товары.КЛ_ЭтоСборка
НовыйРеквизитФормы = Новый РеквизитФормы("КЛ_ЭтоСборка",
Новый ОписаниеТипов("Булево")
,"Объект.Товары"
,"Это сборка");
МассивРеквизитовФормы.Добавить(НовыйРеквизитФормы);
//Новый реквизит КЛ_СтатусОбработки
НовыйРеквизитФормы = Новый РеквизитФормы("КЛ_СтатусОбработки",
Новый ОписаниеТипов("ПеречислениеСсылка.СтатусыДокументовРеализации")
,
,"Статус обработки");
МассивРеквизитовФормы.Добавить(НовыйРеквизитФормы);
ИзменитьРеквизиты(МассивРеквизитовФормы);
НовыйЭлемент = Элементы.Добавить("КЛ_СтатусОбработки", Тип("ПолеФормы"), Элементы.ГруппаШапкаЛевая);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.КнопкаОчистки = Истина;
НовыйЭлемент.УстановитьДействие("ПриИзменении","КЛ_ПриИзмененииСтатусаОбработки");
НовыйЭлемент = Элементы.Вставить("КЛ_ЭтоСборка", Тип("ПолеФормы"),Элементы.Товары,Элементы.ТоварыКоличество);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеФлажка;
КонецПроцедуры
1) в типовых конфигурациях у объектов (не у всех, но добавить можно!) есть тч ДополнительныеРеквизиты, и форма сама все размещает типовым механизмом.
2) Расширения позволяют создавать свою форму и обновлять ее при изменении основной конфигурации.
Ваш код придется переписывать основательно для некоторого количество реквизитов, которые могут располагаться в разных местах формы, и эти места будут зависеть от типовой формы
Имеется отдельная библиотека (набор общих модулей), которая имеет программный интерфейс по изменению существующих элементов, их событий, а так же их перемещению, и добавлению реквизитов, команд и элементов. Все это хозяйство еще умеет себя контролировать после обновления.
Скажу, что это не отнимает много процессорного времени и упрощает жизнь)
Есть минусы — разрабатывать и поддерживать труднее, и не все изменения можно сделать программно. Иногда приходится все же править форму в конфигураторе(иногда это даже разумно) или идти через Владивосток.
Все никак руки не дойдут сделать редактор формы в предприятии.
Нужно помнить, что чрезмерное увлечение данным механизмом ломает кеш.
(2) А не подскажете, что это за библиотека, где ее взять?
(4) Самописная. Ее писать не долго, а вот с отладкой придется попотеть. Все однотипно создается. Только типы элементов меняются и их виды.
На инфостарт как -то думал выложить, но передумал. Обрету обязанность сопровождения, а выхлопа скорее всего получу мало. Это не распространено. Чаще людям проще сделать расширение. Оно хотя бы в человеческом виде, хоть и приходится каждый раз его воспроизводить заново при изменении формы. Сравнением/объединением не показывает созданные кодом элементы и реквизиты, поэтому приходится извращаться и проверять кодом что изменилось из критичного.
(5)
Так оно вроде практически никогда не нужно, если я правильно понял. Плюс всегда можно выводить реквизиты на какую-то отдельную страницу если, например, не была найдена группа (программно) типовая, в которой она располагалась раньше. А вот с расширением сложнее. Я вот до сих пор не могу понять как быть в ситуации когда, например, наворотишь много изменений в одной форме или много форм в одной конфигурации, а потом при значительных изменениях типовой конфы оказывается значительно сложнее проанализировать все изменения и как-то удобно сравнить объединить. Получается даже больше работы.
И с другой стороны, как уже было подмечено, программные изменения влияют на кэширование форм. Приходится искать баланс)
(7) Это была бы просто наипречудеснейшая доработка. В целом если к ней бы еще добавить генератор кода изменения формы (например как здесьhttps://infostart.ru/public/304736/) , то, наверное, можно было бы даже «патчить» в режиме предприятия после обновления на более детальном уровне, я имею ввиду через «Выполнить()».
Про кэш форм знал тоже мало, т.е .как там в кишках платформы все это работает было совершенно непонятно, а до замеров времени дело не доходило. И из осторожности не злоупотреблял этим (по совету 1С). Спасибо, что поделились своим опытом.
Из своего опыта: при использовании программных изменений в форме в совокупности с условным оформлением может давать различные и неприятные глюки поведения элементов форм (наблюдалось с табличными частями на платформе 8.3.10.2299 разъезжались как бог на душу положит)
(8)
— как то я это пропустил когда искал нечто похожее. Вообще да, об этой генерации кода я и говорил, и почти такое же дерево получилось,
http://prntscr.com/mwo4y7
тоже самое, только у меня вызов процедур моего общего модуля. Вижу по описанию, что по тем же граблям ходил разработчик (или я по его).
Только в моем случае мне нельзя просто менять свойство, потому что потом я не найду концов и замучаюсь отлаживать.
Для существующих вместо такого:
У меня
Я не настаиваю на полном изменении формы программно. Только мелочи и средней сложности. Пока что проблем с кэшем формы не встречал.
это только если есть параметр формы, который значит, что это отладочный пуск. В боевой работе это УО не воспроизводится.
Задумывалось нечто другое. Если, к примеру в константе есть непустая ссылка на справочник внешних отчетов и обработок, то программно подключить эту внешнюю обработку и вызвать из нее некую процедуру или функцию из внешки, а не из конфигурации. Это на случай того, что найден критичный баг. (обновляем базу только в субботу, никак иначе). Эта идея принадлежит не мне, а очень талантливому программисту, моему бывшему коллеге.
P.S
Как раз в планах все эти изменения засунуть в справочник, чтобы не было портянки кода. Так по-проще будет всем я думаю.
ну и если делать коммерческий проект из этого, то я его не потяну. По крайней мере не сейчас. В идеале дождаться, когда в расширении можно будет создавать свои собственные справочники и при этом не нужно будет менять режим совместимости у типовой….и свободное время. Тогда еще можно что-то думать.
Сам давно использую программное изменение форм типовых конфигураций.
Добавлю свои 5 копеек:
если я правильно понял, то вы все равно снимаете форму с поддержки и вносите изменения в процедуру «ПриСозданииНаСервере».
Существует процедура общего модуля, в которую заходит любая форма при открытии (исключений я не нашел, возможно они есть, но мне не попадались):
ПодключаемыеКоманды.ПриСозданииНаСервере(ЭтотОбъект);
Поэтому при доработке я не трогаю сами формы, а просто добавил в конце процедуры «ПриСозданииНаСервере» общего модуля «ПодключаемыеКоманды» вызов своей процедуры:
// + НТ 14.11.2018. Перехватываем событие формы ПриСозданииНаСервере для программного создания элементов формы
НТ_Вспомогательный_Сервер.СоздатьЭлементПрограммно(Форма);
Ну и дальше уже анализируем, что за форма нам попадала и вносим изменения если они нужны.
Таким образом, если не нужно добавлять обработчики событий для добавляемых программно элементов, то саму форму можно вовсе не трогать.