Где программно добавлять реквизиты на управляемую форму 1С, чтобы не сломать обновления?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

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

Вариант 1. Использование общего переопределяемого модуля БСП (Рекомендуемый системный подход)

Библиотека стандартных подсистем (БСП), на которой построены практически все современные конфигурации 1С, предоставляет встроенные механизмы для модификации интерфейса. В конце обработчика события ПриСозданииНаСервере у большинства типовых форм присутствует вызов стандартных методов БСП:


СобытияФорм.ПриСозданииНаСервере(ЭтаФорма, Отказ, СтандартнаяОбработка);
МодификацияКонфигурацииПереопределяемый.ПриСозданииНаСервере(Форма, Отказ, СтандартнаяОбработка);

Для реализации этого сценария выполним следующие шаги:

  1. Создание собственного общего модуля: Создадим в конфигурации (или в расширении) новый общий модуль, например, _МодификацияИнтерфейсаКлиентСервер. Установим для него свойства Сервер, Внешнее соединение и при необходимости Клиент (управляемое приложение).
  2. Заимствование переопределяемого модуля: Добавим общий модуль МодификацияКонфигурацииПереопределяемый в расширение конфигурации.
  3. Внедрение обработчика: Перехватим метод ПриСозданииНаСервере в расширении с помощью аннотации &После.

Рассмотрим пример кода в модуле расширения:


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

Преимущества метода: Основная конфигурация остается на замке. Все изменения форм во всей системе централизованно управляются из одного общего модуля расширения. Это существенно упрощает аудит кода и обновление платформы.

Вариант 2. Использование расширения конкретной управляемой формы

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

Разберем этот процесс по шагам:

  1. Найдем нужную форму в дереве метаданных основной конфигурации.
  2. Нажмем правой кнопкой мыши и выберем пункт Добавить в расширение.
  3. В расширении откроем модуль заимствованной формы.
  4. Создадим обработчик события ПриСозданииНаСервере с аннотацией &После.

Посмотрим на пример реализации внутри модуля расширения формы:


&После("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Вызываем процедуру добавления элементов, передавая контекст текущей формы "ЭтаФорма"
    _МодификацияИнтерфейсаКлиентСервер.ДобавитьНовыеРеквизитыНаФормуРТУ(ЭтаФорма);
    
КонецПроцедуры

Важное правило: Избегайте изменения визуального интерфейса (перетаскивания элементов на форму) непосредственно в редакторе расширения формы. Если разработчики «1С» в очередном релизе сильно изменят структуру этой формы (например, удалят группу, в которую вы визуально поместили свой элемент), расширение перестанет работать или выдаст ошибку при обновлении. Программное добавление элементов через код в обработчике &После("ПриСозданииНаСервере") — это самый надежный и отказоустойчивый путь.

Технология программного добавления реквизитов и элементов

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

Шаг 1. Создание реквизита формы (данных)

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


// Создаем массив для новых реквизитов
МассивРеквизитов = Новый Массив;

// Описываем тип данных для нового реквизита
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("Строка"));
ОписаниеТиповСтрока = Новый ОписаниеТипов(МассивТипов, , Новый КвалификаторыСтроки(150));

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

// Применяем изменения к форме
Форма.ИзменитьРеквизиты(МассивРеквизитов);

Шаг 2. Создание элемента формы (визуального объекта)

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


// Определяем родительскую группу на форме, куда поместим элемент
// Например, найдем стандартную группу комментариев
РодительскаяГруппа = Форма.Элементы.Найти("ГруппаКомментарий");

Если РодительскаяГруппа = Неопределено Тогда
    // Если группа не найдена, добавляем в корень формы
    РодительскаяГруппа = Форма;
КонецЕсли;

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

// Связываем визуальный элемент с созданным ранее реквизитом данных
НовоеПоле.ПутьКДанным = "_ДополнительныйКомментарий";
НовоеПоле.Подсказка = "Введите дополнительный комментарий к документу";

Шаг 3. Подключение обработчиков событий (при изменении поля)

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


НовоеПоле.УстановитьДействие("ПриИзменении", "Подключаемый_ПриИзмененииДопРеквизита");

Важное ограничение платформы «1С:Предприятие 8.3»: Назначаемая процедура-обработчик (в нашем примере Подключаемый_ПриИзмененииДопРеквизита) обязательно должна физически находиться в модуле самой формы и быть объявлена с директивой &НаКлиенте. Напрямую перенаправить обработчик интерактивного события в общий модуль нельзя. Поэтому, если вам нужны интерактивные события для динамических полей, вам придется заимствовать форму в расширение и прописать там эту клиентскую процедуру, которая при необходимости будет вызывать методы ваших общих модулей.

Альтернатива без разработки: Использование механизма свойств БСП

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

Это подсистема «Дополнительные реквизиты и сведения».

Используйте программирование только в тех случаях, когда требуются сложные алгоритмы заполнения полей, динамическое изменение видимости/доступности элементов в зависимости от нетривиальных условий или интеграция со сторонними API-сервисами.

← На главную