Как добавить новый тип в заимствованный составной реквизит документа через расширение в 1С?

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

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

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

Выясним причину поведения платформы

Рассмотрим, что происходит на уровне платформы при заимствовании объектов с составными типами:

  1. Замена типа на обобщенный: Когда реквизит составного типа, содержащий ссылочные данные, переносится в расширение, платформа визуально отображает его тип как Любая ссылка. Это нормальное поведение среды разработки для заимствованных составных типов.
  2. Контроль состава типов: В режимах совместимости ниже 8.3.18 состав типов заимствованного реквизита является строго контролируемым свойством. Платформа сверяет значения с основной конфигурацией и не позволяет добавить к заимствованному реквизиту типы, которых изначально не было в базовой конфигурации. При попытке программно записать ссылку нового типа значение сбрасывается в Неопределено или возникает ошибка несвоевременного совпадения контролируемого свойства Тип.

Способ 1. Обновление режима совместимости (платформа 8.3.18 и выше)

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

Разберем по шагам, как добавить новый тип к заимствованному реквизиту:

  1. Проверим режим совместимости основной конфигурации и расширения. Он должен быть установлен в значение 8.3.18 или выше.
  2. Заимствуем основной документ и нужные типы метаданных в расширение.
  3. Заимствуем необходимый реквизит составного типа.
  4. Открываем палитру свойств заимствованного реквизита и в поле Тип отмечаем флажками дополнительные типы данных (как из основной конфигурации, так и новые типы, созданные внутри расширения).

Если используется платформа версии 8.3.20 или выше, обобщенные типы (Любая ссылка, СправочникСсылка, ДокументСсылка) автоматически начинают принимать ссылки на новые объекты, созданные непосредственно в расширении.

Способ 2. Создание собственного реквизита в расширении

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

Рассмотрим порядок действий для реализации этого подхода:

  1. В расширении добавляем **новый собственный реквизит** документа (не заимствованный из основной конфигурации). Называем его, например, Расш_ДокументОснование.
  2. Указываем для него составной тип, включающий все необходимые типы основной конфигурации плюс новый требуемый тип.
  3. На форме документа скрываем визуальную видимость типового реквизита и выводим новое поле, связанное с Расш_ДокументОснование.
  4. Перехватываем обработчики событий модуля объекта и модуля формы для синхронизации и обработки логики.

Посмотрим на пример перехвата события ПередЗаписью в модуле объекта расширения:


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

Также дополняем процедуру ОбработкаЗаполнения или ВводНаОсновании для корректной обработки нового типа документа-основания при создании подчиненных объектов.

Способ 3. Расширение определяемого типа (для платформы 8.3.20+)

Если в основной конфигурации тип реквизита задан через ОпределяемыйТип (например, ОпределяемыйТип.ДокументОснование), то начиная с платформы 8.3.20 можно расширить состав типов самого определяемого типа.

  1. Заимствуем необходимый ОпределяемыйТип в расширение.
  2. В свойствах заимствованного определяемого типа добавляем новый объект метаданных.
  3. Реквизит документа, ссылающийся на данный определяемый тип, автоматически начнет принимать новое значение без необходимости модификации самого реквизита.

Важные нюансы и ограничения

При использовании собственных реквизитов в расширении важно учитывать особенности хранения данных в 1С:

← На главную