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

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

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

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

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

Выбор способа зависит от контекста: проверяете ли вы ссылку на документ, объект, значение из реквизита составного типа или строку запроса. Ошибка в выборе метода приводит либо к лишним обращениям к базе данных, либо к некорректной логике, которая «молча» пропускает нужные документы.

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

Проверка типа через ТипЗнч() и Тип() — базовый способ

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

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

// действия для реализации

КонецЕсли;

Имя типа строится по шаблону: вид объекта метаданных во множественном числе, точка, имя объекта как в конфигураторе. Для ссылок — «ДокументСсылка.ИмяДокумента», для объектов — «ДокументОбъект.ИмяДокумента». Это принципиально разные типы: ссылка не равна объекту, и сравнение ТипЗнч(Объект) с «ДокументСсылка.…» всегда даст Ложь.

Если нужно проверить несколько допустимых типов, удобно собрать их в массив и использовать метод Найти():

ДопустимыеТипы = Новый Массив;

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

ДопустимыеТипы.Добавить(Тип("ДокументСсылка.ПоступлениеТоваровУслуг"));

Если ДопустимыеТипы.Найти(ТипЗнч(ДокументСсылка)) <> Неопределено Тогда

// документ подходит

КонецЕсли;

Проверка через метаданные — когда имя типа неизвестно заранее

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

Проверить, что значение — ссылка на любой документ, можно так:

Если Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)) Тогда

// это ссылка на какой-то документ

КонецЕсли;

Для получения имени вида документа по ссылке используют метаданные:

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

Обратный вариант — найти объект метаданных по имени и сравнить с метаданными ссылки. Это безопаснее, чем сравнение строк, потому что не зависит от переименований в коде:

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

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

КонецЕсли;

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

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

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

ВЫБРАТЬ

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

ИЗ

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

ГДЕ

ХозрасчетныйОбороты.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг

Оператор ССЫЛКА в условии ГДЕ позволяет отфильтровать записи по виду документа-регистратора без обращения к данным самого документа. Это стандартный приём для отчётов по регистрам, где регистратор имеет составной тип.

Когда нужно обратиться к реквизиту документа через поле составного типа, сначала приводят значение к конкретному типу:

ВЫБРАТЬ

ВЫРАЗИТЬ(Задание.ДокументОснование КАК Документ.ЗаказКлиента).Номер КАК НомерЗаказа

ИЗ

Задача.Задание КАК Задание

ГДЕ

Задание.ДокументОснование ССЫЛКА Документ.ЗаказКлиента

Если применить ВЫРАЗИТЬ к значению другого типа, результатом будет NULL для всех реквизитов приведённого типа. Поэтому приведение почти всегда сочетают с проверкой ССЫЛКА в условии.

Проверка типа в подписках на события и обработчиках

В подписках на события (ПриЗаписи, ОбработкаПроведения, ОбработкаЗаполнения) в обработчик приходит объект, а не ссылка. Поэтому сравнивать нужно с «ДокументОбъект.ИмяДокумента» либо использовать метаданные источника.

Процедура ПриЗаписиДокументаПриЗаписи(Источник, Отказ) Экспорт

Если ТипЗнч(Источник) = Тип("ДокументОбъект.РеализацияТоваровУслуг") Тогда

// логика для реализации

КонецЕсли;

КонецПроцедуры

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

В управляемых формах частая задача — определить тип значения, выбранного в поле составного типа. Здесь работает тот же ТипЗнч(), но помните: пока пользователь не выбрал значение, тип может быть неопределённым (значение Неопределено), и сравнение корректно отработает только после проверки на заполненность.

Типичные ошибки
01
Сравнение ДокументОбъект с типом ДокументСсылка — результат всегда Ложь, логика молча не срабатывает
02
Использование Тип() с именем документа, которого нет в данной конфигурации, — исключение прерывает обработку
03
Проверка типа через строковое представление ссылки — ломается при изменении синонима и не работает для одинаковых представлений
04
Вызов Источник.Ссылка.Метаданные() там, где достаточно Источник.Метаданные(), — лишнее обращение к данным

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

Если вы не разработчик, а пользователь или консультант, тип документа виден прямо в интерфейсе. В списке «Все документы» или в журналах колонка с видом документа показывает его название — это и есть пользовательское представление типа.

В форме самого документа вид указан в заголовке окна перед номером и датой: «Реализация (акты, накладные, УПД) 0000-000123 от …». Через кнопку «Ещё» → «Вывести список» в журнале можно выгрузить таблицу, где вид документа будет отдельной колонкой.

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

Порядок действий при выборе способа проверки
  1. 1
    Определите, что у вас на руках: ссылка, объект или поле запроса
  2. 2
    Для ссылки или объекта с известным видом используйте ТипЗнч() = Тип()
  3. 3
    Для универсальной проверки «это документ вообще» используйте Документы.ТипВсеСсылки()
  4. 4
    Для запроса применяйте оператор ССЫЛКА, для доступа к реквизитам — ВЫРАЗИТЬ
  5. 5
    Проверьте результат на тестовом документе каждого ожидаемого вида

Сравнение способов проверки типа

Каждый метод имеет свою область применения, стоимость и ограничения. Сводная таблица поможет быстро выбрать подходящий вариант.

СпособГде применяетсяПлюсыОграничения
ТипЗнч() = Тип()Модуль объекта, формы, общие модулиПросто и наглядноТребует точного имени, исключение при отсутствии типа
Метаданные()Универсальные обработкиНе зависит от строковых имён, работает с любым видомЧуть более громоздкий код
ТипВсеСсылки()Проверка «любой документ»Одна проверка на все видыНе различает конкретные виды
ССЫЛКА в запросеЗапросы, СКДБыстро, без соединенийТолько в тексте запроса
ВЫРАЗИТЬЗапросы к составным типамДоступ к реквизитам конкретного видаNULL при несовпадении типа
Контрольные точки

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

Код отрабатывает на документе нужного вида
Норма

Ветка условия выполняется

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

Условие пропускается — проверьте, не сравниваете ли объект со ссылкой

Код отрабатывает на документе другого вида
Норма

Ветка условия игнорируется

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

Условие срабатывает на чужих видах — ошибка в имени типа

Запрос с ССЫЛКА
Норма

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

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

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

Частые вопросы о проверке типа документа

Чем отличается ДокументСсылка от ДокументОбъект при проверке типа?

Ссылка — это лёгкий идентификатор записи в базе, объект — загруженные в память данные документа с возможностью изменения. Это разные типы: ТипЗнч(Ссылки) даст «ДокументСсылка.Имя», а ТипЗнч(Объекта) — «ДокументОбъект.Имя». Сравнивать нужно с тем типом, который реально находится в переменной.

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

Сначала проверьте наличие объекта метаданных: Метаданные.НайтиПоПолномуИмени("Документ.ИмяДокумента"). Если результат Неопределено — документа в конфигурации нет, и вызывать Тип() нельзя, иначе возникнет исключение. Такой приём обязателен для универсальных обработок и расширений.

Можно ли проверить тип документа по строке с его именем?

Да, через Метаданные.НайтиПоПолномуИмени("Документ." + ИмяВида) и последующее сравнение с Ссылка.Метаданные(). Прямое сравнение строковых представлений ссылок не используйте — представление зависит от синонима и настроек, а не от типа.

Как проверить тип регистратора в движениях документа?

В запросе к таблице регистра примените условие «Регистратор ССЫЛКА Документ.ИмяВида». Если работаете с набором записей в коде, тип регистратора проверяется через ТипЗнч(НаборЗаписей.Отбор.Регистратор.Значение).

Почему ТипЗнч возвращает Неопределено или неожиданный тип?

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

Итог

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

Основной инструмент проверки типа документа — ТипЗнч() в паре с Тип(), для универсального кода — метаданные, для запросов — ССЫЛКА и ВЫРАЗИТЬ. Всегда учитывайте разницу между ссылкой и объектом и проверяйте существование типа перед обращением к нему в переносимом коде.