Как убрать пробелы по краям строки прямо в тексте запроса 1С
Содержание
В запросе 1С пробелы слева и справа убирает функция СОКРЛП(Строка): например, ГДЕ СОКРЛП(Контрагенты.ИНН) = &ИНН. Она доступна в языке запросов начиная с платформы 8.3.20. На более старых платформах такой функции в запросах нет — там строку чистят до запроса (параметр) или после него (в коде).
Чаще всего функцию СокрЛП в запросах 1С используют для поиска по ИНН и артикулам, сопоставления загрузок из Excel и чистки дублей в ОБЪЕДИНИТЬ. Главный нюанс — скорость: функция над полем в условии отключает индекс, поэтому на больших таблицах строку лучше очистить один раз во временной таблице.
Синтаксис СОКРЛП в языке запросов и требования к платформе
Функция принимает одно выражение строкового типа и возвращает ту же строку без начальных и конечных пробелов. Пробелы внутри строки не трогает.
ВЫБРАТЬ
Контрагенты.Ссылка КАК Контрагент,
СОКРЛП(Контрагенты.Наименование) КАК Наименование,
СОКРЛП(Контрагенты.ИНН) КАК ИНН
ИЗ
Справочник.Контрагенты КАК Контрагенты
Что нужно знать о синтаксисе:
- 🔤 Регистр не важен:
СОКРЛП,СокрЛПисокрлпзапрос поймёт одинаково. Английский вариант —TRIMALL. - 📦 Аргументом может быть поле, параметр, строковый литерал или результат другой функции:
СОКРЛП(ПОДСТРОКА(Т.Комментарий, 1, 100)). - 🧩 Функцию можно вкладывать в другие строковые функции, появившиеся в той же версии:
ВРЕГ(СОКРЛП(Т.Артикул)),ДЛИНАСТРОКИ(СОКРЛП(Т.Код)).
Почему запрос не принимает СОКРЛП
Если при выполнении или в конструкторе запроса появляется синтаксическая ошибка на строке с СОКРЛП, проверьте две вещи:
- Версию платформы:
Справка → О программе. Номер должен быть не ниже 8.3.20. - Режим совместимости конфигурации: в Конфигураторе откройте свойства корня конфигурации, раздел «Совместимость». Если там стоит режим версии ниже 8.3.20, новые функции языка запросов могут быть недоступны, даже если сама платформа свежая.
Режим совместимости типовой конфигурации вручную не меняйте. Его поднимает разработчик конфигурации в очередном релизе. Если функция нужна в отчёте, а режим старый — используйте обходные способы из раздела про старые платформы.
Чем СОКРЛП отличается от СОКРЛ и СОКРП
В языке запросов три функции обрезки, как и во встроенном языке. Разница — с какой стороны они режут.
| Функция | English | Что убирает | Пример: " А-15 " |
|---|---|---|---|
СОКРЛ | TRIML | пробелы слева | "А-15 " |
СОКРП | TRIMR | пробелы справа | " А-15" |
СОКРЛП | TRIMALL | пробелы с обеих сторон | "А-15" |
Когда какую брать:
- ✂️
СОКРЛП— почти всегда для сравнения и группировки. Вы не знаете, с какой стороны пользователь поставил лишний пробел. - ⬅️
СОКРЛ— когда справа пробелы значимы или их там гарантированно нет, а слева строку «сдвинули» при вставке из Excel. - ➡️
СОКРП— для строк фиксированной длины, которые хранятся с добивкой пробелами справа, если левый край трогать нельзя.
Пробелы в середине ("ООО Ромашка" с двумя пробелами) ни одна из трёх функций не уберёт. Для этого есть СТРЗАМЕНИТЬ:
СТРЗАМЕНИТЬ(СОКРЛП(Контрагенты.ИНН), " ", "") КАК ИННБезПробелов
Так удобно нормализовать ИНН, телефоны и артикулы, где пробелов внутри быть не должно вовсе.
СокрЛП в условиях ГДЕ: поиск по реквизиту с лишними пробелами
Классическая ситуация: пользователь ищет контрагента по ИНН 7701234567, а в карточке ИНН записан как " 7701234567" — с пробелом после вставки из письма. Прямое сравнение такую запись не найдёт.
Очистка поля в условии
ВЫБРАТЬ
Контрагенты.Ссылка
ИЗ
Справочник.Контрагенты КАК Контрагенты
ГДЕ
СОКРЛП(Контрагенты.ИНН) = &ИНН
Параметр тоже очистите, но уже в коде, до запроса — это бесплатно:
Запрос.УстановитьПараметр("ИНН", СокрЛП(ИННИзФормы));
Очистка вместе с ПОДОБНО
Для поиска по части строки функцию комбинируют с оператором ПОДОБНО:
ГДЕ
СОКРЛП(Номенклатура.Артикул) ПОДОБНО &Шаблон
Если шаблон задан как "А-15%", запрос найдёт и "А-150", и " А-15Б". Без СОКРЛП вторая строка выпала бы из результата из-за пробелов в начале.
Как найти записи с лишними пробелами
Прежде чем бороться с последствиями, полезно увидеть масштаб. Запрос-фильтр для поиска «грязных» наименований:
ВЫБРАТЬ
Номенклатура.Ссылка,
Номенклатура.Наименование
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Наименование <> СОКРЛП(Номенклатура.Наименование)
Ведущие пробелы такое условие ловит надёжно. С хвостовыми сложнее: часть СУБД при сравнении строк не учитывает пробелы в конце, и запись с пробелом только справа может не попасть в выборку. Для полной проверки сравнивайте значения в коде, где правила сравнения не зависят от СУБД:
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если Выборка.Наименование <> СокрЛП(Выборка.Наименование) Тогда
Сообщить("Лишние пробелы: " + Выборка.Наименование);
КонецЕсли;
КонецЦикла;
Соединение и объединение таблиц по очищенной строке
Самое частое применение СокрЛП в запросах 1С — сопоставление данных из двух источников, где ключом служит строка: артикул, ИНН, номер договора.
Сопоставление загружаемой таблицы со справочником
Типовой сценарий: из Excel пришла таблица цен по артикулам, нужно найти номенклатуру. Таблица значений передаётся в запрос параметром и помещается во временную таблицу.
ВЫБРАТЬ
СОКРЛП(Загрузка.Артикул) КАК Артикул,
Загрузка.Цена КАК Цена
ПОМЕСТИТЬ ВТ_Загрузка
ИЗ
&ТаблицаЗагрузки КАК Загрузка
ИНДЕКСИРОВАТЬ ПО
Артикул
;
////////////////////////////////////////////////////////////
ВЫБРАТЬ
СОКРЛП(Номенклатура.Артикул) КАК Артикул,
Номенклатура.Ссылка КАК Номенклатура
ПОМЕСТИТЬ ВТ_Номенклатура
ИЗ
Справочник.Номенклатура КАК Номенклатура
ИНДЕКСИРОВАТЬ ПО
Артикул
;
////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_Загрузка.Артикул,
ВТ_Загрузка.Цена,
ВТ_Номенклатура.Номенклатура
ИЗ
ВТ_Загрузка КАК ВТ_Загрузка
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Номенклатура КАК ВТ_Номенклатура
ПО ВТ_Загрузка.Артикул = ВТ_Номенклатура.Артикул
Здесь два приёма, без которых запрос на больших объёмах начнёт тормозить:
- Строки очищаются один раз, при помещении во временные таблицы, а не в условии
ПО. - Временные таблицы индексируются по очищенному полю, и соединение идёт по индексу.
У таблицы значений, которую передают в запрос через ИЗ &ТаблицаЗагрузки, колонки должны быть типизированы. Создавайте колонку как ТЗ.Колонки.Добавить("Артикул", Новый ОписаниеТипов("Строка",, Новый КвалификаторыСтроки(50))). С нетипизированной колонкой запрос выдаст ошибку.
Строки без пары (ВТ_Номенклатура.Номенклатура ЕСТЬ NULL) — это артикулы, которых нет в базе. Их удобно вывести отдельным списком для проверки.
ОБЪЕДИНИТЬ без дублей
ОБЪЕДИНИТЬ без ВСЕ убирает одинаковые строки. Но "ООО Ромашка" и "ООО Ромашка " для него — разные значения, и в итоге получится два «одинаковых» контрагента. Чистите поле в каждой части объединения:
ВЫБРАТЬ
СОКРЛП(Поступление.НомерВходящегоДокумента) КАК Номер
ИЗ
Документ.ПоступлениеТоваровУслуг КАК Поступление
ОБЪЕДИНИТЬ
ВЫБРАТЬ
СОКРЛП(Счет.НомерВходящегоДокумента)
ИЗ
Документ.СчетФактураПолученный КАК Счет
Имена документов и реквизитов здесь — для иллюстрации; в вашей конфигурации сверьте их в дереве метаданных конструктора запроса.
Скорость: функция в запросе, очистка в коде или чистые данные
Любая функция над полем в ГДЕ или ПО мешает СУБД использовать индекс по этому полю. Условие СОКРЛП(Контрагенты.ИНН) = &ИНН заставит пройти всю таблицу, даже если ИНН проиндексирован. На справочнике в 5 000 записей разницы не заметно. На регистре в миллионы строк — заметно.
| Способ | Когда подходит | Минусы |
|---|---|---|
СОКРЛП прямо в ГДЕ / ПО | разовые выборки, небольшие справочники | полный просмотр таблицы, индекс не работает |
Очистка при помещении во ВТ + ИНДЕКСИРОВАТЬ ПО | сопоставление двух наборов, загрузки | одна полная выборка всё равно нужна |
| Очистка результата в коде | старая платформа, вывод в форму | данные гоняются на сервер приложения целиком |
| Очистка при записи объекта | постоянная проблема с одним реквизитом | нужна доработка, плюс разовая чистка старых записей |
Чистить данные при записи
Надёжнее всего устранить причину: не давать сохранять строки с пробелами по краям. В типовой конфигурации это делают через расширение, а не правкой модуля объекта:
&Перед("ПередЗаписью")
Процедура Расш1_ПередЗаписью(Отказ)
ИНН = СокрЛП(ИНН);
Наименование = СокрЛП(Наименование);
КонецПроцедуры
После этого запросы снова могут сравнивать поле напрямую и пользоваться индексом. Уже накопленные «грязные» записи нужно перезаписать отдельной обработкой.
Массовую перезапись справочника выполняйте только после резервной копии базы и в нерабочее время: при записи срабатывают подписки и регистрация изменений для обменов, а на распределённых базах это уйдёт в узлы.
NULL, пустые строки и строки неограниченной длины
NULL на входе
Если поле пришло из левого соединения и пары не нашлось, его значение — NULL. СОКРЛП(NULL) тоже даёт NULL, а не пустую строку. Сравнение NULL с чем угодно не истинно, поэтому строка выпадет из условия.
Если в результате нужна пустая строка, оберните выражение:
ЕСТЬNULL(СОКРЛП(Контрагенты.ИНН), "") КАК ИНН
Для проверки «реквизит не заполнен или состоит из одних пробелов» удобна такая запись:
ГДЕ
ЕСТЬNULL(СОКРЛП(Контрагенты.ИНН), "") = ""
Пустая строка и строка из пробелов
Строка " " после СОКРЛП превращается в "". Это удобно: пустые и «пробельные» значения перестают различаться в группировках и не создают отдельную строку отчёта с пустым на вид ключом.
Поля неограниченной длины
Реквизиты вида «Комментарий» в типовых конфигурациях часто имеют неограниченную длину. Такие поля в запросе нельзя сравнивать, группировать и упорядочивать. Сначала приведите их к строке фиксированной длины:
СОКРЛП(ВЫРАЗИТЬ(Документ.Комментарий КАК СТРОКА(200))) КАК Комментарий
ВЫРАЗИТЬ обрежет текст до 200 символов, а СОКРЛП уберёт пробелы по краям уже от этого фрагмента.
Поля составного и нестрокового типа
СОКРЛП рассчитана на строку. Если поле составного типа (например, «Субконто» может быть строкой, ссылкой или числом), выделите строковую часть через ВЫРАЗИТЬ(Поле КАК СТРОКА(100)). Для ссылок нужно брать представление или конкретный реквизит, а не обрезать саму ссылку.
Табуляции и переносы строк
Во встроенном языке СокрЛП отсекает все незначащие символы, включая табуляцию и переводы строки. В запросе функция выполняется на стороне СУБД, и на такое поведение для непробельных символов не рассчитывайте. Если в данных встречаются табуляции или неразрывные пробелы из Excel, уберите их явно через СТРЗАМЕНИТЬ или почистите в коде.
Как обойтись без СОКРЛП в запросах на платформе до 8.3.20
На старых платформах в языке запросов нет ни СОКРЛП, ни СТРЗАМЕНИТЬ, ни ДЛИНАСТРОКИ. Задачу решают тремя способами.
- Очистить параметр в коде.
Запрос.УстановитьПараметр("ИНН", СокрЛП(ИНН))— помогает, когда пробелы в искомом значении, а в базе данные чистые. - Искать через ПОДОБНО с запасом. Условие
Контрагенты.ИНН ПОДОБНО "%" + &ИНН + "%"найдёт значение с пробелами по краям. Минус — найдёт и лишнее, если искомая строка входит в более длинную, поэтому результат придётся отфильтровать в коде. - Дочистить результат после запроса. Выгрузите результат в таблицу значений и пройдите по ней циклом, применяя
СокрЛПк нужной колонке. Для сопоставления двух наборов очистите ключевую колонку обоих и сравнивайте уже в коде, черезНайтиилиНайтиСтрокитаблицы значений.
ТЗ = Запрос.Выполнить().Выгрузить();
Для Каждого Строка Из ТЗ Цикл
Строка.Артикул = СокрЛП(Строка.Артикул);
КонецЦикла;
ТЗ.Индексы.Добавить("Артикул");
Индекс по колонке ускорит последующие НайтиСтроки на больших таблицах.
Частые ошибки при использовании СокрЛП в запросах
- ❌ Функция в условии
ПОна больших таблицах. Соединение двух регистров поСОКРЛПс обеих сторон превращается в перебор «каждый с каждым». Вынесите очистку во временные таблицы с индексом. - ❌ Очистили поле, но не параметр.
СОКРЛП(Т.ИНН) = &ИННне найдёт запись, если пробел пришёл в самом параметре из формы. - ❌ Забыли про
ЕСТЬNULLпосле левого соединения. Строки без пары молча выпадают из условия, и итог отчёта оказывается меньше ожидаемого. - ❌ Ждали, что исчезнут двойные пробелы внутри.
СОКРЛПрежет только края. Для середины —СТРЗАМЕНИТЬ. - ❌ Группировка по исходному полю. Если вы выбираете
СОКРЛП(Т.Артикул) КАК Артикул, вСГРУППИРОВАТЬ ПОуказывайте то же выражениеСОКРЛП(Т.Артикул), а не исходное поле — иначе группировка пойдёт по неочищенному значению и «одинаковые» артикулы разойдутся по разным строкам.
Частые вопросы
Можно ли использовать СОКРЛП в системе компоновки данных?
СОКРЛП меняет данные в базе?
Работает ли СОКРЛП в файловой базе?
Можно ли сортировать по СОКРЛП?
УПОРЯДОЧИТЬ ПО СОКРЛП(Т.Наименование). Строки с пробелом в начале перестанут «всплывать» в начало списка.Как убрать в запросе не пробелы, а нули в начале кода?
СОКРЛП для этого не подходит, она убирает только пробелы. Ведущие нули удобнее отбросить в коде или сравнивать код целиком, с нулями, как он хранится в базе.