Имя: Пароль:
1C
1С v8
Как искать выражения глобальным поиском состоящие из нескольких слов ?
0 raykom
 
13.05.14
22:05
Т.е по вхождению в любом порядке ?

Задать например "контрагенты цикл" и что бы выдал все строки, куда входят два этих слова в любом порядке и не обязательно, что подряд.

Спасибо
1 zak555
 
13.05.14
22:05
как в яндексе
2 raykom
 
13.05.14
22:07
Синтаксис имеешь в виду ? Через + ?

А проста слова подряд написал - пустой поиск. Видимо ищет полное совпедение
Чота я попробовал - пустой поиск приходит
3 RomaH
 
naïve
13.05.14
22:39
я года два назад решал такую задачу - то ли контрагентов, то ли номенклатуру искал

уже не помню заморочек
но суть была в разложении фразы на слова
потом убирались слова "паразиты" - короткие

затем составлялись комбинации (от одного слова до максимума)
и производился поиск - как только нашел, поиск прерывался

напомни суть заморочки с поиском по фразе

сейчас к стати ищу контрагентов, но простым запросом - по любому вхождению фразы

например
дор клин бол
найдет все наименования содержащие данные слова в любом порядке в любом месте слова
4 RomaH
 
naïve
13.05.14
22:40
от глобального поиска отказался, ибо на коротких словах (до 5 букв) оно ругается на превышение чего-то там
5 quest
 
13.05.14
23:01
снегопат. на край сам скрипт напишешь
6 raykom
 
13.05.14
23:21
Епть ... НУйого в пень руками найду
7 quest
 
13.05.14
23:30
ну ойпть... выгружай ысе в текстовые файлы и юзай grep
8 _fvadim
 
14.05.14
00:00
(7) я выгребал все наименования запросом в тз, тз в массив, массив в строкувнутр, а уж строку-то я регэкспами и шерстил.
9 ProProg
 
14.05.14
00:02
(0) есть у меня готовое решение
10 ProProg
 
14.05.14
00:04
Все очень просто

условие ПОДОБНО
плюс И

Получаешь массив слов из разложения строки
И на каждое слово
ПОДОБНО
а все условия со словами И
11 ProProg
 
14.05.14
00:05
Наименование ПОБОДНО тряляляля
И
Наименование ПОДОБНО парапарапаб
И
......
так далее
12 vde69
 
модератор
14.05.14
00:06
читаем про полнотекстовый поиск

"(ООО AND Солнышко) OR (ЧОП AND Пупкин) "
13 ProProg
 
14.05.14
00:07
если что то надо отсеять проверяешь длину слова. если короткое то пропустить.
Вот и все дела.
14 orefkov
 
14.05.14
00:11
Если поиск в модулях конфигурации, то в снегопате  есть скрипт extsearch.js, в котором можно применить такой регэксп:
контрагенты.*цикл|цикл.*контрагенты
Если три слова, то посложнее. Хотя гуру регэкспов может смогут что-то более правильное предложить. Либо можно скрипт доточить.
15 ProProg
 
14.05.14
00:15
(14) могу дать подсказку. хоть не шарю в ваших скриптах
16 ProProg
 
14.05.14
00:18
есть необределенное количество слов.

1) получаем массив
2) получаем количество массива
3) делаем цикл по счетчику:

в первом заходе запрос по первому слову получение результата

во втором запрос по результату первого слова с поиском по второму
в третьем по результату второго слова

и так далее.

в итоге все время уменьшается уменьшается
и в итоге приходим к сто процентному совпадению всех

можно даже универсально.
17 ProProg
 
14.05.14
00:18
с каждым словом получаем результат всех ранее входящих слов. и на последнем итоговый результат всех слов.
18 ProProg
 
14.05.14
00:24
Примерно так

ВремТаб = Новый ТаблицаЗначений;

Для Каждого Стр Цз МассивСлов

Если ВремТаб.Количество()  > 0 Тогда

//Это если мы ВремТаб образовалась в результате цикла

Тут запрос по врем таб с новым словом из массива. далее если мы на слове получаем запрос значит всяпоисковая строка не сработала и на нуле прерываем вообще все полностью

Иначе

Если это Первое слово то запрос по источнику.
ВремТаб = ЗапросПоСлову.Выгрузить();

КонецЕсли;

Если ТабРезультата.Количество = 0 Тогда
Прервать;
КонецЕсли;

КонецЦикла;
19 RomaH
 
naïve
14.05.14
07:46
(12) читали и пробовали, а ты пробовал?
короткие слова типа "ООО" на больших массивах данных что-то там переполняют
20 RomaH
 
naïve
14.05.14
07:47
Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
    
    СтандартнаяОбработка    = Ложь;
    
    МассивСтрокПоиска        = Новый Массив;
    МассивСлов                = Новый Массив;

    ТекущийПользователь = ОбщегоНазначения.ТекущийПользователь();
    
    ИспользоватьУлучшеныйПоиск        = ТекущийПользователь.ИспользоватьУлучшеныйПоиск;    
    ИспользоватьПолнотекстовыйПоиск    = ТекущийПользователь.ИспользоватьПолнотекстовыйПоиск;
    
    СтрокаПоиска = Параметры.СтрокаПоиска;
    
    Если ПустаяСтрока(СтрокаПоиска) Тогда
        ДанныеВыбора = Новый СписокЗначений;
        Возврат;
    КонецЕсли;
    
    //Попытаемся использовать регулярные выражения
    Если ИспользоватьУлучшеныйПоиск Тогда
        МассивСтрокПоиска = ПолучитьМассивСтрокПоиска(СтрокаПоиска);
    КонецЕсли;
    //Регулярные выражения
    
    Текст1 = СОКРЛП(СтрокаПоиска);
    Текст1 = РаботаСДиалогамиКлиентСервер.СформироватьСтрокуДляПоискаВЗапросе(Текст1);
    
    КатегорияВнереализации = Неопределено;
    Параметры.Свойство("КатегорияВнереализации",КатегорияВнереализации);
    
    ДоговорПрофосмотра = Неопределено;
    Параметры.Свойство("ДоговорПрофосмотра",ДоговорПрофосмотра);
    
    Запрос = Новый Запрос;
    Запрос.УстановитьПараметр("КатегорияВнереализации",КатегорияВнереализации);
    Запрос.УстановитьПараметр("ДоговорПрофосмотра",ДоговорПрофосмотра);
    
    Если ИспользоватьУлучшеныйПоиск И МассивСтрокПоиска.Количество() > 0 Тогда
        
        ТекстУсловия = "(ЛОЖЬ ";
        
        Для К = 0 По МассивСтрокПоиска.ВГраница() Цикл
            
            Если ТипЗнч(МассивСтрокПоиска[К]) = Тип("Массив") Тогда
                
                МассивСлов = МассивСтрокПоиска[К];
                
                УсловиеФильтра = "(ИСТИНА";
                
                Для Ш = 0 ПО МассивСлов.ВГраница() Цикл
                    
                    ИП = Формат(Ш,"ЧГ=0");
                    Слово = МассивСлов[Ш];
                    УсловиеФильтра = УсловиеФильтра +
                    "
                    |    И (Контрагенты.Наименование ПОДОБНО &ТекстФильтра" + ИП + "
                    |    ИЛИ Контрагенты.НаименованиеПолное ПОДОБНО &ТекстФильтра" + ИП + ")";
                    
                    Запрос.УстановитьПараметр("ТекстФильтра" + ИП,"%" + Слово + "%");
                    
                КонецЦикла;
                
                УсловиеФильтра = УсловиеФильтра + ")";
                
                Продолжить;
                
            КонецЕсли;
            
            ИП = Формат(К,"ЧГ=0");
            Запрос.УстановитьПараметр("Текст" + ИП,"" + МассивСтрокПоиска[К] + "");
            
            ТекстУсловия = ТекстУсловия +
            "
            |    ИЛИ Контрагенты.Наименование ПОДОБНО &Текст" + ИП + "
            |    ИЛИ Контрагенты.НаименованиеПолное ПОДОБНО &Текст" + ИП;
            
        КонецЦикла;
        
        ТекстУсловия = ТекстУсловия + ")";
        
    Иначе
        Запрос.УстановитьПараметр("Текст1","" + Текст1 + "%");
        УсловиеФильтра =
        "(Контрагенты.Наименование ПОДОБНО &Текст1
        |            ИЛИ Контрагенты.НаименованиеПолное ПОДОБНО &Текст1)";
        ТекстУсловия = "ИСТИНА";
    КонецЕсли;
    ЗапросТекст =
    "ВЫБРАТЬ РАЗРЕШЕННЫЕ
    |    Контрагенты.Ссылка,
    |    Контрагенты.ПометкаУдаления,
    |    Контрагенты.Код,
    |    Контрагенты.Наименование КАК Наименование,
    |    Контрагенты.НаименованиеПолное КАК НаименованиеПолное,
    |    Контрагенты.Вес,
    |    Контрагенты.КоличествоСвязей
    |ПОМЕСТИТЬ втКонтрагентыФильтр
    |ИЗ
    |    Справочник.Контрагенты КАК Контрагенты
    |        ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
    |            ДоговорНаПроведениеМедОсмотровСписокМестРаботы.Контрагент КАК Контрагент
    |        ИЗ
    |            Документ.ДоговорНаПроведениеМедОсмотров.СписокМестРаботы КАК ДоговорНаПроведениеМедОсмотровСписокМестРаботы
    |        ГДЕ
    |            (ДоговорНаПроведениеМедОсмотровСписокМестРаботы.Ссылка = &ДоговорПрофосмотра
    |                    ИЛИ &ДоговорПрофосмотра = ЗНАЧЕНИЕ(Документ.ДоговорНаПроведениеМедОсмотров.ПустаяСсылка))) КАК КонтрагентыПоДоговору
    |        ПО (КонтрагентыПоДоговору.Контрагент = Контрагенты.Ссылка
    |                ИЛИ КонтрагентыПоДоговору.Контрагент = ЗНАЧЕНИЕ(Справочник.Контрагенты.ЧастноеЛицо))
    |ГДЕ
    |    НЕ Контрагенты.НельзяВыбрать
    |    И ВЫБОР
    |            КОГДА &КатегорияВнереализации <> ЗНАЧЕНИЕ(Перечисление.КатегорииВнереализации.ПенсионерИнвалидЖД)
    |                ТОГДА НЕ Контрагенты.ТолькоДляПенсионеров
    |            ИНАЧЕ ИСТИНА
    |        КОНЕЦ
    |    И (НЕ КонтрагентыПоДоговору.Контрагент ЕСТЬ NULL
    |            ИЛИ &ДоговорПрофосмотра = НЕОПРЕДЕЛЕНО)";
    
    ЗапросТекст = ЗапросТекст +
    "
    |
    |;
    |
    |";
    
    Если МассивСтрокПоиска.Количество() > 2 Тогда //выйгрыш в скорости не значительный, можно не использовать разделение
        ЗапросТекст = ЗапросТекст +
        "
        |ВЫБРАТЬ
        |    Контрагенты.Ссылка,
        |    Контрагенты.ПометкаУдаления,
        |    Контрагенты.Код,
        |    Контрагенты.Наименование КАК Наименование,
        |    Контрагенты.НаименованиеПолное КАК НаименованиеПолное,
        |    Контрагенты.Вес,
        |    Контрагенты.КоличествоСвязей
        |ПОМЕСТИТЬ втКонтрагенты
        |ИЗ
        |    втКонтрагентыФильтр КАК Контрагенты
        |ГДЕ
        |    &ТекстФильтра
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ ПЕРВЫЕ 51
        |    Контрагенты.Ссылка,
        |    Контрагенты.ПометкаУдаления,
        |    Контрагенты.Код,
        |    Контрагенты.Наименование КАК Наименование
        |ИЗ
        |    втКонтрагенты КАК Контрагенты
        |ГДЕ
        |    &ТекстУсловияДляНаименования
        |
        |УПОРЯДОЧИТЬ ПО
        |    Контрагенты.Вес УБЫВ,
        |    Контрагенты.КоличествоСвязей УБЫВ,
        |    Наименование
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |УНИЧТОЖИТЬ втКонтрагенты";
        
    Иначе
        ЗапросТекст = ЗапросТекст +
        "ВЫБРАТЬ
        |    Контрагенты.Ссылка,
        |    Контрагенты.ПометкаУдаления,
        |    Контрагенты.Код,
        |    Контрагенты.Наименование КАК Наименование,
        |    Контрагенты.НаименованиеПолное КАК НаименованиеПолное
        |ИЗ
        |    втКонтрагентыФильтр КАК Контрагенты
        |ГДЕ
        |    &ТекстФильтра
        |
        |УПОРЯДОЧИТЬ ПО
        |    Контрагенты.Вес УБЫВ,
        |    Контрагенты.КоличествоСвязей УБЫВ,
        |    Наименование";
    КонецЕсли;
    
    ЗапросТекст = СтрЗаменить(ЗапросТекст,"&ТекстУсловияДляНаименования",ТекстУсловия);
    ЗапросТекст = СтрЗаменить(ЗапросТекст,"&ТекстФильтра",УсловиеФильтра);
    
    Запрос.Текст = ЗапросТекст;
    
    Результат = Запрос.Выполнить().Выбрать();
    
    ДанныеВыбора = Новый СписокЗначений;
    
    Пока Результат.Следующий() Цикл
        ДанныеВыбора.Добавить(Результат.Ссылка,,Результат.ПометкаУдаления);    
    КонецЦикла;
    
    Если ДанныеВыбора.Количество() > 50 И Параметры.Свойство("НайденоБольше50") Тогда
        Параметры.НайденоБольше50.НайденоБольше50 = Истина;
    КонецЕсли;
    
КонецПроцедуры


Функция ПолучитьМассивСтрокПоиска(Текст)
    
    КомпонентаRegExp = Неопределено;
    
    МассивСтрокПоиска = Новый Массив;
    МассивСлов = Новый Массив;
    
    Если ИнициализироватьКомпонентуРегулярныхВыражений(КомпонентаRegExp) Тогда
        
        КомпонентаRegExp.Строка = Текст;
        
        ШаблонРВ = "[А-Яа-я0-9]+";
        
        КомпонентаRegExp.Шаблон = ШаблонРВ;
        
        ТекстПоиска = "";
        
        Пока КомпонентаRegExp.Найти() Цикл
            Для Номер = 0 По КомпонентаRegExp.КоличествоГрупп Цикл
                МассивСлов.Добавить(СокрЛП(КомпонентаRegExp.Группа(Номер)));
            КонецЦикла;
        КонецЦикла;
        
        Если МассивСлов.Количество() > 5 Тогда //Слишком много вложенных ИЛИ получается - запрос не проходит
            Возврат МассивСтрокПоиска;
        КонецЕсли;
            
        МассивПерестановок = ОбщегоНазначенияПовтИсп.ПолучитьИндексыПерестановкиПоДлинеМассива(МассивСлов.Количество());
        
        Для Каждого Перестановка Из МассивПерестановок Цикл
            
            СтрокаПоиска = "";
            
            Для Каждого ИндексСлова Из Перестановка Цикл
                Слово = МассивСлов[ИндексСлова - 1];
                СтрокаПоиска = СтрокаПоиска + "%" + Слово + "%[^а-я0-9]";
            КонецЦикла;
            СтрокаПоиска = Лев(СтрокаПоиска,СтрДлина(СтрокаПоиска)- СтрДлина("[^а-я0-9]"));
        
            МассивСтрокПоиска.Добавить(СтрокаПоиска);
            
        КонецЦикла;
        
        МассивСтрокПоиска.Добавить(МассивСлов);
        
    КонецЕсли;
    
    Возврат МассивСтрокПоиска;
    
КонецФункции
21 RomaH
 
naïve
14.05.14
07:57
22 RomaH
 
naïve
14.05.14
08:05
блин, а (0) совсем не о том
23 vde69
 
модератор
14.05.14
08:30
Процедура ПроизвестиПоиск()
    ПараметрыСеанса.ИспользоватьОтборПоДатам = ИспользоватьОтборПоДатам;
    ПараметрыСеанса.ИспользоватьОтборПоПлощадкам = ИспользоватьОтборПоПлощадкам;
    ПараметрыСеанса.ОтборПоДатамКонец = ОтборПоДатамКонец;
    ПараметрыСеанса.ОтборПоДатамНачало = ОтборПоДатамНачало;
    ПараметрыСеанса.ОтборПоПлощадкам = Новый ФиксированныйМассив (ОтборПоПлощадкам.ВыгрузитьЗначения());
    
    СтрокиПоиска = Обработки.ПоискЛотов.НайтиЛоты (РазделАнализа, Метаданные.РегистрыСведений.Лоты);


..............
..............
..............


Функция ПолучитьСтрокиДляПоиска(РазделАнализа)    
    Результат = Новый Массив;
    
    ПределСтроки = 250;
    
    Стр = СокрЛП(РазделАнализа.Наименование);
    Для Каждого эл из РазделАнализа.КлючиПоиска Цикл
        Стр2 = Стр + " OR " + эл.Ключ + " ";
        Если СтрДлина(Стр2) > ПределСтроки Тогда
            Результат.Добавить(Стр);
            Стр = эл.Ключ;
        Иначе
            Стр = Стр2;
        КонецЕсли;
    КонецЦикла;
    Результат.Добавить(Стр);
    
    Возврат Результат;
КонецФункции

Функция НайтиЛоты (РазделАнализа, ОбластьПоиска) Экспорт
    
    Результат = Новый Массив;
    
    Если ПолнотекстовыйПоиск.ПолучитьРежимПолнотекстовогоПоиска() <> РежимПолнотекстовогоПоиска.Разрешить Тогда
        Возврат Результат;
    КонецЕсли;

    СтрокиПоиска = ПолучитьСтрокиДляПоиска(РазделАнализа);
    
    Для Каждого Стр из СтрокиПоиска Цикл
        Список = ПолнотекстовыйПоиск.СоздатьСписок(стр, 100);
        Список.ОбластьПоиска.Добавить(Метаданные.РегистрыСведений.Лоты);
        Список.ПерваяЧасть();

        Для Каждого эл из Список Цикл
            Результат.Добавить(эл.Значение);
        КонецЦикла;
        
        Пока (Список.ПолноеКоличество() - Список.НачальнаяПозиция()) > Список.Количество() Цикл
            Список.СледующаяЧасть();
            Для Каждого эл из Список Цикл
                Результат.Добавить(эл.Значение);
            КонецЦикла;
        КонецЦикла;
    КонецЦикла;
    
    Возврат Результат;
КонецФункции