Разработка и Конфигурация · 10 мин
Как убрать пробелы в строке в запросе 1С
Как убрать пробелы в строке в запросе 1С: функция СОКРЛП, замена двойных пробелов, очистка неразрывных пробелов и работа с пробелами в запросах и коде.
Пробелы в строковых значениях — частая причина ошибок сравнения, дублирования элементов справочников и некорректных итогов в отчётах 1С. Например, контрагент «ООО Ромашка» и «ООО Ромашка » с пробелом в конце для системы — две разные строки, хотя для пользователя это одно и то же значение.
В языке запросов 1С есть встроенная функция СОКРЛП(), которая убирает пробельные символы слева и справа от строки. Однако она не трогает пробелы внутри строки — для их удаления приходится комбинировать функции запроса или выносить обработку в код на встроенном языке.
Ниже разобраны основные приёмы: обрезка краевых пробелов в запросе, удаление двойных и внутренних пробелов, работа с неразрывными пробелами, а также типичные ошибки при сравнении строк и способы проверить результат.
Функция СОКРЛП в запросе: базовый приём
Функция СОКРЛП() отсекает все пробельные символы в начале и в конце строки: обычные пробелы, табуляции, переводы строк. Это основной инструмент очистки строк непосредственно в тексте запроса.
ВЫБРАТЬ
СОКРЛП(Контрагенты.Наименование) КАК Наименование
ИЗ
Справочник.Контрагенты КАК Контрагенты
Функцию можно применять не только в списке выборки, но и в условиях отбора и соединениях. Это полезно, когда нужно сопоставить данные из разных источников, где строки могут отличаться краевыми пробелами:
ВЫБРАТЬ
Товары.Номенклатура КАК Номенклатура
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
СОКРЛП(Товары.Номенклатура.Артикул) = &Артикул
Учтите: применение функции к полю в условии отбора отключает использование индекса по этому полю. На больших таблицах это заметно замедляет запрос, поэтому по возможности очищайте данные при записи, а не при каждом чтении.
Как убрать пробелы внутри строки
В языке запросов 1С нет функции замены подстроки, поэтому удалить пробелы в середине строки непосредственно в запросе нельзя. Стандартное решение — обработка результата запроса в коде функцией СтрЗаменить():
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ЧистаяСтрока = СтрЗаменить(Выборка.Наименование, " ", "");
КонецЦикла;
Такой код убирает вообще все пробелы, включая те, что стоят между словами. Это уместно для артикулов, кодов, номеров документов и телефонов, но обычно вредно для наименований, где пробелы между словами нужны.
Замена двойных пробелов на одинарные
Если задача — привести «ООО Ромашка» к «ООО Ромашка», применяют циклическую замену двойного пробела на одинарный, пока дубли не исчезнут:
Пока СтрНайти(Строка, " ") > 0 Цикл
Строка = СтрЗаменить(Строка, " ", " ");
КонецЦикла;
Строка = СокрЛП(Строка);
Этот приём безопасен для любых строк: он сохраняет одиночные пробелы между словами и убирает только повторные. После цикла обязательно примените СокрЛП, чтобы обрезать краевые пробелы.
Пока СтрНайти(Строка, " ") > 0 Цикл
Строка = СтрЗаменить(Строка, " ", " ");
КонецЦикла;
Строка = СокрЛП(Строка);Очистка данных перед записью в базу
Самая надёжная стратегия — не чистить строки в каждом запросе, а гарантировать, что в базу попадают уже нормализованные значения. Для этого обработку размещают в подписке на событие ПередЗаписью или ПриЗаписи справочника либо в процедуре обработки заполнения.
Процедура ПередЗаписью(Отказ)
Наименование = СокрЛП(Наименование);
Пока СтрНайти(Наименование, " ") > 0 Цикл
Наименование = СтрЗаменить(Наименование, " ", " ");
КонецЦикла;
КонецПроцедуры
Такой подход особенно важен при обменах данными и загрузке из Excel: внешние источники регулярно присылают строки с хвостовыми пробелами. Если очистка происходит в одной точке входа, все последующие запросы и сравнения работают с чистыми данными.
Неразрывные пробелы и другие невидимые символы
Частая ловушка — неразрывный пробел (символ с кодом 160). Визуально он неотличим от обычного пробела, но СОКРЛП и СокрЛП его не удаляют, а сравнение строк даёт ложное неравенство. Такие символы часто приходят из веб-страниц, Excel и скопированного текста.
Удалить неразрывный пробел можно явной заменой через Символ(160):
Строка = СтрЗаменить(Строка, Символ(160), " ");
Строка = СокрЛП(Строка);
Аналогично обрабатывают табуляцию (Символ(9)), перевод строки (Символы.ПС) и возврат каретки (Символы.ВК). Если источник данных «грязный», имеет смысл заменить все эти символы на обычный пробел, а затем выполнить стандартную очистку.
Как обнаружить невидимые символы
Проверить, какие именно символы содержит строка, можно перебором кодов символов:
Для Позиция = 1 По СтрДлина(Строка) Цикл
Сообщить(КодСимвола(Строка, Позиция));
КонецЦикла;
Обычный пробел имеет код 32, неразрывный — 160, табуляция — 9. Увидев в начале или конце строки неожиданные коды, вы поймёте, почему СокрЛП «не работает».
Проверьте коды символов через КодСимвола()
Проверьте наличие символа 160 и пробелов между словами
Перенесите очистку на этап записи данных
Сравнение строк с учётом пробелов в условиях запроса
При соединении таблиц и сравнении строк в запросе пробелы играют решающую роль: «А-123» и «А-123 » не совпадут. Безопасный шаблон — приводить обе сравниваемые стороны к очищенному виду:
ВЫБРАТЬ
Данные.Контрагент КАК Контрагент
ИЗ
ВнешниеДанные КАК Данные
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты
ПО СОКРЛП(Данные.НаименованиеКонтрагента) = СОКРЛП(Контрагенты.Наименование)
Для регистронезависимого сравнения добавьте приведение регистра через ВРЕГ() или НРЕГ(). Помните, что пустая строка после СОКРЛП остаётся пустой строкой, а не становится NULL — проверки на ЕСТЬ NULL и на равенство "" это разные условия.
Сравнение вариантов
Быстро и просто для краевых пробелов; не убирает пробелы внутри и убивает индекс в условиях
Полный контроль: любые символы, двойные пробелы; требует обхода выборки и больше кода
Данные всегда чистые, запросы быстрые; нужно исправить уже накопленные данные отдельной обработкой
Массовое исправление уже накопленных данных
Если пробелы уже попали в базу, потребуется разовая обработка. Порядок действий: сделать резервную копию, написать обработку, которая выбирает элементы с пробелами, очищает реквизиты и записывает их, затем проверить результат на копии.
Найти «грязные» записи можно запросом сравнением поля с его очищенной версией:
ВЫБРАТЬ
Контрагенты.Ссылка КАК Ссылка
ИЗ
Справочник.Контрагенты КАК Контрагенты
ГДЕ
Контрагенты.Наименование <> СОКРЛП(Контрагенты.Наименование)
При записи очищенных элементов учитывайте, что сработают подписки на события и проверки заполнения. Иногда целесообразно использовать ОбменДанными.Загрузка = Истина, но это отключает контрольные механизмы — применяйте такой режим осознанно и только в разовой обработке.
Проверка результата очистки
После очистки убедитесь, что данные действительно приведены к нужному виду. Повторный запрос поиска «грязных» записей должен вернуть пустой результат — это главный критерий успеха.
Дополнительно проверьте несколько элементов вручную: откройте карточки, где раньше были пробелы, и сравните наименования с ожидаемыми. Если очистка затрагивала ключевые реквизиты, по которым строятся соединения, прогоните типовой отчёт и сверьте итоги с контрольными значениями до обработки.
Как проверить результат
Возвращает пустой результат
Остались записи с краевыми пробелами
Нет кодов 9, 32, 160 по краям
Присутствуют невидимые символы
Количество совпадений соответствует ожиданиям
Часть записей не соединяется
Часто задаваемые вопросы
Можно ли убрать все пробелы из строки прямо в запросе 1С?
Нет. В языке запросов есть только СОКРЛП, обрезающая пробелы по краям. Полное удаление пробелов делается в коде через СтрЗаменить(Строка, " ", "") после выполнения запроса.
Почему СокрЛП не убирает пробел в конце строки?
Скорее всего, это не обычный пробел, а неразрывный пробел (код 160) или табуляция. Проверьте коды символов функцией КодСимвола и замените такие символы явно через СтрЗаменить(Строка, Символ(160), "").
Чем СОКРЛП в запросе отличается от СокрЛП в коде?
Логика одинаковая — обе функции обрезают пробельные символы по краям строки. Различие в месте применения: СОКРЛП работает на стороне СУБД внутри запроса, а СокрЛП — в коде встроенного языка над уже полученными значениями.
Замедляет ли СОКРЛП выполнение запроса?
В списке выборки влияние незначительно. Но если функция применена к полю в условии отбора или соединения, СУБД не сможет использовать индекс по этому полю, и на больших таблицах запрос заметно замедлится.
Как убрать пробелы в числе, загруженном как строка?
Сначала замените неразрывные пробелы и обычные пробелы на пустую строку через СтрЗаменить, затем преобразуйте результат функцией Число(). Перед преобразованием убедитесь, что в строке не осталось других посторонних символов.
Как предотвратить появление пробелов в будущем?
Добавьте очистку строковых реквизитов в подписку ПередЗаписью справочников и документов, а также нормализуйте данные в процедурах загрузки из внешних файлов и обменов — тогда в базу будут попадать уже чистые значения.
Что важно запомнить
Краевые пробелы в запросе убирает СОКРЛП, внутренние пробелы и неразрывные символы — только СтрЗаменить в коде. Надёжнее всего очищать строки при записи в базу, а массовое исправление старых данных выполнять после резервного копирования с проверкой результата.