| 
    
        
     
     | 
    
  | 
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ки раз стала выше     
         | 
 | Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |