Разработка и Конфигурация · 12 мин
СокрЛП в запросе 1С: обрезка пробелов и строк неограниченной длины
Как использовать СокрЛП в запросе 1С: синтаксис, обрезка пробелов в строках, работа со строками неограниченной длины, типичные ошибки и примеры кода.
Функция СокрЛП в запросах 1С решает две практические задачи: убирает незначащие пробелы в начале и конце строки и позволяет корректно работать со строковыми реквизитами неограниченной длины. Вторая задача встречается даже чаще: поля типа «Строка(0)» нельзя напрямую сравнивать, группировать и использовать в соединениях, а оборачивание в СокрЛП превращает их в обычные строки ограниченной длины.
Тема возникает у разработчика обычно в момент ошибки «Неверные параметры в операции сравнения» или когда запрос с группировкой по текстовому полю внезапно перестаёт выполняться. Ниже разобраны синтаксис, ограничения платформы, рабочие приёмы и способы проверить результат.
Важно понимать: СокрЛП в языке запросов и одноимённая функция встроенного языка 1С — разные вещи. В запросе функция ограничена по поведению и не всегда делает то, что ожидает разработчик, привыкший к модулю. Именно из-за этой разницы возникает большинство ошибок.
Синтаксис СокрЛП в языке запросов
В языке запросов 1С доступны три родственные функции: СокрЛ (убирает пробелы слева), СокрП (справа) и СокрЛП (с обеих сторон). Синтаксис простой — функция принимает один строковый аргумент:
ВЫБРАТЬ
СокрЛП(Контрагенты.Наименование) КАК Наименование
ИЗ
Справочник.Контрагенты КАК Контрагенты
Результатом выражения будет строка. Если исходное поле имело тип «Строка» неограниченной длины, результат приобретает ограниченную длину — именно это свойство чаще всего используют на практике. Пробелы внутри строки (между словами) функция не трогает, как и во встроенном языке.
Функцию можно применять в секциях ВЫБРАТЬ, ГДЕ, ИМЕЮЩИЕ, в условиях соединений и в параметрах виртуальных таблиц — везде, где допустимо выражение над строковым полем.
Зачем СокрЛП применяют к строкам неограниченной длины
Главный сценарий — обход ограничений платформы. Поля типа «Строка(0)» (например, реквизиты «Комментарий», «Описание», «ДополнительнаяИнформация») нельзя использовать в условии равенства, в ГРУППИРОВКЕ, в УПОРЯДОЧИТЬ и в соединениях таблиц. Попытка сделать это приводит к ошибке исполнения запроса.
Оборачивание поля в СокрЛП решает проблему, потому что результат функции — уже строка ограниченной длины. Типичный пример — поиск дублей по описанию или сравнение текстовых полей двух таблиц:
ВЫБРАТЬ
СокрЛП(Товары.Описание) КАК Описание,
КОЛИЧЕСТВО(*) КАК КоличествоДублей
ИЗ
Справочник.Номенклатура КАК Товары
СГРУППИРОВАТЬ ПО
СокрЛП(Товары.Описание)
ИМЕЮЩИЕ
КОЛИЧЕСТВО(*) > 1
Тот же приём работает в соединениях: СокрЛП(Таблица1.Комментарий) = СокрЛП(Таблица2.Комментарий). Без преобразования платформа отклонит такой запрос ещё на этапе проверки в консоли запросов.
СокрЛП против ВЫРАЗИТЬ: что выбрать
Обе конструкции превращают неограниченную строку в ограниченную, но ведут себя по-разному. СокрЛП дополнительно удаляет краевые пробелы и не даёт управлять итоговой длиной. ВЫРАЗИТЬ(Поле КАК Строка(N)) позволяет задать длину явно, но пробелы не трогает.
Если задача — только сделать поле пригодным для сравнения или группировки, предпочтительнее ВЫРАЗИТЬ: поведение прозрачнее, длина задана явно, и в плане запроса выражение читается однозначно. Если дополнительно нужно нормализовать данные (убрать случайные пробелы при сравнении наименований), уместен СокрЛП.
| Критерий | СокрЛП(Поле) | ВЫРАЗИТЬ(Поле КАК Строка(N)) |
|---|---|---|
| Удаление краевых пробелов | Да | Нет |
| Управление итоговой длиной | Нет (предел платформы) | Да, задаётся вручную |
| Пригодность для группировки | Да | Да |
| Риск безмолвной обрезки длинного текста | Есть | Есть, но точка обрезки контролируется |
Сравнение вариантов
Подходит, когда нужно одновременно убрать пробелы и сделать строку сравнимой. Ограничение: итоговая длина не контролируется разработчиком.
Подходит для чистого приведения типа с явной длиной. Пробелы не удаляются — при необходимости комбинируется с СокрЛП.
Подходит, когда нужен фиксированный фрагмент с начала строки, например первые 100 символов описания для группировки.
Практические примеры использования
Поиск контрагента по наименованию без учёта пробелов
Классическая ситуация: пользователь вводит наименование с лишним пробелом в конце, и сравнение «в лоб» не находит элемент справочника. Нормализация обеих сторон сравнения решает проблему:
ВЫБРАТЬ
Контрагенты.Ссылка
ИЗ
Справочник.Контрагенты КАК Контрагенты
ГДЕ
СокрЛП(Контрагенты.Наименование) = СокрЛП(&Наименование)
Учтите, что такой запрос не сможет использовать индекс по наименованию, потому что функция применяется к полю. На больших таблицах это означает полное сканирование. Альтернатива — очищать параметр на стороне кода (СокрЛП во встроенном языке) и сравнивать с необработанным полем, если данные в базе уже чистые.
Сравнение комментариев двух документов
Поля «Комментарий» в документах почти всегда имеют неограниченную длину. Соединить документы по совпадающему комментарию можно только через преобразование:
ВЫБРАТЬ
Реализация.Ссылка КАК Реализация,
Счет.Ссылка КАК СчетФактура
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.СчетФактура КАК Счет
ПО СокрЛП(Реализация.Комментарий) = СокрЛП(Счет.Комментарий)
Такой запрос допустим, но на больших объёмах будет медленным: соединение по вычисляемому выражению не использует индексы. Для регулярных задач лучше хранить нормализованную копию значения в отдельном реквизите ограниченной длины и соединяться по ней.
- 1Определите, какое поле участвует в сравнении или группировке, и проверьте его тип в конфигураторе
- 2Если поле — Строка неограниченной длины, оберните его в ВЫРАЗИТЬ(Поле КАК Строка(N)) с достаточной длиной
- 3Если дополнительно мешают краевые пробелы, примените СокрЛП к обеим сторонам сравнения
- 4Выполните запрос в консоли и проверьте, что строки не обрезались неожиданно
- 5На больших таблицах проверьте время выполнения и при необходимости замените вычисляемое сравнение на служебный реквизит
Ограничения и подводные камни
Первое ограничение — обрезка длинных значений. Результат СокрЛП в запросе имеет ограниченную длину, и содержимое сверх неё теряется. Для полей вроде «Описание» с многострочным текстом это реальный риск: два разных длинных описания с одинаковым началом после обрезки станут «равными», и группировка даст ложные дубли.
Второй момент — производительность. Любая функция над полем в условии или соединении отключает использование индекса по этому полю. На справочнике в десятки тысяч элементов разница может быть незаметна, на регистре с миллионами записей запрос «зависнет» на полном сканировании.
Третий нюанс — значения NULL. Если поле может принимать NULL (например, пришло из левого соединения), СокрЛП(NULL) вернёт NULL, и сравнение с пустой строкой не сработает. Используйте ЕСТЬNULL(СокрЛП(Поле), "") там, где возможны пустые ссылки соединения.
Типичные ошибки и как их избежать
Самая частая ошибка — ожидание, что СокрЛП в запросе уберёт двойные пробелы внутри строки. Этого не происходит ни в запросе, ни во встроенном языке: функция работает только с краями. Для очистки внутренних пробелов в запросе штатного средства нет — данные придётся обрабатывать кодом или исправлять в источнике.
Вторая ошибка — применение СокрЛП только к одной стороне сравнения. Если в базе наименование хранится с пробелом в конце, а параметр передан чистым, выражение СокрЛП(Поле) = &Параметр сработает, а Поле = СокрЛП(&Параметр) — нет. Нормализовывать нужно ту сторону, где данные «грязные», и надёжнее — обе.
Третья ошибка — использование СокрЛП в списке выбираемых полей с последующей выгрузкой в таблицу значений и поиском по колонке, когда разработчик забывает, что значения уже обрезаны. Дальнейшие сравнения этой колонки с исходными данными базы дают неожиданные расхождения.
Проверка результата и альтернативные приёмы
После написания запроса проверьте три вещи: запрос выполняется без ошибок типов, строки не обрезаны неожиданно, скорость приемлема на реальном объёме данных. Быстрый способ убедиться в отсутствии обрезки — вывести максимальную длину результата в тестовом запросе и сравнить с ожидаемой.
Если СокрЛП не решает задачу, рассмотрите альтернативы. Для сравнения без учёта регистра и пробелов иногда проще привести данные на этапе записи: хранить в объекте уже нормализованное значение. Для поиска по подстроке используйте ПОДОБНО с шаблоном, помня, что это тоже отключает индекс. Для выборки фрагмента текста пригодится ПОДСТРОКА.
Ещё один рабочий приём — вычисляемое поле в запросе с последующим помещением во временную таблицу. Если преобразованное значение нужно в нескольких местах сложного запроса, вычислите его один раз, поместите во временную таблицу и соединяйтесь уже с ней — это и читаемее, и часто быстрее.
Как проверить результат
Длина строки ограничена, сравнение работает без преобразований
Длина 0 (неограниченная) — без СокрЛП или ВЫРАЗИТЬ запрос не выполнится
Значения полные, текст не обрывается на полуслове
Длинные значения усечены — увеличьте длину в ВЫРАЗИТЬ
Запрос отрабатывает быстро на реальном объёме данных
Заметная задержка — функция над полем отключила индекс, нужен другой подход
Все ожидаемые строки присутствуют, пустые значения обработаны через ЕСТЬNULL
Часть строк потерялась из-за сравнения с NULL
FAQ
Чем СокрЛП в запросе отличается от СокрЛП в модуле?
Во встроенном языке функция просто возвращает строку без краевых пробелов, длина не ограничивается. В запросе результат дополнительно приводится к строке ограниченной длины, из-за чего длинный текст может обрезаться. Логика удаления пробелов при этом одинаковая — только по краям.
Почему запрос с условием по полю «Комментарий» выдаёт ошибку?
Реквизит «Комментарий» обычно имеет неограниченную длину, а такие поля нельзя сравнивать напрямую. Оберните поле в ВЫРАЗИТЬ(Поле КАК Строка(N)) или СокрЛП — после преобразования сравнение станет допустимым.
Можно ли в запросе убрать двойные пробелы внутри строки?
Штатной функции для этого в языке запросов нет: СокрЛП работает только с краями. Варианты — нормализовать данные кодом при записи, обработать результат запроса после выгрузки в таблицу значений или использовать СтрЗаменить во встроенном языке.
Что вернёт СокрЛП, если поле равно NULL?
Функция вернёт NULL, и сравнение такого значения с пустой строкой даст ложь. Если поле приходит из левого соединения и может быть пустым, используйте конструкцию ЕСТЬNULL(СокрЛП(Поле), "") — тогда пустые значения корректно сравнятся с пустой строкой.
СокрЛП или ВЫРАЗИТЬ — что быстрее?
Заметной разницы в скорости самих функций нет; обе отключают использование индекса по полю, если применены в условии или соединении. Выбирайте по смыслу: нужна нормализация пробелов — СокрЛП, нужен контроль длины — ВЫРАЗИТЬ. Для производительности важнее избегать функций над полями в условиях на больших таблицах.
Как сгруппировать данные по длинному текстовому полю?
Преобразуйте поле через ВЫРАЗИТЬ(Поле КАК Строка(N)) с длиной, достаточной для различения значений, и группируйте по этому выражению. Учтите риск: значения, совпадающие в первых N символах, попадут в одну группу, поэтому для поиска точных дублей длинных текстов такой способ не подходит.
Что важно запомнить
СокрЛП в запросе 1С убирает краевые пробелы и преобразует строку неограниченной длины в ограниченную, что позволяет сравнивать и группировать такие поля. Для контроля длины надёжнее ВЫРАЗИТЬ(Поле КАК Строка(N)), а в условиях на больших таблицах любые функции над полями отключают индексы — это главный риск производительности.