При работе с конфигурациями 1С, особенно на поддержке, разработчики часто сталкиваются с необходимостью добавления нетиповых реквизитов и элементов на управляемые формы. Эта задача становится особенно актуальной в контексте использования механизмов расширений, позволяющих дорабатывать функционал без снятия конфигурации с поддержки. Перед нами встает важный выбор: либо добавлять всю форму в расширение, либо размещать реквизиты и связанные с ними элементы программно. Каждый подход имеет свои особенности, преимущества и недостатки, которые мы сейчас подробно рассмотрим.
Как показывает практика и обсуждения на форумах, даже опытные программисты могут расходиться во мнениях относительно наилучшего способа. Основной вопрос сводится к тому, как обеспечить стабильность доработок при обновлениях типовой конфигурации и при этом сохранить удобство разработки и сопровождения.
Мы рассмотрим два ключевых метода, которые чаще всего применяются при доработке форм с использованием расширений, а также затронем альтернативный штатный механизм.
Когда мы выбираем этот путь, мы буквально "захватываем" типовую форму в наше расширение. Это позволяет нам визуально работать с формой в конфигураторе, добавлять реквизиты, группы, поля ввода и другие элементы так же, как если бы мы работали с основной конфигурацией.
В конфигураторе, в основном дереве объектов конфигурации, мы находим нужную форму (например, форму элемента справочника или документа). Затем, нажав правой кнопкой мыши по этой форме, мы выбираем пункт меню "Добавить в расширение". После этого форма появляется в нашем расширении, и мы можем открывать её редактор и вносить необходимые изменения.
Основной и самый существенный минус этого подхода проявляется при обновлении типовой конфигурации поставщика. Если разработчики 1С внесут значительные изменения в ту же форму, которую мы заимствовали в расширение, могут возникнуть серьезные проблемы:
Когда форма добавлена в расширение, мы получаем доступ к ее модулю формы. В этом модуле мы можем создавать новые процедуры и функции, а также переопределять или дополнять типовые обработчики событий с помощью аннотаций &Перед, &После, &Вместо. Это позволяет нам реализовать логику для наших новых реквизитов и элементов, а также модифицировать поведение существующих.
Для доступа к модулю формы расширения, после добавления формы в расширение, мы просто открываем ее в конфигураторе и переходим на вкладку "Модуль".
Этот подход считается более надежным с точки зрения устойчивости к обновлениям, но требует более глубоких знаний программного API и навыков кодирования.
Мы не заимствуем форму целиком в расширение. Вместо этого, мы используем модуль формы расширения для программного добавления новых реквизитов на форму и создания элементов управления, которые будут связаны с этими реквизитами. Код для этих действий обычно размещается в обработчике события ПриСозданииНаСервере() формы.
Рассмотрим, как мы можем программно добавить новый реквизит и поле ввода на форму. Для этого мы будем использовать процедуры в модуле формы расширения.
Прежде всего, нам нужно программно добавить реквизит формы. Это можно сделать в обработчике события ПриСозданииНаСервере():
// В модуле формы расширения
&НаСервере
Процедура ПриСозданииНаСервере(Отказ)
// Вызываем типовую процедуру, если она есть
// Например, в типовых формах на БСП обычно есть что-то подобное
// ВыполнитьДействиеРасширенияФормыПриСозданииНаСервере(ЭтаФорма, Отказ);
// Добавляем новый реквизит формы
Если Не ЭтаФорма.Реквизиты.Найти("МойНовыйРеквизит") Тогда
ЭтаФорма.ДобавитьРеквизит("МойНовыйРеквизит", Новый ОписаниеТипов("Строка", , , Новый КвалификаторыСтроки(20)));
КонецЕсли;
// После добавления реквизита, нам нужно создать элемент формы
// И привязать его к нашему реквизиту.
// Найдем группу, куда хотим поместить наш элемент.
// Например, если хотим добавить его в основную группу (обычно 'ГруппаРеквизиты')
ГруппаДляЭлемента = ЭтаФорма.Элементы.Найти("ГруппаРеквизиты"); // Это может быть любая другая группа
Если ГруппаДляЭлемента <> Неопределено Тогда
Если ЭтаФорма.Элементы.Найти("МойНовыйЭлемент") = Неопределено Тогда
НовыйЭлемент = ЭтаФорма.Элементы.Добавить("МойНовыйЭлемент", Тип("ПолеФормы"), ГруппаДляЭлемента);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = "МойНовыйРеквизит";
НовыйЭлемент.Заголовок = "Мой новый реквизит";
// Можем настроить другие свойства элемента
// НовыйЭлемент.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлемента.Авто;
// НовыйЭлемент.Ширина = 20;
КонецЕсли;
КонецЕсли;
// Можно также добавить обработчик события для нового элемента
// Например, при изменении
// Если НовыйЭлемент.ЕстьСобытие("ПриИзменении") Тогда
// НовыйЭлемент.УстановитьДействие("ПриИзменении", "МойНовыйЭлементПриИзменении");
// КонецЕсли;
КонецПроцедуры
// Пример обработчика события (если нужен)
&НаКлиенте
Процедура МойНовыйЭлементПриИзменении(Элемент)
Сообщить("Значение реквизита изменилось: " + Элемент.Значение);
КонецПроцедуры
Важно понимать, что в реальных типовых конфигурациях на БСП часто существуют специальные процедуры и функции для работы с расширениями, которые вызываются в стандартных обработчиках форм. Например, в ПриСозданииНаСервере() может быть вызов общего модуля, который обрабатывает добавление элементов из расширений. Мы можем использовать эти точки расширения для вставки нашего кода.
Прежде чем приступать к программному добавлению реквизитов на формы, мы должны рассмотреть штатный механизм "Дополнительные реквизиты", доступный в конфигурациях на базе Библиотеки стандартных подсистем (БСП), таких как УНФ 3.0. Этот механизм предназначен специально для добавления произвольных реквизитов к объектам конфигурации без изменения самой конфигурации.
Для того чтобы объект мог использовать дополнительные реквизиты, необходимо выполнить несколько шагов:
ДополнительныеРеквизиты. Мы можем скопировать её, например, из справочника Пользователи, который уже использует этот механизм.ГруппаДополнительныеРеквизиты. В эту группу система автоматически будет выводить поля дополнительных реквизитов.НаборыДополнительныхРеквизитовИСведений необходимо создать или найти предопределенный элемент для нашего объекта и убедиться, что для него установлен флаг Используется в значение Истина.ПриСозданииНаСервере, ПриЧтенииНаСервере и ОбработкаПроверкиЗаполненияНаСервере. Эти фрагменты кода отвечают за инициализацию, чтение и проверку заполнения дополнительных реквизитов. Эти методы обычно находятся в общем модуле УправлениеСвойствами.
Пример кода, который может быть размещен в модуле формы объекта для поддержки дополнительных реквизитов (используя точки расширения в расширении):
// В модуле формы расширения
&НаСервере
Процедура ПриСозданииНаСервере(Отказ)
// ... Ваш код ...
// После вызова типовой ПриСозданииНаСервере (если она есть)
// Инициализация подсистемы свойств для объекта
УправлениеСвойствами.ПриСозданииНаСервере(ЭтаФорма, Отказ);
// ... Ваш код ...
КонецПроцедуры
&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
// ... Ваш код ...
// После вызова типовой ПриЧтенииНаСервере (если она есть)
УправлениеСвойствами.ПриЧтенииНаСервере(ЭтаФорма, ТекущийОбъект);
// ... Ваш код ...
КонецПроцедуры
&НаСервере
Функция ОбработкаПроверкиЗаполненияНаСервере(Отказ, ПроверяемыеРеквизиты)
// ... Ваш код ...
// Вызываем типовую обработку
Результат = Истина;
Если УправлениеСвойствами.ОбработкаПроверкиЗаполненияНаСервере(ЭтаФорма, Отказ, ПроверяемыеРеквизиты) Тогда
// Если типовая обработка вернула Истина, можем продолжить свою проверку
Результат = Результат И УправлениеСвойствами.ОбработкаПроверкиЗаполненияНаСервере(ЭтаФорма, Отказ, ПроверяемыеРеквизиты);
Иначе
Результат = Ложь;
КонецЕсли;
// ... Ваш код ...
Возврат Результат;
КонецФункции
Для программной работы с дополнительными реквизитами, например, для чтения или записи их значений, мы можем использовать методы из общего модуля УправлениеСвойствами.
Независимо от выбранного подхода к доработке форм, при работе с расширениями важно придерживаться некоторых общих принципов:
&Перед, &После, &Вместо для вмешательства в типовые процедуры и функции. Это позволяет точечно изменять логику, не копируя весь типовой код.Таким образом, мы видим, что каждый подход имеет свои сильные и слабые стороны:
В большинстве случаев, опытные разработчики рекомендуют сочетать подходы: использовать дополнительные реквизиты БСП для простых случаев, а для уникальных функциональных реквизитов, требующих специфического отображения или сложной логики, применять программное размещение элементов. Полное заимствование формы в расширение рассматривается как крайняя мера, когда другие варианты неосуществимы, и только при осознании всех рисков, связанных с обновлениями.
Внимательно анализируйте требования к доработке, частоту обновлений типовой конфигурации и квалификацию вашей команды разработчиков при выборе оптимального подхода.