|
v7: Ускорить обработку 2 документов | ☑ | ||
---|---|---|---|---|
0
Sima42
29.09.21
✎
20:05
|
Добрый день. Есть документ. В этом документе в табличной части порядка 9000 тыс строк. Есть ещё один документ там 10 тыс строк. Я беру первый документ сравниваю табличные данные с други документом. Если найден то ставлю единичку. Вопрос в скорости обработки. Запускаю и час времени курю. Как ускорить этот процесс?
|
|||
1
ДенисЧ
29.09.21
✎
20:09
|
В 77 в документе 9 миллионов строк?
Вы там рыбного супа переели? |
|||
2
ДенисЧ
29.09.21
✎
20:10
|
"Запускаю и час времени курю. Как ускорить этот процесс?"
Или бросай курить, или затягивайся сильней. На крайний случай можешь чистым кислородом дуть на сигарету. |
|||
3
Sima42
29.09.21
✎
20:15
|
Извините ошибся 9 и 10 тыс
|
|||
4
acanta
29.09.21
✎
20:19
|
Надеюсь дбф.. там номер строки в документах сколько знаков поддерживает?
|
|||
5
Злопчинский
29.09.21
✎
20:21
|
(4) 4 знака. но на работоспособность это не влияет.
|
|||
6
Злопчинский
29.09.21
✎
20:22
|
(0) "сравниваю табличные данные" - весьма обобщенное описание. можно посеветовать только одно - сравнивайте быстрее!
|
|||
7
Злопчинский
29.09.21
✎
20:25
|
Вариантов куча.
ИТЗ из 1С++ - там есть вычитание ТЗ. можно тупо штатно - выгрузить 1док в ТЗ1, проставить +1 в допколонке. - выгрузить 2док в ТЗ2, проставить -1 в допколонке. ТЗ2 влепить в конец ТЗ1. и ТЗ1.Свернуть(), где в допколонке получится 0 - там строки совпадают. Удаляем эти строки из ТЗ1 (умно! а то опять час ждать будешь), то что осталось - несовпадающие строки. все. |
|||
8
Злопчинский
29.09.21
✎
20:28
|
"9000 тыс строк" - 9 миллинов строк? считаем что все-таки 9тыс...
. как описано выше - "сравнить" на таком количестве строк займет секунд 30, а то и меньше м.б.временные затраты в основном на алгоритм "сравнения". может он у тебя хитровпендренный типа если в ТЗ1 товар1 с харктеристикой "красный", а в ТЗ2 с харктеристикой "синий" - то это одинаковые строки только в том случае если цена в дух ТЗ отличается не более чем на 13,78%. . если сравнение тупое простое по совпадению реквизитов в троках - то как описано выше - это все будет очень быстро |
|||
9
Sima42
29.09.21
✎
20:31
|
Процедура СоздатьТХТ2()
ТабЗнач = СоздатьОбъект("ТаблицаЗначений"); ТабЗнач.НоваяКолонка("ГТИН"); ТабЗнач2 = СоздатьОбъект("ТаблицаЗначений"); ТабЗнач2.НоваяКолонка("ГТИН"); Док = СоздатьОбъект("Документ.ВводКодов"); Если Док.НайтиДокумент(ДокКод)=1 тогда Док.ВыбратьСтроки(); Пока Док.ПолучитьСтроку()=1 цикл //Док.Печ=1; ТабЗнач.НоваяСтрока(); ТабЗнач.ГТИН=Док.КодыДатаматрикс; КонецЦикла; Док.Записать(); КонецЕсли; ВыбратьСтроки(); Пока ПолучитьСтроку()=1 цикл ТабЗнач2.НоваяСтрока(); ТабЗнач2.ГТИН=КодГолова; КонецЦикла; ТабЗнач2.Сортировать("ГТИН+"); ТабЗнач.Сортировать("ГТИН+"); ТабЗнач2.ВыбратьСтроки(); Пока ТабЗнач2.ПолучитьСтроку()=1 цикл ТабЗнач.ВыбратьСтроки(); Пока ТабЗнач.ПолучитьСтроку()=1 цикл Если СокрЛП(ТабЗнач.ГТИН)=СокрЛП(ТабЗнач2.ГТИН) тогда ТабЗнач.УдалитьСтроку(); Прервать; КонецЕсли; КонецЦикла; КонецЦикла; Пер=0; Док = СоздатьОбъект("Документ.ВводКодов"); Если Док.НайтиДокумент(ДокКод)=1 тогда Док.ВыбратьСтроки(); Пер=0; НачатьТранзакцию(); Пока Док.ПолучитьСтроку()=1 цикл Пер=Пер+1; ТабЗнач.ВыбратьСтроки(); Пока ТабЗнач.ПолучитьСтроку()=1 цикл Если СокрЛП(ТабЗнач.ГТИН)=СокрЛП(Док.КодыДатаматрикс) тогда Док.Печ=0; Прервать; КонецЕсли; КонецЦикла; Если Пер>=500 Тогда Пер=0; ЗафиксироватьТранзакцию(); НачатьТранзакцию(); КонецЕсли; КонецЦикла; Док.Записать(); ЗафиксироватьТранзакцию(); КонецЕсли; КонецПроцедуры |
|||
10
Sima42
29.09.21
✎
20:33
|
При таком коде если в ТЗ1 - 9 тыс и в ТЗ2 - 10 тыс то за минуту все делает. Но если в ТЗ1 - 300 тук а в ТЗ2 - 10 тыс. То на час 1с ка повисла
|
|||
11
pechkin
29.09.21
✎
20:35
|
Мердж уже предлагали делать?
|
|||
12
Злопчинский
29.09.21
✎
20:39
|
Переделать нахрен все.
|
|||
13
Sima42
29.09.21
✎
20:39
|
Процедура СоздатьТХТ2()
ТабЗнач = СоздатьОбъект("ТаблицаЗначений"); ТабЗнач.НоваяКолонка("ГТИН"); ТабЗнач2 = СоздатьОбъект("ТаблицаЗначений"); ТабЗнач2.НоваяКолонка("ГТИН"); Док = СоздатьОбъект("Документ.ВводКодов"); Если Док.НайтиДокумент(ДокКод)=1 тогда Док.ВыбратьСтроки(); Пока Док.ПолучитьСтроку()=1 цикл Док.Печ=1; ТабЗнач.НоваяСтрока(); ТабЗнач.ГТИН=Док.КодыДатаматрикс; КонецЦикла; Док.Записать(); КонецЕсли; ВыбратьСтроки(); Пока ПолучитьСтроку()=1 цикл ТабЗнач2.НоваяСтрока(); ТабЗнач2.ГТИН=КодГолова; КонецЦикла; ТабЗнач2.Сортировать("ГТИН+"); ТабЗнач.Сортировать("ГТИН+"); ТабЗнач2.ВыбратьСтроки(); Пока ТабЗнач2.ПолучитьСтроку()=1 цикл ТабЗнач.ВыбратьСтроки(); Пока ТабЗнач.ПолучитьСтроку()=1 цикл Если СокрЛП(ТабЗнач.ГТИН)=СокрЛП(ТабЗнач2.ГТИН) тогда ТабЗнач.УдалитьСтроку(); Прервать; КонецЕсли; КонецЦикла; КонецЦикла; Пер=0; Док = СоздатьОбъект("Документ.ВводКодов"); Если Док.НайтиДокумент(ДокКод)=1 тогда Док.ВыбратьСтроки(); Пер=0; НачатьТранзакцию(); Пока Док.ПолучитьСтроку()=1 цикл Пер=Пер+1; ТабЗнач.ВыбратьСтроки(); Пока ТабЗнач.ПолучитьСтроку()=1 цикл Если СокрЛП(ТабЗнач.ГТИН)=СокрЛП(Док.КодыДатаматрикс) тогда Док.Печ=0; Прервать; КонецЕсли; КонецЦикла; Если Пер>=500 Тогда Пер=0; ЗафиксироватьТранзакцию(); НачатьТранзакцию(); КонецЕсли; КонецЦикла; Док.Записать(); ЗафиксироватьТранзакцию(); КонецЕсли; КонецПроцедуры |
|||
14
Sima42
29.09.21
✎
20:39
|
Так читаться будет лучше
|
|||
15
Sima42
29.09.21
✎
20:40
|
(12) Как?
|
|||
16
Злопчинский
29.09.21
✎
20:40
|
ССЗБ
чтомешало в разных документах одинаковую сущность назвать одинаково- и там и там назвать КодыДатаМатрикс..? |
|||
17
Злопчинский
29.09.21
✎
20:42
|
(10) "То на час 1с ка повисла"
потому что удаление строки из середины таблицы - тяжелая операция. переделать тупо как я написал выше - склеить две таблицы и свернуть. |
|||
18
Sima42
29.09.21
✎
20:42
|
(16) Может и нужно было. Меня это как то не напрягает
|
|||
19
Злопчинский
29.09.21
✎
20:44
|
(15) если тупо - то как я написал в (7) - удаление строк у тебя идет по совпадению ГТИН в двух таблицах.
|
|||
20
Sima42
29.09.21
✎
20:45
|
(17) В принципе код до получения ТЗ с не совпадающими данными она делает быстро. Затуп происходит на работе с документом.
Тут Док = СоздатьОбъект("Документ.ВводКодов"); Если Док.НайтиДокумент(ДокКод)=1 тогда Док.ВыбратьСтроки(); Пер=0; НачатьТранзакцию(); Пока Док.ПолучитьСтроку()=1 цикл Пер=Пер+1; ТабЗнач.ВыбратьСтроки(); Пока ТабЗнач.ПолучитьСтроку()=1 цикл Если СокрЛП(ТабЗнач.ГТИН)=СокрЛП(Док.КодыДатаматрикс) тогда Док.Печ=0; Прервать; КонецЕсли; КонецЦикла; Если Пер>=500 Тогда Пер=0; ЗафиксироватьТранзакцию(); НачатьТранзакцию(); КонецЕсли; КонецЦикла; Док.Записать(); ЗафиксироватьТранзакцию(); КонецЕсли; |
|||
21
Злопчинский
29.09.21
✎
20:52
|
(18) думать надо вперед, а не жпс.
Док1.ВыгрузитьТабличнуюЧасть(ТЗ1,"КодыдатаМатрикс"); Док2.ВыгрузитьТабличнуюЧасть(ТЗ2,"КодыдатаМатрикс"); ТЗ1.НоваяКолонка("Флаг","Число"); ТЗ2.НоваяКолонка("Флаг","Число"); ТЗ1.Заполнить(1,,,"Флаг"); ТЗ2.Заполнить(2,,,"Флаг"); КС1 = ТЗ1.КоличествоСтрок(); КС2 = ТЗ2.КоличествоСтрок(); ТЗ1.КоличествоСтрок(КС1+КС2); ТЗ1.Заполнить(ТЗ2,КС1+1); ТЗ1.Свернуть("КодыдатаМатрикс","Флаг"); ТЗ1.Сортировать("Флаг+"); //1,2,3 поз = 0; Если ТЗ1.НайтиЗначение(3,поз,"Флаг") = 1 Тогда ТЗ1.КоличествоСтрок(поз-1); КонецЕсли; . типа так... |
|||
22
Злопчинский
29.09.21
✎
20:54
|
ТЗ1.КоличествоСтрок(поз-1);
модифицировать на обратный проход и удалять пока Флаг = 3 |
|||
23
Злопчинский
29.09.21
✎
20:54
|
(20) ясен пень.. 9 тыс раз проходить по таблице в 10 тыс строк...
|
|||
24
Ёпрст
29.09.21
✎
20:57
|
Да уж..выкинь к едрени ыени запись дока, для начала. Лишнюю
|
|||
25
Ёпрст
29.09.21
✎
20:58
|
Транзакцию, тоже в топку
|
|||
26
Ёпрст
29.09.21
✎
20:58
|
В этом коде ни то ни то не нужно
|
|||
27
Злопчинский
29.09.21
✎
21:00
|
Пока Док.ПолучитьСтроку()=1 цикл
Пер=Пер+1; ТабЗнач.ВыбратьСтроки(); Пока ТабЗнач.ПолучитьСтроку()=1 цикл Если СокрЛП(ТабЗнач.ГТИН)=СокрЛП(Док.КодыДатаматрикс) тогда Док.Печ=0; Прервать; КонецЕсли; КонецЦикла; . Передалть нах на типа . Пока Док.ПолучитьСтроку()=1 цикл Пер=Пер+1; поз = 0; Если ТабЗнач.НайтиЗначение(ТабЗнач.ГТИН,поз,"КодыДатаматрикс") = 1 тогда Док.Печ=0; КонецЕсли; КонецЦикла; |
|||
28
Злопчинский
29.09.21
✎
21:04
|
(21) если в доках имена реквизитов разные - код тот же самый - выгрузить в ТЗ, будут в ТЗ разные колонки, добавить во вторую ТЗ (а лучше в обе), новую колонку с унифицированным именем, пробежаться по тЗ перекинуть значения в унифицированную колонку построчно, далее по коду...
|
|||
29
Злопчинский
29.09.21
✎
21:05
|
(26) поддерживаю
|
|||
30
Sima42
29.09.21
✎
21:11
|
(25) Это уже от безысходности
|
|||
31
Злопчинский
29.09.21
✎
21:12
|
(30) не путайте безысходность и бездуховность.
|
|||
32
Злопчинский
29.09.21
✎
21:16
|
(30) поправь обработку документа как в (270 и всё, я думаю что результат тебя удовлетворит
|
|||
33
Sima42
29.09.21
✎
22:08
|
(32) Действительно стало лучше. Получились такие цифры.
2500 и 9000 - 2 мин 10 сек. 9500 и 10000 - 1 мин. Завтра попробую ещё ТЗ сделать по вашему методу. Спасибо большое! |
|||
34
Злопчинский
29.09.21
✎
23:14
|
(33) "Действительно стало лучше"
внезапно... . "Завтра попробую ещё ТЗ сделать по вашему методу." пробуй-пробуй, с методом КоличествоСтрок(N) для добавления строки или удаления - аккуратно, там есть засады. лучше использовать циклом НоваяСтрока() для добавления и обратным удалением для обрезки. Так будет железобетонно. |
|||
35
Злопчинский
29.09.21
✎
23:17
|
Впили себе в ГМ функцию, пригодится
. //------------------------------------------------------------------------------------ // Функция глОтобратьПоКолонке(ТЗВход,Колонка,Значение) Экспорт //возвращает отобранную ТЗ Перем ТЗ, ТЗВрем; ТЗВход.Выгрузить(ТЗ); ТЗ.Сортировать(Колонка+"*"); //по внутр значению, важно! НомСтр = 0; Если ТЗ.НайтиЗначение(Значение, НомСтр, Колонка) = 0 Тогда //нет такого значения ТЗ.УдалитьСтроки(); Возврат ТЗ; Иначе //найдем строку, в которой уже не встречается Значение ТЗКС = ТЗ.КоличествоСтрок(); Для счСтрок = НомСтр По ТЗКС Цикл Если ТЗ.ПолучитьЗначение(счСтрок, Колонка) <> Значение Тогда //нужное значение есть до пред.строки НомСтр2 = счСтрок - 1; Прервать; КонецЕсли; Если счСтрок = ТЗКС Тогда //нужное значение встречается до конца таблицы НомСтр2 = ТЗКС; КонецЕсли; КонецЦикла; КонецЕсли; ТЗВрем = СоздатьОбъект("ТаблицаЗначений"); ТЗ.Выгрузить(ТЗВрем,НомСтр,НомСтр2); //выгрузим только строки с нужным значением Возврат ТЗВрем; КонецФункции //глОтобратьПоКолонке() |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |