В процессе разработки на платформе 1С:Предприятие 8 часто возникает задача фильтрации данных по длине строкового поля. Например, нам нужно найти все договоры, наименование которых заполнено не полностью, или выявить записи, где строковый код короче установленного стандарта (например, меньше 36 символов). Сложность заключается в том, что язык запросов 1С имеет свои ограничения, которые зависят от версии платформы и используемой системы управления базами данных (СУБД). Разберем по шагам все доступные способы решения этой задачи.
Начнем с самого современного и предпочтительного метода. Начиная с версии платформы 8.3.20, в языке запросов появилась полноценная поддержка функции ДЛИНАСТРОКИ. Рассмотрим, как это выглядит на практике:
ВЫБРАТЬ
Договоры.Ссылка,
Договоры.Наименование
ИЗ
Справочник.ДоговорыКонтрагентов КАК Договоры
ГДЕ
ДЛИНАСТРОКИ(Договоры.Наименование) < 36
Проанализируем этот подход. Это наиболее «чистый» код, который легко читать и поддерживать. Однако важно помнить, что если ваша конфигурация работает на более старых версиях платформы или режим совместимости установлен ниже 8.3.20, этот запрос вызовет ошибку. В таких случаях нам придется прибегнуть к альтернативным методам.
Если функция ДЛИНАСТРОКИ недоступна, наиболее надежным и производительным способом является использование оператора ПОДОБНО. Выясним причину его эффективности: символ подчеркивания _ в шаблоне 1С заменяет ровно один любой символ. Если мы хотим найти строки, длина которых меньше 36 символов, мы можем проверить, НЕ соответствует ли строка шаблону из 36 символов.
Посмотрим на пример реализации:
ВЫБРАТЬ
Договоры.Ссылка
ИЗ
Справочник.ДоговорыКонтрагентов КАК Договоры
ГДЕ
НЕ Договоры.Наименование ПОДОБНО "____________________________________%"
В этом примере в кавычках указано 36 знаков подчеркивания и символ процента % в конце. Разберем логику: если строка содержит 36 и более символов, она попадет под этот шаблон. Отрицание НЕ позволяет нам отфильтровать только те записи, которые «не доросли» до указанной длины. Этот метод универсален и отлично работает во всех версиях 1С 8.x.
Рассмотрим ситуацию, когда разработчики пытаются использовать функцию ПОДСТРОКА. Суть метода заключается в том, чтобы попытаться «отрезать» символ на 36-й позиции. Если строка короче, то функция вернет пустую строку.
Проанализируем пример из обсуждения:
ВЫБРАТЬ
Банки.Наименование
ИЗ
Справочник.Банки КАК Банки
ГДЕ
ПОДСТРОКА(Банки.Наименование, 36, 1) = ""
Однако здесь кроется важный нюанс. В зависимости от настроек СУБД (MS SQL Server или PostgreSQL) и типа данных в поле (фиксированная строка или переменная), результат может отличаться. Рассмотрим подробнее:
ПОДСТРОКА на 36-й позиции вернет пробел, а не пустую строку.Для повышения надежности этого метода рекомендуется использовать сравнение с пустой строкой через оператор «меньше или равно» или проверять на наличие пробела:
ГДЕ
ПОДСТРОКА(Поле, 36, 1) <= ""
ИЛИ ПОДСТРОКА(Поле, 36, 1) = " "
Выясним, как ведут себя эти функции, если поле имеет тип Строка неограниченной длины. В языке запросов 1С многие операции со строками неограниченной длины запрещены или работают крайне медленно. Для корректной работы нам необходимо сначала ограничить длину строки с помощью оператора ВЫРАЗИТЬ.
Посмотрим на правильную конструкцию:
ВЫБРАТЬ
Задачи.Описание
ИЗ
Задача.ЗадачиПользователя КАК Задачи
ГДЕ
ДЛИНАСТРОКИ(ВЫРАЗИТЬ(Задачи.Описание КАК СТРОКА(100))) < 50
Здесь мы сначала приводим поле к ограниченному типу СТРОКА(100), а затем применяем функцию вычисления длины. Без этой манипуляции запрос может завершиться с ошибкой на уровне СУБД.
Разберем, почему один и тот же запрос может выдавать разные результаты на разных серверах:
MS SQL Server: Эта система по умолчанию игнорирует замыкающие пробелы при операциях сравнения. Если вы сравниваете "Текст" = "Текст ", SQL Server вернет ИСТИНА. Это усложняет поиск строк с учетом их реального наполнения символами.
PostgreSQL: Данная СУБД более строго относится к пробелам. Строка с пробелом в конце и строка без него — это разные значения. Если ваше приложение кроссплатформенное, всегда используйте метод с ПОДОБНО или ДЛИНАСТРОКИ, так как они наиболее предсказуемо транслируются в SQL-команды обеих систем.
Подведем итоги нашего исследования. Для решения задачи определения длины строки в запросе 1С:
ДЛИНАСТРОКИ(Поле), если ваша платформа 8.3.20+ и режим совместимости позволяет это.НЕ Поле ПОДОБНО "____%" (с нужным количеством подчеркиваний), если нужно обеспечить работу на старых версиях или гарантировать одинаковое поведение на разных СУБД.ПОДСТРОКА, учитывая возможность наличия пробелов и особенности хранения данных с фиксированной длиной.ВЫРАЗИТЬ(... КАК СТРОКА(N)) при работе с полями неограниченной длины в блоке ГДЕ.Применяя эти знания, вы сможете эффективно оптимизировать ваши запросы и избежать типичных ошибок при работе со строковыми данными в 1С.