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

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

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

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

Способ 1. Проверка через коллекцию метаданных (универсальный метод)

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

Проанализируем пример функции, которую можно разместить в модуле объекта или в общем модуле:


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

    // Если в коллекциях метаданных объекта нет, значит он внешний
    Возврат Истина;
КонецФункции

В качестве параметра МетаданныеОбъекта следует передавать ЭтотОбъект.Метаданные(). Этот метод хорош тем, что он не зависит от языка интерфейса платформы и работает максимально быстро.

Способ 2. Анализ полного имени метаданных

Разберем еще один элегантный способ, основанный на свойстве ПолноеИмя. Платформа 1С формирует полное имя объекта по определенным правилам. Для встроенных объектов оно начинается с префикса "Отчет.ИмяОбъекта" или "Обработка.ИмяОбъекта". Для внешних объектов используется префикс "ВнешнийОтчет.ИмяОбъекта" или "ВнешняяОбработка.ИмяОбъекта".

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


Функция ЭтоВнешняяОбработкаОтчет(Объект) Экспорт
    ПолноеИмяМетаданных = Объект.Метаданные().ПолноеИмя;
    
    // Проверяем наличие ключевого слова "Внешний" в начале полного имени
    Возврат СтрНачинаетсяС(ПолноеИмяМетаданных, "Внешний") 
        Или СтрНачинаетсяС(ПолноеИмяМетаданных, "Внешняя");
КонецФункции

Важный нюанс: если вы работаете в управляемых формах, помните, что ЭтотОбъект внутри формы — это ДанныеФормыСтруктура, а не сам объект обработки. Чтобы получить доступ к метаданным в контексте формы на сервере, используйте конструкцию РеквизитФормыВЗначение("Объект").Метаданные().ПолноеИмя. Разобраться в нюансах контекста выполнения кода поможет публикация об управлении местом выполнения кода в управляемых формах.

Способ 3. Определение на стороне клиента (без вызова сервера)

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


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    Если СтрНачинаетсяС(ИмяФормы, "ВнешнийОтчет.") Или СтрНачинаетсяС(ИмяФормы, "ВнешняяОбработка.") Тогда
        Сообщить("Запущен внешний файл!");
    Иначе
        Сообщить("Запущен встроенный объект конфигурации.");
    КонецЕсли;
КонецПроцедуры

Это решение является очень быстрым, так как не требует обращения к базе данных или тяжелым объектам метаданных на сервере.

Способ 4. Проверка через путь к файлу (временное хранилище)

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

Мы можем проверить свойство ИспользуемоеИмяФайла. Если объект открыт как внешний файл напрямую через «Файл — Открыть», там будет путь к диску. Если через справочник доп. обработок — путь к временному хранилищу. У встроенных же объектов это свойство пустое или имеет другой формат.


&НаСервере
Функция ОпределитьИсточникЗапуска()
    ОбъектОбъект = РеквизитФормыВЗначение("Объект");
    ПутьКФайлу = ОбъектОбъект.ИспользуемоеИмяФайла;
    
    Если ПустаяСтрока(ПутьКФайлу) Тогда
        Возврат "Встроенный";
    ИначеЕсли СтрНайти(ПутьКФайлу, "e1cib\tempstorage\") > 0 Тогда
        Возврат "Внешний (из справочника БСП)";
    Иначе
        Возврат "Внешний (файловый)";
    КонецЕсли;
КонецФункции

Способ 5. Использование Сериализатора XDTO (продвинутый уровень)

Проанализируем ситуацию, когда нам нужна абсолютная гарантия независимости от языка. Метод СериализаторXDTO.ТипОбъекта(Объект) возвращает тип в пространстве имен XML. Для внешних объектов он всегда будет содержать латинские термины ExternalDataProcessorObject или ExternalReportObject, независимо от того, на каком языке установлена Windows или 1С.


ТипXDTO = СериализаторXDTO.ТипОбъекта(ЭтотОбъект);
Если СтрНайти(ТипXDTO.Имя, "External") > 0 Тогда
    // Это гарантированно внешний объект
КонецЕсли;

Резюме и рекомендации

Мы рассмотрели несколько подходов к решению задачи. Подведем итоги и выберем лучшие практики:

  1. Для обычных форм и серверного кода лучше всего подходит проверка через Метаданные.Обработки.Содержит().
  2. Для управляемых форм на стороне сервера оптимально использовать анализ ПолноеИмя через преобразование реквизита формы.
  3. Для клиентской логики используйте проверку ИмяФормы, чтобы избежать лишних серверных вызовов.
  4. Если ваша база использует Библиотеку стандартных подсистем (БСП), помните о параметре ДополнительнаяОбработкаСсылка, который передается в форму при запуске из справочника — это самый простой способ понять, что обработка запущена как «дополнительная».

Выбирайте метод исходя из архитектуры вашего решения, стараясь избегать жесткой привязки к строковым русскоязычным названиям типов, чтобы ваш код оставался работоспособным в любых условиях. Если подобные доработки внедряются сразу в несколько систем, их техническое обслуживание упрощается при использовании программы для автоматического обновления и тестирования баз 1С по расписанию.

← На главную