Как в запросе 1С выбрать строки только определенной длины?

Программист 1С v8.3 (Управляемые формы)
← На главную

В процессе разработки отчетов и обработок на платформе 1С:Предприятие программисты часто сталкиваются с необходимостью отфильтровать данные по длине строкового поля. Типичный пример — выборка штрихкодов, где важно отобрать только 13-значные коды (EAN-13), исключив при этом некорректные записи или коды других форматов. Сложность заключается в том, что в языке запросов 1С долгое время отсутствовала прямая функция определения длины. Рассмотрим подробнее, как решить эту задачу различными способами, начиная от классических «хаков» и заканчивая современными инструментами платформы. Для точечной миграции данных между базами, где объекты заводились вручную и имеют разные ссылки, удобно выполнить перенос данных между похожими конфигурациями 1С с сопоставлением по произвольным полям поиска.

Способ 1: Использование современной функции ДЛИНА_СТРОКИ()

Прежде чем приступать к сложным конструкциям, проанализируем версию вашей платформы. Начиная с версии 8.3.20, в языке запросов появилась штатная функция ДЛИНА_СТРОКИ(). Это самый оптимальный и производительный метод, так как он транслируется напрямую в SQL-запрос к СУБД.

Рассмотрим пример использования этой функции в условии запроса:


ВЫБРАТЬ
    Штрихкоды.Штрихкод КАК Штрихкод,
    Штрихкоды.Владелец КАК Номенклатура
ИЗ
    РегистрСведений.ШтрихкодыНоменклатуры КАК Штрихкоды
ГДЕ
    ДЛИНА_СТРОКИ(Штрихкоды.Штрихкод) = 13

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

Способ 2: Использование оператора ПОДОБНО (Шаблоны)

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

Выясним, как составить условие для поиска строки длиной ровно 13 символов. Нам нужно указать в шаблоне 13 знаков подчеркивания:


ГДЕ
    Штрихкоды.Штрихкод ПОДОБНО "_____________"

Важный нюанс: этот метод хорошо работает для строк переменной длины (VARCHAR). Однако, если ваше поле в базе данных имеет фиксированную длину (CHAR), СУБД может дополнять строку пробелами справа до максимальной длины. В этом случае шаблон с подчеркиваниями может вернуть некорректный результат. Для более строгой проверки, например, только цифр, можно использовать конструкцию ПОДОБНО "[0-9][0-9]..." (повторить 13 раз).

Способ 3: Комбинация функции ПОДСТРОКА

Проанализируем ситуацию, когда нам нужно проверить отсутствие символа на позиции N + 1. Логика проста: если на 14-й позиции символа нет (пустая строка), а на 13-й позиции символ есть, значит, длина строки составляет ровно 13 символов.

Разберем пример реализации этого условия:


ГДЕ
    ПОДСТРОКА(Штрихкоды.Штрихкод, 14, 1) = ""
    И НЕ ПОДСТРОКА(Штрихкоды.Штрихкод, 13, 1) = ""

Здесь функция ПОДСТРОКА(Строка, Начало, Длина) пытается извлечь один символ, начиная с указанной позиции. Если позиция выходит за границы реальной длины строки, возвращается пустая строка "". Обратите внимание, что в запросах 1С пустая строка и строка из пробела часто считаются эквивалентными, что может вызвать проблемы при работе с реквизитами фиксированной длины.

Способ 4: Метод с использованием оператора ВЫРАЗИТЬ

Этот способ основан на механизме приведения типов. Оператор ВЫРАЗИТЬ при попытке привести длинную строку к более короткой фиксированной строке просто обрезает ее. Мы можем использовать это для сравнения. При необходимости можно воспользоваться решением для обхода ошибки несовместимости типов при сравнении строк.

Посмотрим на пример логики:


ГДЕ
    Штрихкоды.Штрихкод = ВЫРАЗИТЬ(Штрихкоды.Штрихкод КАК СТРОКА(13))
    И НЕ Штрихкоды.Штрихкод = ВЫРАЗИТЬ(Штрихкоды.Штрихкод КАК СТРОКА(12))

Как это работает? Первое условие отсекает все строки, длина которых больше 13 (так как после обрезания до 13 символов они перестанут быть равны оригиналу). Второе условие отсекает все строки, длина которых 12 и меньше (так как при обрезании до 12 они останутся равны оригиналу, а нам нужно обратное).

Способ 5: Хаки с конкатенацией («Метод Ё»)

В обсуждениях часто встречается интересный прием с добавлением заведомо отсутствующего в данных символа к строке перед выполнением операции ПОДСТРОКА. Это помогает обойти особенности сравнения пустых строк и пробелов.

Рассмотрим пример:


ГДЕ
    ПОДСТРОКА(Штрихкоды.Штрихкод + "Ё", 1, 14) ПОДОБНО "%Ё"
    И НЕ ПОДСТРОКА(Штрихкоды.Штрихкод + "Ё", 1, 13) ПОДОБНО "%Ё"

В данном случае мы «приклеиваем» символ «Ё» к штрихкоду. Если итоговая подстрока длиной 14 символов заканчивается на «Ё», значит, оригинальная строка была длиной 13 символов. Этот метод достаточно надежен, но его сложно читать другим разработчикам.

Способ 6: Возможности Системы компоновки данных (СКД)

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

Проанализируем два варианта реализации в СКД:

  1. Вычисляемое поле: Перейдите на закладку «Вычисляемые поля», добавьте поле ДлинаШтрихкода и в выражении напишите ДлинаСтроки(Штрихкод). После этого в настройках отчета на закладке «Отбор» вы сможете просто указать: ДлинаШтрихкода Равно 13.
  2. Выражение отбора: В настройках компоновки можно сразу прописать условие отбора, используя функции языка выражений 1С, которые будут вычисляться уже после получения данных из БД.

Важные рекомендации по производительности

Важно понимать, что использование любых функций (ПОДСТРОКА, ВЫРАЗИТЬ, ПОДОБНО с процентом в начале) в блоке ГДЕ приводит к тому, что СУБД не может использовать индексы для поиска. Это вызовет полное сканирование таблицы (Full Scan), что на больших объемах данных (например, миллионы штрихкодов) приведет к значительным задержкам.

Как оптимизировать:

Подводя итог, мы видим, что язык запросов 1С предоставляет множество гибких инструментов для работы со строками. Для современных систем используйте ДЛИНА_СТРОКИ(), для старых — комбинацию ПОДСТРОКА или ПОДОБНО, а для сложных отчетов — механизмы вычисляемых полей СКД.

← На главную