В процессе разработки на платформе 1С:Предприятие часто возникает задача предоставить пользователю выбор конкретного типа данных из тех, что разрешены в составном реквизите. Например, если у нас есть определяемый тип ВладелецПрисоединенныхФайлов, включающий в себя справочники Контрагенты, Договоры и Организации, нам может потребоваться программно сформировать список этих типов, чтобы пользователь мог выбрать один из них для дальнейшей обработки. Рассмотрим подробно, как это реализовать, используя возможности метаданных и встроенного языка.
Прежде всего, проанализируем, как платформа хранит информацию о составных типах. Любой реквизит или определяемый тип, имеющий признак "составной тип данных", описывается объектом ОписаниеТипов. Этот объект содержит метод Типы(), который возвращает массив всех типов, входящих в данное описание. Наша задача — перебрать этот массив и на его основе создать удобный для пользователя СписокЗначений.
Если нам необходимо получить состав типов из конкретного ОпределяемогоТипа, мы обращаемся напрямую к метаданным конфигурации. Для сторонних инструментов может потребоваться выгрузка метаданных в JSON. Разберем по шагам, как это сделать программно:
// Выбираем конкретный определяемый тип по имени
НужныйОТ = Метаданные.ОпределяемыеТипы.Найти("ВладелецПрисоединенныхФайлов");
// Получаем массив типов, входящих в это определение
МассивТипов = НужныйОТ.Тип.Типы();
// Создаем список значений для выбора пользователем
СписокТиповДляВыбора = Новый СписокЗначений;
Для Каждого ТекущийТип Из МассивТипов Цикл
// Для каждого типа получаем его человекочитаемое описание через метаданные
ОбъектМетаданных = Метаданные.НайтиПоТипу(ТекущийТип);
Если ОбъектМетаданных <> Неопределено Тогда
ПредставлениеТипа = ОбъектМетаданных.Синоним;
Если ПустаяСтрока(ПредставлениеТипа) Тогда
ПредставлениеТипа = ОбъектМетаданных.Имя;
КонецЕсли;
СписокТиповДляВыбора.Добавить(ТекущийТип, ПредставлениеТипа);
Иначе
// Обработка примитивных типов (Строка, Число и т.д.)
СписокТиповДляВыбора.Добавить(ТекущийТип, Строка(ТекущийТип));
КонецЕсли;
КонецЦикла;
Важно помнить, что обращение к объекту Метаданные должно происходить на стороне сервера. Полученный СписокЗначений можно передать на клиент и использовать в методе ПоказатьВыборИзСписка().
Иногда составной тип определен не в глобальном ОпределяемомТипе, а непосредственно в реквизите документа или справочника. Выясним, как извлечь описание типов в этом случае. Рассмотрим ситуацию на примере реквизита Склад документа ЗаказПоставщику, который может быть как складом, так и подразделением.
// Обращаемся к метаданным реквизита
ОписаниеТиповРеквизита = Метаданные.Документы.ЗаказПоставщику.Реквизиты.Склад.Тип;
// Извлекаем массив типов
МассивТипов = ОписаниеТиповРеквизита.Типы();
СписокДляПользователя = Новый СписокЗначений;
Для Каждого ТипЭлемента Из МассивТипов Цикл
// Получаем синоним для отображения пользователю
МетаДанныеОбъекта = Метаданные.НайтиПоТипу(ТипЭлемента);
Представление = ?(МетаДанныеОбъекта <> Неопределено, МетаДанныеОбъекта.Синоним, Строка(ТипЭлемента));
СписокДляПользователя.Добавить(ТипЭлемента, Представление);
КонецЦикла;
// Сортируем список по алфавиту для удобства
СписокДляПользователя.СортироватьПоПредставлению();
Проанализируем ситуацию: если нам не нужно создавать кастомный список, а достаточно просто вызвать стандартное окно выбора типа, которое предоставляет сама платформа 1С. У объекта ОписаниеТипов есть встроенный метод ВыбратьТип(). Это самый быстрый способ решения задачи, не требующий ручного обхода массива типов.
Рассмотрим пример вызова стандартного окна:
// На сервере получаем описание типов
ОписаниеТипов = Метаданные.ОпределяемыеТипы.ПрисоединенныйФайл.Тип;
// На клиенте вызываем диалог (в асинхронном режиме для управляемых форм)
ОписаниеТипов.ПоказатьВыборТипа(Новый ОписаниеОповещения("ПослеВыбораТипа", ЭтотОбъект));
// В процедуре обратного вызова обрабатываем результат
&НаКлиенте
Процедура ПослеВыбораТипа(ВыбранныйТип, ДополнительныеПараметры) Экспорт
Если ВыбранныйТип <> Неопределено Тогда
Сообщить("Пользователь выбрал тип: " + ВыбранныйТип);
// Здесь можно создать пустую ссылку выбранного типа
НовыйОбъект = Новый(ВыбранныйТип);
КонецЕсли;
КонецПроцедуры
При работе с программным формированием списка типов следует учитывать несколько важных моментов:
Синоним из метаданных, а не системное имя. Это делает интерфейс дружелюбным. Если синоним не задан, используйте Имя (посмотреть структуру всех синонимов поможет отчет по структуре метаданных — для этого есть универсальный инструмент анализа структуры и метаданных 1С).Строка, Число, Дата. Метод Метаданные.НайтиПоТипу() вернет для них Неопределено, поэтому обязательно делайте проверку, как показано в примерах выше.СписокЗначений.СортироватьПоПредставлению().Новый(ВыбранныйТип). Для ссылочных типов это создаст пустую ссылку данного типа. При проектировании сложных связей полезно опираться на модель объекта.УдалениеОбъекта), которые не нужно показывать пользователю. В этом случае при обходе массива добавьте условие фильтрации.Таким образом, мы разобрали основные подходы к извлечению состава типов. Выбор метода зависит от ваших целей: если нужен полный контроль над списком и его оформлением — используйте ручной обход коллекции Метаданные; если же требуется стандартное поведение системы — метод ВыбратьТип() будет наиболее эффективным решением.