Создаем программно элементы из общего модуля.
Для примера рассмотрю добавление колонки «Скрепка» в форму списка документа. Если к документу привязан файл, то в списке в новой колонке должна отображаться «скрепка».
Часто требуется внести изменения в типовые формы объектов (документов, справочников, журналов, обработок и т.д.)
Есть несколько методов решения этих задач:
— Снимать с поддержки форму, вносить в нее изменения. Все просто, но проблемы возникнут при обновлении релиза конфигурации.
— Переносить форму в расширение и править там. Тоже просто, но если при обновлении релиза форма поменяется (добавятся новые поля к примеру), то придется еще дорабатывать расширение.
— Создавать элементы формы программно в общем модуле. Проблем с обновлением на новый релиз не будет. Рассмотрим данный метод.
В типовых конфигурациях в формах объектов в процедуре ПриСозданииНаСервере есть обращение к общему модулю СобытияФорм.ПриСозданииНаСервере
Далее идет обращение к общему модулю МодификацияКонфигурацииПереопределяемый.ПриСозданииНаСервере
В этом модуле процедура ПриСозданииНаСервере пустая. Тут и добавляем ссылку уже на наш модуль (не типовой модуль).
Доработка_ФормаПриСозданииНаСервере.ИзменитьФорму
В этой процедуре разбиваем формы по объектам и названиям форм.
Для удобства можно добавлять отельные общие модули для каждого объекта.
Доработка_ДокументСчетФактураПолученныйФормаСпискаДокументов
Доработка_ДокументСчетФактураПолученныйФормаДокумента
Тут редактируем запрос в динамическом списке. Методом СтрЗаменить. Добавляем левое соединение, добавляем новое поле в выборку запроса.
Программно добавляем колонку. ПутьКДанным указываем наша новое поле, которое мы добавили в запрос "Список.Д_ЕстьФайлы".
Процедура ПриСозданииНаСервере(Форма, Объект = Неопределено) Экспорт
ДинСписок = Форма.Список;
ТекстЗапроса =
"Документ.СчетФактураПолученный КАК ДокументСчетФактураПолученный
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НаличиеФайлов КАК НаличиеФайлов
| ПО ДокументСчетФактураПолученный.Ссылка = НаличиеФайлов.ОбъектСФайлами";
ДинСписок.ТекстЗапроса = СтрЗаменить(ДинСписок.ТекстЗапроса, "Документ.СчетФактураПолученный КАК ДокументСчетФактураПолученный", ТекстЗапроса);
ТекстЗапроса = "ДокументСчетФактураПолученный.Ссылка,
| ВЫБОР
| КОГДА НаличиеФайлов.ЕстьФайлы ЕСТЬ NULL ТОГДА 1
| КОГДА НаличиеФайлов.ЕстьФайлы ТОГДА 0
| ИНАЧЕ 1
| КОНЕЦ КАК Д_ЕстьФайлы,";
ДинСписок.ТекстЗапроса = СтрЗаменить(ДинСписок.ТекстЗапроса, "ДокументСчетФактураПолученный.Ссылка,", ТекстЗапроса);
ПодчиненныйЭлемент = Форма.Элементы.Вставить("Д_ЕстьФайлы", Тип("ПолеФормы"), Форма.Элементы.Список, Форма.Элементы.СодержитНекорректныхКонтрагентов);
ПодчиненныйЭлемент.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Нет;
ПодчиненныйЭлемент.ПутьКДанным = "Список.Д_ЕстьФайлы";
ПодчиненныйЭлемент.Вид = ВидПоляФормы.ПолеКартинки;
ПодчиненныйЭлемент.КартинкаШапки = БиблиотекаКартинок.Скрепка;
ПодчиненныйЭлемент.КартинкаЗначений = БиблиотекаКартинок.Скрепка;
ПодчиненныйЭлемент.Ширина = 1;
КонецПроцедуры
В результате появляется заполненная колонка.
Еще для примера приведу добавление "полей ввода" на форму.
Процедура ПриСозданииНаСервере(Форма, Объект = Неопределено) Экспорт
//Поле ввода. Реквизит формы
Реквизит = Новый РеквизитФормы("Д_ФИОРодительныйПадеж", Новый ОписаниеТипов("Строка"), , "ФИО родительный падеж", Истина);
мРеквизиты = Новый Массив;
мРеквизиты.Добавить(Реквизит);
Форма.ИзменитьРеквизиты(мРеквизиты);
НовыйЭлемент = Форма.Элементы.Вставить("Д_ФИОРодительныйПадеж", Тип("ПолеФормы"), Форма.Элементы.ГруппаОсновныеСведения ,Форма.Элементы.ДолжностьПоВизитке);
НовыйЭлемент.ПутьКДанным = "Д_ФИОРодительныйПадеж";
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ОтметкаНезаполненного = Истина;
НовыйЭлемент.АвтоОтметкаНезаполненного = Истина;
//Поле ввода. Реквизит объекта
НовыйЭлемент = Форма.Элементы.Добавить("Д_ДанныеОТранспортировкеИГрузе", Тип("ПолеФормы"), Форма.Элементы.ГруппаДополнительно);
НовыйЭлемент.ПутьКДанным = "Объект.Д_ДанныеОТранспортировкеИГрузе";
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.Заголовок = "Данные о транспортировке и грузе";
НовыйЭлемент.РастягиватьПоГоризонтали = Ложь;
НовыйЭлемент.Ширина = 28;
КонецПроцедуры
Проверял на конфигурации 1С:Комплексная автоматизация 2
Платформа 1С:Предприятие 8.3 (8.3.13.1644)
Не знал о такой лазейке. Впрочем точно тот же эффект можно получить при программном изменении формы в расширении.
очень спорная мысль. с чего вы решили, что не будет? в последних релизах ЗУП, УТ, ЕРП разрабы так лихо выпиливают таблицы в метаданных и добавляют новые, что упор на модификацию форм посредством кода скорее ущербен, чем удобен.
мне лично проще проверить форму в расширении и «доработать», чем копаться в тонне переопределяемого кода и держать весь этот хламо-код в голове.
дело вкуса и …лени
(2) Не забывайте только что расширения можно применять далеко не во всех конфигурациях — у многих компаний используются конфигурации с режимом совместимости со старыми версиями платформы, при которых использовать расширения либо вообще не получится, либо с рядом ограничений, поэтому такой метод будет еще долгое время востребован
(3) тс привел пример пример своего ноу-хау с кодом из методов общих модулей в новых конфигурациях.
поэтому я смущен категоричным пиаром программного способа как «высшего» метода
к чему тс было балаболить о том, что весьма условно?
а так да, все относительно и я же написал
Ну фраза
также относится и к расширениям — никакой гарантии ни то, ни другое не дает, что после обновления системы на новый релиз что-то из этого не перестанет работать — плюс расширения будет конечно в том, что исправить это можно будет более оперативнее и менее заметно для пользователей. В данном случае, думаю, автор имел в виду что при обновлении не потребуется «мержить» между собой много кода модифицированных модулей.
Давно пользуюсь подобной лазейкой. Но, как универсальное решение данный способ, увы, не подходит.
Общий модуль «СобытияФорм» есть даже далеко не во всех типовых конфигурациях на УФ (он не входит в состав БСП), и даже там где есть —
решении .
не везде вызывается из форм. В итоге приходится вклинивать функцию редактирования формы сразу в несколько разных обработчиков (в основном из модулей БСП, но и в некоторые специфичные для конкретной конфигурации и раздела учета — например для бухгалтерского учета). И делать проверку — обработана форма уже или ещё нет — т.к. в некоторых формах разные обработчики могу вызывать повторно. Это всё я уже реализую в опубликованном тут моём
Но, это всё более менее хорошо до тех пор, пока в формах такие обработчики вызываются — но есть формы — где они вовсе не вызываются. Да есть и просто автогенерируемые формы — там вообще ничего такого не вызывается и не будет вызываться (и расширения не помогут) пока такую форму не создашь физически в конфигураторе.
Ну и главное — такая модификация элементов форм работает ровно до момент, пока не нужно связывать с программно добавленными элементами обработчики событий — вот тут наступает полная трабла — т.к. обработчик события можно назначить только из модуля формы («спасибо» ужасное фирме 1С за такое ограничение).
Правда при размещени кнопок, имеющих внешние обработчики ещё как-то можно бороться (как типвыми так и не типовыми способами — смотря что доступно в форме) — об этом у меня есть в планах желание написать статью, а публикация, фактически использующая данную технику — уже на подходе.
То, вот, с обработчиками таких событий как, например, «ПриИзменении» или «ОбработкаВыбора» — вот тут беда…. без модификации формы или применения расширений — никак не обойтись!
(3)Так там и БСП будет более ранних версий — где таких общих функций может и не быть вовсе, или их применение в формах тоже будет сведено к минимуму — так что большинство форм не будет их вызывать!
(1)Способ из особо хорош, когда нужно массово модифицирвать формы, не влезая в модуль каждой, даже в расширении
Ничего нового — постоянно так делаю, с той лишь разницей, что весь код именно в расширении, а конфа на замке (разумеется, если есть возможность использования расширений).
Отмечу лишь, что не во всех формах есть подходящие под это дело процедуры общих модулей и вот тогда приходится все таки добавлять в расширение форму.
(7) Такие вызовы общих модулей используются уже с БСП 2, конечно не в таком специальном виде как в публикации через общие модули «СобытияФорм«, но в подавляющем большинстве форм имеются вызовы общих модулей других подсистем (например, «версионирование данных», «доп. отчетов и обработок»), которые в принципе можно использовать по аналогии с описанным способом — в них также доступен контекст вызываемой формы (вроде что-то похожее использовалось даже в УТ 10).
В принципе все это решается еще проще — созданием подписки на событие получения формы менеджеров всех объектов, в которой можно переопределить поведение всех необходимых форм объектов.
(10)
Вот тут подробнее. Сколько не смотрел я это событие — так ничего толкового из него не вынес — событие срабатывает в серверном контексте, причём контекст объекта формы не доступен — максимум что там можно — только подменить один путь к форме на другой (читай одно имя вызова формы, другим) — и всё 🙁 фигня фигней — конечно в ряде случаев может быть полезно — когда Вы делаете свою форму — то её можно насильно подсовывать вместо других — анализируя путь исходного вызова формы. Но менять именно саму форму в этом событии совсем нельзя!
(11) Вы правы, поработать с формой через подписку не получится, погорячился, а жаль ;(
(1) Конечно, добавить модуль «МодификацияКонфигурацииПереопределяемый» в расширении и писать в &После(«ПриСозданииНаСервере») все что нужно. 1) Не нужно настраивать поддержку. 2) При обновлении больше времени на сравнение объединение будет уходить у поставленной на редактирование конфы.
Не во всех конфигурациях он есть, в БУХ 3.0 и ЗУП 3.1 такого модуля нет.
(3) три года назад поднимали совместимость с 8.1 на 8.2. А затем я поднял последовательно до 8.3.5. Тогда только 8.3.8 еще была.
Пару дней работы и все переписано грубо говоря, так что долго это наверно пока УПП поддерживается, КА уже сдулось. Пару лет и никто про это не вспомнит!
(15) Далеко не все хотят возиться с доработками (или же это нецелесообразно в краткосрочной перспективе, или же не хватает соответствующей компетенции), необходимыми для отключения в конфигурации режима совместимости со старыми версиями платформы, бывает это даже связано с тем, что у специалиста нет понимания и уверенности в том, что конфа будет работать также стабильно и без «глюков» как и до отключения совместимости, так что думаю в старых конфах этот метод просуществует еще долго.
(16) а по поводу статьи. Давно была статья, как вести доработку в типовых. Просто наверно про нее уже забыли. А тут лишь кусочек, единственное чуть больше примеров как писать этот код. Но в книжке разработчика все написано и так.
Предпочитаю вносить изменения в конфигурацию. Каждый раз при обновлении приходиться восстанавливать свои изменения (если обновление затронуло их). Зато гарантированно держу полный контроль — где надо проверить корректную работоспособность, где не надо.
А при использовании расширений и описанной здесь методики надо вести актуальный Чек-лист, что бы после каждого обновления прогнать по нему тестирование.
(18) так точно, всегда надо обдумывать, что в расширение пихать, а что лучше в конфе изменить.
(0) С появлением схемы запроса доработка динамических списков при помощи этого объекта выглядит намного стабильнее и универсальнее, чем через конкатенацию в тексте запроса.
Такой баян что я… на дворе конец 2019 года, а тут статья про переопределение события форм… жесть.
Утверждать что этот метод самый лучший и универсальный я бы не стал 🙂
К примеру, попробуйте добавить таким способом обработчик события для добавленного элемента формы не «снимая с поддержки» эту форму.
Как вариант, безусловно заслуживает внимания, но есть ряд недостатков (на мой взгляд), основной среди которых — отсутствие наглядности.
Представьте что таких элементов на форму потребовалось добавить не один, а несколько и даже несколько десятков, а также что при этом необходимо перегруппировать существующие элементы формы. Разобраться в таком коде будет очень сложно. В случае же использования расширения, либо создания отдельной формы это сделать намного проще.
Указанный же способ в основном я использую для изменения доступностью и видимостью элементов формы.
Это как в медицине — для каждой болезни свой метод лечения. Универсального же лекарства не существует и вряд ли будет создано в будущем 🙂