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

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

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

Способ 1. Современный метод: Функция ДЛИНАСТРОКИ

Начиная с версии платформы 8.3.20, разработчики 1С наконец-то добавили встроенную функцию для вычисления количества символов. Это наиболее правильный и производительный метод. Рассмотрим его синтаксис:


ВЫБРАТЬ
    Номенклатура.Наименование КАК Наименование,
    ДЛИНАСТРОКИ(Номенклатура.Наименование) КАК Длина
ИЗ
    Справочник.Номенклатура КАК Номенклатура

Важные нюансы использования функции ДЛИНАСТРОКИ:

  1. Концевые пробелы: Функция ведет себя аналогично стандарту SQL (например, функции LEN в MS SQL Server). Она не учитывает пробелы в конце строки. Если в строке "Текст " три пробела на конце, функция вернет значение 5.
  2. Обработка NULL: Если в поле содержится NULL (например, при левом соединении), функция также вернет NULL. Чтобы избежать проблем в расчетах, рекомендуется использовать конструкцию ЕСТЬNULL(ДЛИНАСТРОКИ(Поле), 0).
  3. Режим совместимости: Это критически важный момент. Даже если вы используете платформу 8.3.22, но в настройках вашей конфигурации установлен «Режим совместимости» ниже 8.3.20, эта функция не будет работать и вызовет ошибку синтаксиса запроса.

Способ 2. Метод сравнения через ВЫРАЗИТЬ (для старых платформ)

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

Рассмотрим пример, как проверить, что длина строки равна конкретному числу (например, 3):


ВЫБРАТЬ
    Контрагенты.Ссылка,
    ВЫБОР
        КОГДА ВЫРАЗИТЬ(Контрагенты.Наименование КАК СТРОКА(0)) = Контрагенты.Наименование ТОГДА 0
        КОГДА ВЫРАЗИТЬ(Контрагенты.Наименование КАК СТРОКА(1)) = Контрагенты.Наименование ТОГДА 1
        КОГДА ВЫРАЗИТЬ(Контрагенты.Наименование КАК СТРОКА(2)) = Контрагенты.Наименование ТОГДА 2
        КОГДА ВЫРАЗИТЬ(Контрагенты.Наименование КАК СТРОКА(3)) = Контрагенты.Наименование ТОГДА 3
        ИНАЧЕ 4 // Больше трех
    КОНЕЦ КАК ДлинаСтроки
ИЗ
    Справочник.Контрагенты КАК Контрагенты

Этот метод хорошо работает для коротких строк (артикулы, коды, краткие наименования), но становится громоздким для длинных текстов.

Способ 3. Посимвольный перебор через ПОДСТРОКА

Еще один классический «хак» — использование функции ПОДСТРОКА. Мы проверяем наличие символа в определенной позиции. Если в позиции N символ есть (не пустая строка), а в позиции N+1 его уже нет — значит, длина строки равна N.

Посмотрим на пример реализации:


ВЫБРАТЬ
    Номенклатура.Ссылка,
    ВЫБОР
        КОГДА ПОДСТРОКА(Номенклатура.Наименование, 1, 1) = "" ТОГДА 0
        КОГДА ПОДСТРОКА(Номенклатура.Наименование, 2, 1) = "" ТОГДА 1
        КОГДА ПОДСТРОКА(Номенклатура.Наименование, 3, 1) = "" ТОГДА 2
        КОГДА ПОДСТРОКА(Номенклатура.Наименование, 4, 1) = "" ТОГДА 3
        ИНАЧЕ 100 // Условное обозначение длинной строки
    КОНЕЦ КАК Длина
ИЗ
    Справочник.Номенклатура КАК Номенклатура

Для оптимизации этого процесса программисты часто используют метод бинарного поиска. Вместо проверки каждого символа (1, 2, 3, 4...), мы проверяем границы диапазонов: сначала проверяем 128-й символ, затем 64-й и так далее. Это позволяет вычислить длину строки до 256 символов всего за 8 условий ВЫБОР. Для реализации такого подхода можно использовать готовую схему вычисления длины строки в запросе методом половинного деления.

Способ 4. Использование вспомогательной таблицы чисел

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

Разберем этот алгоритм по шагам:

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

// Создаем таблицу чисел от 0 до 999
ВЫБРАТЬ
    aa.a * 100 + bb.b * 10 + cc.c КАК Номер
ПОМЕСТИТЬ ВТ_Цифры
ИЗ
    (ВЫБРАТЬ 0 КАК a ОБЪЕДИНИТЬ ВЫБРАТЬ 1 ... ОБЪЕДИНИТЬ ВЫБРАТЬ 9) КАК aa
    ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ 0 КАК b ...) КАК bb ПО ИСТИНА
    ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ 0 КАК c ...) КАК cc ПО ИСТИНА
;

// Вычисляем длину
ВЫБРАТЬ
    Данные.Наименование,
    МАКСИМУМ(ВТ_Цифры.Номер) КАК Длина
ИЗ
    Справочник.Номенклатура КАК Данные
    ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Цифры КАК ВТ_Цифры
    ПО (НЕ ПОДСТРОКА(Данные.Наименование, ВТ_Цифры.Номер, 1) = "")
СГРУППИРОВАТЬ ПО
    Данные.Наименование

Производительность и рекомендации

Проанализируем влияние этих методов на скорость работы базы данных. Важно помнить о понятии SARGability (способность СУБД использовать индексы). Любое использование функций ДЛИНАСТРОКИ или ПОДСТРОКА в секции ГДЕ заставляет SQL-сервер выполнять полное сканирование таблицы (Table Scan) вместо быстрого поиска по индексу.

Практические советы:

Подведем итог: если ваша платформа 8.3.20 и выше — смело используйте ДЛИНАСТРОКИ(). Во всех остальных случаях наиболее стабильным и читаемым методом будет сравнение через ВЫРАЗИТЬ(... КАК СТРОКА(N)).

← На главную