Как создать объект или открыть форму на основании описания типов в 1С?

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

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

Сначала проанализируем ограничения платформы, о которых важно помнить при реализации универсальных алгоритмов:

  1. Оператор Новый не создает прикладные объекты базы данных: Конструкция вида Новый("СправочникОбъект.Номенклатура") или Новый(Тип) не предназначена для ссылочных данных информационной базы. Создание элементов справочников, документов и других прикладных объектов выполняется строго через менеджеры соответствующих объектов (например, Справочники[Имя].СоздатьЭлемент() или Документы[Имя].СоздатьДокумент()).
  2. Особенности метода Метаданные.НайтиПоТипу(): Данный метод возвращает объект метаданных только для ссылочных и прикладных типов. При передаче примитивных типов (Число, Строка, Дата, Булево) или универсальных коллекций метод вернет Неопределено.
  3. Контекст выполнения: Обращение к менеджерам объектов и непосредственное создание объектов базы данных должны выполняться на стороне сервера.

Способ 1. Универсальное создание объекта базы данных на сервере

Рассмотрим, как извлечь нужный тип из описания типов, определить его класс метаданных и программно создать новый объект. Если в ОписаниеТипов содержится один или несколько типов, мы можем получить массив типов через метод Типы().

Посмотрим на пример универсального серверного кода:


// Предположим, у нас есть ОписаниеТипов
ОписаниеТипов = Новый ОписаниеТипов("СправочникСсылка.Номенклатура");

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

Способ 2. Открытие формы создания нового объекта без явного создания в базе

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


ТипОбъекта = ОписаниеТипов.Типы()[0];
ОбъектМД = Метаданные.НайтиПоТипу(ТипОбъекта);

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

Способ 3. Получение значения по умолчанию через ОписаниеТипов

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


// Метод возвращает значение по умолчанию для первого типа в описании
// Для ссылочных типов это будет пустая ссылка соответствующего справочника или документа
ЗначениеПоУмолчанию = ОписаниеТипов.ПривестиЗначение();

Обработка составных типов

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

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