При разработке расширений для типовых конфигураций, таких как УТ 11, ERP 2 или КА 2, программисты часто сталкиваются с необходимостью добавить новый тип документа или справочника в уже существующий реквизит с составным типом. Типичный пример — доработка обработки ПомощникПродаж, где табличная часть содержит реквизит Документ, предназначенный для хранения ссылок на созданные объекты. Если мы добавляем в систему новый вид документа через расширение, стандартный реквизит просто «не поймет» новый тип, и данные не будут сохранены.
В этой статье мы подробно разберем, как решить проблему расширения состава типов, рассмотрим ограничения платформы и выберем оптимальный путь реализации в зависимости от версии вашей платформы.
Разберем сначала первопричину проблемы. Когда вы заимствуете реквизит с составным типом в расширение, платформа фиксирует тот набор типов, который был в основной конфигурации на момент заимствования. Попытка просто «доставить галочку» напротив нового документа в редакторе типов часто оказывается безуспешной на старых релизах платформы (до 8.3.18), так как метаданные расширения не всегда корректно объединяются с основной конфигурацией в части состава типов БД.
Важно помнить: тип ЛюбаяСсылка в расширениях использовать крайне не рекомендуется. Это приводит к созданию избыточных связей в базе данных и может вызвать ошибки при генерации запросов к динамическим спискам. Платформа требует явного перечисления типов для корректного построения таблиц.
Это самый современный и правильный метод. Если реквизит в типовой конфигурации базируется на объекте ОпределяемыйТип (например, ОпределяемыйТип.ДокументыПродажи), задача значительно упрощается. Начиная с версии 8.3.18, платформа позволяет расширять состав заимствованных определяемых типов.
Рассмотрим пошагово:
ОпределяемыйТип, заимствуйте его в ваше расширение.ОпределяемыйТип, автоматически начнут поддерживать ваш новый объект.Если реквизит не привязан к определяемому типу, а имеет прямой составной тип (перечисление документов), нам придется «пересобрать» его в расширении вручную. Проанализируем нюанс: чтобы тип в расширении «перекрыл» тип основной конфигурации, нужно обеспечить видимость всех составляющих.
Алгоритм действий:
ПомощникПродаж) и нужный реквизит в расширение.Режим совместимости вашего расширения и основной конфигурации. Для корректной работы с типами оно должно быть не ниже 8.3.15.Иногда требуется изменить состав типов только «на лету» для визуального отображения в форме. Выясним причину: если нам не нужно сохранять данные в этот реквизит базы данных (например, это реквизит формы или временной таблицы), мы можем использовать объект ОписаниеТипов.
Рассмотрим пример кода в модуле формы:
&НаСервере
Процедура ДобавитьТипКРеквизитуНаФорме()
// Получаем текущие типы реквизита
ТекущееОписание = ЭтаФорма.Элементы.ТаблицаДокументыДокумент.ОграничениеТипа;
// Создаем массив новых типов
МассивТипов = ТекущееОписание.Типы();
МассивТипов.Добавить(Тип("ДокументСсылка.МойНовыйДокументИзРасширения"));
// Устанавливаем новое описание типов
НовоеОписание = Новое ОписаниеТипов(МассивТипов);
ЭтаФорма.Элементы.ТаблицаДокументыДокумент.ОграничениеТипа = НовоеОписание;
КонецПроцедуры
Внимание: Этот способ изменит поведение только в интерфейсе. Если вы попытаетесь записать в этот реквизит объект нового типа и нажать «Записать», платформа выдаст ошибку, так как на уровне метаданных БД состав типов остался прежним.
Если типовой механизм слишком жестко ограничен и расширение типа не помогает, проанализируем ситуацию с точки зрения обхода ограничений. Мы можем создать в расширении собственный реквизит с нужным нам типом.
Рассмотрим шаги реализации:
Документ_Расширение с типом ЛюбаяСсылка или конкретным составным типом.Документ скройте.ПередЗаписью или через подписку на событие обеспечьте логику: если в вашем реквизите выбран стандартный тип, дублируйте его в основной реквизит. Если выбран ваш новый тип — оставляйте основной пустым, но обрабатывайте данные из своего реквизита.Как советовали опытные участники форума, в некоторых случаях (особенно для сложных обработок вроде ПомощникПродаж) проще создать в расширении копию обработки, внести в нее все необходимые изменения (включая типы реквизитов) и заменить вызовы типовой обработки на свою.
Для этого используется перехват в общем модуле, где вызывается форма помощника:
&Вместо("ОткрытьФормуПомощника")
Процедура Расш1_ОткрытьФормуПомощника(Параметры)
// Вместо типовой формы открываем форму из расширения
ОткрытьФорму("Обработка.ПомощникПродаж.Форма.ФормаРасширение", Параметры);
КонецПроцедуры
Выбор метода зависит от вашей версии платформы. Если вы работаете на 8.3.18+ и в конфигурации используются Определяемые типы, это ваш приоритетный путь. В остальных случаях наиболее надежным (хоть и трудоемким) является метод заимствования всех объектов, входящих в составной тип, либо использование «обходных» реквизитов в расширении. Помните, что расширение метаданных напрямую влияет на структуру таблиц в SQL, поэтому всегда проверяйте работоспособность на копии базы перед обновлением продакшена. Для аудита структуры метаданных и контроля целостности доработок можно использовать инструмент для анализа состава расширений и поиска ошибок.