Разработка и Конфигурация · 11 мин
Как убрать пробелы в запросе 1С 8
Как убрать пробелы в запросе 1С 8.3: СокрЛП, СтрЗаменить, обработка неразрывных пробелов, условия поиска и сравнение строк без лишних символов.
Лишние пробелы в строковых данных — одна из самых частых причин «неправильной» работы запросов в 1С: не находятся контрагенты при поиске по наименованию, дублируются элементы справочников, не срабатывают соединения таблиц. Пробелы бывают ведущими и замыкающими, двойными внутри строки и неразрывными, скопированными из Excel или Word. Для каждого случая в языке запросов 1С есть свой инструмент.
Главное ограничение, о котором нужно помнить сразу: язык запросов 1С не является языком обработки данных. Он умеет выбирать, группировать и соединять, а функции преобразования строк в нём минимальны. Поэтому часть задач решается встроенной функцией СокрЛП, часть — через сочетание функций, а часть — только выгрузкой результата и обработкой встроенным языком.
Ниже разобраны рабочие приёмы: от простого срезания краёв до удаления всех пробелов внутри строки и очистки значений при сравнении и поиске.
Функция СокрЛП в запросе: срезание крайних пробелов
Базовый инструмент — функция СокрЛП, доступная в языке запросов. Она удаляет незначащие символы (пробелы, табуляции, переносы строк) в начале и в конце строки, но не трогает пробелы внутри. Синтаксис простой: СокрЛП(Выражение).
Типичный пример — выборка наименований номенклатуры без лишних пробелов по краям:
ВЫБРАТЬ
СокрЛП(Номенклатура.Наименование) КАК Наименование
ИЗ
Справочник.Номенклатура КАК Номенклатура
Функцию можно применять не только в списке выборки, но и в условиях и соединениях. Например, чтобы найти контрагента по наименованию, введённому пользователем с клавиатуры (где почти всегда есть случайные пробелы), сравнивайте обработанные значения с обеих сторон:
ВЫБРАТЬ
Контрагенты.Ссылка
ИЗ
Справочник.Контрагенты КАК Контрагенты
ГДЕ
СокрЛП(Контрагенты.Наименование) = СокрЛП(&Наименование)
Важно понимать: СокрЛП не изменяет данные в базе. Она работает только в момент выполнения запроса, возвращая очищенное значение в выборку. Если нужно физически убрать пробелы в данных, потребуется обработка с записью изменённых объектов.
Как убрать все пробелы внутри строки: СтрЗаменить в запросе
Начиная с платформы 8.3.6, в языке запросов доступна функция СтрЗаменить. С её помощью можно удалить пробелы не только по краям, но и внутри строки — например, привести к единому виду ИНН, артикулы, телефоны, в которые пробелы попали при ручном вводе или импорте.
Чтобы убрать вообще все пробелы, вторым параметром указывается строка с пробелом, третьим — пустая строка:
ВЫБРАТЬ
СтрЗаменить(Контрагенты.ИНН, " ", "") КАК ИНН
ИЗ
Справочник.Контрагенты КАК Контрагенты
Если задача — заменить двойные пробелы одинарными, одним вызовом СтрЗаменить не обойтись: функция за один проход заменяет только те вхождения, которые нашла при первом сканировании. Для надёжного схлопывания повторных пробелов вызов вкладывают несколько раз: СтрЗаменить(СтрЗаменить(СтрЗаменить(Поле, " ", " "), " ", " "), " ", " "). Обычно двух-трёх вложений достаточно, но гарантии нет — при большом числе подряд идущих пробелов надёжнее обрабатывать строку встроенным языком.
Комбинация обеих функций даёт полную очистку: сначала убираются все внутренние пробелы или нормализуются повторы, затем СокрЛП срезает края:
ВЫБРАТЬ
СокрЛП(СтрЗаменить(СтрЗаменить(Номенклатура.Артикул, " ", " "), " ", " ")) КАК Артикул
ИЗ
Справочник.Номенклатура КАК Номенклатура
СтрЗаменить в запросе работает заметно медленнее, чем простая выборка, особенно на больших таблицах и длинных строках. Если функция используется в условии ГДЕ, индексы по этому полю перестают применяться — на больших справочниках проверяйте время выполнения на копии базы.
Неразрывные пробелы и другие невидимые символы
Самая коварная ситуация — когда СокрЛП и СтрЗаменить «не работают», а пробелы визуально остаются. Причина почти всегда в том, что в данных не обычный пробел (код 32), а неразрывный пробел (код 160), который попадает в базу при копировании из Excel, Word или веб-страниц. СокрЛП его не удаляет, и сравнение строк даёт ложное неравенство.
В запросе неразрывный пробел можно убрать через СтрЗаменить, указав символ по коду. Функции Символ() в языке запросов нет, поэтому символ передают параметром, сформированным во встроенном коде:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| СтрЗаменить(Контрагенты.Наименование, &НПП, "") КАК Наименование
|ИЗ
| Справочник.Контрагенты КАК Контрагенты";
Запрос.УстановитьПараметр("НПП", Символ(160));
Если в данных встречаются и обычные, и неразрывные пробелы, замены выполняют последовательно: сначала СтрЗаменить по Символ(160), затем по обычному пробелу, в конце — СокрЛП. Для диагностики полезно вывести коды символов проблемной строки обработкой во встроенном языке — так сразу видно, какие именно символы мешают сравнению.
Поиск и сравнение строк без учёта пробелов
Частая прикладная задача — не вывести очищенную строку, а найти записи, игнорируя различия в пробелах. Здесь есть два подхода. Первый — привести обе сравниваемые строки к одному виду прямо в условии, как показано выше: СокрЛП(Поле) = СокрЛП(&Параметр) или сравнение через СтрЗаменить, если пробелы могут быть внутри.
Второй подход — поиск по шаблону с оператором ПОДОБНО, когда нужно найти подстроку независимо от окружающих пробелов:
ВЫБРАТЬ
Контрагенты.Ссылка
ИЗ
Справочник.Контрагенты КАК Контрагенты
ГДЕ
Контрагенты.Наименование ПОДОБНО "%" + &Фрагмент + "%"
При соединении таблиц по строковым полям (например, при сопоставлении загруженных из файла данных со справочником) очищайте обе стороны соединения одинаково. Асимметричная обработка — когда слева СокрЛП, а справа нет — даёт потерю строк, которую сложно заметить на больших выборках.
Как проверить результат
Запись находится независимо от пробелов по краям
Запись не найдена — вероятно, пробелы неразрывные или внутри строки
Длина уменьшилась ровно на число удалённых пробелов
Длина не изменилась — символ не является обычным пробелом
Количество строк результата совпадает с ожидаемым по контрольному примеру
Часть строк потеряна — обработка сторон соединения различается
Очистка данных в базе, а не только в выборке
Когда пробелы мешают постоянно — ломают обмены, плодят дубли при загрузках — правильнее один раз почистить сами данные. Запросом это сделать нельзя: язык запросов не изменяет данные. Нужна обработка на встроенном языке, которая перебирает объекты, очищает строковые реквизиты и записывает их.
Типовая схема такой обработки: запросом выбираются ссылки на элементы, у которых значение отличается от очищенного (например, НЕ Наименование = СокрЛП(Наименование)), затем в цикле каждый объект получается методом ПолучитьОбъект(), реквизит обрабатывается функциями СокрЛП и СтрЗаменить встроенного языка, объект записывается. Запись выполняйте в транзакции порциями, а для больших объёмов — с контролем на тестовой копии.
- 1Сделайте резервную копию базы или выполняйте работу на копии
- 2Напишите запрос, выбирающий элементы, где значение отличается от СокрЛП(значение)
- 3В цикле по выборке получайте объект, очищайте реквизит СокрЛП и СтрЗаменить (включая Символ(160))
- 4Записывайте объект, при необходимости в режиме обмена данными для отключения лишней бизнес-логики
- 5Проверьте на контрольных примерах поиск, печатные формы и обмены после очистки
Ограничения языка запросов и альтернативы
Не все задачи очистки решаются в запросе. В языке запросов нет регулярных выражений, нет функции Символ(), нет циклов. Удалить произвольный набор символов (табуляции, переносы строк, спецсимволы) одной конструкцией нельзя — только цепочкой вложенных СтрЗаменить, что быстро становится громоздким и медленным.
Практические альтернативы: выгрузить результат запроса в таблицу значений и обработать строки встроенным языком с полным набором строковых функций; использовать СКД с вычисляемыми полями, где выражение пишется на встроенном языке; либо нормализовать данные один раз обработкой и дальше поддерживать чистоту на уровне ввода (например, обработкой заполнения или проверкой при записи).
Сравнение вариантов очистки
Быстро и просто, но убирает только крайние пробелы и не трогает неразрывные
Убирает пробелы внутри строки и любые заданные символы, но требует платформы 8.3.6+ и замедляет запрос
Полный контроль над символами и возможность изменить данные в базе, но требует написания кода и осторожности при записи
Подходит для отчётов: очистка на встроенном языке без изменения запроса, но только в рамках схемы компоновки
Частые ошибки при работе с пробелами в запросах
Наиболее распространённая ошибка — ожидание, что СокрЛП уберёт все пробелы. Функция работает только с краями строки, и двойные пробелы внутри наименования после неё остаются. Вторая типичная ошибка — игнорирование неразрывных пробелов: сравнение визуально одинаковых строк возвращает ложь, и разработчик долго ищет причину в логике запроса.
Ещё одна группа ошибок связана с производительностью и типами. Применение СокрЛП или СтрЗаменить к полю в условии соединения отключает использование индекса, и на больших таблицах запрос может выполняться в разы дольше. А при передаче параметра-строки неограниченной длины сравнение со строковым полем фиксированной длины иногда ведёт себя неожиданно — параметр стоит приводить через ВЫРАЗИТЬ или заранее обрабатывать во встроенном коде.
FAQ
Как убрать пробелы в начале и в конце строки в запросе 1С?
Используйте функцию СокрЛП(Поле) в списке выборки или в условии. Она удаляет пробелы, табуляции и переносы строк по краям, но не изменяет данные в базе — очищается только результат выборки.
Как удалить все пробелы внутри строки в запросе?
Функцией СтрЗаменить(Поле, " ", ""), доступной с платформы 8.3.6. Для схлопывания двойных пробелов в одинарные вызов функции вкладывают несколько раз, так как за один проход заменяются не все повторы.
Почему СокрЛП не убирает пробел, хотя он виден в строке?
Скорее всего, это неразрывный пробел с кодом 160, попавший в данные при копировании из Excel или web-страниц. Уберите его через СтрЗаменить с параметром Символ(160), переданным из встроенного кода.
Можно ли запросом физически очистить данные в справочнике?
Нет, язык запросов только читает данные. Для изменения значений нужна обработка на встроенном языке: выборка ссылок запросом, затем получение объектов, очистка реквизитов и запись — обязательно после теста на копии базы.
Влияет ли СокрЛП в условии запроса на скорость выполнения?
Да. Применение строковых функций к полю в условии или соединении отключает использование индекса по этому полю. На больших таблицах лучше заранее очистить данные обработкой, а в запросе сравнивать поля напрямую.
Что делать, если версия платформы ниже 8.3.6 и СтрЗаменить недоступна?
Используйте СокрЛП для крайних пробелов, а для очистки внутри строки выгрузите результат запроса в таблицу значений и обработайте строки функциями встроенного языка, где СтрЗаменить доступна вне зависимости от версии.
Что важно запомнить
Крайние пробелы в запросе 1С убирает СокрЛП, внутренние — СтрЗаменить (с платформы 8.3.6), неразрывные — замена по Символ(160) через параметр. Запрос не изменяет данные в базе: для постоянной очистки нужна обработка с записью объектов, предварительно проверенная на копии.