Почему метод СодержитТип для ТипВсеСсылки возвращает Истина для Неопределено?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке конфигураций на платформе 1С:Предприятие мы часто используем методы ТипВсеСсылки() для проверки принадлежности значения к какому-либо классу объектов, например, к справочникам или документам. Однако многие разработчики сталкиваются с неожиданным поведением: проверка значения Неопределено через СодержитТип() возвращает Истина. Давайте разберем, почему так происходит и как правильно организовать проверки в коде.

Разберем причину поведения платформы

Чтобы понять, почему платформа считает Неопределено частью общего списка ссылочных типов, необходимо взглянуть на архитектуру объектов ОписаниеТипов. Когда мы вызываем Документы.ТипВсеСсылки() или Справочники.ТипВсеСсылки(), система формирует объект ОписаниеТипов, который включает в себя все существующие в конфигурации ссылочные типы.

Ключевой момент заключается в том, что в 1С любое поле, которое может содержать ссылку на объект (составной тип), по своей внутренней логике обязано поддерживать отсутствие данных. Для обозначения пустого значения в таких реквизитах используется Неопределено. Поэтому платформа автоматически расширяет ОписаниеТипов, полученное через ТипВсеСсылки(), включая в него возможность хранения пустого значения.

Таким образом, когда вы выполняете следующий код:


ТипМоегоЗначения = ТипЗнч(ПроверяемоеЗначение);
Результат = Справочники.ТипВсеСсылки().СодержитТип(ТипМоегоЗначения);

Если в ПроверяемоеЗначение передано Неопределено, метод СодержитТип() вернет Истина. Это происходит не из-за ошибки в коде, а из-за того, что Неопределено концептуально является «универсальным» для ссылочных объектов типом, допустимым в рамках любого состава ссылок.

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

Поскольку СодержитТип() в данном контексте всегда будет учитывать Неопределено, нам необходимо скорректировать логику проверок. Рассмотрим основные рекомендации, как избежать ложноположительных результатов.

  1. Явная проверка на Неопределено: Перед выполнением проверки принадлежности к ссылочным типам всегда выполняйте явную проверку значения. Это самый надежный способ.
  2. Использование оператора Есть: В условиях всегда сначала проверяйте значение на Неопределено.

Пример корректной реализации проверки

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


Процедура ПроверитьЗначение(ПроверяемоеЗначение)
    
    // Сначала проверяем на пустоту
    Если ПроверяемоеЗначение = Неопределено Тогда
        Сообщить("Значение не является ссылкой, так как это Неопределено");
        Возврат;
    КонецЕсли;
    
    // Только если это не Неопределено, проверяем тип
    ТипМоегоЗначения = ТипЗнч(ПроверяемоеЗначение);
    
    ЕстьВДокументах = Документы.ТипВсеСсылки().СодержитТип(ТипМоегоЗначения);
    ЕстьВСправочниках = Справочники.ТипВсеСсылки().СодержитТип(ТипМоегоЗначения);
    
    Если ЕстьВДокументах Или ЕстьВСправочниках Тогда
        Сообщить("Значение является ссылкой на объект метаданных");
    Иначе
        Сообщить("Значение не является ссылкой на документы или справочники");
    КонецЕсли;
    
КонецПроцедуры

Подведем итоги

Мы выяснили, что данное поведение платформы является штатным механизмом обеспечения целостности данных при работе с составными типами. Методы ТипВсеСсылки() включают Неопределено в перечень допустимых типов, так как любой объектный реквизит может быть пустым.

Основные выводы для вашей работы:

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

← На главную