Одной из самых распространенных ловушек для начинающих разработчиков на платформе «1С:Предприятие» является ситуация, когда при сравнении значения из базы данных с обычным текстом программа упорно возвращает Ложь. На первый взгляд ситуация кажется абсурдной: в отладчике мы видим текст «Брокеры», сравниваем его со словом «Брокеры», но условие Если не выполняется. Давайте подробно разберем, почему так происходит, и научимся правильно работать с типами данных.
Для начала проанализируем ситуацию, описанную в теме. Разработчик пытается выполнить сравнение: Объект.Партнер.ГруппаДоступа = "Брокеры". В этом выражении левая и правая части принадлежат к принципиально разным классам объектов:
Строка. Это просто набор символов.СправочникСсылка.ГруппыДоступаПартнеров.В системе 1С ссылка — это не текст. Внутри базы данных ссылка представляет собой уникальный 128-битный идентификатор (GUID), например, 5b2e3f1a-6d4c-11eb-a2b3-00155d010101. Когда мы пишем условие сравнения, система сравнивает этот сложный идентификатор с текстовой строкой. Естественно, они никогда не будут равны, поэтому результатом всегда будет Ложь.
Почему же в отладчике мы видим именно текст? Рассмотрим механизм работы платформы. Для удобства человека 1С всегда показывает Представление объекта. Если у справочника в свойствах указано, что основным представлением является «Наименование», то везде, где система должна вывести ссылку (в списках, отчетах или окне отладки), она будет показывать текст наименования.
Чтобы убедиться в разнице типов самостоятельно, мы можем воспользоваться функцией ТипЗнч(). Давайте проанализируем следующий пример кода:
// Проверим типы данных в отладчике или через сообщить
ТипСлева = ТипЗнч(Объект.Партнер.ГруппаДоступа); // Вернет Тип("СправочникСсылка.ГруппыДоступаПартнеров")
ТипСправа = ТипЗнч("Брокеры"); // Вернет Тип("Строка")
Если ТипСлева <> ТипСправа Тогда
Сообщить("Сравнение невозможно: разные типы данных!");
КонецЕсли;
Важный совет: при работе в отладчике всегда обращайте внимание не только на колонку «Значение», но и на колонку «Тип». Это снимет 90% вопросов о том, почему сравнение работает не так, как ожидалось.
Самый очевидный способ исправить ошибку — обратиться к строковому реквизиту ссылки. Мы можем сравнить текст с текстом. Для этого используется обращение через точку к свойству Наименование.
Если Объект.Партнер.ГруппаДоступа.Наименование = "Брокеры" Тогда
// Теперь условие выполнится, так как мы сравниваем Строку со Строкой
КонецЕсли;
Однако давайте разберем, почему опытные разработчики стараются избегать такого подхода:
ГруппаДоступа.Наименование) порождает отдельный неявный запрос к базе данных. Если таких проверок много (например, в цикле при проведении документа), это может существенно замедлить работу системы.Если группа «Брокеры» является ключевой для логики вашей программы, правильнее всего сделать её предопределенной в конфигураторе. В этом случае мы сможем обращаться к ней напрямую через метаданные, не привязываясь к текстовым строкам.
Рассмотрим, как будет выглядеть правильное сравнение двух ссылок:
ЭталоннаяГруппа = Справочники.ГруппыДоступаПартнеров.Брокеры;
Если Объект.Партнер.ГруппаДоступа = ЭталоннаяГруппа Тогда
// Это самый надежный и быстрый способ
КонецЕсли;
В данном случае мы сравниваем Ссылка = Ссылка. Система сопоставляет GUID-ы, что происходит мгновенно и гарантирует 100% точность, даже если пользователь изменит название группы в режиме «Предприятие».
Бывают ситуации, когда мы не можем создать предопределенный элемент (например, справочник полностью заполняется пользователями). В этом случае, чтобы не обращаться к наименованию в каждой строке кода, мы можем один раз найти ссылку и использовать её для сравнения.
// Найдем ссылку один раз
СсылкаБрокеры = Справочники.ГруппыДоступаПартнеров.НайтиПоНаименованию("Брокеры");
// Проверим, что объект вообще найден
Если Не СсылкаБрокеры.Пустая() Тогда
// Теперь сравниваем ссылки, а не строки
Если Объект.Партнер.ГруппаДоступа = СсылкаБрокеры Тогда
// Логика для брокеров
КонецЕсли;
КонецЕсли;
Этот метод лучше прямого сравнения с .Наименование, так как позволяет избежать лишних обращений к базе данных в итерационных процессах.
Если вам нужно быстро проверить значение в отладочных целях или при написании внешней обработки, где производительность не критична, можно воспользоваться функцией Строка(). Она принудительно преобразует любой объект в его текстовое представление.
Если Строка(Объект.Партнер.ГруппаДоступа) = "Брокеры" Тогда
// Ссылка будет преобразована в текст, и сравнение сработает
КонецЕсли;
Проанализировав этот метод, мы должны помнить: он обладает теми же недостатками, что и сравнение через .Наименование, но при этом работает чуть медленнее, так как платформа тратит время на преобразование типов.
Для создания надежного и быстрого кода в 1С всегда следуйте правилу: сравнивайте объекты одного типа. Если вы работаете со ссылками — сравнивайте их со ссылками. Если со строками — со строками. Помните, что визуальное отображение данных в интерфейсе или отладчике — это лишь «маска» для пользователя, а программный код должен оперировать внутренними типами данных системы.
Наилучшей практикой считается использование предопределенных элементов или хранение ссылок в константах и настройках, что делает ваше решение гибким и устойчивым к изменениям данных в информационной базе.