Управляемые формы. Изменение формы списка или формы объекта без внесения изменений в типовые формы (без использования расширений)

Вносим изменения в типовые формы объектов (документы, справочники, журналы, обработки, общие формы). Не снимая с поддержки эти формы.
Создаем программно элементы из общего модуля.
Для примера рассмотрю добавление колонки «Скрепка» в форму списка документа. Если к документу привязан файл, то в списке в новой колонке должна отображаться «скрепка».

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

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

— Переносить форму в расширение и править там. Тоже просто, но если при обновлении релиза форма поменяется (добавятся новые поля к примеру), то придется еще дорабатывать расширение.

— Создавать элементы формы программно в общем модуле. Проблем с обновлением на новый релиз не будет. Рассмотрим данный метод.

 

В типовых конфигурациях в формах объектов в процедуре ПриСозданииНаСервере есть обращение к общему модулю СобытияФорм.ПриСозданииНаСервере

 

 

Далее идет обращение к общему модулю МодификацияКонфигурацииПереопределяемый.ПриСозданииНаСервере

 

 

В этом модуле процедура ПриСозданииНаСервере пустая. Тут и добавляем ссылку уже на наш модуль (не типовой модуль). 

Доработка_ФормаПриСозданииНаСервере.ИзменитьФорму 

 

 

В этой процедуре разбиваем формы по объектам и названиям форм.

Для удобства можно добавлять отельные общие модули для каждого объекта.

Доработка_ДокументСчетФактураПолученныйФормаСпискаДокументов

Доработка_ДокументСчетФактураПолученныйФормаДокумента

 

 

Тут редактируем запрос в динамическом списке. Методом СтрЗаменить. Добавляем левое соединение, добавляем новое поле в выборку запроса.

Программно добавляем колонку. ПутьКДанным указываем наша новое поле, которое мы добавили в запрос "Список.Д_ЕстьФайлы".

 
Процедура ПриСозданииНаСервере(Форма, Объект = Неопределено) Экспорт

ДинСписок = Форма.Список;

ТекстЗапроса =
"Документ.СчетФактураПолученный КАК ДокументСчетФактураПолученный
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НаличиеФайлов КАК НаличиеФайлов
| ПО ДокументСчетФактураПолученный.Ссылка = НаличиеФайлов.ОбъектСФайлами";

ДинСписок.ТекстЗапроса = СтрЗаменить(ДинСписок.ТекстЗапроса, "Документ.СчетФактураПолученный КАК ДокументСчетФактураПолученный", ТекстЗапроса);

ТекстЗапроса = "ДокументСчетФактураПолученный.Ссылка,
| ВЫБОР
|  КОГДА НаличиеФайлов.ЕстьФайлы ЕСТЬ NULL ТОГДА 1
|  КОГДА НаличиеФайлов.ЕстьФайлы ТОГДА 0
|  ИНАЧЕ 1
| КОНЕЦ КАК Д_ЕстьФайлы,";

ДинСписок.ТекстЗапроса = СтрЗаменить(ДинСписок.ТекстЗапроса, "ДокументСчетФактураПолученный.Ссылка,", ТекстЗапроса);

ПодчиненныйЭлемент                    = Форма.Элементы.Вставить("Д_ЕстьФайлы", Тип("ПолеФормы"), Форма.Элементы.Список, Форма.Элементы.СодержитНекорректныхКонтрагентов);
ПодчиненныйЭлемент.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Нет;
ПодчиненныйЭлемент.ПутьКДанным        = "Список.Д_ЕстьФайлы";
ПодчиненныйЭлемент.Вид                = ВидПоляФормы.ПолеКартинки;
ПодчиненныйЭлемент.КартинкаШапки      = БиблиотекаКартинок.Скрепка;
ПодчиненныйЭлемент.КартинкаЗначений   = БиблиотекаКартинок.Скрепка;
ПодчиненныйЭлемент.Ширина             = 1;

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

 

В результате появляется заполненная колонка.

 

 

Еще для примера приведу добавление "полей ввода" на форму.

 
Процедура ПриСозданииНаСервере(Форма, Объект = Неопределено) Экспорт

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

//Поле ввода. Реквизит объекта
НовыйЭлемент = Форма.Элементы.Добавить("Д_ДанныеОТранспортировкеИГрузе", Тип("ПолеФормы"), Форма.Элементы.ГруппаДополнительно);
НовыйЭлемент.ПутьКДанным = "Объект.Д_ДанныеОТранспортировкеИГрузе";
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.Заголовок = "Данные о транспортировке и грузе";
НовыйЭлемент.РастягиватьПоГоризонтали = Ложь;
НовыйЭлемент.Ширина = 28;

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

 

Проверял на конфигурации 1С:Комплексная автоматизация 2 

Платформа 1С:Предприятие 8.3 (8.3.13.1644)

22 Comments

  1. MikhailDr

    Не знал о такой лазейке. Впрочем точно тот же эффект можно получить при программном изменении формы в расширении.

    Reply ↓
  2. VmvLer
    Создавать элементы формы программно в общем модуле. Проблем с обновлением на новый релиз не будет

    очень спорная мысль. с чего вы решили, что не будет? в последних релизах ЗУП, УТ, ЕРП разрабы так лихо выпиливают таблицы в метаданных и добавляют новые, что упор на модификацию форм посредством кода скорее ущербен, чем удобен.

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

    дело вкуса и …лени

    Reply ↓
  3. Bassgood

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

    Reply ↓
  4. VmvLer

    (3) тс привел пример пример своего ноу-хау с кодом из методов общих модулей в новых конфигурациях.

    поэтому я смущен категоричным пиаром программного способа как «высшего» метода

    Проблем с обновлением на новый релиз не будет

    к чему тс было балаболить о том, что весьма условно?

    а так да, все относительно и я же написал

    дело вкуса и …лени
    Reply ↓
  5. Bassgood

    Ну фраза

    Проблем с обновлением на новый релиз не будет

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

    Reply ↓
  6. Darklight

    Давно пользуюсь подобной лазейкой. Но, как универсальное решение данный способ, увы, не подходит.

    Общий модуль «СобытияФорм» есть даже далеко не во всех типовых конфигурациях на УФ (он не входит в состав БСП), и даже там где есть —

    не везде вызывается из форм. В итоге приходится вклинивать функцию редактирования формы сразу в несколько разных обработчиков (в основном из модулей БСП, но и в некоторые специфичные для конкретной конфигурации и раздела учета — например для бухгалтерского учета). И делать проверку — обработана форма уже или ещё нет — т.к. в некоторых формах разные обработчики могу вызывать повторно. Это всё я уже реализую в опубликованном тут моём решении.

    Но, это всё более менее хорошо до тех пор, пока в формах такие обработчики вызываются — но есть формы — где они вовсе не вызываются. Да есть и просто автогенерируемые формы — там вообще ничего такого не вызывается и не будет вызываться (и расширения не помогут) пока такую форму не создашь физически в конфигураторе.

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

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

    То, вот, с обработчиками таких событий как, например, «ПриИзменении» или «ОбработкаВыбора» — вот тут беда…. без модификации формы или применения расширений — никак не обойтись!

    Reply ↓
  7. Darklight

    (3)Так там и БСП будет более ранних версий — где таких общих функций может и не быть вовсе, или их применение в формах тоже будет сведено к минимуму — так что большинство форм не будет их вызывать!

    Reply ↓
  8. Darklight

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

    Reply ↓
  9. TMV

    Ничего нового — постоянно так делаю, с той лишь разницей, что весь код именно в расширении, а конфа на замке (разумеется, если есть возможность использования расширений).

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

    Reply ↓
  10. Bassgood

    (7) Такие вызовы общих модулей используются уже с БСП 2, конечно не в таком специальном виде как в публикации через общие модули «СобытияФорм«, но в подавляющем большинстве форм имеются вызовы общих модулей других подсистем (например, «версионирование данных», «доп. отчетов и обработок»), которые в принципе можно использовать по аналогии с описанным способом — в них также доступен контекст вызываемой формы (вроде что-то похожее использовалось даже в УТ 10).

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

    Reply ↓
  11. Darklight

    (10)

    событие получения формы менеджеров всех объектов, в которой можно переопределить поведение всех необходимых форм объектов.

    Вот тут подробнее. Сколько не смотрел я это событие — так ничего толкового из него не вынес — событие срабатывает в серверном контексте, причём контекст объекта формы не доступен — максимум что там можно — только подменить один путь к форме на другой (читай одно имя вызова формы, другим) — и всё 🙁 фигня фигней — конечно в ряде случаев может быть полезно — когда Вы делаете свою форму — то её можно насильно подсовывать вместо других — анализируя путь исходного вызова формы. Но менять именно саму форму в этом событии совсем нельзя!

    Reply ↓
  12. Bassgood

    (11) Вы правы, поработать с формой через подписку не получится, погорячился, а жаль ;(

    Reply ↓
  13. байт

    (1) Конечно, добавить модуль «МодификацияКонфигурацииПереопределяемый» в расширении и писать в &После(«ПриСозданииНаСервере») все что нужно. 1) Не нужно настраивать поддержку. 2) При обновлении больше времени на сравнение объединение будет уходить у поставленной на редактирование конфы.

    Reply ↓
  14. vakorp
    В типовых конфигурациях в формах объектов в процедуре ПриСозданииНаСервере есть обращение к общему модулю СобытияФорм.ПриСозданииНаСервере

    Не во всех конфигурациях он есть, в БУХ 3.0 и ЗУП 3.1 такого модуля нет.

    Reply ↓
  15. Xershi

    (3) три года назад поднимали совместимость с 8.1 на 8.2. А затем я поднял последовательно до 8.3.5. Тогда только 8.3.8 еще была.

    Пару дней работы и все переписано грубо говоря, так что долго это наверно пока УПП поддерживается, КА уже сдулось. Пару лет и никто про это не вспомнит!

    Reply ↓
  16. Bassgood

    (15) Далеко не все хотят возиться с доработками (или же это нецелесообразно в краткосрочной перспективе, или же не хватает соответствующей компетенции), необходимыми для отключения в конфигурации режима совместимости со старыми версиями платформы, бывает это даже связано с тем, что у специалиста нет понимания и уверенности в том, что конфа будет работать также стабильно и без «глюков» как и до отключения совместимости, так что думаю в старых конфах этот метод просуществует еще долго.

    Reply ↓
  17. Xershi

    (16) а по поводу статьи. Давно была статья, как вести доработку в типовых. Просто наверно про нее уже забыли. А тут лишь кусочек, единственное чуть больше примеров как писать этот код. Но в книжке разработчика все написано и так.

    Reply ↓
  18. nnafanail

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

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

    Reply ↓
  19. DedMoroz1983

    (18) так точно, всегда надо обдумывать, что в расширение пихать, а что лучше в конфе изменить.

    Reply ↓
  20. Andrefan

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

    Reply ↓
  21. triviumfan

    Такой баян что я… на дворе конец 2019 года, а тут статья про переопределение события форм… жесть.

    Reply ↓
  22. vic777tor

    Утверждать что этот метод самый лучший и универсальный я бы не стал 🙂

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

    Как вариант, безусловно заслуживает внимания, но есть ряд недостатков (на мой взгляд), основной среди которых — отсутствие наглядности.

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

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

    Это как в медицине — для каждой болезни свой метод лечения. Универсального же лекарства не существует и вряд ли будет создано в будущем 🙂

    Reply ↓

Leave a Comment

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