Как переопределить состав составного типа в расширении 1С

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

При разработке расширений для типовых конфигураций, таких как УТ 11, ERP 2 или КА 2, программисты часто сталкиваются с необходимостью добавить новый тип документа или справочника в уже существующий реквизит с составным типом. Типичный пример — доработка обработки ПомощникПродаж, где табличная часть содержит реквизит Документ, предназначенный для хранения ссылок на созданные объекты. Если мы добавляем в систему новый вид документа через расширение, стандартный реквизит просто «не поймет» новый тип, и данные не будут сохранены.

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

Почему простое добавление типа в расширении часто не работает

Разберем сначала первопричину проблемы. Когда вы заимствуете реквизит с составным типом в расширение, платформа фиксирует тот набор типов, который был в основной конфигурации на момент заимствования. Попытка просто «доставить галочку» напротив нового документа в редакторе типов часто оказывается безуспешной на старых релизах платформы (до 8.3.18), так как метаданные расширения не всегда корректно объединяются с основной конфигурацией в части состава типов БД.

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

Решение 1: Расширение определяемого типа (для платформы 8.3.18 и выше)

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

Рассмотрим пошагово:

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

Решение 2: Полное переопределение состава типа в расширении

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

Алгоритм действий:

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

Решение 3: Использование программного изменения ОписанияТипов (только для форм)

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

Рассмотрим пример кода в модуле формы:


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

Внимание: Этот способ изменит поведение только в интерфейсе. Если вы попытаетесь записать в этот реквизит объект нового типа и нажать «Записать», платформа выдаст ошибку, так как на уровне метаданных БД состав типов остался прежним.

Решение 4: Создание дублирующего реквизита

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

Рассмотрим шаги реализации:

  1. В расширении добавьте к объекту (или в табличную часть) новый реквизит, например, Документ_Расширение с типом ЛюбаяСсылка или конкретным составным типом.
  2. Выведите его на форму, а стандартный реквизит Документ скройте.
  3. В обработчике ПередЗаписью или через подписку на событие обеспечьте логику: если в вашем реквизите выбран стандартный тип, дублируйте его в основной реквизит. Если выбран ваш новый тип — оставляйте основной пустым, но обрабатывайте данные из своего реквизита.

Решение 5: Подмена обработки целиком

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

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


&Вместо("ОткрытьФормуПомощника")
Процедура Расш1_ОткрытьФормуПомощника(Параметры)
    // Вместо типовой формы открываем форму из расширения
    ОткрытьФорму("Обработка.ПомощникПродаж.Форма.ФормаРасширение", Параметры);
КонецПроцедуры

Резюме

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

← На главную