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

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

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

Метод 1. Проверка через коллекцию метаданных

Наиболее универсальный и «чистый» с точки зрения архитектуры платформы способ — использование метода Содержит() у коллекции Метаданные.Документы. Этот метод принимает на вход объект метаданных и возвращает истину, если объект принадлежит к этой коллекции.

Рассмотрим пример кода, который позволяет проверить произвольный объект:


// Получаем метаданные объекта (ссылки или самого объекта)
МетаданныеОбъекта = СсылкаНаОбъект.Метаданные();

// Проверяем наличие объекта в коллекции документов
Если Метаданные.Документы.Содержит(МетаданныеОбъекта) Тогда
    Сообщить("Это документ");
Иначе
    Сообщить("Это другой тип объекта (справочник, регистр и т.д.)");
КонецЕсли;

Проанализируем преимущества этого подхода: он работает корректно как для объектов, созданных в памяти, так и для ссылок, уже записанных в базу данных. Однако стоит помнить, что вызов метода Метаданные() может быть относительно «дорогим» при массовой обработке тысяч объектов в цикле.

Метод 2. Проверка типа через ТипВсеСсылки()

Если у нас есть описание типа (Тип) или мы работаем со ссылкой, можно использовать метод менеджера Документы.ТипВсеСсылки(). Этот метод возвращает описание типов, включающее все документы, определенные в конфигурации.

Разберем, как это работает на практике:


// Проверка через описание типов всех документов
Если Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(ПроверяемоеЗначение)) Тогда
    // Логика для документа
КонецЕсли;

Этот способ удобен тем, что нам не нужно обращаться к конкретному объекту метаданных. Мы работаем напрямую с типами платформы. Важный нюанс: этот метод эффективен, когда вам нужно проверить, является ли «тип данных» документальным, даже если самого объекта (ссылки) еще не существует или это пустая ссылка.

Метод 3. Анализ полного имени метаданных (строковый метод)

Когда важна максимальная скорость выполнения (например, в высоконагруженных циклах обработки данных), обращение к коллекциям метаданных может замедлять работу. В таких случаях мы рекомендуем использовать строковую проверку полного имени объекта. У любого объекта метаданных есть свойство ПолноеИмя(), которое для документов всегда начинается с префикса Документ..

Посмотрим на пример реализации:


МетаданныеОбъекта = ПроверяемыйОбъект.Метаданные();
Если СтрНачинаетсяС(МетаданныеОбъекта.ПолноеИмя(), "Документ.") Тогда
    // Это точно документ
КонецЕсли;

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

Метод 4. Использование Библиотеки Стандартных Подсистем (БСП)

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

Пример использования функции из состава БСП:


// Проверка через типовой функционал БСП
Если ОбщегоНазначения.ЭтоДокумент(МетаданныеОбъекта) Тогда
    // Обработка документа
КонецЕсли;

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

Метод 5. Использование свойства Родитель

Существует еще один «хитрый» способ, упомянутый опытными разработчиками: проверка родителя в дереве метаданных. Хотя этот метод менее популярен, он наглядно показывает иерархию объектов в системе.


Если Ссылка.Метаданные().Родитель = Метаданные.Документы Тогда
    // Объект является документом
КонецЕсли;

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

Сравнительный анализ и рекомендации

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

  1. Массовая обработка данных в цикле: Используйте проверку по ПолноеИмя() с префиксом или заранее кэшируйте массив типов из Документы.ТипВсеСсылки().Типы() в повторно используемый модуль.
  2. Разовая проверка в бизнес-логике: Используйте Метаданные.Документы.Содержит() или функции БСП. Это делает код понятным для других разработчиков.
  3. Интеграция и сериализация: Если данные приходят извне (например, через XML или JSON), можно использовать XMLТипЗнч(). Для документов имя типа в XML часто содержит подстроку DocumentRef.
  4. Проверка по строковому имени: Если у вас есть только имя документа (например, "РеализацияТоваровУслуг"), проще всего проверить наличие менеджера: Документы[ИмяОбъекта] <> Неопределено.

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

← На главную