К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как получить тип документа в 1С: рабочие способы с примерами кода

Как получить тип документа в 1С: ТипЗначения, Метаданные(), Тип(), проверка ссылок и объектов. Примеры кода для управляемых и обычных форм.

Получить тип документа в 1С требуется в самых разных задачах: при универсальной обработке ссылок, построении отчётов по разным видам документов, проверке условий в обработчиках и при написании обменов. Платформа предлагает несколько механизмов — от встроенных функций до работы с метаданными, и выбор зависит от того, что у вас есть на входе: ссылка, объект, строка запроса или реквизит формы.

Главная сложность в том, что «тип» в 1С может означать разное: объект встроенного типа Тип, строковое имя вида документа, полное имя метаданных или представление, которое видит пользователь. Путаница между этими понятиями — самая частая причина ошибок вроде сравнения строки с типом и молча неработающих условий.

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

Получение типа через ТипЗначения()

Функция ТипЗначения() — базовый инструмент, когда у вас есть готовое значение: ссылка на документ, объект документа или реквизит. Она возвращает объект встроенного типа Тип, который можно сравнивать с другими типами.

ТипДокумента = ТипЗначения(ДокументСсылка);

Если ТипДокумента = Тип("ДокументСсылка.РеализацияТоваровУслуг") Тогда

// Это реализация

КонецЕсли;

Обратите внимание на важное различие: тип ссылки и тип объекта — разные типы. Для ссылки это ДокументСсылка.ИмяДокумента, для объекта, полученного через ПолучитьОбъект(), — ДокументОбъект.ИмяДокумента. Если сравнить ссылку с типом объекта, условие никогда не выполнится, и ошибку можно искать часами.

Чтобы не дублировать проверки для ссылки и объекта, удобнее работать через метаданные — об этом в следующем разделе.

Имя вида документа через Метаданные()

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

ИмяВида       = ДокументСсылка.Метаданные().Имя;          // "РеализацияТоваровУслуг"

ПолноеИмя = ДокументСсылка.Метаданные().ПолноеИмя(); // "Документ.РеализацияТоваровУслуг"

Представление = ДокументСсылка.Метаданные().Синоним; // "Реализация товаров и услуг"

Этот способ удобен, когда нужна строка: например, для записи в журнал, передачи в другую систему или формирования универсального сообщения пользователю. Полное имя вида Документ.ИмяДокумента также используется в методах Метаданные.НайтиПоПолномуИмени() и при динамическом обращении Документы[ИмяВида].

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

Проверка типа документа в запросе

В языке запросов тип значения получают функцией ТИПЗНАЧЕНИЯ(), а проверку вида документа обычно делают двумя способами: через оператор ССЫЛКА или через сравнение с ТИП().

ВЫБРАТЬ

ТИПЗНАЧЕНИЯ(Хозрасчетный.Регистратор) КАК ТипРегистратора,

Хозрасчетный.Регистратор КАК Регистратор

ИЗ

РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный

ГДЕ

Хозрасчетный.Регистратор ССЫЛКА Документ.ОперацияБух

Условие ССЫЛКА Документ.ИмяДокумента работает быстрее и читается проще, поэтому для фильтрации предпочтительнее. Сравнение ТИПЗНАЧЕНИЯ(Поле) = ТИП(Документ.ИмяДокумента) применяют, когда тип нужно именно вывести или сгруппировать по нему.

Помните про ограничение: поля составного типа в запросе нельзя напрямую соединять с таблицами без уточнения типа — сначала сузьте состав через ВЫРАЗИТЬ(... КАК Документ.ИмяДокумента) или условие ССЫЛКА, иначе получите ошибку или заметное падение производительности.

Порядок действий при универсальной проверке типа
  1. 1
    Определите, что у вас на входе: ссылка, объект, поле запроса или реквизит формы.
  2. 2
    Для кода на встроенном языке используйте ТипЗначения() или Метаданные().Имя.
  3. 3
    Для запроса применяйте ТИПЗНАЧЕНИЯ() и условие ССЫЛКА.
  4. 4
    Проверьте результат на документе известного вида: выведите тип через Сообщить() или в отладчике.
  5. 5
    Убедитесь, что сравнение работает и для ссылки, и для объекта, если процедура универсальная.

Тип документа в форме и в пользовательском режиме

Реквизит формы и Объект.Ссылка

На управляемой форме документа основной реквизит обычно называется Объект и имеет тип ДанныеФормыСтруктура. Через него доступна ссылка: Объект.Ссылка, а дальше работают те же ТипЗначения() и Метаданные(). Для нового, ещё не записанного документа ссылка будет пустой, но тип у неё уже определён — это удобно для проверок вида документа до записи.

Как узнать тип без программирования

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

Обратная задача: получить документ по типу и работать динамически

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

ИмяВида = "ПоступлениеТоваровУслуг";

ПустаяСсылка = Документы[ИмяВида].ПустаяСсылка();

НовыйДокумент = Документы[ИмяВида].СоздатьДокумент();

// Проверка существования вида документа в конфигурации

Если Метаданные.Документы.Найти(ИмяВида) <> Неопределено Тогда

// Вид существует

КонецЕсли;

Перед динамическим обращением обязательно проверяйте существование вида через Метаданные.Документы.Найти(). Обращение Документы["НесуществующееИмя"] вызовет исключение, которое в серверных процедурах приведёт к откату транзакции.

Если имя вида приходит извне — из файла обмена, настроек или ввода пользователя — добавьте защиту: приведите строку к ожидаемому формату и проверьте по метаданным. Это простая мера, которая предотвращает падение регламентных заданий из-за опечатки в настройках.

Проверка результата и типичные ошибки

После написания кода проверьте его на контрольных примерах: минимум на двух документах разных видов и на граничных случаях — пустой ссылке, незаписанном документе, значении Неопределено. Функция ТипЗначения(Неопределено) вернёт тип Неопределено, а вот вызов Неопределено.Метаданные() вызовет ошибку — добавляйте проверку на пустое значение.

Типичные ошибки
01
Сравнение строки с типом: ТипЗначения(Ссылка) = "ДокументСсылка.РеализацияТоваровУслуг" — условие никогда не выполнится, нужен Тип("...") в правой части.
02
Сравнение типа ссылки с типом объекта — ДокументСсылка.X и ДокументОбъект.X это разные типы.
03
Вызов Метаданные() у Неопределено или у примитивного значения — исключение в runtime.
04
Динамическое обращение Документы[Имя] без проверки Метаданные.Документы.Найти() — падение при опечатке в имени.
05
Соединение составного поля в запросе без ВЫРАЗИТЬ или ССЫЛКА — ошибка запроса или лишние соединения с каждой таблицей составного типа.
Контрольные точки

Как проверить результат

Сравнение типов в коде
Норма

Условие срабатывает для документа нужного вида и не срабатывает для чужого

Тревожный признак

Условие всегда ложно — вероятно, смешаны типы ссылки и объекта

Имя вида через Метаданные().Имя
Норма

Возвращается строка имени, как в конфигураторе

Тревожный признак

Ошибка «Метод не обнаружен» — на входе не ссылка и не объект документа

Фильтр ССЫЛКА в запросе
Норма

В выборку попадают только документы нужного вида

Тревожный признак

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

Часто задаваемые вопросы

Чем отличается ТипЗначения() от Метаданные()?

ТипЗначения() возвращает объект встроенного типа Тип и различает ссылку и объект. Метаданные() возвращает описание вида документа из конфигурации и одинаково работает для ссылки и объекта. Для сравнения типов удобнее первое, для получения имени вида строкой — второе.

Как получить список всех видов документов конфигурации?

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

Как проверить, что значение — именно документ, а не справочник?

Используйте Метаданные.НайтиПоТипу(ТипЗначения(Значение)) и проверьте, что родитель полученного объекта метаданных — «Документы», либо сравните полное имя с шаблоном «Документ.*». Альтернатива в запросе — функция ЕСТЬNULL с приведением или условие ССЫЛКА по конкретным видам.

Можно ли получить тип документа по строке с GUID ссылки?

GUID сам по себе вид документа не содержит. Нужно перебрать виды документов, для каждого сформировать ссылку через Документы[Имя].ПолучитьСсылку(Новый УникальныйИдентификатор(GUID)) и проверить существование через сравнение с полученной из базы. Готовых типовых функций «тип по GUID» в платформе нет.

Почему в запросе ТИПЗНАЧЕНИЯ() возвращает не то, что я ожидаю?

Чаще всего поле имеет составной тип, и для разных записей тип различается — это нормально. Если же тип везде один, но не тот, проверьте, не сравниваете ли вы результат со строкой вместо ТИП(Документ.Имя). Для отладки выгрузите результат запроса в таблицу значений и посмотрите колонку в консоли запросов.

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

Используйте ДокументСсылка.Метаданные().Синоним — это то название, которое видит пользователь в интерфейсе («Реализация товаров и услуг»). Для полного представления конкретного документа с номером и датой достаточно Строка(ДокументСсылка).

Итог

Что важно запомнить

В коде тип документа получают через ТипЗначения() (для сравнения типов) и Метаданные().Имя / ПолноеИмя() (для строки вида), в запросе — через ТИПЗНАЧЕНИЯ() и условие ССЫЛКА. Помните о различии типов ссылки и объекта и проверяйте существование вида перед динамическим обращением к Документы[Имя].