В процессе работы с платформой 1С специалисты часто сталкиваются с ситуацией, когда в строковых реквизитах (например, в наименовании номенклатуры) внезапно появляются «лишние» пробелы. Особенно это критично для числовых показателей: длины, ширины или артикулов. Визуально это выглядит как обычный пробел, разделяющий тысячи (например, «1 500»), но при попытке поиска по строке «1500» система ничего не находит. Причина кроется в использовании неразрывного пробела (НПП), который платформа вставляет автоматически для удобства чтения чисел. Рассмотрим подробно, как избавиться от этого символа и как настроить систему так, чтобы он не появлялся в будущем.
Проанализируем ситуацию: почему обычная замена СтрЗаменить(Наименование, " ", "") часто не дает результата? Дело в том, что символ, разделяющий группы разрядов в 1С, — это не стандартный пробел (код 32), а специальный символ с кодом 160 (в кодировке Windows-1251) или U+00A0 в Unicode. Он предназначен для того, чтобы число не разрывалось при переносе строки. Платформа 1С подставляет его автоматически, если при преобразовании числа в строку не указаны специальные параметры форматирования.
Если данные уже записаны в базу с неразрывными пробелами, нам потребуется функция СтрЗаменить(). Разберем по шагам, как правильно указать целевой символ. В языке 1С существует встроенная системная константа Символы.НПП, которая как раз и соответствует неразрывному пробелу. Также можно использовать функцию Символ(160).
Посмотрим на пример кода для очистки строки:
// Способ с использованием системной константы
НаименованиеБезПробелов = СтрЗаменить(Объект.Наименование, Символы.НПП, "");
// Способ с использованием кода символа (если константа недоступна)
НаименованиеБезПробелов = СтрЗаменить(Объект.Наименование, Символ(160), "");
Важно помнить, что иногда в строке могут присутствовать и обычные пробелы, и неразрывные. В таком случае рекомендуется последовательно очистить строку от обоих типов символов.
Лучший способ решить проблему — не допускать попадания неразрывного пробела в строку на этапе формирования наименования. Если вы программно формируете строку из числовых реквизитов (например, «Ширина» + «Высота»), используйте функцию Формат() с параметром ЧГ=0 (Группировка разрядов = 0).
Проанализируем пример формирования строки:
// Неправильно: 1С применит региональные настройки и вставит НПП
Наименование = "Ширина " + Строка(ЧислоШирина) + " мм";
// Правильно: принудительно отключаем группировку разрядов
ПараметрыФормата = "ЧГ=0";
Наименование = "Ширина " + Формат(ЧислоШирина, ПараметрыФормата) + " мм";
Использование ЧГ=0 гарантирует, что число 1500 будет преобразовано в строку "1500" без каких-либо разделителей, независимо от настроек операционной системы или сервера 1С.
Если пользователь вводит данные в форму вручную, и пробелы появляются в числовых полях, мы можем изменить настройки самого реквизита или элемента формы. В конфигураторе на закладке «Оформление» у реквизита типа «Число» есть свойство «Формат».
Разберем, что нужно сделать в конструкторе форматной строки:
После этих действий платформа перестанет отображать и записывать число с разделителями групп разрядов в данном конкретном поле.
Когда неразрывных пробелов в базе накопилось много, их нужно вычистить массово. Для этого создадим простую обработку, которая обойдет справочник в цикле. Рассмотрим пример кода для внешней обработки:
Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
ТекущееНаименование = Выборка.Наименование;
// Проверяем наличие неразрывного пробела
Если Найти(ТекущееНаименование, Символы.НПП) > 0 Тогда
ОбъектСпр = Выборка.ПолучитьОбъект();
ОбъектСпр.Наименование = СтрЗаменить(ТекущееНаименование, Символы.НПП, "");
Попытка
ОбъектСпр.Записать();
Сообщить("Исправлено: " + ТекущееНаименование);
Исключение
Сообщить("Ошибка записи объекта: " + ТекущееНаименование);
КонецПопытки;
КонецЕсли;
КонецЦикла;
Важный момент: если вы используете типовые конфигурации (например, БП 3.0, УТ 11), для таких целей лучше использовать стандартную обработку «Групповое изменение реквизитов». В ней можно выбрать справочник, нажать «Дополнительные параметры» -> «Выполнить произвольный алгоритм» и вставить туда строку замены.
Иногда в наименование попадают не только неразрывные пробелы, но и другие невидимые символы (табуляция, переносы строк), особенно при копировании данных из Excel или PDF. В таких ситуациях эффективно использовать регулярные выражения через объект VBScript.RegExp.
Рассмотрим пример универсальной функции очистки:
Функция ОчиститьСтрокуОтВсехПробелов(ВходнаяСтрока)
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.Global = Истина;
RegExp.MultiLine = Истина;
// Шаблон \s находит любые пробельные символы, включая НПП и табуляцию
RegExp.Pattern = "\s";
Возврат RegExp.Replace(ВходнаяСтрока, "");
КонецФункции
Этот метод позволяет одним действием очистить строку от любого «мусора», который визуально не виден, но мешает поиску или выгрузке данных в другие системы.
Часто неразрывные пробелы попадают в 1С в момент загрузки данных из внешних файлов. В банковских выписках или прайс-листах Excel суммы и размеры почти всегда разделены неразрывными пробелами для красоты отображения.
Практический совет: при написании загрузчиков всегда добавляйте «санитарную» обработку всех входящих строковых данных. Лучше потратить миллисекунды на выполнение СтрЗаменить(Строка, Символы.НПП, "") при загрузке, чем потом сталкиваться с проблемами при поиске номенклатуры на складе.
Подведем итог: проблема неразрывных пробелов решается либо на этапе формирования строки через Формат(Значение, "ЧГ=0"), либо на этапе пост-обработки через СтрЗаменить(). Правильное использование этих инструментов сделает поиск по базе надежным, а данные — чистыми.