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

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

Как узнать длину строки в запросе 1С

В языке запросов 1С нет функции СтрДлина. Разбираем рабочие способы определить длину строки: ПОДОБНО, СКД, постобработка результата и вычисляемые поля.

Разработчики, перешедшие на 1С из SQL, часто ищут в языке запросов аналог функции LEN() или LENGTH() — и не находят. В языке запросов 1С действительно нет прямой функции для определения длины строки: СтрДлина() существует только во встроенном языке и в запросе недоступна. Это архитектурное ограничение, а не недосмотр конкретной версии платформы.

Тем не менее задача «узнать длину строки в запросе» решается несколькими обходными путями: через оператор ПОДОБНО с шаблоном из символов подчёркивания, через вычисляемые поля СКД, через постобработку результата запроса во встроенном языке и через хранение длины в отдельном реквизите. Выбор зависит от того, зачем нужна длина: для фильтрации, для вывода в отчёт или для проверки данных.

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

Почему в языке запросов 1С нет функции длины строки

Язык запросов 1С — это надстройка над SQL конкретной СУБД, и платформа транслирует текст запроса в диалект Microsoft SQL Server, PostgreSQL, Oracle или DB2. Набор функций языка запросов ограничен теми операциями, которые платформа умеет одинаково транслировать на все поддерживаемые СУБД. Функция длины строки в этот набор не входит, поэтому конструкция вида СтрДлина(Наименование) в тексте запроса вызовет ошибку «Ожидается выражение» или «Функция не обнаружена».

Важно не путать два контекста. Во встроенном языке 1С функция СтрДлина(Строка) существует и возвращает число — количество символов в строке. В языке запросов её нет, и любые примеры из интернета, где СтрДлина вставлена прямо в текст запроса, нерабочие. Это самая частая ошибка новичков.

Способ 1. Фильтрация по длине через ПОДОБНО

Если длина нужна не как число, а как условие отбора — например, «найти все артикулы длиннее 10 символов» — задачу решает оператор ПОДОБНО. Символ подчёркивания _ в шаблоне означает ровно один произвольный символ, поэтому шаблон из 11 подчёркиваний совпадёт с любой строкой длиной не менее 11 символов.

ВЫБРАТЬ

Номенклатура.Артикул КАК Артикул

ИЗ

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

ГДЕ

Номенклатура.Артикул ПОДОБНО "___________"

Чтобы найти строки строго заданной длины, комбинируют два условия: строка подобна шаблону из N подчёркиваний и НЕ подобна шаблону из N+1 подчёркиваний. Для поиска пустых или коротких значений условие инвертируют.

Шаблон удобно формировать программно, передавая его параметром:

Запрос.Текст =

"ВЫБРАТЬ

| Т.Артикул

|ИЗ

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

|ГДЕ

| Т.Артикул ПОДОБНО &Шаблон";

Запрос.УстановитьПараметр("Шаблон", СтрЗаполнить("_", 11));

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

Способ 2. Постобработка результата во встроенном языке

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

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

ДлинаНаименования = СтрДлина(Выборка.Наименование);

// дальнейшая обработка

КонецЦикла;

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

Способ не подходит только в одном случае: когда условие по длине должно отсечь записи на стороне сервера СУБД до передачи данных клиенту. Тогда выбирайте фильтрацию через ПОДОБНО или хранимый реквизит с длиной.

Порядок действий для постобработки
  1. 1
    Сформируйте запрос, выбирающий нужные строковые поля без длины
  2. 2
    Выполните запрос и выгрузите результат в таблицу значений или откройте выборку
  3. 3
    Добавьте колонку «Длина» с типом Число при работе с таблицей значений
  4. 4
    В цикле заполните её через СтрДлина(Поле)
  5. 5
    Проверьте несколько строк вручную, сравнив с фактической длиной значения

Способ 3. Вычисляемое поле в СКД

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

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

Учтите: вычисляемые поля считаются после получения данных, поэтому отобрать записи по значению вычисляемого поля стандартным отбором СКД на уровне запроса нельзя. Фильтр применится уже к готовому набору, что на больших выборках менее эффективно.

Способ 4. Хранимый реквизит с длиной строки

Когда условие по длине используется постоянно — например, контроль длины штрихкода, ИНН или кода в обмене данными — правильное архитектурное решение: хранить длину в отдельном числовом реквизите и заполнять его в обработчике ПередЗаписью или в подписке на событие.

Процедура ПередЗаписью(Отказ)

ДлинаАртикула = СтрДлина(Артикул);

КонецПроцедуры;

После этого в запросе доступна обычная фильтрация, сортировка и группировка по числовому полю: ГДЕ ДлинаАртикула > 10. Такой запрос использует индекс и работает быстро даже на больших справочниках. Цена решения — необходимость заполнить реквизит для существующих данных и следить за его актуальностью.

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

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

ПОДОБНО с подчёркиваниями

Подходит для разового отбора по длине. Не возвращает саму длину, медленный на больших таблицах.

СтрДлина в цикле после запроса

Универсально и просто. Не подходит, когда отбор по длине нужен на стороне СУБД.

Вычисляемое поле СКД

Лучший вариант для отчётов. Не позволяет фильтровать данные на уровне запроса.

Хранимый реквизит с длиной

Самый быстрый для постоянных отборов и сортировок. Требует изменения конфигурации и заполнения исторических данных.

Проверка результата и контрольные точки

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

Отдельно проверьте поведение на строках фиксированной длины. Если реквизит объявлен как Строка(50) с фиксированной длиной, хранимое значение дополняется пробелами, и ПОДОБНО с шаблоном из подчёркиваний будет «видеть» строку длиннее фактической. Перед применением шаблона такое поле стоит обрезать или перевести на переменную длину.

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

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

Длина тестовой строки
Норма

Совпадает с фактическим числом символов

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

Значение больше из-за хвостовых пробелов фиксированной строки

Пустые значения
Норма

Пустая строка даёт длину 0 или отсекается условием

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

NULL в поле ломает сравнение или даёт неожиданный отбор

Скорость запроса
Норма

Отбор выполняется за приемлемое время на рабочей базе

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

Полное сканирование таблицы, запрос зависает на больших данных

Типичные ошибки и ограничения

Главная ошибка — попытка вставить СтрДлина прямо в текст запроса. Платформа выдаст синтаксическую ошибку, потому что такой функции в языке запросов нет. Вторая частая ошибка — забыть про NULL: если строковое поле содержит NULL (например, в левом соединении), сравнения и ПОДОБНО вернут ложь, и запись «молча» выпадет из результата. Используйте ЕСТЬNULL(Поле, "") там, где это уместно.

Третья ошибка — ожидание, что ПОДОБНО с шаблоном подчёркиваний работает как индексный поиск. На таблицах в миллионы записей такой отбор может выполняться минутами. Если условие по длине применяется регулярно, переходите на хранимый реквизит.

Типичные ошибки
01
Вставка СтрДлина() в текст запроса — синтаксическая ошибка, функция доступна только во встроенном языке
02
Игнорирование NULL в строковом поле — записи неожиданно выпадают из результата отбора
03
Использование ПОДОБНО с подчёркиваниями на большой таблице — полное сканирование и таймауты
04
Забытые хвостовые пробелы в строках фиксированной длины — завышенная длина и неверный отбор

Как выбрать способ под свою задачу

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

Маршрут решения

Как выбрать действие

Нужно отобрать записи по длине один раз или редкоИспользуйте ПОДОБНО с шаблоном из подчёркиваний, сформированным параметром
Длина нужна как колонка в отчёте на СКДДобавьте вычисляемое поле со СтрДлина(Поле)
Длина нужна в разовой обработке или выгрузкеВыполните запрос и посчитайте СтрДлина в цикле по результату
Отбор или сортировка по длине применяются постоянно на больших данныхДобавьте хранимый числовой реквизит и заполняйте его при записи объекта

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

Итог

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

Функции длины строки в языке запросов 1С нет. Для отбора используйте ПОДОБНО с шаблоном из подчёркиваний, для отчётов — вычисляемое поле СКД со СтрДлина, для обработок — расчёт в цикле после запроса, а для постоянных отборов на больших данных — хранимый реквизит с длиной.

Частые вопросы

Можно ли вызвать СтрДлина прямо в тексте запроса 1С?

Нет. СтрДлина — функция встроенного языка, а не языка запросов. Её вызов в тексте запроса приведёт к синтаксической ошибке. В запросе длину имитируют через ПОДОБНО, а точное значение получают уже после выполнения запроса.

Как найти записи, где строковое поле пустое?

Проверяйте два условия: поле равно пустой строке ИЛИ поле ЕСТЬ NULL, потому что незаполненное значение в соединениях часто представлено именно NULL. Конструкция вида ГДЕ Поле = "" ИЛИ Поле ЕСТЬ NULL закрывает оба случая.

Почему ПОДОБНО с подчёркиваниями находит строки длиннее, чем есть на самом деле?

Скорее всего, реквизит объявлен строкой фиксированной длины, и значение дополнено пробелами до полного размера. Переведите реквизит на переменную длину или учитывайте пробелы при формировании шаблона.

Работает ли вычисляемое поле СКД со СтрДлина в отборе отчёта?

Вычисляемое поле считается после получения данных, поэтому отбор по нему применяется к уже выбранному набору, а не на уровне запроса к СУБД. На больших таблицах это медленнее, чем фильтрация в запросе через ПОДОБНО или хранимый реквизит.

Как посчитать длину строки без пробелов?

Во встроенном языке сначала удалите пробелы, затем возьмите длину: СтрДлина(СтрЗаменить(Значение, " ", "")). Тот же приём работает в выражении вычисляемого поля СКД. В самом запросе такая комбинация недоступна.

Есть ли разница в поведении на разных СУБД?

Текст запроса 1С платформа транслирует в диалект конкретной СУБД, и набор доступных функций от СУБД не зависит. Ограничение единое: прямой функции длины строки нет ни на одной поддерживаемой СУБД, поэтому обходные способы универсальны.