Как присвоить реквизиту табличной части внешней обработки тип объекта из расширения?

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

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

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

Почему возникает проблема взаимодействия внешних обработок с расширениями?

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

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

Расширения как "мини-конфигурации": Расширения конфигурации, появившиеся в платформе 8.3.6 (и получившие развитие в 8.3.10), представляют собой мощный механизм для доработки функционала конфигурации без изменения ее самой. Они позволяют добавлять новые объекты метаданных, изменять существующие формы и модули, а также дополнять функциональность типовых объектов. Расширения "наследуют" объекты основной конфигурации и расширяют их возможности, но при этом они не являются частью самой внешней обработки.

Доступность типов из расширений: Исторически, в ранних версиях платформы 1С:Предприятие объекты, созданные в расширениях, не были напрямую доступны из внешних обработок в режиме Конфигуратора при выборе типов для реквизитов. Это приводило к невозможности явного указания типа ДокументСсылка.МойДокументИзРасширения или СправочникСсылка.__Партии (где "__" указывает на объект расширения) через стандартный механизм выбора типов. Тем не менее, ожидается, что в будущих версиях платформы (например, 8.3.28) эта проблема будет решена, и объекты расширений будут доступны для выбора в режиме Конфигуратора во внешних отчетах и обработках.

Отличия реквизитов обработки и реквизитов формы

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

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

  2. Реквизиты формы: Эти реквизиты создаются на закладке "Реквизиты" конкретной формы внешней обработки (в дереве форм, если мы открываем форму обработки). Для реквизитов формы, в отличие от реквизитов объекта, становится доступен тип "Произвольный". Это ключевое отличие. Тип "Произвольный" дает нам максимальную гибкость и возможность управлять типом данных, которые могут храниться в этом реквизите, уже на этапе выполнения кода. Именно через реквизиты формы мы сможем реализовать наше решение.

Неработающие подходы (для понимания проблемы)

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

  1. Создание реквизита табличной части как реквизита объекта внешней обработки:

    Мы создаем новый реквизит для табличной части на закладке "Реквизиты" самой внешней обработки (не формы). Для такого реквизита мы пытаемся выбрать тип ссылки на документ из расширения. В режиме Конфигуратора, как правило, такой тип недоступен для выбора. Максимум, что мы можем выбрать для ссылочных данных – это тип "ЛюбаяСсылка".

  2. Программное ограничение типа для реквизита объекта обработки с типом "ЛюбаяСсылка":

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

    
    &НаСервере
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
        // Пример неработающего кода для реквизита объекта обработки
        // Элементы.РезультатПартия - это элемент формы, связанный с реквизитом объекта обработки
        ОписаниеТипа = Новый ОписаниеТипов("СправочникСсылка.__Партии");
        Элементы.РезультатПартия.ОграничениеТипа = ОписаниеТипа;
    КонецПроцедуры
    

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

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

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

Теперь, когда мы понимаем причины проблемы и отличия между реквизитами, давайте перейдем к действенному решению, которое подтверждено практикой и отзывами коллег. Суть его заключается в использовании реквизита формы с типом "Произвольный" и последующим программным ограничением этого типа. Мы рассмотрим это решение по шагам.

  1. Удаляем "неправильный" реквизит (при необходимости):

    Если вы уже создали реквизит табличной части как реквизит самого объекта внешней обработки и присвоили ему тип "ЛюбаяСсылка" (или пытались присвоить другой тип из расширения), рекомендуем удалить его. Это позволит избежать путаницы и гарантировать чистый старт.

  2. Добавляем реквизит формы для табличной части:

    Вместо реквизита объекта внешней обработки, мы создаем новый реквизит на форме нашей обработки. Для этого:

    • Откройте форму вашей внешней обработки.
    • Перейдите на закладку "Реквизиты" (в окне формы).
    • Нажмите кнопку "Добавить" (или клавишу Insert).
    • Присвойте новому реквизиту имя, например, РезультатПартия.
    • Самое главное: в поле "Тип" выберите значение "Произвольный". Именно этот тип даст нам необходимую гибкость для дальнейших действий.
    • Если у вас табличная часть, то этот реквизит формы будет элементом этой табличной части. Создайте табличную часть на форме, например, с именем ТабличнаяЧастьФормы, затем добавьте к ней новый реквизит с типом "Произвольный".
    • Теперь разместите этот реквизит на форме как элемент табличной части, например, Элементы.РезультатПартия.
  3. Программно прописываем ограничение типа в процедуре ПриСозданииНаСервере:

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

    Для установки ограничения типа нам потребуется два основных объекта:

    • ОписаниеТипов: Этот объект позволяет сформировать описание нужных типов. Мы можем указать один или несколько типов, включая ссылки на объекты из расширений. Для обращения к объекту расширения используем префикс __ (два нижних подчеркивания) перед именем объекта, например, ДокументСсылка.__МойДокументИзРасширения или СправочникСсылка.__Партии.
    • Элементы.ИмяЭлементаФормы.ОграничениеТипа: Это свойство элемента формы, связанного с нашим реквизитом, позволяет установить ограничение по типу. В качестве значения этому свойству мы присваиваем созданный объект ОписаниеТипов.

    Рассмотрим пример кода:

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

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

Дополнительные рекомендации и нюансы

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

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

← На главную