Разработка и Конфигурация · 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Сформируйте запрос, выбирающий нужные строковые поля без длины
- 2Выполните запрос и выгрузите результат в таблицу значений или откройте выборку
- 3Добавьте колонку «Длина» с типом Число при работе с таблицей значений
- 4В цикле заполните её через СтрДлина(Поле)
- 5Проверьте несколько строк вручную, сравнив с фактической длиной значения
Способ 3. Вычисляемое поле в СКД
Если длина строки нужна в отчёте на СКД, не обязательно вычислять её в запросе. СКД поддерживает вычисляемые поля, выражения которых пишутся на встроенном языке, — а там СтрДлина() доступна. На закладке «Вычисляемые поля» добавьте поле ДлинаНаименования с выражением СтрДлина(Наименование) и включите его в настройки отчёта.
Внутри выражений СКД также работают функции общих модулей с признаком серверного вызова, поэтому логику можно вынести в отдельную функцию, если вычисление сложнее простой длины — например, длина без пробелов или длина в байтах для интеграционных проверок.
Учтите: вычисляемые поля считаются после получения данных, поэтому отобрать записи по значению вычисляемого поля стандартным отбором СКД на уровне запроса нельзя. Фильтр применится уже к готовому набору, что на больших выборках менее эффективно.
Способ 4. Хранимый реквизит с длиной строки
Когда условие по длине используется постоянно — например, контроль длины штрихкода, ИНН или кода в обмене данными — правильное архитектурное решение: хранить длину в отдельном числовом реквизите и заполнять его в обработчике ПередЗаписью или в подписке на событие.
Процедура ПередЗаписью(Отказ)
ДлинаАртикула = СтрДлина(Артикул);
КонецПроцедуры;
После этого в запросе доступна обычная фильтрация, сортировка и группировка по числовому полю: ГДЕ ДлинаАртикула > 10. Такой запрос использует индекс и работает быстро даже на больших справочниках. Цена решения — необходимость заполнить реквизит для существующих данных и следить за его актуальностью.
Для типовых конфигураций без снятия с поддержки аналогичную роль играет дополнительный реквизит, заполняемый подпиской, либо расширение конфигурации, куда выносят и реквизит, и обработчик.
Сравнение вариантов
Подходит для разового отбора по длине. Не возвращает саму длину, медленный на больших таблицах.
Универсально и просто. Не подходит, когда отбор по длине нужен на стороне СУБД.
Лучший вариант для отчётов. Не позволяет фильтровать данные на уровне запроса.
Самый быстрый для постоянных отборов и сортировок. Требует изменения конфигурации и заполнения исторических данных.
Проверка результата и контрольные точки
Какой бы способ ни был выбран, результат стоит проверить на контрольных примерах. Возьмите строку известной длины, включая крайние случаи: пустую строку, строку из одного символа, строку с пробелами в конце и строку с переносами строк. Убедитесь, что вычисленная длина совпадает с ожидаемой.
Отдельно проверьте поведение на строках фиксированной длины. Если реквизит объявлен как Строка(50) с фиксированной длиной, хранимое значение дополняется пробелами, и ПОДОБНО с шаблоном из подчёркиваний будет «видеть» строку длиннее фактической. Перед применением шаблона такое поле стоит обрезать или перевести на переменную длину.
Как проверить результат
Совпадает с фактическим числом символов
Значение больше из-за хвостовых пробелов фиксированной строки
Пустая строка даёт длину 0 или отсекается условием
NULL в поле ломает сравнение или даёт неожиданный отбор
Отбор выполняется за приемлемое время на рабочей базе
Полное сканирование таблицы, запрос зависает на больших данных
Типичные ошибки и ограничения
Главная ошибка — попытка вставить СтрДлина прямо в текст запроса. Платформа выдаст синтаксическую ошибку, потому что такой функции в языке запросов нет. Вторая частая ошибка — забыть про NULL: если строковое поле содержит NULL (например, в левом соединении), сравнения и ПОДОБНО вернут ложь, и запись «молча» выпадет из результата. Используйте ЕСТЬNULL(Поле, "") там, где это уместно.
Третья ошибка — ожидание, что ПОДОБНО с шаблоном подчёркиваний работает как индексный поиск. На таблицах в миллионы записей такой отбор может выполняться минутами. Если условие по длине применяется регулярно, переходите на хранимый реквизит.
Как выбрать способ под свою задачу
Критерий выбора простой: определите, где именно нужна длина — в условии отбора, в колонке отчёта или в разовой обработке. От этого зависит инструмент, и попытка натянуть один способ на все случаи обычно приводит либо к медленным запросам, либо к избыточному коду.
Как выбрать действие
В смешанных сценариях способы комбинируют: например, грубый отбор по длине через ПОДОБНО на сервере, а точное значение длины — через СтрДлина при обходе результата. Это даёт и приемлемую скорость, и точные данные.
Что важно запомнить
Функции длины строки в языке запросов 1С нет. Для отбора используйте ПОДОБНО с шаблоном из подчёркиваний, для отчётов — вычисляемое поле СКД со СтрДлина, для обработок — расчёт в цикле после запроса, а для постоянных отборов на больших данных — хранимый реквизит с длиной.
Частые вопросы
Можно ли вызвать СтрДлина прямо в тексте запроса 1С?
Нет. СтрДлина — функция встроенного языка, а не языка запросов. Её вызов в тексте запроса приведёт к синтаксической ошибке. В запросе длину имитируют через ПОДОБНО, а точное значение получают уже после выполнения запроса.
Как найти записи, где строковое поле пустое?
Проверяйте два условия: поле равно пустой строке ИЛИ поле ЕСТЬ NULL, потому что незаполненное значение в соединениях часто представлено именно NULL. Конструкция вида ГДЕ Поле = "" ИЛИ Поле ЕСТЬ NULL закрывает оба случая.
Почему ПОДОБНО с подчёркиваниями находит строки длиннее, чем есть на самом деле?
Скорее всего, реквизит объявлен строкой фиксированной длины, и значение дополнено пробелами до полного размера. Переведите реквизит на переменную длину или учитывайте пробелы при формировании шаблона.
Работает ли вычисляемое поле СКД со СтрДлина в отборе отчёта?
Вычисляемое поле считается после получения данных, поэтому отбор по нему применяется к уже выбранному набору, а не на уровне запроса к СУБД. На больших таблицах это медленнее, чем фильтрация в запросе через ПОДОБНО или хранимый реквизит.
Как посчитать длину строки без пробелов?
Во встроенном языке сначала удалите пробелы, затем возьмите длину: СтрДлина(СтрЗаменить(Значение, " ", "")). Тот же приём работает в выражении вычисляемого поля СКД. В самом запросе такая комбинация недоступна.
Есть ли разница в поведении на разных СУБД?
Текст запроса 1С платформа транслирует в диалект конкретной СУБД, и набор доступных функций от СУБД не зависит. Ограничение единое: прямой функции длины строки нет ни на одной поддерживаемой СУБД, поэтому обходные способы универсальны.