Каждый технический специалист или опытный пользователь 1С рано или поздно сталкивается со странным поведением системы, когда документ визуально присутствует в списке, но при попытке найти его через стандартную строку поиска по номеру система выдает пустой результат. При этом, если скопировать номер из карточки документа и вставить его в поле поиска, то нужный объект мгновенно находится.
В этой статье мы подробно разберем, почему возникает такая проблема на платформе «1С:Предприятие», из-за чего ручной ввод номера не дает результатов, и как раз и навсегда исправить эту ошибку в вашей базе данных.
Давайте проанализируем техническую сторону вопроса. Когда пользователь вводит номер вручную (например, 17 507), он нажимает на клавиатуре стандартную клавишу пробела. На уровне кодировки символов этот знак имеет код 32 (в таблице ASCII и Unicode).
Однако в платформе 1С для разделения разрядов в числах (тысяч, миллионов) используется так называемый неразрывный пробел. В системе он обозначается как Символы.НПП и имеет код 160 (Unicode U+00A0).
Для СУБД (будь то Microsoft SQL Server, PostgreSQL или файловая база данных) и для самой платформы 1С строки с разными кодами символов — это абсолютно разные строки. Для наглядности:
"17" + Символ(32) + "507""17" + Символ(160) + "507"Именно по этой причине точный поиск не может сопоставить эти значения. А метод «скопировать и вставить» работает только потому, что при копировании из поля базы данных в буфер обмена переносится именно символ с кодом 160.
Стандартные механизмы автонумерации платформы 1С всегда формируют строковые номера без каких-либо пробелов внутри. Появление символа Символы.НПП всегда свидетельствует о внешнем воздействии или ошибках разработки. Рассмотрим основные источники проблемы:
Строка(ЧисловойНомер), система автоматически форматирует число по правилам региональных настроек. Для русской локализации это означает разделение триад неразрывным пробелом. В результате число 17507 превращается в строку "17 507".Для решения проблемы с уже созданными документами необходимо очистить их номера от лишних неразрывных пробелов. Обратите внимание, что стандартная замена через обычный пробел в кавычках не принесет результата:
// Этот код НЕ сработает для удаления неразрывного пробела!
НовыйНомер = СтрЗаменить(НомерДокумента, " ", "");
Чтобы корректно удалить символ с кодом 160, рассмотрим несколько правильных программных способов, которые можно реализовать в групповой обработке документов.
Платформа 1С предоставляет системную константу Символы.НПП, которая указывает именно на неразрывный пробел:
Выборка = Документы.ЗаявкаПокупателя.Выбрать();
Пока Выборка.Следующий() Цикл
Если Найти(Выборка.Номер, Символы.НПП) > 0 Тогда
ДокОбъект = Выборка.ПолучитьОбъект();
ДокОбъект.Номер = СтрЗаменить(ДокОбъект.Номер, Символы.НПП, "");
ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
КонецЕсли;
КонецЦикла;
Если вы хотите быть абсолютно уверены в коде заменяемого символа, укажите его код 160 напрямую:
НовыйНомер = СтрЗаменить(ПроблемныйНомер, Символ(160), "");
В случаях, когда в номерах могут присутствовать и другие нежелательные символы (табуляция, переносы строк), рекомендуется использовать регулярные выражения или посимвольный перебор строки с фильтрацией только цифровых и буквенных знаков.
Чтобы гарантировать чистоту данных и исключить повторное появление проблемы, нам необходимо заблокировать каналы поступления некорректных номеров в систему.
Если номера генерируются программно из числовых показателей, разработчику следует всегда использовать функцию Формат с отключенной группировкой разрядов (параметр ЧГ=0):
// Правильное преобразование числа в строку номера без пробелов
СтрокаНомера = Формат(ЧисловойНомер, "ЧГ=0");
Для гарантированной защиты базы данных от ошибок ручного ввода пользователями или некорректных сторонних обработок, создадим подписку на событие ПередЗаписью для необходимых документов. В обработчике события пропишем принудительную очистку номера:
Процедура ПередЗаписьюДокументаОчисткаНомера(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
// Удаляем обычные и неразрывные пробелы из номера перед сохранением
Источник.Номер = СтрЗаменить(Источник.Номер, " ", "");
Источник.Номер = СтрЗаменить(Источник.Номер, Символы.НПП, "");
КонецПроцедуры
В качестве системной меры администратор базы данных может изменить настройки группировки чисел для всей системы. Для этого в Конфигураторе перейдите в меню Администрирование -> Региональные установки информационной базы и установите параметр «Группировка» в значение «0» (без разделения разрядов). Однако помните, что это действие повлияет на формат вывода чисел во всех стандартных отчетах, поэтому применять его следует осмотрительно.