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

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

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

Анализ структуры описания типов

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

Способ 1: Получение типов из Определяемого типа

Если нам необходимо получить состав типов из конкретного ОпределяемогоТипа, мы обращаемся напрямую к метаданным конфигурации. Для сторонних инструментов может потребоваться выгрузка метаданных в JSON. Разберем по шагам, как это сделать программно:


// Выбираем конкретный определяемый тип по имени
НужныйОТ = Метаданные.ОпределяемыеТипы.Найти("ВладелецПрисоединенныхФайлов");

// Получаем массив типов, входящих в это определение
МассивТипов = НужныйОТ.Тип.Типы();

// Создаем список значений для выбора пользователем
СписокТиповДляВыбора = Новый СписокЗначений;

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

Важно помнить, что обращение к объекту Метаданные должно происходить на стороне сервера. Полученный СписокЗначений можно передать на клиент и использовать в методе ПоказатьВыборИзСписка().

Способ 2: Получение типов из реквизита конкретного объекта

Иногда составной тип определен не в глобальном ОпределяемомТипе, а непосредственно в реквизите документа или справочника. Выясним, как извлечь описание типов в этом случае. Рассмотрим ситуацию на примере реквизита Склад документа ЗаказПоставщику, который может быть как складом, так и подразделением.


// Обращаемся к метаданным реквизита
ОписаниеТиповРеквизита = Метаданные.Документы.ЗаказПоставщику.Реквизиты.Склад.Тип;

// Извлекаем массив типов
МассивТипов = ОписаниеТиповРеквизита.Типы();

СписокДляПользователя = Новый СписокЗначений;

Для Каждого ТипЭлемента Из МассивТипов Цикл
    // Получаем синоним для отображения пользователю
    МетаДанныеОбъекта = Метаданные.НайтиПоТипу(ТипЭлемента);
    Представление = ?(МетаДанныеОбъекта <> Неопределено, МетаДанныеОбъекта.Синоним, Строка(ТипЭлемента));
    
    СписокДляПользователя.Добавить(ТипЭлемента, Представление);
КонецЦикла;

// Сортируем список по алфавиту для удобства
СписокДляПользователя.СортироватьПоПредставлению();

Способ 3: Использование стандартного диалога выбора типа

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

Рассмотрим пример вызова стандартного окна:


// На сервере получаем описание типов
ОписаниеТипов = Метаданные.ОпределяемыеТипы.ПрисоединенныйФайл.Тип;

// На клиенте вызываем диалог (в асинхронном режиме для управляемых форм)
ОписаниеТипов.ПоказатьВыборТипа(Новый ОписаниеОповещения("ПослеВыбораТипа", ЭтотОбъект));

// В процедуре обратного вызова обрабатываем результат
&НаКлиенте
Процедура ПослеВыбораТипа(ВыбранныйТип, ДополнительныеПараметры) Экспорт
    Если ВыбранныйТип <> Неопределено Тогда
        Сообщить("Пользователь выбрал тип: " + ВыбранныйТип);
        // Здесь можно создать пустую ссылку выбранного типа
        НовыйОбъект = Новый(ВыбранныйТип);
    КонецЕсли;
КонецПроцедуры

Тонкости и рекомендации

При работе с программным формированием списка типов следует учитывать несколько важных моментов:

  1. Синонимы объектов: Всегда старайтесь выводить пользователю Синоним из метаданных, а не системное имя. Это делает интерфейс дружелюбным. Если синоним не задан, используйте Имя (посмотреть структуру всех синонимов поможет отчет по структуре метаданных — для этого есть универсальный инструмент анализа структуры и метаданных 1С).
  2. Примитивные типы: В составном типе могут присутствовать Строка, Число, Дата. Метод Метаданные.НайтиПоТипу() вернет для них Неопределено, поэтому обязательно делайте проверку, как показано в примерах выше.
  3. Сортировка: По умолчанию типы в массиве могут идти в порядке их добавления в конфигураторе. Для больших списков обязательно вызывайте СписокЗначений.СортироватьПоПредставлению().
  4. Пустые ссылки: Если ваша задача — не просто узнать тип, а создать объект этого типа, используйте конструктор Новый(ВыбранныйТип). Для ссылочных типов это создаст пустую ссылку данного типа. При проектировании сложных связей полезно опираться на модель объекта.
  5. Исключение типов: Иногда в составном типе есть "технические" типы (например, УдалениеОбъекта), которые не нужно показывать пользователю. В этом случае при обходе массива добавьте условие фильтрации.

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

← На главную