В практике разработки на платформе 1С:Предприятие программисты часто сталкиваются с ситуацией, когда визуально одинаковые значения ИНН, артикулов или других цифровых кодов при сравнении выдают результат Ложь. Казалось бы, простая задача — сравнить строку из базы данных с эталонным значением — превращается в поиск скрытых символов и разбор особенностей типизации. В этой статье мы подробно разберем, почему возникают такие сложности и как правильно организовать сравнение данных.
Рассмотрим классическую ситуацию: у нас есть выборка из запроса, содержащая ИНН организации, и мы хотим проверить его на соответствие конкретному значению. Проблема часто заключается в том, что 1С по-разному обрабатывает типы данных Число и Строка, а также накладывает свои правила форматирования при выводе или преобразовании чисел.
Выясним основную причину неудачи первого варианта кода автора темы:
// Ошибочный подход
ВыборкаИзЗапроса.ДоговорОрганизацияИНН = "111111111"
Если в базе данных поле ИНН имеет тип Строка, а мы пытаемся сравнить его с числом или строкой, содержащей пробелы, условие не выполнится. Однако самая коварная ошибка кроется в неразрывных пробелах (НПП). Проанализируем, откуда они берутся.
В 1С функция Строка(Число) или неявное преобразование числа в строку автоматически добавляет разделители групп разрядов. Для числа 111 111 111 платформа вставит специальные символы между тройками цифр. Это не обычные пробелы (код 32), а неразрывные пробелы (код 160, Символы.НПП).
Посмотрим на пример кода, который помог автору решить проблему:
ИНН_Эталон = 111111111;
Если ВыборкаИзЗапроса.ДоговорОрганизацияИНН = СтрЗаменить(ИНН_Эталон, Символы.НПП, "") Тогда
// Код сработает, так как мы удалили невидимые разделители разрядов
КонецЕсли;
Хотя этот метод рабочий, он считается "обходным". Рассмотрим более профессиональный способ подготовки данных.
Чтобы не заниматься удалением символов после того, как они уже появились, мы можем сразу указать платформе, как именно нужно преобразовать число в строку для сравнения. Разберем работу функции Формат().
Параметр ЧГ=0 (группировка разрядов) позволяет получить "чистую" строку из цифр без каких-либо пробелов:
ЧисловойИНН = 7701234567;
СтроковыйИНН = Формат(ЧисловойИНН, "ЧГ=0");
// Результат будет "7701234567" без пробелов
Именно этот метод является наиболее надежным, так как он исключает появление Символы.НПП в принципе, а не пытается бороться с последствиями.
Важно помнить, что ИНН — это не число, а цифровой код. ИНН многих организаций (особенно в Москве) начинаются с нуля. Если вы храните или обрабатываете ИНН как число, ведущий ноль будет потерян.
Проанализируем ситуацию:
Если ИНН = 0712345678 Тогда...Ложь.Золотое правило: ИНН, КПП, БИК и номера счетов всегда должны храниться и сравниваться как Строка. При сравнении всегда используйте кавычки: "0712345678".
В обсуждении на форуме пользователь выполнял сравнение внутри выборки (в цикле). С точки зрения производительности это неоптимально. Рассмотрим, как вынести это условие на уровень запроса.
Если нам нужно найти конкретную организацию, правильнее сделать так:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Договоры.Ссылка
|ИЗ
| Справочник.ДоговорыКонтрагентов КАК Договоры
|ГДЕ
| Договоры.Организация.ИНН = &НужныйИНН";
Запрос.УстановитьПараметр("НужныйИНН", "111111111");
В этом случае SQL-сервер сам выполнит фильтрацию, и в 1С придут только нужные данные. Это значительно ускорит работу, если в базе тысячи договоров.
Иногда ИНН в базу заносится пользователями вручную, и в конце или начале строки могут оказаться случайные пробелы. Для надежного сравнения рекомендуется использовать функцию СокрЛП() (Сократить Левые и Правые пробелы).
Посмотрим на правильное комбинированное сравнение:
ЗначениеИзБазы = ВыборкаИзЗапроса.ДоговорОрганизацияИНН;
Эталон = "111111111";
// СокрЛП уберет обычные пробелы, если они были случайно введены
Если СокрЛП(ЗначениеИзБазы) = СокрЛП(Эталон) Тогда
// Успешное сравнение
КонецЕсли;
Проанализируем курьезный пример из сообщения №6 форума: СокрЛП(ВРег(111111111)).
Здесь допущено сразу несколько логических ошибок:
ВРег() (Верхний регистр) применяется к строкам, чтобы сделать все буквы заглавными. Применять её к числу бессмысленно — у цифр нет регистра.СокрЛП() на числовой константе без предварительного преобразования также не имеет смысла, так как в самом коде число пробелов не содержит.Никогда не используйте функции работы со строками для типов Число без явного понимания того, как платформа выполнит приведение типов.
Если вы загружаете ИНН из Excel, проблема усугубляется. Excel часто хранит длинные числа в экспоненциальной форме (например, 1.11E+09). При чтении таких данных в 1С вы можете получить совершенно не то, что ожидаете.
Рекомендуем при загрузке из внешних файлов использовать следующий алгоритм:
СтрНайти или регулярные выражения.Для корректного сравнения ИНН в 1С придерживайтесь следующих правил:
Формат(Значение, "ЧГ=0") для избавления от неразрывных пробелов при конвертации чисел.СокрЛП() для удаления случайных пробелов по краям строк.ГДЕ).Соблюдение этих простых правил убережет вас от трудноуловимых ошибок и обеспечит стабильную работу ваших алгоритмов обработки данных.