![]() |
|
v7: Ускорить поиск товара | ☑ | ||
---|---|---|---|---|
0
evgpinsk_
07.09.19
✎
09:35
|
Есть справочник ТМЦ
К нему есть подчинённый справочник "КодыТМЦПоставщиков" http://prntscr.com/p2yhcx Есть ТЗ (состоит из одного столбца "Код поставщика") заполняется списком пусть из 1000 строк. Задача создать второй столбец "ТМЦ" , который будет находиться по "коду поставщика" Решаю через перебор строк ТЗ и вызова для каждой строки функции: Функция НайтиТМЦПоКоду(КодПоставщика) Спр_кодов=СоздатьОбъект("Справочник.КодыТМЦПоставщиков"); Спр_прайсов=СоздатьОбъект("Справочник.ПрайсыПоставщиков"); Спр_прайсов.НайтиПоКоду(ПрайсПставщика); Спр_кодов.ВыбратьЭлементыПоРеквизиту("Прайс",Спр_прайсов.ТекущийЭлемент(),0,1); Пока Спр_кодов.ПолучитьЭлемент()=1 цикл Если (Спр_кодов.Наименование=СокрЛП(КодПоставщика)) и (Спр_кодов.ПометкаУдаления()=0) тогда НайденныйТМЦ=Спр_кодов.ТекущийЭлемент().Владелец; Возврат 1; КонецЕсли; КонецЦикла; Возврат 0; КонецФункции Проблема, что для большого количества строк ТЗ заполнение второго столбца идёт очень долго. Как ускорить? |
|||
1
Злопчинский
07.09.19
✎
09:51
|
какой-то треш и угар
функцию для чего вызываете? для заполнения тз? |
|||
2
Злопчинский
07.09.19
✎
09:52
|
вызываете в цикле?
верхний цикл тыща строк и для каждой строки тз акпкбор подчиненного справочника? еще бы не медленно |
|||
3
Злопчинский
07.09.19
✎
09:53
|
создатьобъект - вынести за все циклы
|
|||
4
Злопчинский
07.09.19
✎
09:53
|
стукнись в скайп оперативно, посмотрю сделаем онлайн вместе
|
|||
5
Злопчинский
07.09.19
✎
09:56
|
даже в том коде который есть - судя по всему ты для каждого тмц перебираешь коды поставщиков для ВСЕХ тмц
|
|||
6
Злопчинский
07.09.19
✎
09:57
|
Впихни ИспользоватьРодителя(ТекущийТМЦ)
|
|||
7
Злопчинский
07.09.19
✎
10:00
|
Спр_кодов.ТекущийЭлемент().Владелец;
- убрать текущийэдемент. когда у тебя есть открытая выборка по справочнику то при движении по ней ты уже имеешь доступ к строке справочника. ипользуя текущийэлемент ты принрудительно заставляешь систему еще раз перечитать элемент справочника - нахрена? |
|||
8
Злопчинский
07.09.19
✎
10:03
|
Спр_кодов.Наименование - хотя это строка 30 символов но система возвращает с обрезкой правых пробелов, но я бы на всякий случай влепитл бы СокрЛП
|
|||
9
Сияющий в темноте
07.09.19
✎
10:14
|
А почему искать по тз?
либо формекс и индексированная таблица либо внутренние представления в обьект Dictionary. |
|||
10
Злопчинский
07.09.19
✎
10:20
|
да, итз - будет побыстрее. но на небольших обьемах и тз обычная норм.
а заполнение можно или чорным запросом сделать для начала или прямым запросом |
|||
11
Cthulhu
07.09.19
✎
10:34
|
Функция НайтиТМЦПоКоду(КодПоставщика,ДляПрайса,Спр_кодов)
Спр_кодов.ВыбратьЭлементыПоРеквизиту("Прайс",ДляПрайса,0,1); Пока Спр_кодов.ПолучитьЭлемент() <>0 Цикл Если (Спр_кодов.Наименование=СокрЛП(КодПоставщика))И(Спр_кодов.ПометкаУдаления()=0) Тогда Возврат(Спр_кодов.Владелец) КонецЕсли КонецЦикла; Возврат(0); КонецФункции //НайтиТМЦПоКоду Процедура Сформировать() Перем ДопустимЭтаТЗ,тПрайс,Спр_кодов; //ДопустимЭтаТЗ=СоздатьОбъект("ТаблицаЗначений"); // ну, допустим //ДопустимЭтаТЗ.НоваяКолонка("КодПоставщика"); // эта ТЗ заполнена //ДопустимЭтаТЗ.НоваяКолонка("Тмц","Справочник.ТМЦ"); // (хрензнаетсколькострок) тПрайс=СоздатьОбъект("Справочник.ПрайсыПоставщиков"); тПрайс.НайтиПоКоду(ПрайсПставщика); тПрайс=тПрайс.ТекущийЭлемент(); Спр_кодов=СоздатьОбъект("Справочник.КодыТМЦПоставщиков"); ДопустимЭтаТЗ.ВыбратьСтроки(); Пока ДопустимЭтаТЗ.ПолучитьСтроку()<>0 Цикл ДопустимЭтаТЗ.Тмц=НайтиТМЦПоКоду(ДопустимЭтаТЗ.КодПоставщика,тПрайс,Спр_кодов) КонецЦикла; КонецПроцедуры // а вообще - люто рекомендую замер производительности в отладчике! |
|||
12
zercv
07.09.19
✎
10:36
|
ИМХО нужно смотреть на всю архитектуру, и начинать именно с нее.
Я лично несколько раз тоже начинал с "как ускорить функцию", хотя нужно с начало начинать с архитектуры. |
|||
13
Злопчинский
07.09.19
✎
10:59
|
код поставщика явно выбирается по нужному прайсу для текущей номенклатуры. не забудьте использоватьродителя
|
|||
14
evgpinsk_
07.09.19
✎
11:16
|
(12) Справочник ТМЦ, обычный всё понятно
Далее есть спарвочник "Прайсы". Грубо - теже поставщики И далее, 3й справочник "КодыТМЦПоставщиков", скрин приводил в (0) Для каждого товара есть несколько разных поставщиков и у каждого поставщика свой код товара. Приходую товар по кодам поставщиков. В приходной накладной есть код поставщика. Мне нужно находить по коду свой ТМЦ из 1с |
|||
15
evgpinsk_
07.09.19
✎
11:16
|
Спасибо за ответы, чуть позже перечитаю рекомендации выше
|
|||
16
zercv
07.09.19
✎
11:28
|
(14) если справочники подчиненные находи по нужному справочнику и бери просто владельца, либо выведи доп.реквизит с ссылкой на нужную ТМЦ.
У меня: Справочник ТМЦ. Справочник Поставщики. Справочник АртикулПоставщика, подчиненный поставщику, в котором есть реквизит "ТМЦ" (ссылка на ТМЦ, к которому сопоставлен этот артикул). В результате делаю поиск по "АртикулПоставщика" и нахожу нужный ТМЦ. |
|||
17
evgpinsk_
07.09.19
✎
11:31
|
(16) Да, уже думал так переделать архитектуру. Но просто много чего накручено уже на текущую, переделки будет не мало.
|
|||
18
evgpinsk_
07.09.19
✎
11:32
|
(7) Перечитаю внимательно все рекомендации попозже )
Самоучка по 1с, и не все нюансы могу знать ) |
|||
19
zercv
07.09.19
✎
11:34
|
(17) не всегда долго переделывать :) (экспорт, импорт и т.д.)
Иногда долго надеяться и искать вариант решение того, что нужно просто переделать :-) |
|||
20
evgpinsk_
07.09.19
✎
11:38
|
(19) Верно. Но если мой код можно оптимизировать и результат устроит, проще код оптимизировать
|
|||
21
evgpinsk_
07.09.19
✎
12:06
|
(11) Не совсем понял, чем ваш приведённый код отличается от моего?
Насколько я понимаю, основной тормоз идёт изза этого: Спр_кодов.ВыбратьЭлементыПоРеквизиту("Прайс",ДляПрайса,0,1); Пока Спр_кодов.ПолучитьЭлемент() Сейчас у меня: справочник ТМЦ - 35000 позиций Справочник "КодыТМЦПоставщиков" - 23000 позиций |
|||
22
evgpinsk_
07.09.19
✎
12:08
|
п.с. какбы понять, каким образом Миста форматирует иногда часть сообщений тегом [code]..[/code] ?
Предварительного просмотра вроде как нет здесь , что очень не удобно |
|||
23
Сияющий в темноте
07.09.19
✎
12:19
|
(22) убедить Волшебника,чтобы код работал явно,а не по обнаружению слов,похожих на язык 1с.
|
|||
24
evgpinsk_
07.09.19
✎
12:30
|
(6) (13)
Не пойму где здесь может помочь ИспользоватьРодителя ? |
|||
25
Djelf
гуру
07.09.19
✎
12:36
|
(21) Нет. Основной тормоз идет из-за
Если (Спр_кодов.Наименование=СокрЛП(КодПоставщика)) и (Спр_кодов.ПометкаУдаления()=0) тогда Разберись со справочником чтобы пометки удаления и дубликатов вообще не было. Тогда сможешь использовать НайтиПоНаименованию вообще без цикла. Ну или прямой запрос сильно ускорит. [code] SELECT Коды.PARENTEXT [ТМЦ :Справочник.ТМЦ] FROM Справочник_КодыТМЦПоставщиков AS Коды WHERE Коды.Прайс=@Прайс AND Коды.DESCR=@Код AND Коды.ISMARK<>'*' LIMIT 1 [/code] (24) Все верно, не поможет. |
|||
26
zercv
07.09.19
✎
12:46
|
(25) при этом, если база скл, из-за сложной архитектуры и возможно долгой отроботке запроса, есть шанс нагрузить всю бд, в результате чего будет ошибка и закрытие приложение.
(0) долго это сколько? |
|||
27
Djelf
гуру
07.09.19
✎
12:48
|
(26) Чего? оО Это элементарный запрос, попадающий в индекс. Он выполнится за 0.01с
|
|||
28
evgpinsk_
07.09.19
✎
13:09
|
(26) У меня идёт чтение из Excel файла, тоже не оптимизировано. Пока читаю Excel построчно через Лист2.Cells(i,j).value
Файл из 100 позиций - само чтение файла 18 секунд Если в момент чтения ещё искать товары по артикулам поставщиков - то этот же файл 42 секунды. |
|||
29
evgpinsk_
07.09.19
✎
13:17
|
(25) "Разберись со справочником чтобы пометки удаления и дубликатов вообще не было.
Тогда сможешь использовать НайтиПоНаименованию вообще без цикла. " Дело в том, что Артикулы разных поставщиков могут пересекаться между собой. Пока не совсем понимаю, каким образом при моей текущий структуре можно обойтись только НайтиПоНаименованию. Сейчас стурктуру 3х справочников изображу: |
|||
30
Djelf
гуру
07.09.19
✎
13:33
|
(29) Точно. Так не получится. Что то я с sqlite уже навигационный поиск забываю ;)
Вот для поиска по Наименованию и пригодилось бы ИспользоватьВладельца, только местами нужно поменять ТМЦ и Прайс. |
|||
31
evgpinsk_
07.09.19
✎
13:36
|
Структура сейчас такая /правда не совсем красиво писать структуру для 1с/:
http://prntscr.com/p3085x Нужно подумать, имеет ли смысл менять архитектуру |
|||
32
evgpinsk_
07.09.19
✎
13:39
|
(25) Не имел дело с прямыми запросами. Я так понимаю нужно добавлять 1С++ ?
Имеет смысл тратить время на изучения для решения данной задачи? ) |
|||
33
Djelf
гуру
07.09.19
✎
13:44
|
(32) dbf или sql?
Смысл имеет. В узких местах местах раз так в 1000 и более можно по скорости выиграть. А 1С++ даже в "холостом" режиме за счет turbobl имеет смысл подключать. |
|||
34
evgpinsk_
07.09.19
✎
13:45
|
(33) dbf
|
|||
35
evgpinsk_
07.09.19
✎
13:47
|
(33) Позволяю тратить на программирование только 10% своего рабочего времени, вспомнил что пытался внедрить 1с++, но както быстро он не зашёл )
Не хватило квалификации ) Хотя конечно ускориться в 1000 раз не помешало |
|||
36
evgpinsk_
07.09.19
✎
13:51
|
(16) Т.е. в моём случае нужно поменять структуру следующим образом. Справочник "КодыПоставщик" исправить подчиние с текущего справочника "Номенклатура" на справочник "Прайсы"
http://prntscr.com/p30d76 Имеет смысл? Переделок в кодах будет много, много где завязано |
|||
37
evgpinsk_
07.09.19
✎
13:57
|
Тогда сначала мы используем: КодыПоставщиков.ИспользоватьВладельца(Прайс)
т.е. отфильтровали все товары данного Поставщика а затем через: КодыПоставщиков.НайтиПоНаименованию(АртикулаПоставщика,1,1) найти нужный товар. Это даст существенный выигрыш времени? |
|||
38
Djelf
гуру
07.09.19
✎
14:26
|
(37) Да. Вместо 24с будет 24мс.
|
|||
39
HawkEye
07.09.19
✎
14:41
|
(0) что такое Прайс на скрине? строка? элемент Прайса?
|
|||
40
HawkEye
07.09.19
✎
14:43
|
+(39) судя по коду, элемент справочника Прайс..
|
|||
41
evgpinsk_
07.09.19
✎
14:44
|
(39) в первом посту скрин-ответ
(40) да |
|||
42
evgpinsk_
07.09.19
✎
14:45
|
(38) Либо внедрить 1с++ и прямой запрос, так? ))
Нужно думать какой путь выбрать ) |
|||
43
HawkEye
07.09.19
✎
14:45
|
(41) значит получается, у тебя может быть несколько одинаковых кодов поставщика, относящихся к разным элементам Номенклатуры и что-бы разобрать к какому из них, используется справочник прайс, т.к. ты знаешь чей Прайс ты сейчас используешь...
|
|||
44
HawkEye
07.09.19
✎
14:47
|
+(43) а значит логичнее сначала найти все коды, а потом сравнивать прайсы т.к. кол-во элементов в прайсе в сотни раз больше одинаковых кодов, одно это (замена циклов местами) увеличит работу твоего кода раз в 100, при имеющейся архитектуре...
|
|||
45
HawkEye
07.09.19
✎
14:50
|
+(44) но есть проблема.... нет метода ВыбратьПоНаименованию() ))))
тогда можно запросом дернуть все коды поставщика с нужным тебе прайсом и засунуть результат в ТЗ, ДО цикла а в цикле (точнее в твоей функции) искать нужный код в ТЗ.... |
|||
46
HawkEye
07.09.19
✎
14:52
|
(42) перепиши код по человечески и будет тебе приемлемая скорость работы без прямых запросов, 1С++ и переделывания архитектуры....
|
|||
47
evgpinsk_
07.09.19
✎
14:54
|
(43) " значит получается, у тебя может быть несколько одинаковых кодов поставщика, относящихся к разным элементам Номенклатуры"
нет, у поставщиков коды товаров уникальны. " что-бы разобрать к какому из них, используется справочник прайс" не совсем. Просто из логики введён справочник Прайс. Вместо него можно было бы например использовать справочник "Контрагенты" |
|||
48
HawkEye
07.09.19
✎
14:54
|
+(45) либо добавь реквизит в КодыТМЦПоставщиков в которое запиши то-же самое что и в наименовании, чтоб можно было сформировать выборку по реквизиту
в коде сделай Спр_кодов.ВыбратьЭлементыПоРеквизиту("КОДПОставщика",НужныйТебеКОд,0,1); а в цикле сравнивай это нужный тебе прайс или нет... |
|||
49
HawkEye
07.09.19
✎
14:56
|
(47) если кодПоставщика у тебя уникальный, на кой черт ты делаешь:
Спр_прайсов.НайтиПоКоду(ПрайсПставщика); Спр_кодов.ВыбратьЭлементыПоРеквизиту("Прайс",Спр_прайсов.ТекущийЭлемент(),0,1);?! бред какой-то.. зная уникальный идентификатор запускать цикл по всему прайсу... Спр_кодов.НайтиПоНаименованию(НужныйКод) - заменит вочти весь твой код из (0) |
|||
50
HawkEye
07.09.19
✎
14:58
|
+(49) отдельное фи... пихать артикул в наименование... есть же реквизит "код" у которого уникальность отслеживается платформой....
|
|||
51
evgpinsk_
07.09.19
✎
14:59
|
(49) (50) Сейчас обдумаю )
|
|||
52
HawkEye
07.09.19
✎
15:00
|
(47) ты бы определился...
в (29): "Артикулы разных поставщиков могут пересекаться между собой" в (47): "у поставщиков коды товаров уникальны." когда правда то была? |
|||
53
evgpinsk_
07.09.19
✎
15:02
|
(52) Есь два поставщика: Васыя и Петя.
У первого есть артикул товар "154222" в моей базе это Помидор У второго есть артикул товар "154222" в моей базе это гвздь |
|||
54
evgpinsk_
07.09.19
✎
15:03
|
Но в прайсе у Васи артикул "154222" уникален.
И в прайсе к Пети артикул "154222" тоже уникален. |
|||
55
HawkEye
07.09.19
✎
15:04
|
(53) кого волнует что там у твоих поставщиков... мы так-то в твоей базе... и в твоей базе артикул ни разу не уникален...
|
|||
56
evgpinsk_
07.09.19
✎
15:06
|
(55) Я ответил просто на вопрос. Т.еуникальный индекс состоит из двух полей:
ПрайсПоставщика Артикул |
|||
57
HawkEye
07.09.19
✎
15:07
|
а если он не уникален, то варианта два:
1. в Справочник.КодыТМЦПоставщиков заводишь реквизит "АртикулПоставщтика" - заполняешь его, тем, что есть в наименовании... потом в своей процедуре делаешь ВыбратьПоРеквизиту("АртикулПоставщтика", КодПоставщика) потом сравниваешь с прайсом, прайс не мешало бы найти ДО попадания в свою функцию... ОДИН раз для всех строк... 2. вариант, запросо (или перебором) формируешь ТЗ по прайсу, а в свой функции ищешь в ТЗ... |
|||
58
evgpinsk_
07.09.19
✎
15:07
|
(49) "Спр_кодов.НайтиПоНаименованию(НужныйКод) - заменит почти весь твой код из (0)"
т.е. решение должно быть такое: я фильтрую свой справочник по Наименование/АртикулуПостащика/ - получу одну или несколько строк, и потом циклом в них проверяю на совпадени Прайсов/Поставщиков. неужели так просто , сейчас обмазгую |
|||
59
HawkEye
07.09.19
✎
15:08
|
(56) в том-то и дело, что когда приходишь за помощью, надо отвечать на те вопросы которые тебе задают, а не на те, которые в твоей голове звучат...
|
|||
60
evgpinsk_
07.09.19
✎
15:10
|
(59) Да вроде старался отвечать )
(52) - здесь нет противоречия вроде как |
|||
61
Djelf
гуру
07.09.19
✎
15:18
|
(42) Не 1с++, там фоксовкий провайдер, удобнее 1sqlite http://catalog.mista.ru/public/559826/
Да и внедрять то особенно нечего...
|
|||
62
evgpinsk_
08.09.19
✎
01:51
|
(57) Всё получилось по 1му варианту. Скорость в 10ки раз стала выше
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |