При работе с документами или справочниками часто возникает задача отфильтровать элементы по строковому номеру или коду. Например, в информационной базе часть номеров содержит буквенные префиксы ("АА000000001", "0H0T000018"), а другая часть состоит исключительно из цифр ("00000000001"). Разберем, как в запросе 1С отобрать только те записи, строковый номер которых состоит исключительно из цифр и может быть преобразован в числовое значение.
Первое, что часто приходит в голову разработчикам, — применить конструкцию ВЫРАЗИТЬ(Поле КАК Число). Однако в языке запросов платформы 1С:Предприятие оператор ВЫРАЗИТЬ предназначен исключительно для работы с полями составного типа (для сужения ссылочных типов или явного указания типа при обращении через точку). Он не выполняет преобразование типов данных (в отличие от функций CAST или CONVERT в реляционных СУБД) и при попытке преобразовать строку в число вызовет ошибку выполнения запроса.
Для проверки состава строки непосредственно в теле запроса воспользуемся оператором ПОДОБНО. Оператор поддерживает шаблонные спецсимволы, включая диапазоны и инверсию символов в квадратных скобках:
% — произвольная последовательность любых символов;_ — один произвольный символ;[...] — любой одиночный символ из перечисленных внутри скобок (например, [0-9] означает любую цифру);[^...] — любой одиночный символ, кроме перечисленных внутри скобок (знак ^ означает отрицание).Если нам необходимо найти строки, содержащие хотя бы один символ, отличный от цифры, шаблон запишется как "%[^0-9]%". Соответственно, чтобы отобрать только те записи, где посторонних символов нет, применим отрицание НЕ ПОДОБНО.
Посмотрим на пример условия в секции ГДЕ:
ВЫБРАТЬ
Документ.Ссылка КАК Ссылка,
Документ.НомерДоп КАК НомерДоп
ИЗ
Документ.ПриходнаяНакладная КАК Документ
ГДЕ
Документ.НомерДоп НЕ ПОДОБНО "%[^0-9]%"
Проанализируем важные особенности работы данного условия, которые необходимо учитывать при разработке:
"" успешно проходит проверку НЕ ПОДОБНО "%[^0-9]%", так как в ней нет символов, отличных от цифр. Если пустые значения необходимо исключить из выборки, добавьте явную проверку:
ГДЕ
Документ.НомерДоп <> ""
И Документ.НомерДоп НЕ ПОДОБНО "%[^0-9]%"
[^0-9], условие отсечет такие строки. Для корректной работы реквизит должен быть переменной длины."%...") исключает возможность использования индексов СУБД по строковому полю. При обработке больших таблиц запрос выполнит полное сканирование (Table Scan).Если выборка из базы уже получена или проверка выполняется на встроенном языке 1С, рассмотрим альтернативные варианты решения задачи.
1. Использование функций Библиотеки Стандартных Подсистем (БСП)
В типовых конфигурациях доступны удобные методы БСП:
// Проверка на наличие только цифр
ТолькоЦифры = СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке(СтрокаЗначения, Истина);
// Проверка по произвольному набору допустимых символов
СтрокаКорректна = СтроковыеФункцииКлиентСервер.СтрокаСодержитТолькоСимволы(СтрокаЗначения, "0123456789");
2. Проверка через блок Попытка ... Исключение
Если требуется безопасная попытка преобразования произвольной строки к числовому типу во встроенном языке:
Попытка
ЧисловоеЗначение = Число(СокрЛП(СтрокаЗначения));
ЭтоЧисло = Истина;
Исключение
ЧисловоеЗначение = 0;
ЭтоЧисло = Ложь;
КонецПопытки;
Рекомендация по архитектуре: Если по числовому представлению номера требуется регулярно выполнять быстрые отборы, сортировку или строить отчеты, рекомендуется создать отдельный числовой реквизит в объекте метаданных и автоматически заполнять его в обработчике события ПередЗаписью.