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