Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 7.7 и ранее

v7: Ускорить обработку 2 документов

v7: Ускорить обработку 2 документов
Я
   Sima42
 
29.09.21 - 20:05
Добрый день. Есть документ. В этом документе в табличной части порядка 9000 тыс строк. Есть ещё один документ там 10 тыс строк. Я беру первый документ сравниваю табличные данные с други документом. Если найден то ставлю единичку. Вопрос в скорости обработки. Запускаю и час времени курю. Как ускорить этот процесс?
   ДенисЧ
 
1 - 29.09.21 - 20:09
В 77 в документе 9 миллионов строк?

Вы там рыбного супа переели?
   ДенисЧ
 
2 - 29.09.21 - 20:10
"Запускаю и час времени курю. Как ускорить этот процесс?"

Или бросай курить, или затягивайся сильней. На крайний случай можешь чистым кислородом дуть на сигарету.
   Sima42
 
3 - 29.09.21 - 20:15
Извините ошибся 9 и 10 тыс
   acanta
 
4 - 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%.
.
если сравнение тупое простое по совпадению реквизитов в троках - то как описано выше - это все будет очень быстро
   Sima42
 
9 - 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;
ЗафиксироватьТранзакцию();
НачатьТранзакцию();
КонецЕсли;
КонецЦикла;
Док.Записать();
ЗафиксироватьТранзакцию();
КонецЕсли;

КонецПроцедуры
   Sima42
 
10 - 29.09.21 - 20:33
При таком коде если в ТЗ1 - 9 тыс и в ТЗ2 - 10 тыс то за минуту все делает. Но если в ТЗ1 - 300 тук а в ТЗ2 - 10 тыс. То на час 1с ка повисла
   pechkin
 
11 - 29.09.21 - 20:35
Мердж уже предлагали делать?
   Злопчинский
 
12 - 29.09.21 - 20:39
Переделать нахрен все.
   Sima42
 
13 - 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;
                ЗафиксироватьТранзакцию();
                НачатьТранзакцию();
            КонецЕсли;
        КонецЦикла;
        Док.Записать();
        ЗафиксироватьТранзакцию();
    КонецЕсли;
    
КонецПроцедуры
   Sima42
 
14 - 29.09.21 - 20:39
Так читаться будет лучше
   Sima42
 
15 - 29.09.21 - 20:40
(12) Как?
   Злопчинский
 
16 - 29.09.21 - 20:40
ССЗБ
чтомешало в разных документах одинаковую сущность назвать одинаково- и там и там назвать КодыДатаМатрикс..?
   Злопчинский
 
17 - 29.09.21 - 20:42
(10) "То на час 1с ка повисла"
потому что удаление строки из середины таблицы - тяжелая операция.
переделать тупо как я написал выше - склеить две таблицы и свернуть.
   Sima42
 
18 - 29.09.21 - 20:42
(16) Может и нужно было. Меня это как то не напрягает
   Злопчинский
 
19 - 29.09.21 - 20:44
(15) если тупо - то как я написал в (7) - удаление строк у тебя идет по совпадению ГТИН в двух таблицах.
   Sima42
 
20 - 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) поддерживаю
   Sima42
 
30 - 29.09.21 - 21:11
(25) Это уже от безысходности
 
 
   Злопчинский
 
31 - 29.09.21 - 21:12
(30) не путайте безысходность и бездуховность.
   Злопчинский
 
32 - 29.09.21 - 21:16
(30) поправь обработку документа как в (270 и всё, я думаю что результат тебя удовлетворит
   Sima42
 
33 - 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);    //выгрузим только строки с нужным значением

    Возврат ТЗВрем;
КонецФункции//глОтобратьПоКолонке()


Список тем форума
 
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.