В практике разработчика 1С иногда возникают специфические задачи, которые кажутся простыми на первый взгляд, но требуют нестандартного подхода при реализации в языке запросов. Одной из таких задач является фильтрация данных по количеству слов в строковом поле. Например, когда нам нужно выбрать из справочника «Основные средства» только те наименования, которые начинаются с определенного слова и содержат строго заданное количество слов. Рассмотрим, как решить эту задачу, используя стандартный оператор ПОДОБНО, и разберем все «подводные камни» этого метода.
Представим ситуацию: необходимо выбрать элементы, наименование которых начинается со слова «Автомобиль» и состоит ровно из 4 слов. Разделителем слов считается пробел. Примеры подходящих строк:
Примеры строк, которые не должны попасть в выборку:
Проанализируем базовую попытку решения. Использование простого шаблона "Автомобиль % % %" не дает нужного результата, так как символ % в языке запросов 1С означает последовательность из любого количества произвольных символов. Таким образом, запрос с маской "Автомобиль % % %" выберет все строки, где есть слово «Автомобиль» и как минимум три пробела после него, что соответствует четырем и более словам.
Разберем по шагам наиболее эффективный способ ограничения количества слов в рамках одного запроса. Поскольку оператор ПОДОБНО не умеет напрямую «считать» вхождения, мы применим логическое отрицание. Суть метода заключается в том, чтобы отобрать строки, подходящие под минимальный критерий (4 слова), и исключить те, которые подходят под критерий «лишнего» слова (5 слов).
Рассмотрим пример кода запроса:
ВЫБРАТЬ
Справочник3.Ссылка КАК Ссылка,
Справочник3.Наименование КАК Наименование
ИЗ
Справочник.Справочник3 КАК Справочник3
ГДЕ
Справочник3.Наименование ПОДОБНО "Автомобиль % % %"
И НЕ Справочник3.Наименование ПОДОБНО "Автомобиль % % % %"
Проанализируем ситуацию: первое условие ПОДОБНО "Автомобиль % % %" гарантирует нам наличие начального слова и как минимум трех пробелов, разделяющих последующие слова. Второе условие И НЕ Справочник3.Наименование ПОДОБНО "Автомобиль % % % %" отсекает все записи, в которых встречается четвертый пробел, а значит, и пятое слово.
Вышеописанный метод отлично работает в идеальных условиях, но реальные данные в базе 1С часто содержат ошибки ввода. Выясним причину, по которой запрос может выдать некорректный результат, если в строке присутствуют лишние пробелы.
1. Двойные пробелы в середине строки. Если пользователь случайно ввел два пробела между словами (например, «Автомобиль тойота лэнд крузер»), система воспримет двойной пробел как разделитель, между которым находится «пустое» слово. В итоге визуально трехсловная фраза может быть распознана как четырехсловная. Чтобы сделать поиск более надежным, рекомендуется добавить проверку на отсутствие двойных пробелов:
ГДЕ
Справочник3.Наименование ПОДОБНО "Автомобиль % % %"
И НЕ Справочник3.Наименование ПОДОБНО "Автомобиль % % % %"
И НЕ Справочник3.Наименование ПОДОБНО "% %"
2. Пробелы в конце строки. Наличие пробела в самом конце наименования также может исказить результат. Рассмотрим подробнее: строка «Автомобиль тойота лэнд крузер » (с пробелом в конце) формально содержит 4 значимых слова, но наличие завершающего пробела заставит условие НЕ ПОДОБНО "Автомобиль % % % %" сработать ложно, и запись будет исключена. Для борьбы с этим можно использовать функцию ПОДСТРОКА или предварительно очищать данные, но в рамках чистого запроса лучше всего проверять отсутствие пробела в конце маской И НЕ Справочник3.Наименование ПОДОБНО "% ".
Посмотрим на пример использования квадратных скобок в операторе ПОДОБНО. Хотя 1С не поддерживает полноценные регулярные выражения в запросах, конструкция [^ ] (любой символ, кроме пробела) может помочь уточнить поиск. Если мы хотим гарантировать, что между пробелами действительно есть значащие символы, можно составить более сложную маску, хотя это значительно утяжелит выполнение запроса.
Важно помнить о производительности. Любой запрос с использованием оператора ПОДОБНО, начинающийся с процента ("%Текст"), приводит к полному сканированию таблицы (Full Table Scan), что крайне медленно на больших объемах данных. Однако в нашем случае условие начинается с жестко заданного слова "Автомобиль%". Это позволяет SQL-серверу использовать индекс по полю Наименование, что делает поиск достаточно быстрым.
Хотя мы разобрали, как решить задачу «синтетически» (то есть только средствами запроса), в реальной разработке на платформе 1С стоит рассмотреть и другие варианты:
ПОДОБНО "Автомобиль%", а затем в цикле обработать результат на языке 1С, используя функцию СтрРазделить().Разберем пример программной проверки:
МассивСлов = СтрРазделить(Выборка.Наименование, " ", Ложь);
Если МассивСлов.Количество() = 4 Тогда
// Это наше искомое основное средство
КонецЕсли;
В данном примере параметр Ложь в функции СтрРазделить указывает на то, что пустые строки (возникающие при двойных пробелах) не должны игнорироваться, что соответствует логике работы оператора ПОДОБНО в запросе.
Мы проанализировали способ фильтрации строк по количеству слов в запросе 1С. Использование комбинации ПОДОБНО и НЕ ПОДОБНО является классическим решением для подобных задач, часто встречающихся на аттестациях или собеседованиях. Несмотря на «синтетичность» метода, понимание принципов его работы помогает лучше освоить логику работы СУБД и механизмы сравнения строк в 1С.