|
v7: использование в запросе условия на сравнение строки содержащей символ " | ☑ | ||
---|---|---|---|---|
0
andrewch60
09.02.23
✎
04:19
|
Необходимо запросом выбрать из большого справочника элементы по наименованию
список наименований может исчисляться сотнями. хотел сразу сделать через условие наименование В Список значений, но забыл, что "лампа" войдет и в "лампа 60w" пытаюсь сделать через склеивание в цикле Условия через сравнение на равенство и столкнулся с проблемкой, что в наименованиях содержится символ " забыл, как с этим бороться ТекстЗапроса = "//{{ЗАПРОС(Материалы) |Без итогов; |Наименование = Справочник.Материалы.Наименование; |ЕдиницаИзмерения = Справочник.Материалы.ЕдиницаИзмерения; |Цена = Справочник.Материалы.Цена; |СтранаПроисхождения = Справочник.Материалы.СтранаПроисхождения; |Материал = Справочник.Материалы.ТекущийЭлемент; |Группировка Наименование без групп; |Группировка Цена без групп; |"//}}ЗАПРОС ; СтрУсловия = ""; Для н=1 По РазмерСпискаН Цикл Стр = ""; СтрУсловия = СтрУсловия + " ИЛИ (СокрП(Наименование) = """""+ СтрЗаменить(СписокНаименований.ПолучитьЗначение(н, Стр), """","""""""""") + """"")" + РазделительСтрок; КонецЦикла; ТекстЗапроса = ТекстЗапроса + "Условие(" + Сред(СтрУсловия, 6) + ");"; получаю ошибку : ИЛИ (СокрП(Наименование) = "Светильник SQ0314-0005 НББ64-60-025 УХЛ4 (шар стекло " <<?>> "Кольца""/прямое основание) TDM") Запрос[114] : Ожидается ')' перед '"Кольца"' вывод текста запроса перед исполнением : //{{ЗАПРОС(Материалы) Без итогов; Наименование = Справочник.Материалы.Наименование; ЕдиницаИзмерения = Справочник.Материалы.ЕдиницаИзмерения; Цена = Справочник.Материалы.Цена; СтранаПроисхождения = Справочник.Материалы.СтранаПроисхождения; Материал = Справочник.Материалы.ТекущийЭлемент; Группировка Наименование без групп; Группировка Цена без групп; Условие((СокрП(Наименование) = "Лампа Navigator 82 462 NLLB-A60-10-230-6.5K-E27") ИЛИ (СокрП(Наименование) = "Лампа Navigator 82 463 NLLB-A60-12-230-6.5K-E27") ИЛИ (СокрП(Наименование) = "Лампа Navigator 82 506 NLLB-C37-7-230-4K-E14-FR") ИЛИ (СокрП(Наименование) = "ATN000501 ATLASDESIGN 1-постовая РАМКА, ШАМПАНЬ") ... ИЛИ (СокрП(Наименование) = "Светильник SQ0314-0002 НББ64-60-025 УХЛ4 (шар пластик/наклонное основание) TDM") ИЛИ (СокрП(Наименование) = "Светильник SQ0314-0005 НББ64-60-025 УХЛ4 (шар стекло ""Кольца""/прямое основание) TDM") ИЛИ (СокрП(Наименование) = "ATN000583 ATLASDESIGN РОЗЕТКА компьютерная RJ45, механизм, ШАМПАНЬ") ); |
|||
1
Irbis
09.02.23
✎
06:14
|
""
|
|||
2
NorthWind
09.02.23
✎
06:57
|
Насколько я помню, в запрос же можно передать контейнер (массив, ТЗ) в качестве параметра. Так сложите туда ваши наименования, и всех делов ...
|
|||
3
NorthWind
09.02.23
✎
07:07
|
В семерке, точно помню, передавался СписокЗначений...
|
|||
4
Злопчинский
09.02.23
✎
07:36
|
"Необходимо запросом выбрать из большого справочника элементы по наименованию"
группировки убрать вообще. для выборки элементов справочника они не нужны, тем более нет агрегирующих функций. . Условие(СписокНаименований.НайтиЗначение(СокрП(Наименование))<>0); |
|||
5
Злопчинский
09.02.23
✎
07:38
|
Ну и в списокНаименований загонять не строки, а нужные текущие элементы спр.материалы и
Условие(СЗМатериалы.НайтиЗначение(Материал)<>0); |
|||
6
Злопчинский
09.02.23
✎
07:39
|
к (5): если есть такая возможность
|
|||
7
Злопчинский
09.02.23
✎
07:44
|
а не проще СРАЗУ искать по наименованиям?
Цикл ДанныеОТкудаТо НаименованиеВнешнее = ПолучитьНаименование(); Результат = СпрМатериалы.НайтиПоНаименованию(НаименованиеВнешнее); Если Результат = 0 Тогда Продолжить; КонецЕсли; Материал = СпрМатериалы.ТекущийЭлемент(); // делаем что надо с найденным материалом .... КонецЦикла; |
|||
8
АгентБезопасной Нацио
09.02.23
✎
08:02
|
Еще одна угнанная учетка...
|
|||
9
Злопчинский
09.02.23
✎
08:05
|
(8) не, просто народ возвращается от богомерзких поделий к православным клюшкам... ;-)
|
|||
10
АгентБезопасной Нацио
09.02.23
✎
08:27
|
(9) его страна обитания, такое ощущение, что и не уходила.
там все клюшечники, и один другого краше... впрочем, судя по темам, он 10 лет на клюшках... |
|||
11
NorthWind
09.02.23
✎
08:48
|
(5) А почему не
Условие (Материал В СЗМатериалы); ? |
|||
12
Irbis
09.02.23
✎
08:56
|
(11) Там вариантов реализации тьма, от в списке и загрузки в отдельный подзапрос ТЗ до ПОДОБНО и подстрока подобия. Чтобы советовать, похоже нужно знать реальную задачу.
|
|||
13
andrewch60
09.02.23
✎
13:56
|
Не касался 7ки почти лет 8
Может я плохо описал ситуацию Попросили сделать загрузку ТЧ ПоступленийМатериалов от одной организации из DBF файла. Он содержит Наименование и цену. Справочник Материалов большой, партионного учета нет. Т е один материал по новой цене вносится новым элементом. Не факт, что и с одинаковой ценой не вносили дубли Решил, что в цикле по каждой строке ТЧ из ДБФ искать по наименованию и цене материалы будет долго. свернул таблицу по Наименованию и по Цене, выгрузил список Наименований и список Цен Попробовал Условие (Наименование В СписокНаименований); Условие (Цена В СписокЦен); Посмотрел, что элементы справочника с наименованиями "лампа", "лампа Navigator", "лампа Navigator 82" попадут в выборку при сравнении с "Лампа Navigator 82 463 NLLB-A60-12-230-6.5K-E27" Т е сравнение идет на частичное совпадение, что не подходит. НайтиПоНаименованию тоже не катит - он найдет первый элемент с таким наименованием, а их может быть много |
|||
14
andrewch60
09.02.23
✎
13:59
|
(1) СтрЗаменить(СписокНаименований.ПолучитьЗначение(н, Стр), """","""""""""") у меня и удваивает " внутри наименования:
из Светильник SQ0314-0005 НББ64-60-025 УХЛ4 (шар стекло "Кольца"/прямое основание) TDM получаю "Светильник SQ0314-0005 НББ64-60-025 УХЛ4 (шар стекло ""Кольца""/прямое основание) TDM" ИЛИ (СокрП(Наименование) = "Светильник SQ0314-0005 НББ64-60-025 УХЛ4 (шар стекло ""Кольца""/прямое основание) TDM") |
|||
15
Irbis
09.02.23
✎
14:07
|
Плохо клюшки помню, но для объектов там было что-то типа .Выбрать() с параметрами типа выбрать по реквизиту.
|
|||
16
andrewch60
09.02.23
✎
14:13
|
(15) Да, только у этого реквизита должна быть галка "Отбор по реквизиту"(тогда вроде отдельный индекс создавался по нему) и Наименование туда не входит
не хочу изменять конфигурацию, и в любом случае запрос должен намного быстрее отработать, если эту проблемку с кавычкой решить. И помнится, что она как то решаема... кстати ПОДОБНО и подзапрос с параметром ТЗ вроде только в 8ке... но не уверен |
|||
17
АгентБезопасной Нацио
09.02.23
✎
14:28
|
как соотносятся названия в файле, цены, и названия материалов?
|
|||
18
Irbis
09.02.23
✎
14:28
|
(16) >> кстати ПОДОБНО и подзапрос с параметром ТЗ вроде только в 8ке... но не уверен
Да это я плохо посмотрел на раздел |
|||
19
Irbis
09.02.23
✎
14:30
|
СтрЗаменить(СписокНаименований.ПолучитьЗначение(н, Стр), """","""""""""") зачем в заменяемой подстроке столько "? По смыслу задачи должно быть ровно 6
|
|||
20
АгентБезопасной Нацио
09.02.23
✎
14:31
|
(16) черный запрос быстрее не отработает. Он отбирает по ключу, если возможно, и тянет на клиента dbf (результат первичной выборки), в котором уже с клиента локально ищет (за давностью лет, не помню, как индексирует)
Поставь 1sqlite |
|||
21
Irbis
09.02.23
✎
14:31
|
Или вообще воспользоваться поиском и генерацией символа по коду в таблице кодов
|
|||
22
АгентБезопасной Нацио
09.02.23
✎
14:32
|
+(20) если, конечно, база файловая. а если не файловая, то вообще лепота.
|
|||
23
andrewch60
09.02.23
✎
14:46
|
(17) полное совпадение наименования и цены. иначе создаем новый элемент
|
|||
24
andrewch60
09.02.23
✎
14:48
|
(19) ночью уже сколько не пробовал ... в текущей версии глянул - 6. результат - ошибка та же
|
|||
25
andrewch60
09.02.23
✎
14:48
|
(24) СтрУсловия = СтрУсловия + " ИЛИ (СокрП(Наименование) = """+ СтрЗаменить(СписокНаименований.ПолучитьЗначение(н, Стр), """","""""") + """)" + РазделительСтрок;
|
|||
26
Fedor-1971
09.02.23
✎
14:49
|
(23) В таком раскладе: Условие(Наименование В СписокНаименований);
Список наименований запихиваешь в СписокЗначений |
|||
27
Irbis
09.02.23
✎
14:50
|
Проверь визуально получившуюся строку в отладчике. Чудес на свете не бывает. Я бы вообще сначала собрал бы строку, а потом один раз заменил " на ""
|
|||
28
Fedor-1971
09.02.23
✎
14:50
|
26+ тогда без разницы есть ли в наименовании ", иначе придётся удвоить все "
|
|||
29
andrewch60
09.02.23
✎
14:53
|
(20) один раз запросом выбрать и потом уже цикл по отбору по цене очень вряд ли будет работать медленнее, чем поиск в цикле по всему справочнику. Кстати поиск по наименованию(как писал выше) только первый элемент вернет... Т е мне не подходит
|
|||
30
Fedor-1971
09.02.23
✎
14:56
|
(27) не факт, что анализ текста запроса не провалится в ошибку
(29) Попробуй ВыбратьЭлементыПоРеквизиту, а потом цикл по ПолучитьЭлемент() |
|||
31
andrewch60
09.02.23
✎
14:57
|
(27) я в первом после вставлял вывод текста запроса перед исполнением :
вывод текста запроса перед исполнением : //{{ЗАПРОС(Материалы) Без итогов; Наименование = Справочник.Материалы.Наименование; ЕдиницаИзмерения = Справочник.Материалы.ЕдиницаИзмерения; Цена = Справочник.Материалы.Цена; СтранаПроисхождения = Справочник.Материалы.СтранаПроисхождения; Материал = Справочник.Материалы.ТекущийЭлемент; Группировка Наименование без групп; Группировка Цена без групп; Условие((СокрП(Наименование) = "Лампа Navigator 82 462 NLLB-A60-10-230-6.5K-E27") ИЛИ (СокрП(Наименование) = "Лампа Navigator 82 463 NLLB-A60-12-230-6.5K-E27") ИЛИ (СокрП(Наименование) = "Лампа Navigator 82 506 NLLB-C37-7-230-4K-E14-FR") ИЛИ (СокрП(Наименование) = "ATN000501 ATLASDESIGN 1-постовая РАМКА, ШАМПАНЬ") ... ИЛИ (СокрП(Наименование) = "Светильник SQ0314-0002 НББ64-60-025 УХЛ4 (шар пластик/наклонное основание) TDM") ИЛИ (СокрП(Наименование) = "Светильник SQ0314-0005 НББ64-60-025 УХЛ4 (шар стекло ""Кольца""/прямое основание) TDM") ИЛИ (СокрП(Наименование) = "ATN000583 ATLASDESIGN РОЗЕТКА компьютерная RJ45, механизм, ШАМПАНЬ") ); вроде как выглядит красиво... " в наименовании заменилось на "" кажется, что какую то дикую мелочь упускаю |
|||
32
andrewch60
09.02.23
✎
15:00
|
(30) ВыбратьЭлементыПоРеквизиту с Наименованием не работает
|
|||
33
Irbis
09.02.23
✎
15:00
|
В визуальном контроле ""Кольца"" не должно быть
|
|||
34
andrewch60
09.02.23
✎
15:04
|
(33) допустим , что нам нужно только одно сравнение на = Светильник SQ0314-0005 НББ64-60-025 УХЛ4 (шар стекло "Кольца"/прямое основание) TDM
как должен выглядеть текст запроса (переменную использовать нельзя)? |
|||
35
Irbis
09.02.23
✎
15:07
|
При визуальном контроле в отладчике примерно так:
= "Светильник SQ0314-0005 НББ64-60-025 УХЛ4 (шар стекло "Кольца"/прямое основание) TDM" Двойная кавычка в строке наименования нужна чтобы корректно строка отображалась, визуально такого не должно наблюдаться |
|||
36
Builder
09.02.23
✎
15:33
|
(18) Ну в клюшках черные запросы умеют искать подстроку в строке через В.
|
|||
37
Злопчинский
09.02.23
✎
15:56
|
че вы морочитесь?
делайте проще, это ж не каждые 5 секунд загрузка будет вертеться //******************************************* Процедура Сформировать() ТекстЗапроса = " |Без итогов; |Наименование = Справочник.Номенклатура.Наименование; |ЕдиницаИзмерения = Справочник.Номенклатура.БазоваяЕдиница; |Цена = Справочник.Номенклатура.МинОстаток; |Номенклатура = Справочник.Номенклатура.ТекущийЭлемент; |Группировка Наименование; |Группировка Цена; |Условие(СписокНаименований.НайтиЗначение(СокрП(Наименование))<>0); //|Условие(МояФункция(Наименование,Цена)=1); |";//}}ЗАПРОС Запрос = СоздатьОбъект("Запрос"); Запрос.Выполнить(ТекстЗапроса); ТЗ = СоздатьОбъект("ТаблицаЗначений"); Запрос.Выгрузить(ТЗ,1,0); //ПечатьТЗ(ТЗ); ТЗ.НоваяКолонка("Ключ","Строка"); Цикл по ТЗ ТЗ.Ключ = ТЗ.Наименование+"^"+ТЗ.Цена; // РЕГИСТР НАИМЕНОВАНИЯ и ФОРМАТ ЦЕНЫ!!!! СОБЛЮАДСТЬ!!! КонецЦикла; Цикл по данным ДБФ КлючДБФ = ДБФ.Наименование+разделитель+ДБФЦена. ТЗ.НайтиЗначение(КлючДБФ,поз,"Ключ"); КонецЦикла КонецПроцедуры |
|||
38
Злопчинский
09.02.23
✎
15:58
|
Можно прочитать данные из ДБФ, сформировать ключ ДБФ, загнать эти ключи в СЗ (глобальный для обработки)
а в запросе в МояФункция() делать Функция МояФункция(Наименование,Цена) Ключ = Наименование+Цена; поз = СЗключейДБФ.НайтиЗначение(Ключ); Возврат ?(поз=0,0,1); КонецФункции |
|||
39
Злопчинский
09.02.23
✎
15:59
|
тогда запрос вернет строки подходящие только по наименованию и цене
дальше с этой выборкой (ТЗ результата запроса) - что хошь то и делай |
|||
40
Злопчинский
09.02.23
✎
15:59
|
развели бодягу на неделю...
|
|||
41
andrewch60
09.02.23
✎
17:57
|
(37) |Условие(СписокНаименований.НайтиЗначение(СокрП(Наименование))<>0);
так работает, спасибо хотя не пойму, почему такой запрос не получается сделать рабочим... ТекстЗапроса = " |Без итогов; |Наименование = Справочник.Материалы.Наименование; |ЕдиницаИзмерения = Справочник.Материалы.ЕдиницаИзмерения; |Цена = Справочник.Материалы.Цена; |СтранаПроисхождения = Справочник.Материалы.СтранаПроисхождения; |Материал = Справочник.Материалы.ТекущийЭлемент; |Группировка Наименование без групп; |Группировка Цена без групп; |Условие(СокрЛП(Наименование) = ""Светильник"""" TDM"");"; |
|||
42
Chai Nic
09.02.23
✎
18:04
|
Когда в далеком 2000 году я проходил курсы конфигурирования в 1с 7.7, сертифицированный 1совский препод по секрету сказал, что запрос это самый неудачный механизм платформы и им пользоваться не надо. Уже тогда.
С тех пор прошло много лет. Появились 1с++ с прямыми SQL запросами, которые работают предсказуемо быстро. Но люди почему-то до сих пор занимаются ерундой и тратят время на "черные запросы", которые мало того что неочевидны, так ещё и непредсказуемы по скорости. Например, запрос может половину базы забрать в каталог временных файлов а потом в этой куче ковыряться, хрустя диском. |
|||
43
Злопчинский
09.02.23
✎
18:55
|
(41) "хотя не пойму, почему..."
1. потому что идея в условие пихать сравнение кучи строк - мудачная. 2. потому что итоговая строка условия тебя выглядит так Условие(СокрП(Наименование) = "Светильник"" TDM"); напиши в виде литерала БЕЗ синтаксических ограничивающих кавычек только с внутренними кавчками в наименовании как у тебя этот светильник ТДМ называется |
|||
44
Злопчинский
09.02.23
✎
19:27
|
.. но запихнуть в литерал для сравнения наименование
Светильник "TDM" у меня не получилось... |
|||
45
andrewch60
09.02.23
✎
20:04
|
(43) 1 идея может и хреновая, если есть другая хорошая...
2 именно так и выглядит итоговая строка (для простоты оставил одно условие на Светильник "TDM ) всего одно сравнение, всего одна кавычка... а запрос так и не работает... |
|||
46
andrewch60
09.02.23
✎
20:05
|
теперь уже не для решения моей задачи, запрос с кучей ИЛИ и без кавычек работает крайне медленно
но любопытства ради |
|||
47
andrewch60
09.02.23
✎
20:07
|
(4) без группировок 7ка вроде как ничего не выбирает вообще...
|
|||
48
Злопчинский
09.02.23
✎
20:28
|
(47) да, ошибся. это я с прямым углом попутал...
|
|||
49
Злопчинский
09.02.23
✎
20:29
|
(45) Условие(СписокНаименований.НайтиЗначение(СокрП(Наименование))<>0);
и не мучай себе мозги. с кавычками в наименовании мне не удалось добиться чтобы запрос не ругался.. |
|||
50
Злопчинский
09.02.23
✎
20:30
|
(46) по сути запрос тупо перебирает все записи и начинает сравнивать с литералами. Сравнение строк всегда медленно.
|
|||
51
Злопчинский
09.02.23
✎
20:31
|
(35) мне кавычки внутри наименования не удалось победить.
|
|||
52
andrewch60
09.02.23
✎
20:35
|
(50) и через список без сравнения строк никак не может обойтись... но пути господни неисповедимы)
|
|||
53
Злопчинский
09.02.23
✎
20:36
|
Можно вообще без запроса сделать и будет еще быстрее...
типа попробовать прочитали запись с ДБФ. НаименованиеДБФ СпрМ.ПорядокНаименований(); СпрМ.ВыбратьЭлементы(); СпрМ.НайтиПоНаименованию(НаименованиеДБФ); // тут тупо сдвинули выборку не в начало а куда-то в середину - МОЖЕТ ПРОКАТИТ Пока СпрМ.ПолучитьЭлемент()=1 Цикл Если СпрМ.Наименование <> НаименованиеДБФ Тогда Прервать; КонецЕсли; // а тут делаем что надо |
|||
54
Злопчинский
09.02.23
✎
20:37
|
(52) ну потому что пихать для обмена в качестве ключа доступа/синхронизации в ДБA наименование - так себе идея? но вполне рабоачая.
а то что у вас туева хуча дублей материалов (которые все "ломают") - ССЗБ |
|||
55
Злопчинский
09.02.23
✎
20:37
|
(53) ща попробую тестовый накидать
|
|||
56
Злопчинский
09.02.23
✎
20:51
|
(55) не.. так не пойдет, выборка рушится
|
|||
57
Злопчинский
09.02.23
✎
21:00
|
(52) ну а как ты хочешь, если во внешнем файле у тебя ключ синхронизации - длинная строка, не гуид какой-нить.
|
|||
58
andrewch60
09.02.23
✎
21:00
|
(55) не мучайтесь, запрос с Условие(СписокНаименований.НайтиЗначение(СокрП(Наименование))>0); отрабатывает меньше чем за 1 сек. Совпадений почему то почти нет... Более чем приемлемо
Больше не вижу проблемы спасибо единственное : раньше пользовался OpenConf а сейчас почему то : Не могу создать объект OpenConf.CommonServices Скрипт Intellisence не загружен Не могу создать объект OpenConf.CommonServices Скрипт Форматирование текста не загружен ... а ,помнится, было очень удобно может подскажете, где взять последнюю версию? |
|||
59
Злопчинский
09.02.23
✎
21:01
|
(58) ну и ок.
|
|||
60
Злопчинский
09.02.23
✎
21:03
|
(58) "Совпадений почему то почти нет..."
а тут тебе не регистронезависимый индекс. надо соблюдать совпадение регистров. один лишний пробел/запт/слэш/или чтонить - и всё, совпадения не будет... то есть если в СЗ будет "ЧТОТО", а ты ищешь "Чтото" - то результат =0 |
|||
61
Злопчинский
09.02.23
✎
21:04
|
(58) OpenConf Light Pack на ИС и поправки к нему для х64
и на ИС сборки скриптов 1-2 публикации есть а так - наверное на форуме 1С++ |
|||
62
Злопчинский
09.02.23
✎
21:06
|
(60) т.е. в СписокНаименований я бы совал НРег(СокрЛП(НаименованиеВнешнее))
а в услвоии сооответсвоенно НРег(СокрЛП(Наименование)) |
|||
63
andrewch60
09.02.23
✎
21:22
|
(60) за это отдельное спасибо, не пришло в голову
с запт/слэш/или чтонить ничего не поделаешь, а вот с регистром - да |
|||
64
Злопчинский
09.02.23
✎
22:16
|
(63) ну и с небуквенными символами тоже можно без проблем (быстродействие только)
перед тем как совать НаименованиеВнешнее в СЗ - нормализуй его, типа //***************************************************************** //заменяет в строке Источник символы из набора НормальныйШаблон //на символ Нормализатор; //если в наборе НормальныйШаблон присутствует символ Нормализатора, //то нормализация происходит на пустой символ // Функция глНормализоватьСтроку(Знач Источник, Знач НормальныйШаблон="\/:*?""<>| ", Знач Нормализатор="#") Экспорт Если Найти(НормальныйШаблон,Нормализатор)<>0 Тогда Нормализатор = ""; КонецЕсли; Источник = СокрЛП(Источник); Дл = СтрДлина(НормальныйШаблон); Для ы=1 по Дл Цикл Источник = СтрЗаменить(Источник,Сред(НормальныйШаблон,ы,1),Нормализатор); КонецЦикла; Возврат Источник; КонецФункции //глНормализоватьСтроку() НаименованиеВнешнее = глНормализоватьСтроку(НаименованиеВнешнее,НормальныйШаблон,""); НормальныйШаблон = "-–№”""«»,\/:*?<>|!#() "+РазделительСтрок+СимволТабуляции+Симв(9)+Симв(160); //сюда еще можно добавить всякой хрени все нефонетические символы а в условии используй МояФункция, в которую передавай Наименование из запроса ив функции наименование из запроса тоже нормализуй вызовом той же самой глНормализоватьСтроку и только потом найтизначение - нормализованное из запроса среди нормализованных из внешнего источника |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |