При разработке в среде 1С:Предприятие программисты часто сталкиваются с особенностью платформы: функция ТипЗнч при попытке преобразования ее результата в строку возвращает синоним объекта (например, "Валюта"), а не его техническое имя (например, "СправочникСсылка.Валюты"). Это происходит потому, что строковое представление типа в 1С ориентировано на пользователя и учитывает локализацию интерфейса. Однако для логики программы, формирования имен файлов или обмена данными нам часто требуется именно внутреннее системное имя. Разберем подробно, как решить эту задачу различными методами.
Для начала проанализируем ситуацию. Когда мы пишем Строка(ТипЗнч(Ссылка)), платформа обращается к метаданным и возвращает человекочитаемое описание. Это удобно для вывода в отчеты, но абсолютно непригодно для программного сравнения или формирования условий. Рассмотрим ситуацию: если конфигурация поддерживает несколько языков, результат этой функции будет меняться в зависимости от языка текущего сеанса пользователя. Поэтому полагаться на строковые представления типов при написании бизнес-логики — плохая практика.
Если ваша задача заключается не в получении строки, а в проверке «является ли этот объект справочником Валюты», то преобразовывать тип в строку вообще не нужно. В 1С это делается гораздо эффективнее и быстрее через прямое сравнение объектов типа Тип.
Рассмотрим пример правильного кода для проверки типа значения:
// Правильный способ сравнения типов без использования строк
Если ТипЗнч(ТекущееЗначение) = Тип("СправочникСсылка.Валюты") Тогда
// Выполняем действия, если это ссылка на валюту
Сообщить("Это ссылка на справочник Валюты");
КонецЕсли;
Этот метод работает быстрее всего, так как платформа сравнивает внутренние идентификаторы типов, а не текстовые строки. Выясним причину: при компиляции модуля Тип("...") вычисляется один раз, и дальнейшее сравнение происходит мгновенно.
Часто нам все же нужно получить строковое представление, например, для логирования или динамического формирования запросов. В этом случае на помощь приходит работа с XML-типами. Метод XMLТипЗнч возвращает объект ТипДанныхXML, который содержит техническое имя, используемое платформой для сериализации. Это имя всегда на английском языке и имеет строгую структуру.
Посмотрим на пример реализации функции, которая возвращает строковый тип:
Функция ПолучитьТехническоеИмяТипа(Значение) Экспорт
ТипXML = XMLТипЗнч(Значение);
Если ТипXML = Неопределено Тогда
Возврат Строка(ТипЗнч(Значение)); // Для примитивных типов
КонецЕсли;
// Возвращает строку вида "CatalogRef.Валюты"
Возврат ТипXML.ИмяТипа;
КонецФункции
Проанализируем результат: для справочника вы получите CatalogRef.Имя, для документа — DocumentRef.Имя. Если вам нужно привести это к виду 1С (на русском языке), можно использовать простую замену подстрок. Этот метод считается надежным и используется даже в стандартных библиотеках (БСП).
Если у нас есть значение, и мы хотим получить его полное имя в дереве конфигурации (например, "Справочник.Валюты"), мы можем воспользоваться глобальным поиском по типам. Важно понимать, что объект метаданных не содержит информацию о том, "ссылка" это или "объект", он описывает саму сущность.
Разберем по шагам, как это работает:
ТипЗнч.Метаданные.НайтиПоТипу(), чтобы найти описание в конфигурации.ПолноеИмя() найденного объекта.
ЗначениеРеквизита = Объект.ВалютаУчета;
ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗнч(ЗначениеРеквизита));
Если ОбъектМетаданных <> Неопределено Тогда
// Результат будет: "Справочник.Валюты"
ТехническоеИмя = ОбъектМетаданных.ПолноеИмя();
Сообщить("Полное имя в метаданных: " + ТехническоеИмя);
Иначе
Сообщить("Тип является примитивным или системным");
КонецЕсли;
Важный нюанс: этот метод вернет "Справочник.Валюты", даже если вы передали саму ссылку. Если вам нужно именно уточнение "Ссылка", вам придется добавить его программно, проверив, является ли тип ссылочным.
В реальных задачах реквизит может иметь составной тип данных. В этом случае простого ТипЗнч от значения может быть недостаточно, если само значение в данный момент равно Неопределено. Для анализа всех возможных типов реквизита следует использовать объект ОписаниеТипов.
Проанализируем ситуацию на примере обхода метаданных документа:
Для каждого Реквизит Из Метаданные.Документы.РеализацияТоваровУслуг.Реквизиты Цикл
Сообщить("Реквизит: " + Реквизит.Имя);
// Получаем объект ОписаниеТипов
ДоступныеТипы = Реквизит.Тип.Типы();
Для каждого ТекущийТип Из ДоступныеТипы Цикл
МЗ = Метаданные.НайтиПоТипу(ТекущийТип);
Если МЗ <> Неопределено Тогда
Сообщить(" - Возможный тип: " + МЗ.ПолноеИмя());
Иначе
Сообщить(" - Примитивный тип: " + Строка(ТекущийТип));
КонецЕсли;
КонецЦикла;
КонецЦикла;
Подведем итог и выберем лучший инструмент для каждой ситуации:
Если...Тогда. Самый быстрый способ.Рассмотрим подробнее преимущества использования XML-сериализации. В отличие от метода Строка(), который может вернуть "Справочник ссылка: Валюты", XMLТипЗнч всегда возвращает стандартизированный идентификатор. Это позволяет избежать ошибок при обновлении платформы или смене локали сервера.
Помните: Никогда не используйте строковые сравнения типа Если Строка(Тип) = "Справочник ссылка: Валюты". Это "мина замедленного действия", которая обязательно сработает, когда вашу программу запустят в интерфейсе на другом языке или когда разработчики 1С слегка изменят представление типа в новой версии платформы.