Как программно получить тип предопределенного элемента Плана видов характеристик в 1С?

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

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

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

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

В чем сложность получения типа из ПВХ?

Давайте проанализируем, почему стандартное обращение к свойству предопределенного элемента возвращает не совсем то, что мы ожидаем увидеть. Когда мы обращаемся к реквизиту элемента ПВХ:


ТипЗначенияПВХ = ПланыВидовХарактеристик.АналитикиСтатейБюджетов.Контрагенты.ТипЗначения;

Мы получаем объект типа ОписаниеТипов (TypeDescription). Этот объект может содержать в себе как один-единственный тип (например, только ссылку на справочник), так и целый массив типов (составной тип данных). Платформа 1С напрямую не предоставляет у объекта ОписаниеТипов простого свойства вроде «ИмяТипаСтрокой», потому что типов внутри описания может быть много. Для извлечения конкретных составляющих нам придется поработать со свойствами и методами этого объекта.

Способ 1. Правильный программный обход типов (без создания объектов)

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


// ВНИМАНИЕ: Данный способ использовать НЕ РЕКОМЕНДУЕТСЯ!
Для Каждого ТекущийТип Из ОбъектПВХ.ТипЗначения.Типы() Цикл
    НовыйОбъект = Новый(ТекущийТип); // Попытка создать объект для определения его метаданных
    ИмяМетаданных = НовыйОбъект.Метаданные().ПолноеИмя();
КонецЦикла;

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

  1. Ошибки времени выполнения (Исключения): Метод Новый() не может быть вызван для ссылочных типов (например, для СправочникСсылка.Контрагенты). Вызов конструктора Новый(Тип("СправочникСсылка.Контрагенты")) приведет к аварийному завершению работы кода с ошибкой «Несоответствие типов» или «Не найден конструктор». Создать через Новый() можно только объектный тип (например, СправочникОбъект.Контрагенты), но ПВХ хранит именно ссылки!
  2. Проблемы с производительностью: Даже если вы пытаетесь применить этот метод к типам, которые платформа умеет создавать, инициализация новых тяжелых объектов в памяти сервера ради простого получения их имени — это крайне нерациональный расход ресурсов процессора и оперативной памяти.

Как делать правильно:

Для определения метаданных по объекту Тип в платформе «1С:Предприятие» предусмотрен специальный высокопроизводительный инструмент глобального контекста — метод Метаданные.НайтиПоТипу(). Он работает мгновенно и не создает никаких физических объектов в памяти.

Давайте посмотрим на пример правильной программной реализации:


// Получаем описание типов из предопределенного элемента ПВХ
ОписаниеТиповПВХ = ПланыВидовХарактеристик.АналитикиСтатейБюджетов.Контрагенты.ТипЗначения;

// Обходим все типы, которые входят в это описание
Для Каждого ТекущийТип Из ОписаниеТиповПВХ.Типы() Цикл
    
    // Находим объект метаданных по типу без создания самого объекта
    ОбъектМетаданных = Метаданные.НайтиПоТипу(ТекущийТип);
    
    Если ОбъектМетаданных <> Неопределено Тогда
        // Получаем полное имя, например, "Справочник.Контрагенты"
        ПолноеИмяОбъекта = ОбъектМетаданных.ПолноеИмя();
        Сообщить("Программный тип элемента ПВХ: " + ПолноеИмяОбъекта);
    Иначе
        // Обработка простых/системных типов (Число, Строка, Дата, Булево)
        Сообщить("Простой тип данных: " + ТекущийТип);
    КонецЕсли;
    
КонецЦикла;

Способ 2. Использование функций Библиотеки стандартных подсистем (БСП)

Если ваша конфигурация разработана на основе современных типовых решений фирмы 1С (таких как ERP, КА, УТ, УНФ или Бухгалтерия), то в ней гарантированно присутствует Библиотека стандартных подсистем (БСП). Разработчики БСП уже позаботились о написании безопасных оберток для работы с метаданными. Для быстрого поиска готовых процедур и функций библиотеки подойдёт справочник по методам БСП с примерами использования.

Рассмотрим, как решить нашу задачу в одну строчку с помощью стандартного общего модуля БСП ОбщегоНазначения:


// Получаем массив типов из нашего ПВХ
МассивТипов = ПланыВидовХарактеристик.АналитикиСтатейБюджетов.Контрагенты.ТипЗначения.Типы();

Если МассивТипов.Количество() > 0 Тогда
    // Берем первый тип из описания (если мы уверены, что тип одиночный)
    ПервыйТип = МассивТипов[0];
    
    // Получаем полное имя метаданных через БСП
    ИмяМетаданных = ОбщегоНазначения.ИмяОбъектаМетаданных(ПервыйТип);
    Сообщить("Имя объекта метаданных через БСП: " + ИмяМетаданных);
КонецЕсли;

Также в БСП есть удобная функция для проверки соответствия описания типов конкретному ожидаемому типу. Например, если нам нужно проверить, настроен ли наш элемент ПВХ на работу со справочником контрагентов:


ТипЗначенияПВХ = ПланыВидовХарактеристик.АналитикиСтатейБюджетов.Контрагенты.ТипЗначения;
НужныйТип = Тип("СправочникСсылка.Контрагенты");

Если ОбщегоНазначения.ОписаниеТипаСостоитИзТипа(ТипЗначенияПВХ, НужныйТип) Тогда
    // Выполняем логику, предназначенную исключительно для работы с контрагентами
    Сообщить("Элемент ПВХ предназначен для работы с Контрагентами!");
КонецЕсли;

Способ 3. Решение задачи в интерфейсе без написания кода («Связь по типу»)

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

Писать для этого программный код на сервере, перехватывать события изменения полей и динамически назначать описание типов вручную — это избыточная работа. Платформа 1С умеет делать это автоматически на уровне платформенных механизмов управляемых форм с помощью свойства «Связь по типу» (Type Link).

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

  1. Убедитесь, что в вашей форме (или в реквизитах объекта, например, в табличной части документа) есть два связанных реквизита:
    • Реквизит 1 (Характеристика): имеет тип ссылки на ваш План видов характеристик (например, ПланВидовХарактеристикСсылка.АналитикиСтатейБюджетов).
    • Реквизит 2 (Значение): имеет тип Характеристика.АналитикиСтатейБюджетов. Этот тип динамически формируется платформой и жестко привязан к ПВХ.
  2. Перейдите в редактор управляемой формы и найдите элемент формы, отображающий реквизит «Значение» (поле ввода).
  3. Откройте палитру свойств этого поля ввода (нажав клавишу F4).
  4. Найдите свойство «Связь по типу» (Type Link) и нажмите на кнопку выбора (три точки).
  5. В открывшемся окне укажите путь к реквизиту «Характеристика». Если поля находятся в табличной части, путь будет выглядеть примерно так: Элементы.ТабличнаяЧасть.ТекущиеДанные.Характеристика.
  6. Сохраните изменения и запустите сеанс.

Как это работает на практике: Теперь, когда пользователь выбирает в поле «Характеристика» строку «Контрагент», платформа мгновенно понимает, какой тип назначен этому предопределенному элементу в ПВХ. Поле «Значение» моментально перестраивается и предлагает открыть форму выбора справочника «Контрагенты». Если же пользователь выберет характеристику «Договор», поле ввода автоматически переключится на выбор договоров. И все это происходит абсолютно без написания кода!

Особенности работы с составными типами в ПВХ

Иногда предопределенный элемент ПВХ может поддерживать составной тип данных. Например, свойство «Документ-основание» может принимать значения документов «Реализация товаров и услуг» и «Поступление товаров и услуг» одновременно.

Если вам нужно быстро проверить, разрешен ли конкретный тип в данном элементе ПВХ (среди множества других доступных типов), используйте встроенный метод СодержитТип() объекта ОписаниеТипов. Это избавит вас от необходимости писать циклы:


ТипЗначенияПВХ = ПланыВидовХарактеристик.АналитикиСтатейБюджетов.ДокументОснование.ТипЗначения;

// Проверяем, разрешено ли использовать документы реализации в этой характеристике
Если ТипЗначенияПВХ.СодержитТип(Тип("ДокументСсылка.РеализацияТоваровУслуг")) Тогда
    // Наша логика для работы с реализацией
    Сообщить("В характеристике разрешена ссылка на документ Реализация товаров услуг");
КонецЕсли;

Использование метода СодержитТип() работает на уровне платформы чрезвычайно быстро и является лучшей практикой при работе с составными типами в планах видов характеристик.

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

← На главную