К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как убрать пробелы в запросе 1С

Как убрать пробелы в запросе 1С: функции СокрЛП, СокрЛ, СокрП и СтрЗаменить, удаление неразрывных пробелов, типичные ошибки и примеры кода.

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

Язык запросов 1С предоставляет для этого встроенные функции: СокрЛП, СокрЛ, СокрП и СтрЗаменить. Они работают аналогично одноимённым функциям встроенного языка, но выполняются на стороне СУБД, что важно для производительности при больших объёмах данных.

Ниже разобраны все способы: от простого обрезания пробелов по краям до удаления неразрывных пробелов и пробелов внутри строки, а также ограничения каждого подхода и типичные ошибки.

Функции СокрЛП, СокрЛ и СокрП в запросе

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

ВЫБРАТЬ

СокрЛП(Контрагенты.Наименование) КАК Наименование

ИЗ

Справочник.Контрагенты КАК Контрагенты

Функции можно применять не только в списке выборки, но и в условиях, соединениях и группировках. Например, типичная задача — найти дубли контрагентов, отличающиеся только пробелами:

ВЫБРАТЬ

СокрЛП(Контрагенты.Наименование) КАК Наименование,

КОЛИЧЕСТВО(Контрагенты.Ссылка) КАК КоличествоДублей

ИЗ

Справочник.Контрагенты КАК Контрагенты

СГРУППИРОВАТЬ ПО

СокрЛП(Контрагенты.Наименование)

ИМЕЮЩИЕ

КОЛИЧЕСТВО(Контрагенты.Ссылка) > 1

Важно понимать: СокрЛП удаляет не только обычные пробелы, но и некоторые другие «невидимые» символы по краям — табуляции, переводы строк. Однако неразрывный пробел (символ с кодом 160) она не удаляет, и это одна из самых частых причин «неработающего» сокращения.

Удаление пробелов внутри строки через СтрЗаменить

Когда нужно убрать вообще все пробелы — например, в номере телефона, артикуле или ИНН — используют функцию СтрЗаменить. Она заменяет все вхождения подстроки на другую подстроку:

ВЫБРАТЬ

СтрЗаменить(Товары.Артикул, " ", "") КАК АртикулБезПробелов

ИЗ

Справочник.Номенклатура КАК Товары

Такой приём удаляет каждый обычный пробел в строке, где бы он ни стоял. Это удобно для нормализации кодов и номеров, но опасно для осмысленных текстов: наименование «ООО Ромашка» превратится в «ОООРомашка». Поэтому СтрЗаменить применяют только к полям, где пробелы по смыслу недопустимы.

Если нужно сжать множественные пробелы между словами до одного («ООО Ромашка» → «ООО Ромашка»), в чистом запросе это сделать сложно: придётся строить вложенные замены двойных пробелов на одинарные, что не гарантирует полного результата при трёх и более пробелах подряд. Такую задачу надёжнее решать во встроенном языке после выборки.

Сравнение подходов

СокрЛП

Убирает пробелы только по краям. Безопасна для любых строк, но не трогает пробелы внутри и неразрывный пробел.

СтрЗаменить

Убирает любые пробелы в любом месте строки. Подходит для кодов, артикулов, телефонов; разрушает осмысленные тексты.

Обработка результата в коде

Максимальная гибкость (регулярные замены, НСтр, циклы), но требует выгрузки данных из запроса и медленнее на больших объёмах.

Как убрать неразрывный пробел

Неразрывный пробел — главный виновник ситуаций, когда две строки выглядят одинаково, но сравнение даёт «ложь». В запросе нельзя вызвать Символ(160), поэтому есть два рабочих способа.

Первый — вставить неразрывный пробел прямо в текст запроса как литерал. В конфигураторе его можно ввести, скопировав из обработанной строки или набрав через Alt+0160 на цифровой клавиатуре. Минус способа — символ невидим, и при редактировании запроса его легко случайно удалить.

Второй, более надёжный способ — передать неразрывный пробел параметром:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| СтрЗаменить(СокрЛП(Контрагенты.Наименование), &НПП, "") КАК Наименование

|ИЗ

| Справочник.Контрагенты КАК Контрагенты";

Запрос.УстановитьПараметр("НПП", Символ(160));

Часто неразрывные пробелы стоят и по краям, и внутри строки (например, в суммах прописью из Excel). В этом случае комбинируют оба приёма: сначала СокрЛП для краёв, затем СтрЗаменить для неразрывных пробелов, как показано в примере выше.

Порядок действий при «не сходящихся» строках
  1. 1
    Проверьте, совпадают ли строки после СокрЛП — если нет, ищите неразрывный пробел.
  2. 2
    Добавьте в запрос СтрЗаменить с параметром Символ(160).
  3. 3
    Если проблема осталась — выведите коды символов строки во встроенном языке через КодСимвола и найдите другие невидимые символы (табуляция, разрыв строки).
  4. 4
    После выявления символа добавьте для него отдельную замену в запросе или в коде.

Использование в условиях и соединениях

Отдельный класс задач — поиск и соединение по «очищенному» значению. Например, нужно связать таблицу загруженных заявок со справочником контрагентов по наименованию, игнорируя различия в пробелах:

ВЫБРАТЬ

Заявки.НаименованиеКонтрагента,

Контрагенты.Ссылка

ИЗ

Заявки КАК Заявки

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты

ПО СокрЛП(Заявки.НаименованиеКонтрагента) = СокрЛП(Контрагенты.Наименование)

Здесь есть важное ограничение производительности: когда функция применяется к полю в условии соединения или отбора, СУБД не может использовать индекс по этому полю. На больших таблицах соединение по СокрЛП(Поле) может выполняться в разы дольше обычного.

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

Очистка данных в базе: когда запроса недостаточно

Запрос решает проблему «на лету», но если данные в базе загрязнены систематически, правильнее исправить сами данные. Типовой подход — сервисная обработка, которая в транзакции обходит элементы справочника и перезаписывает поля с применением СокрЛП и замены неразрывных пробелов.

Выборка = Справочники.Контрагенты.Выбрать();

Пока Выборка.Следующий() Цикл

Объект = Выборка.ПолучитьОбъект();

НовоеНаименование = СокрЛП(СтрЗаменить(Объект.Наименование, Символ(160), " "));

Если Объект.Наименование <> НовоеНаименование Тогда

Объект.Наименование = НовоеНаименование;

Объект.Записать();

КонецЕсли;

КонецЦикла;

Обратите внимание на проверку «изменилось ли значение»: запись выполняется только при реальном изменении. Это ускоряет обработку и не создаёт лишних движений в механизмах обмена и версионирования. Перед массовым запуском обработку проверяют на копии базы или на ограниченной выборке.

Дополнительно стоит найти источник загрязнения: если пробелы попадают из загрузки Excel или обмена, исправьте саму процедуру загрузки, иначе через неделю данные снова будут грязными. Точку входа защищают тем же СокрЛП при записи новых элементов.

Типичные ошибки
01
Ожидать, что СокрЛП уберёт неразрывный пробел — она его не трогает, сравнение продолжает не сходиться.
02
Применять СтрЗаменить(Поле, " ", "") к осмысленным наименованиям — слова склеиваются в одну строку.
03
Соединять большие таблицы по СокрЛП(Поле) без необходимости — теряется индекс, запрос резко замедляется.
04
Перезаписывать все элементы справочника без проверки на изменение — лишняя нагрузка и мусор в обменах данными.
05
Чистить данные только в отчёте, не исправляя источник загрузки — проблема возвращается при следующем обмене.

Проверка результата

После очистки — в запросе или обработкой — результат нужно проверить, а не полагаться на визуальный осмотр. Самый надёжный способ в запросе — сравнить длину исходной и обработанной строки через функцию СтрДлина: если длины различаются, пробелы были и удалены.

Контрольные точки

Как проверить результат

Сравнение очищенных значений
Норма

СокрЛП(Поле1) = СокрЛП(Поле2) даёт Истина для визуально одинаковых строк

Тревожный признак

Сравнение по-прежнему Ложь — ищите неразрывный пробел или другие невидимые символы

Длина строки до и после
Норма

СтрДлина уменьшилась ровно на число удалённых пробельных символов

Тревожный признак

Длина не изменилась, хотя пробелы «видны» — это неразрывный пробел

Дубли в справочнике
Норма

Группировка по СокрЛП(Наименование) не даёт групп с количеством больше одного

Тревожный признак

Дубли остались — различия не только в пробелах (регистр, ё/е, скрытые символы)

Если после всех замен строки всё равно не совпадают, выведите посимвольные коды обеих строк во встроенном языке функцией КодСимвола и сравните. Так находят табуляции (код 9), переводы строк (коды 10 и 13) и другие невидимые символы, которые мешают сравнению.

Итог

Что важно запомнить

Пробелы по краям убирают СокрЛП прямо в запросе, пробелы внутри — СтрЗаменить, а неразрывный пробел — только через СтрЗаменить с символом 160, переданным параметром. Для регулярных сравнений данные лучше один раз очистить в базе, чтобы не терять индексы и производительность.

Частые вопросы

Почему СокрЛП в запросе не убирает пробел в конце строки?

Скорее всего, это не обычный пробел, а неразрывный (код 160) — СокрЛП его не удаляет. Проверьте код последнего символа функцией КодСимвола во встроенном языке и добавьте в запрос СтрЗаменить с параметром Символ(160).

Можно ли в запросе 1С заменить несколько пробелов подряд на один?

Надёжного способа в чистом языке запросов нет: вложенные СтрЗаменить двойного пробела на одинарный не гарантируют результат при трёх и более пробелах. Такую нормализацию выполняют в цикле во встроенном языке после выборки данных.

Удаляет ли СокрЛП табуляции и переводы строк?

Да, СокрЛП удаляет по краям строки не только пробелы, но и символы табуляции, перевода строки и возврата каретки. Однако внутри строки эти символы останутся — их придётся убирать через СтрЗаменить.

Сильно ли замедляет запрос использование СокрЛП в соединении?

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

Как убрать пробелы в запросе к таблице значений?

Точно так же: поместите таблицу значений во временную таблицу через параметр и примените СокрЛП или СтрЗаменить к нужным полям в тексте запроса. Либо обработайте колонку таблицы значений в цикле до передачи в запрос.

Чем отличается СокрЛП в запросе от СокрЛП в коде?

Логика одинакова, но в запросе функция выполняется на стороне СУБД над всеми выбранными строками сразу, а в коде — по одной строке в цикле. Для больших выборок обработка в запросе обычно быстрее.