Как правильно сравнивать ИНН и другие цифровые строки в 1С и почему обычное сравнение может не работать?

Программист 1С v8.3 (Обычные формы)
← На главную

В практике разработки на платформе 1С:Предприятие программисты часто сталкиваются с ситуацией, когда визуально одинаковые значения ИНН, артикулов или других цифровых кодов при сравнении выдают результат Ложь. Казалось бы, простая задача — сравнить строку из базы данных с эталонным значением — превращается в поиск скрытых символов и разбор особенностей типизации. В этой статье мы подробно разберем, почему возникают такие сложности и как правильно организовать сравнение данных.

Анализ проблемы: почему "111111111" не равно "111111111"?

Рассмотрим классическую ситуацию: у нас есть выборка из запроса, содержащая ИНН организации, и мы хотим проверить его на соответствие конкретному значению. Проблема часто заключается в том, что 1С по-разному обрабатывает типы данных Число и Строка, а также накладывает свои правила форматирования при выводе или преобразовании чисел.

Выясним основную причину неудачи первого варианта кода автора темы:


// Ошибочный подход
ВыборкаИзЗапроса.ДоговорОрганизацияИНН = "111111111" 

Если в базе данных поле ИНН имеет тип Строка, а мы пытаемся сравнить его с числом или строкой, содержащей пробелы, условие не выполнится. Однако самая коварная ошибка кроется в неразрывных пробелах (НПП). Проанализируем, откуда они берутся.

Решение №1: Борьба с неразрывными пробелами (НПП)

В 1С функция Строка(Число) или неявное преобразование числа в строку автоматически добавляет разделители групп разрядов. Для числа 111 111 111 платформа вставит специальные символы между тройками цифр. Это не обычные пробелы (код 32), а неразрывные пробелы (код 160, Символы.НПП).

Посмотрим на пример кода, который помог автору решить проблему:


ИНН_Эталон = 111111111;
Если ВыборкаИзЗапроса.ДоговорОрганизацияИНН = СтрЗаменить(ИНН_Эталон, Символы.НПП, "") Тогда
    // Код сработает, так как мы удалили невидимые разделители разрядов
КонецЕсли;

Хотя этот метод рабочий, он считается "обходным". Рассмотрим более профессиональный способ подготовки данных.

Решение №2: Использование функции Формат для чистого преобразования

Чтобы не заниматься удалением символов после того, как они уже появились, мы можем сразу указать платформе, как именно нужно преобразовать число в строку для сравнения. Разберем работу функции Формат().

Параметр ЧГ=0 (группировка разрядов) позволяет получить "чистую" строку из цифр без каких-либо пробелов:


ЧисловойИНН = 7701234567;
СтроковыйИНН = Формат(ЧисловойИНН, "ЧГ=0");
// Результат будет "7701234567" без пробелов

Именно этот метод является наиболее надежным, так как он исключает появление Символы.НПП в принципе, а не пытается бороться с последствиями.

Решение №3: Обработка ведущих нулей в ИНН

Важно помнить, что ИНН — это не число, а цифровой код. ИНН многих организаций (особенно в Москве) начинаются с нуля. Если вы храните или обрабатываете ИНН как число, ведущий ноль будет потерян.

Проанализируем ситуацию:

  1. ИНН организации: "0712345678" (тип Строка).
  2. В коде вы пишите: Если ИНН = 0712345678 Тогда...
  3. 1С воспримет это как число 712 345 678.
  4. При сравнении строки "0712345678" и числа 712345678 результат всегда будет Ложь.

Золотое правило: ИНН, КПП, БИК и номера счетов всегда должны храниться и сравниваться как Строка. При сравнении всегда используйте кавычки: "0712345678".

Решение №4: Оптимизация через запрос

В обсуждении на форуме пользователь выполнял сравнение внутри выборки (в цикле). С точки зрения производительности это неоптимально. Рассмотрим, как вынести это условие на уровень запроса.

Если нам нужно найти конкретную организацию, правильнее сделать так:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Договоры.Ссылка
    |ИЗ
    |   Справочник.ДоговорыКонтрагентов КАК Договоры
    |ГДЕ
    |   Договоры.Организация.ИНН = &НужныйИНН";

Запрос.УстановитьПараметр("НужныйИНН", "111111111");

В этом случае SQL-сервер сам выполнит фильтрацию, и в 1С придут только нужные данные. Это значительно ускорит работу, если в базе тысячи договоров.

Решение №5: Очистка данных от лишних пробелов

Иногда ИНН в базу заносится пользователями вручную, и в конце или начале строки могут оказаться случайные пробелы. Для надежного сравнения рекомендуется использовать функцию СокрЛП() (Сократить Левые и Правые пробелы).

Посмотрим на правильное комбинированное сравнение:


ЗначениеИзБазы = ВыборкаИзЗапроса.ДоговорОрганизацияИНН;
Эталон = "111111111";

// СокрЛП уберет обычные пробелы, если они были случайно введены
Если СокрЛП(ЗначениеИзБазы) = СокрЛП(Эталон) Тогда
    // Успешное сравнение
КонецЕсли;

Типичные ошибки, которых следует избегать

Проанализируем курьезный пример из сообщения №6 форума: СокрЛП(ВРег(111111111)).

Здесь допущено сразу несколько логических ошибок:

  1. Функция ВРег() (Верхний регистр) применяется к строкам, чтобы сделать все буквы заглавными. Применять её к числу бессмысленно — у цифр нет регистра.
  2. СокрЛП() на числовой константе без предварительного преобразования также не имеет смысла, так как в самом коде число пробелов не содержит.

Никогда не используйте функции работы со строками для типов Число без явного понимания того, как платформа выполнит приведение типов.

Работа с внешними источниками (Excel)

Если вы загружаете ИНН из Excel, проблема усугубляется. Excel часто хранит длинные числа в экспоненциальной форме (например, 1.11E+09). При чтении таких данных в 1С вы можете получить совершенно не то, что ожидаете.

Рекомендуем при загрузке из внешних файлов использовать следующий алгоритм:

Итоги

Для корректного сравнения ИНН в 1С придерживайтесь следующих правил:

  1. Всегда приводите сравниваемые значения к одному типу (лучше к строке).
  2. Используйте Формат(Значение, "ЧГ=0") для избавления от неразрывных пробелов при конвертации чисел.
  3. Применяйте СокрЛП() для удаления случайных пробелов по краям строк.
  4. По возможности переносите условия сравнения в текст запроса (секция ГДЕ).
  5. Не забывайте, что ИНН — это строка, и ведущие нули имеют значение.

Соблюдение этих простых правил убережет вас от трудноуловимых ошибок и обеспечит стабильную работу ваших алгоритмов обработки данных.

← На главную