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

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

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

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

Лишние пробелы в строковых данных — одна из самых частых причин «непонятного» поведения запросов 1С: соединения таблиц не срабатывают, поиск по наименованию не находит элемент, а сгруппированные данные распадаются на несколько строк. Визуально «Товар А» и «Товар А » выглядят одинаково, но для платформы это разные значения.

Проблема усугубляется тем, что пробелы попадают в базу разными путями: при копировании из Excel или веб-страниц, при загрузке из внешних файлов, при ручном вводе с опечатками. Неразрывный пробел (символ 160) вообще не виден глазом и не удаляется стандартным СокрЛП.

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

Почему лишние пробелы ломают запросы 1С

Строковое сравнение в 1С побайтовое: «Контрагент» и «Контрагент » (с пробелом в конце) — разные значения. Поэтому условие ГДЕ Наименование = &Наименование не найдёт элемент, если в параметре или в базе есть хвостовой пробел. То же касается соединений таблиц по строковым полям — связь просто не установится.

Отдельная ловушка — группировка. Запрос с СГРУППИРОВАТЬ ПО по строковому полю выдаст две строки результата вместо одной, если в данных встречаются варианты с пробелами и без. В отчёте это выглядит как дубли контрагентов или номенклатуры.

Ещё одна точка отказа — поиск по коду или артикулу. Если код заполнен с ведущими пробелами, автоматический подбор и обмены данными начинают создавать дубли справочников, потому что проверка «уже существует» не находит имеющийся элемент.

Запрос не находит заведомо существующий элементВероятны хвостовые пробелы в параметре или данных

Сравните длину строки через СтрДлина с ожидаемой

Дубли в группировке отчётаВ данных есть варианты с пробелами и без

Выполните запрос с ПОДОБНО "% " и "% %" по полю

Поиск по коду создаёт дубли справочникаКоды содержат ведущие или внутренние пробелы

Проверьте коды на символы 32 и 160

СокрЛП, СокрЛ и СокрП: базовая очистка параметров

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

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

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

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Ссылка

|ИЗ

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

|ГДЕ

| Номенклатура.Наименование = &Наименование";

Запрос.УстановитьПараметр("Наименование", СокрЛП(НаименованиеИзФормы));

Важно понимать ограничение: СокрЛП не трогает пробелы внутри строки. «Иванов Иван» с двойным пробелом после очистки останется с двойным пробелом. Для внутренних пробелов нужна замена, о ней ниже.

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

СтрЗаменить: убираем двойные и неразрывные пробелы

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

Строка = "Иванов   Иван   Иванович";

Пока СтрНайти(Строка, " ") > 0 Цикл

Строка = СтрЗаменить(Строка, " ", " ");

КонецЦикла;

Строка = СокрЛП(Строка);

Неразрывный пробел удаляется заменой по коду символа: СтрЗаменить(Строка, Символ(160), " ") — сначала превращаем его в обычный пробел, затем обрабатываем стандартно. Также полезно чистить табуляции Символ(9) и неразрывные дефисы, если данные приходят из веб-источников.

Такую обработку удобно оформить как отдельную функцию «НормализоватьСтроку» в общем модуле и вызывать её во всех местах, где строки уходят в запросы или записываются в базу. Это дешевле, чем чинить последствия дублей.

Порядок действий при очистке строки
  1. 1
    Определите источник строки: ввод пользователя, файл, внешняя система
  2. 2
    Замените неразрывные пробелы: СтрЗаменить(Строка, Символ(160), " ")
  3. 3
    Сведите повторные пробелы циклом замены двойного пробела на одинарный
  4. 4
    Примените СокрЛП для удаления краевых пробелов
  5. 5
    Передайте очищенное значение в параметр запроса
  6. 6
    Проверьте результат запроса на тестовом примере с заведомо «грязной» строкой

Как обработать пробелы прямо в тексте запроса

Язык запросов 1С не содержит функций СокрЛП или замены подстроки. Единственный инструмент поиска по шаблону — оператор ПОДОБНО со спецсимволами: % (любая последовательность), _ (один символ), квадратные скобки для диапазонов.

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

ВЫБРАТЬ

Номенклатура.Ссылка КАК Ссылка,

Номенклатура.Наименование КАК Наименование

ИЗ

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

ГДЕ

(Номенклатура.Наименование ПОДОБНО "% %"

ИЛИ Номенклатура.Наименование ПОДОБНО " %"

ИЛИ Номенклатура.Наименование ПОДОБНО "% ")

Ещё один приём — сравнение с приведением: если нужно сопоставить строки без учёта краевых пробелов прямо в соединении, иногда применяют сравнение через ПОДОБНО в обе стороны, но это тяжёлая операция без использования индексов. На больших таблицах такой запрос будет работать медленно, поэтому правильный путь — чистить сами данные.

Исправление хранимых данных обработкой

Если пробелы уже сидят в справочниках, единственное надёжное решение — разовая обработка, которая выбирает проблемные элементы и перезаписывает их очищенными значениями. Выборку делают запросом с ПОДОБНО, очистку — СокрЛП и СтрЗаменить.

Выборка = Запрос.Выполнить().Выбрать();

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

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

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

Объект.ОбменДанными.Загрузка = Истина; // если не нужны проверки и подписки

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

КонецЦикла;

Несколько обязательных предосторожностей. Перед запуском сделайте резервную копию или выгрузку базы. Решите, нужен ли режим ОбменДанными.Загрузка: он отключает бизнес-логику и подписки, что быстрее, но может нарушить связанные механизмы и обмены. Для больших объёмов записывайте порциями с транзакциями, чтобы при сбое не получить частично обработанные данные без возможности понять, где остановка.

После исправления проверьте, не появились ли дубли наименований: две разные карточки «Товар А» и «Товар А » после очистки станут одинаковыми по строке. Это нормально для поиска, но если наименование участвует в уникальности, потребуется ручное решение по объединению элементов.

Перед массовой обработкой запустите её в режиме «только отчёт»: выведите список элементов, которые будут изменены, со старым и новым значением. На реальных базах так часто находятся записи, где пробел значим (например, в кодах с фиксированным форматом), и их приходится исключать из обработки.
ПЗ
Практическое замечание

Профилактика: как не пускать пробелы в базу

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

Второй уровень — точки входа данных извне. Все загрузки из Excel, CSV, веб-сервисов и обменов должны пропускать строковые поля через функцию очистки. Именно внешние источники приносят неразрывные пробелы и табуляции, которые потом годами мешают поиску.

Третий уровень — периодический контроль. Разовый запрос с ПОДОБНО по ключевым справочникам (номенклатура, контрагенты, физлица) покажет, появляются ли новые записи с пробелами, и поможет найти обходной путь ввода, который не закрыт очисткой.

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

FAQ

Есть ли в языке запросов 1С аналог СокрЛП?

Нет. Язык запросов не содержит функций обрезки или замены строк. Доступен только поиск по шаблону ПОДОБНО. Поэтому очистку выполняют на встроенном языке до передачи параметра или исправляют сами данные обработкой.

Почему СокрЛП не удаляет пробел, который я вижу в конце строки?

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

Как найти в справочнике все записи с лишними пробелами?

Запросом с условием ПОДОБНО: шаблон "% %" находит двойные пробелы внутри, " %" — ведущий пробел, "% " — хвостовой. Объедините условия через ИЛИ и выведите ссылку и значение поля для анализа.

Можно ли убрать пробелы в соединении таблиц запроса?

Технически можно сравнивать через ПОДОБНО, но такое соединение не использует индексы и на больших таблицах работает очень медленно. Правильное решение — очистить хранимые данные или параметры до выполнения запроса.

Опасно ли массово перезаписывать справочник обработкой?

Да, без подготовки. Обязательно сделайте резервную копию, сначала запустите обработку в режиме отчёта без записи, учтите, что после очистки могут появиться одинаковые наименования у разных элементов, и решите, нужны ли подписки и бизнес-логика при записи.

Как свести несколько пробелов подряд к одному?

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

Итог

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

В запросах 1С пробелы убирают не средствами языка запросов, а на встроенном языке: СокрЛП для краёв, СтрЗаменить с циклом для внутренних и неразрывных пробелов. ПОДОБНО используйте для поиска «грязных» записей, а хранимые данные исправляйте разовой обработкой после резервного копирования. Лучшая защита — нормализация строк на входе: в формах, загрузках и обменах.