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

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

СокрЛП в запросе 1С: обрезка пробелов и строк неограниченной длины

Как использовать СокрЛП в запросе 1С: синтаксис, обрезка пробелов в строках, работа со строками неограниченной длины, типичные ошибки и примеры кода.

Функция СокрЛП в запросах 1С решает две практические задачи: убирает незначащие пробелы в начале и конце строки и позволяет корректно работать со строковыми реквизитами неограниченной длины. Вторая задача встречается даже чаще: поля типа «Строка(0)» нельзя напрямую сравнивать, группировать и использовать в соединениях, а оборачивание в СокрЛП превращает их в обычные строки ограниченной длины.

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

Важно понимать: СокрЛП в языке запросов и одноимённая функция встроенного языка 1С — разные вещи. В запросе функция ограничена по поведению и не всегда делает то, что ожидает разработчик, привыкший к модулю. Именно из-за этой разницы возникает большинство ошибок.

Синтаксис СокрЛП в языке запросов

В языке запросов 1С доступны три родственные функции: СокрЛ (убирает пробелы слева), СокрП (справа) и СокрЛП (с обеих сторон). Синтаксис простой — функция принимает один строковый аргумент:

ВЫБРАТЬ

СокрЛП(Контрагенты.Наименование) КАК Наименование

ИЗ

Справочник.Контрагенты КАК Контрагенты

Результатом выражения будет строка. Если исходное поле имело тип «Строка» неограниченной длины, результат приобретает ограниченную длину — именно это свойство чаще всего используют на практике. Пробелы внутри строки (между словами) функция не трогает, как и во встроенном языке.

Функцию можно применять в секциях ВЫБРАТЬ, ГДЕ, ИМЕЮЩИЕ, в условиях соединений и в параметрах виртуальных таблиц — везде, где допустимо выражение над строковым полем.

Зачем СокрЛП применяют к строкам неограниченной длины

Главный сценарий — обход ограничений платформы. Поля типа «Строка(0)» (например, реквизиты «Комментарий», «Описание», «ДополнительнаяИнформация») нельзя использовать в условии равенства, в ГРУППИРОВКЕ, в УПОРЯДОЧИТЬ и в соединениях таблиц. Попытка сделать это приводит к ошибке исполнения запроса.

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

ВЫБРАТЬ

СокрЛП(Товары.Описание) КАК Описание,

КОЛИЧЕСТВО(*) КАК КоличествоДублей

ИЗ

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

СГРУППИРОВАТЬ ПО

СокрЛП(Товары.Описание)

ИМЕЮЩИЕ

КОЛИЧЕСТВО(*) > 1

Тот же приём работает в соединениях: СокрЛП(Таблица1.Комментарий) = СокрЛП(Таблица2.Комментарий). Без преобразования платформа отклонит такой запрос ещё на этапе проверки в консоли запросов.

СокрЛП против ВЫРАЗИТЬ: что выбрать

Обе конструкции превращают неограниченную строку в ограниченную, но ведут себя по-разному. СокрЛП дополнительно удаляет краевые пробелы и не даёт управлять итоговой длиной. ВЫРАЗИТЬ(Поле КАК Строка(N)) позволяет задать длину явно, но пробелы не трогает.

Если задача — только сделать поле пригодным для сравнения или группировки, предпочтительнее ВЫРАЗИТЬ: поведение прозрачнее, длина задана явно, и в плане запроса выражение читается однозначно. Если дополнительно нужно нормализовать данные (убрать случайные пробелы при сравнении наименований), уместен СокрЛП.

КритерийСокрЛП(Поле)ВЫРАЗИТЬ(Поле КАК Строка(N))
Удаление краевых пробеловДаНет
Управление итоговой длинойНет (предел платформы)Да, задаётся вручную
Пригодность для группировкиДаДа
Риск безмолвной обрезки длинного текстаЕстьЕсть, но точка обрезки контролируется

Сравнение вариантов

СокрЛП(Поле)

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

ВЫРАЗИТЬ(Поле КАК Строка(N))

Подходит для чистого приведения типа с явной длиной. Пробелы не удаляются — при необходимости комбинируется с СокрЛП.

ПОДСТРОКА(Поле, 1, N)

Подходит, когда нужен фиксированный фрагмент с начала строки, например первые 100 символов описания для группировки.

Практические примеры использования

Поиск контрагента по наименованию без учёта пробелов

Классическая ситуация: пользователь вводит наименование с лишним пробелом в конце, и сравнение «в лоб» не находит элемент справочника. Нормализация обеих сторон сравнения решает проблему:

ВЫБРАТЬ

Контрагенты.Ссылка

ИЗ

Справочник.Контрагенты КАК Контрагенты

ГДЕ

СокрЛП(Контрагенты.Наименование) = СокрЛП(&Наименование)

Учтите, что такой запрос не сможет использовать индекс по наименованию, потому что функция применяется к полю. На больших таблицах это означает полное сканирование. Альтернатива — очищать параметр на стороне кода (СокрЛП во встроенном языке) и сравнивать с необработанным полем, если данные в базе уже чистые.

Сравнение комментариев двух документов

Поля «Комментарий» в документах почти всегда имеют неограниченную длину. Соединить документы по совпадающему комментарию можно только через преобразование:

ВЫБРАТЬ

Реализация.Ссылка КАК Реализация,

Счет.Ссылка КАК СчетФактура

ИЗ

Документ.РеализацияТоваровУслуг КАК Реализация

ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.СчетФактура КАК Счет

ПО СокрЛП(Реализация.Комментарий) = СокрЛП(Счет.Комментарий)

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

Порядок действий при ошибке сравнения строк
  1. 1
    Определите, какое поле участвует в сравнении или группировке, и проверьте его тип в конфигураторе
  2. 2
    Если поле — Строка неограниченной длины, оберните его в ВЫРАЗИТЬ(Поле КАК Строка(N)) с достаточной длиной
  3. 3
    Если дополнительно мешают краевые пробелы, примените СокрЛП к обеим сторонам сравнения
  4. 4
    Выполните запрос в консоли и проверьте, что строки не обрезались неожиданно
  5. 5
    На больших таблицах проверьте время выполнения и при необходимости замените вычисляемое сравнение на служебный реквизит

Ограничения и подводные камни

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

Второй момент — производительность. Любая функция над полем в условии или соединении отключает использование индекса по этому полю. На справочнике в десятки тысяч элементов разница может быть незаметна, на регистре с миллионами записей запрос «зависнет» на полном сканировании.

Третий нюанс — значения NULL. Если поле может принимать NULL (например, пришло из левого соединения), СокрЛП(NULL) вернёт NULL, и сравнение с пустой строкой не сработает. Используйте ЕСТЬNULL(СокрЛП(Поле), "") там, где возможны пустые ссылки соединения.

Типичные ошибки и как их избежать

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

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

Третья ошибка — использование СокрЛП в списке выбираемых полей с последующей выгрузкой в таблицу значений и поиском по колонке, когда разработчик забывает, что значения уже обрезаны. Дальнейшие сравнения этой колонки с исходными данными базы дают неожиданные расхождения.

Типичные ошибки
01
Сравнение строки неограниченной длины без преобразования — запрос падает с ошибкой ещё до выполнения
02
СокрЛП только с одной стороны сравнения — результат зависит от того, где в данных стоят пробелы
03
Группировка по СокрЛП длинного описания — разные тексты с одинаковым началом ошибочно склеиваются в одну группу
04
Игнорирование NULL из левого соединения — СокрЛП(NULL) не равен пустой строке, строки теряются из результата
05
Использование функции над полем в условии на большой таблице — индекс отключается, запрос выполняется полным сканированием

Проверка результата и альтернативные приёмы

После написания запроса проверьте три вещи: запрос выполняется без ошибок типов, строки не обрезаны неожиданно, скорость приемлема на реальном объёме данных. Быстрый способ убедиться в отсутствии обрезки — вывести максимальную длину результата в тестовом запросе и сравнить с ожидаемой.

Если СокрЛП не решает задачу, рассмотрите альтернативы. Для сравнения без учёта регистра и пробелов иногда проще привести данные на этапе записи: хранить в объекте уже нормализованное значение. Для поиска по подстроке используйте ПОДОБНО с шаблоном, помня, что это тоже отключает индекс. Для выборки фрагмента текста пригодится ПОДСТРОКА.

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

Контрольные точки

Как проверить результат

Тип поля в конфигураторе
Норма

Длина строки ограничена, сравнение работает без преобразований

Тревожный признак

Длина 0 (неограниченная) — без СокрЛП или ВЫРАЗИТЬ запрос не выполнится

Данные в результате
Норма

Значения полные, текст не обрывается на полуслове

Тревожный признак

Длинные значения усечены — увеличьте длину в ВЫРАЗИТЬ

Время выполнения
Норма

Запрос отрабатывает быстро на реальном объёме данных

Тревожный признак

Заметная задержка — функция над полем отключила индекс, нужен другой подход

Строки из левого соединения
Норма

Все ожидаемые строки присутствуют, пустые значения обработаны через ЕСТЬNULL

Тревожный признак

Часть строк потерялась из-за сравнения с NULL

FAQ

Чем СокрЛП в запросе отличается от СокрЛП в модуле?

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

Почему запрос с условием по полю «Комментарий» выдаёт ошибку?

Реквизит «Комментарий» обычно имеет неограниченную длину, а такие поля нельзя сравнивать напрямую. Оберните поле в ВЫРАЗИТЬ(Поле КАК Строка(N)) или СокрЛП — после преобразования сравнение станет допустимым.

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

Штатной функции для этого в языке запросов нет: СокрЛП работает только с краями. Варианты — нормализовать данные кодом при записи, обработать результат запроса после выгрузки в таблицу значений или использовать СтрЗаменить во встроенном языке.

Что вернёт СокрЛП, если поле равно NULL?

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

СокрЛП или ВЫРАЗИТЬ — что быстрее?

Заметной разницы в скорости самих функций нет; обе отключают использование индекса по полю, если применены в условии или соединении. Выбирайте по смыслу: нужна нормализация пробелов — СокрЛП, нужен контроль длины — ВЫРАЗИТЬ. Для производительности важнее избегать функций над полями в условиях на больших таблицах.

Как сгруппировать данные по длинному текстовому полю?

Преобразуйте поле через ВЫРАЗИТЬ(Поле КАК Строка(N)) с длиной, достаточной для различения значений, и группируйте по этому выражению. Учтите риск: значения, совпадающие в первых N символах, попадут в одну группу, поэтому для поиска точных дублей длинных текстов такой способ не подходит.

Итог

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

СокрЛП в запросе 1С убирает краевые пробелы и преобразует строку неограниченной длины в ограниченную, что позволяет сравнивать и группировать такие поля. Для контроля длины надёжнее ВЫРАЗИТЬ(Поле КАК Строка(N)), а в условиях на больших таблицах любые функции над полями отключают индексы — это главный риск производительности.