Разработка и Конфигурация · 10 мин
Как получить тип документа в 1С: рабочие способы с примерами кода
Как получить тип документа в 1С: ТипЗначения, Метаданные(), Тип(), проверка ссылок и объектов. Примеры кода для управляемых и обычных форм.
Получить тип документа в 1С требуется в самых разных задачах: при универсальной обработке ссылок, построении отчётов по разным видам документов, проверке условий в обработчиках и при написании обменов. Платформа предлагает несколько механизмов — от встроенных функций до работы с метаданными, и выбор зависит от того, что у вас есть на входе: ссылка, объект, строка запроса или реквизит формы.
Главная сложность в том, что «тип» в 1С может означать разное: объект встроенного типа Тип, строковое имя вида документа, полное имя метаданных или представление, которое видит пользователь. Путаница между этими понятиями — самая частая причина ошибок вроде сравнения строки с типом и молча неработающих условий.
Ниже разобраны основные способы получения типа документа в коде, в запросе и в пользовательском режиме, с примерами, типичными ошибками и проверками результата.
Получение типа через ТипЗначения()
Функция ТипЗначения() — базовый инструмент, когда у вас есть готовое значение: ссылка на документ, объект документа или реквизит. Она возвращает объект встроенного типа Тип, который можно сравнивать с другими типами.
ТипДокумента = ТипЗначения(ДокументСсылка);
Если ТипДокумента = Тип("ДокументСсылка.РеализацияТоваровУслуг") Тогда
// Это реализация
КонецЕсли;
Обратите внимание на важное различие: тип ссылки и тип объекта — разные типы. Для ссылки это ДокументСсылка.ИмяДокумента, для объекта, полученного через ПолучитьОбъект(), — ДокументОбъект.ИмяДокумента. Если сравнить ссылку с типом объекта, условие никогда не выполнится, и ошибку можно искать часами.
Чтобы не дублировать проверки для ссылки и объекта, удобнее работать через метаданные — об этом в следующем разделе.
Имя вида документа через Метаданные()
Метод Метаданные() доступен и у ссылки, и у объекта документа. Он возвращает объект описания метаданных, из которого можно получить имя вида, синоним и полное имя.
ИмяВида = ДокументСсылка.Метаданные().Имя; // "РеализацияТоваровУслуг"
ПолноеИмя = ДокументСсылка.Метаданные().ПолноеИмя(); // "Документ.РеализацияТоваровУслуг"
Представление = ДокументСсылка.Метаданные().Синоним; // "Реализация товаров и услуг"
Этот способ удобен, когда нужна строка: например, для записи в журнал, передачи в другую систему или формирования универсального сообщения пользователю. Полное имя вида Документ.ИмяДокумента также используется в методах Метаданные.НайтиПоПолномуИмени() и при динамическом обращении Документы[ИмяВида].
Преимущество перед ТипЗначения() в том, что результат не зависит от того, передана ссылка или объект: метаданные у них общие. Поэтому в универсальных процедурах, куда может прийти и то и другое, метаданные надёжнее.
Проверка типа документа в запросе
В языке запросов тип значения получают функцией ТИПЗНАЧЕНИЯ(), а проверку вида документа обычно делают двумя способами: через оператор ССЫЛКА или через сравнение с ТИП().
ВЫБРАТЬ
ТИПЗНАЧЕНИЯ(Хозрасчетный.Регистратор) КАК ТипРегистратора,
Хозрасчетный.Регистратор КАК Регистратор
ИЗ
РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
ГДЕ
Хозрасчетный.Регистратор ССЫЛКА Документ.ОперацияБух
Условие ССЫЛКА Документ.ИмяДокумента работает быстрее и читается проще, поэтому для фильтрации предпочтительнее. Сравнение ТИПЗНАЧЕНИЯ(Поле) = ТИП(Документ.ИмяДокумента) применяют, когда тип нужно именно вывести или сгруппировать по нему.
Помните про ограничение: поля составного типа в запросе нельзя напрямую соединять с таблицами без уточнения типа — сначала сузьте состав через ВЫРАЗИТЬ(... КАК Документ.ИмяДокумента) или условие ССЫЛКА, иначе получите ошибку или заметное падение производительности.
- 1Определите, что у вас на входе: ссылка, объект, поле запроса или реквизит формы.
- 2Для кода на встроенном языке используйте ТипЗначения() или Метаданные().Имя.
- 3Для запроса применяйте ТИПЗНАЧЕНИЯ() и условие ССЫЛКА.
- 4Проверьте результат на документе известного вида: выведите тип через Сообщить() или в отладчике.
- 5Убедитесь, что сравнение работает и для ссылки, и для объекта, если процедура универсальная.
Тип документа в форме и в пользовательском режиме
Реквизит формы и Объект.Ссылка
На управляемой форме документа основной реквизит обычно называется Объект и имеет тип ДанныеФормыСтруктура. Через него доступна ссылка: Объект.Ссылка, а дальше работают те же ТипЗначения() и Метаданные(). Для нового, ещё не записанного документа ссылка будет пустой, но тип у неё уже определён — это удобно для проверок вида документа до записи.
Как узнать тип без программирования
В пользовательском режиме вид документа виден в заголовке формы и в списке документов. Если нужно определить тип технически — например, для обращения в поддержку разработчику — откройте документ и посмотрите навигационную ссылку через «Ещё → Получить ссылку» (в типовых интерфейсах): в ней зашит GUID, а вид документа определяется по форме объекта. В конфигураторе тот же вопрос решается через дерево метаданных: ветка «Документы» содержит все виды с их именами.
Обратная задача: получить документ по типу и работать динамически
Часто тип нужен не сам по себе, а для динамического обращения: создать документ нужного вида, открыть список или получить пустую ссылку. Для этого используют менеджер Документы с индексацией по строковому имени.
ИмяВида = "ПоступлениеТоваровУслуг";
ПустаяСсылка = Документы[ИмяВида].ПустаяСсылка();
НовыйДокумент = Документы[ИмяВида].СоздатьДокумент();
// Проверка существования вида документа в конфигурации
Если Метаданные.Документы.Найти(ИмяВида) <> Неопределено Тогда
// Вид существует
КонецЕсли;
Перед динамическим обращением обязательно проверяйте существование вида через Метаданные.Документы.Найти(). Обращение Документы["НесуществующееИмя"] вызовет исключение, которое в серверных процедурах приведёт к откату транзакции.
Если имя вида приходит извне — из файла обмена, настроек или ввода пользователя — добавьте защиту: приведите строку к ожидаемому формату и проверьте по метаданным. Это простая мера, которая предотвращает падение регламентных заданий из-за опечатки в настройках.
Проверка результата и типичные ошибки
После написания кода проверьте его на контрольных примерах: минимум на двух документах разных видов и на граничных случаях — пустой ссылке, незаписанном документе, значении Неопределено. Функция ТипЗначения(Неопределено) вернёт тип Неопределено, а вот вызов Неопределено.Метаданные() вызовет ошибку — добавляйте проверку на пустое значение.
Как проверить результат
Условие срабатывает для документа нужного вида и не срабатывает для чужого
Условие всегда ложно — вероятно, смешаны типы ссылки и объекта
Возвращается строка имени, как в конфигураторе
Ошибка «Метод не обнаружен» — на входе не ссылка и не объект документа
В выборку попадают только документы нужного вида
Пустой результат при наличии данных или ошибка выполнения запроса
Часто задаваемые вопросы
Чем отличается ТипЗначения() от Метаданные()?
ТипЗначения() возвращает объект встроенного типа Тип и различает ссылку и объект. Метаданные() возвращает описание вида документа из конфигурации и одинаково работает для ссылки и объекта. Для сравнения типов удобнее первое, для получения имени вида строкой — второе.
Как получить список всех видов документов конфигурации?
Переберите коллекцию Метаданные.Документы в цикле: у каждого элемента доступны Имя, Синоним и ПолноеИмя(). Так формируют списки выбора в универсальных обработках и настройках обмена.
Как проверить, что значение — именно документ, а не справочник?
Используйте Метаданные.НайтиПоТипу(ТипЗначения(Значение)) и проверьте, что родитель полученного объекта метаданных — «Документы», либо сравните полное имя с шаблоном «Документ.*». Альтернатива в запросе — функция ЕСТЬNULL с приведением или условие ССЫЛКА по конкретным видам.
Можно ли получить тип документа по строке с GUID ссылки?
GUID сам по себе вид документа не содержит. Нужно перебрать виды документов, для каждого сформировать ссылку через Документы[Имя].ПолучитьСсылку(Новый УникальныйИдентификатор(GUID)) и проверить существование через сравнение с полученной из базы. Готовых типовых функций «тип по GUID» в платформе нет.
Почему в запросе ТИПЗНАЧЕНИЯ() возвращает не то, что я ожидаю?
Чаще всего поле имеет составной тип, и для разных записей тип различается — это нормально. Если же тип везде один, но не тот, проверьте, не сравниваете ли вы результат со строкой вместо ТИП(Документ.Имя). Для отладки выгрузите результат запроса в таблицу значений и посмотрите колонку в консоли запросов.
Как получить представление вида документа для пользователя?
Используйте ДокументСсылка.Метаданные().Синоним — это то название, которое видит пользователь в интерфейсе («Реализация товаров и услуг»). Для полного представления конкретного документа с номером и датой достаточно Строка(ДокументСсылка).
Что важно запомнить
В коде тип документа получают через ТипЗначения() (для сравнения типов) и Метаданные().Имя / ПолноеИмя() (для строки вида), в запросе — через ТИПЗНАЧЕНИЯ() и условие ССЫЛКА. Помните о различии типов ссылки и объекта и проверяйте существование вида перед динамическим обращением к Документы[Имя].