Как добавить элемент формы в расширении и обратиться к нему из модуля менеджера в 1С

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

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

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

Почему новый реквизит не переносится на заимствованную форму визуально?

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

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

Разберем по шагам, как решить эту проблему в конфигураторе:

  1. Откроем заимствованную форму в расширении.
  2. Перейдем на вкладку «Реквизиты» в правой части окна редактора формы.
  3. Найдем основной реквизит формы (обычно он выделен жирным шрифтом и называется Объект).
  4. Нажмем на него правой кнопкой мыши и выберем пункт меню «Добавить в расширение».

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

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

Способ 1. Создание реквизита в объекте БД и его вызов из модуля менеджера

Если вам необходимо, чтобы введенное пользователем значение сохранялось в базе данных вместе с документом, лучшим решением будет добавление реквизита непосредственно к объекту документа в расширении.

Проанализируем этот процесс поэтапно:

  1. В расширении добавим новый реквизит к документу, например, ДополнительныеСведенияДляВыгрузки с типом Строка.
  2. Выведем данный реквизит на форму документа (программным или визуальным способом).
  3. В модуле менеджера документа перехватим процедуру, отвечающую за формирование XML-файла.

Посмотрим на пример кода в расширении формы, реализующего программный вывод элемента, чтобы не заимствовать форму целиком визуально:


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

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


&Вместо("ВыполнитьВыгрузкуВXML")
Процедура Расш1_ВыполнитьВыгрузкуВXML(СсылкаНаДокумент, ПараметрыВыгрузки)
    
    // Получаем объект документа для чтения нового реквизита
    ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();
    
    // Обращаемся к реквизиту, добавленному в расширении
    ЗначениеРеквизита = ДокументОбъект.ДополнительныеСведенияДляВыгрузки;
    
    // Если реквизит заполнен, подменим данные или выполним свою логику
    Если ЗначениеЗаполнено(ЗначениеРеквизита) Тогда
        // Своя логика обработки значения
    КонецЕсли;
    
    // Вызываем оригинальный алгоритм выгрузки, если это необходимо
    ПродолжитьВызов(СсылкаНаДокумент, ПараметрыВыгрузки);
    
КонецПроцедуры

Способ 2. Передача данных через дополнительные свойства без изменения структуры БД

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

Этот способ позволяет передать контекст формы в модуль менеджера «на лету».

Рассмотрим подробнее реализацию этого механизма:

  1. На заимствованной форме создаем **реквизит формы** (не путать с реквизитом объекта), который будет существовать только в памяти открытой формы.
  2. Перед вызовом процедуры экспорта в коде формы конвертируем реквизит формы в объект базы данных и записываем значение во временную структуру ДополнительныеСвойства.

Посмотрим на пример программной реализации на форме документа:


&НаКлиенте
Процедура Расш1_ВыгрузитьДокументПосле(Команда)
    
    // Вызываем серверный метод для подготовки объекта и вызова выгрузки
    ПодготовитьИВыгрузитьНаСервере();
    
КонецПроцедуры

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

Теперь в расширении модуля менеджера мы можем легко извлечь это значение без обращения к базе данных:


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

Способ 3. Динамическая модификация запроса в модуле менеджера

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

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

Проанализируем пример такой реализации:


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

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

Настройка прав доступа (ролей) для нового реквизита в расширении

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

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

Чтобы решить эту проблему, выполните следующие действия в расширении:

  1. Создайте в расширении новую роль (например, Расш1_ОсновнаяРоль) или заимствуйте существующую типовую роль (например, ДобавлениеИзменениеДокументов...).
  2. Перейдите к дереву прав созданной/заимствованной роли в расширении.
  3. Найдите ваш документ и добавленный к нему в расширении реквизит.
  4. Установите галочки для прав «Чтение» и «Просмотр» (а при необходимости и «Редактирование»).
  5. Назначьте эту роль пользователям через профили групп доступа в режиме «1С:Предприятие» или сделайте роль автоназначаемой в свойствах расширения.

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

← На главную