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