Как в 1С:Бухгалтерии 3.0 добавить реквизит на форму документа через расширение без захвата формы?

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

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

Почему в БП 3.0 отсутствует модуль «МодификацияКонфигурацииПереопределяемый»

Выясним причину отсутствия данного модуля в конфигурации. Подсистема «Модификация конфигурации» (включающая модули МодификацияКонфигурацииПереопределяемый, МодификацияКонфигурацииКлиент и аналогичные) является проектным решением разработчиков типовых решений линейки ERP, КА и УТ 11. Она не входит в базовый состав Библиотеки стандартных подсистем (БСП) и целенаправленно не внедрялась фирмой «1С» в состав «Бухгалтерии предприятия».

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

Поиск общей точки входа в процедурах БСП

Проанализируем типовые формы документов (например, РеализацияТоваровУслуг, ПоступлениеТоваровУслуг, СписаниеОС). Практически в каждом обработчике ПриСозданииНаСервере вызываются стандартные процедуры общих модулей БСП, в которые передается контекст открываемой формы. Перехватив выполнение такого модуля в расширении, мы получаем доступ к объекту формы.

Наиболее универсальными и надежными точками входа выступают следующие вызовы:

  1. ПодключаемыеКоманды.ПриСозданииНаСервере — присутствует практически во всех основных документах конфигурации.
  2. УправлениеСвойствами.ПриСозданииНаСервере — модуль подсистемы дополнительных реквизитов и сведений.
  3. ВерсионированиеОбъектов.ПриСозданииНаСервере — обработчик подсистемы истории изменений объектов.

Реализация программного добавления элемента: пошаговый алгоритм

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

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

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


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

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

Если же нам требуется добавить реквизит, существующий только на время работы формы (экранный реквизит без сохранения в таблицах базы данных), сначала выполним метод Форма.ИзменитьРеквизиты(...):


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

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

Ограничения метода и подводные камни

Рассмотрим подробнее сложности, с которыми можно столкнуться при использовании данного подхода:

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

Альтернативные варианты решения задачи

Если задача заключается только в сохранении дополнительных сведений в документе, рекомендуем оценить альтернативы:

  1. Использование механизма «Дополнительные реквизиты и сведения»: Штатная подсистема БСП в БП 3.0 позволяет создавать пользовательские поля для любых документов без изменения метаданных и конфигуратора. Поля автоматически выводятся на форму и доступны для отборов в отчетах.
  2. Минимальный захват формы: Если для элемента необходима обработка события ПриИзменении, захватите форму в расширение, но не изменяйте ее визуальную структуру в конфигураторе. Достаточно перехватить только процедуру модуля формы через директиву &После, сохранив интерфейс формы в исходном виде, что сведет к минимуму риск ошибок при типовых обновлениях.
← На главную