Страницы: 1
RSS
Один файл, два компьютера, разница в скорости колоссальная
 
Добрый день!  
У нас сделана огромная таблица. 600 столбцов на 2000 строк.  
Есть другой лист - на нём по заданным критериям делается отчёт. Там цикл который проверяет условие от 1 до 2000 строки.  
На компьютере сотрудника это делается за 4 секунды примерно... На моём компьютере более мощном, это делает около минуты.  
Как такое может быть куда копать?  
У меня снизу написано справа Ячейка (нажмите esc для отмены) и бегает шкала, а там эта шкала даже не успевает высветиться...  
И ещё в коде у меня отключаются вначале кода обновления все и расчёты, а в конце программы снова включаются.  
 
Одна программа, а работает по разному. Подскажите пожалуйста куда глядеть то))
 
Покажите код, а лучше вместе с файлом (на десяток строк!!! не надо 2000) - тогда ответ думаю будет быстрее и вернее.  
 
А может быть и ускорим раз так в 40...
 
Паша, у Вас проект написан средствами VBA или формулами? Если VBA то нужно во время выполнения всех обращений к листу выключать обновление экрана и автопересчет листа. Возможно у Вашего коллеги выключен автопересчет листа.
 
Если я выложу файлик с 10 строками он вообще тупить не будет((  
У всех стоит 2007 эксель.  
В начале кода обновление экрана и автопересчёт листа выключается а в конце кода включается... странно как то.
 
А как выложить код? тут одни иероглифы вместо русских
 
Код копируйте при русской раскладке...
 
Методом слежения за выполнением по F8 я выделил часть кода на которую уходит больше всего времени. При том что у соседа это делается за 2 секунды где то, и ещё 2 всё остальное (форматирование и тд).  
 
 
'!ОПРЕДЕЛЯЕТ В КАКУЮ ЯЧЕЙКУ ВСТАВЛЯТЬ ЗНАЧНИЕ В ОТЧЁТЕ!  
If ThisWorkbook.Worksheets("Сводный отчёт").Range("I4") = 0 Then  
   Set Первая_Ячейка_в_Отчёте = Range("I4")  
         
       Set Тип_Для_Отчёта_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 4)  
       Set Тип_Для_ЗП_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 5)  
       Set Субсчёт_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 6)  
       Set Процент_Инспектора_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 7)  
       Set Пользователь_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 8)  
       Set Остаток_На_Начало_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 9)  
       Set Передано_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 10)  
       Set Зачтено_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 11)  
       Set Дата_Поступления_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 12)  
       Set Сумма_Поступления_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 13)  
       Set Остаток_На_Конец_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 14)  
         
Else  
     
   Set Первая_Ячейка_в_Отчёте = Range("A4").CurrentRegion.End(xlDown)  
       Set Тип_Для_Отчёта_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 4)  
       Set Тип_Для_ЗП_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A4").Offset(I, 5)  
       Set Субсчёт_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 6)  
       Set Процент_Инспектора_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A4").Offset(I, 7)  
       Set Пользователь_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 8)  
       Set Остаток_На_Начало_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 9)  
       Set Передано_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 10)  
       Set Зачтено_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 11)  
       Set Дата_Поступления_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 12)  
       Set Сумма_Поступления_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 13)  
       Set Остаток_На_Конец_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 14)  
           
         
End If  
 
 
'!ВЫБИРАЕТ ЧТО КОПИРОВАТЬ И КУДА КОПИРОВАТЬ!  
If Проверка_Условия_ДаНет = "да" And Проверка_Инспектора = SpisInsp.Value Then  
      Select Case Mes.Value  
         
         
       
   Case "Январь 2012"  
         
       Set Тип_Для_Отчёта_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 104)  
       Set Субсчёт_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 14)  
       Set Процент_Инспектора_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 11)  
       Set Пользователь_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 10)  
         
       Set Остаток_На_Начало_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 417)  
       Set Передано_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 425)  
       Set Зачтено_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 428)  
       Set Дата_Поступления_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 419)  
       Set Сумма_Поступления_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 418)  
       Set Остаток_На_Конец_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 429)  
                 
         
   Тип_Для_Отчёта_Ячейка_Куда_Вставляет.Value = Тип_Для_Отчёта_Ячейка_Откуда_Копирует.Value  
   Субсчёт_Ячейка_Куда_Вставляет.Value = Субсчёт_Ячейка_Откуда_Копирует.Value  
   Процент_Инспектора_Ячейка_Куда_Вставляет.Value = Процент_Инспектора_Ячейка_Откуда_Копирует.Value  
   Остаток_На_Начало_Ячейка_Куда_Вставляет.Value = Остаток_На_Начало_Ячейка_Откуда_Копирует.Value  
   Передано_Ячейка_Куда_Вставляет.Value = Передано_Ячейка_Откуда_Копирует.Value  
   Зачтено_Ячейка_Куда_Вставляет.Value = Зачтено_Ячейка_Откуда_Копирует.Value  
   Дата_Поступления_Ячейка_Куда_Вставляет.Value = Дата_Поступления_Ячейка_Откуда_Копирует.Value  
   Сумма_Поступления_Ячейка_Куда_Вставляет.Value = Сумма_Поступления_Ячейка_Откуда_Копирует.Value  
   Остаток_На_Конец_Ячейка_Куда_Вставляет.Value = Остаток_На_Конец_Ячейка_Откуда_Копирует.Value  
   Пользователь_Ячейка_Куда_Вставляет.Value = Пользователь_Ячейка_Откуда_Копирует.Value
 
Влад попал:-) Или это Игорь хотел код?
Я сам - дурнее всякого примера! ...
 
Я решил проблему)) вроде бы  
 
Сперва запускался цикл проверки КУДА ВСТАВЛЯТЬ он его пробегал и только потом был цикл ЧТО ВСТАВЛЯТЬ когда он бежит по 2000 строчек, потом заново. В цикл Куда вставлять врубил сперва ВСТАВЛЯТЬ ЛИ после чего уже всё дальше выполнялось. В итоге = 2 секунды))) тогда что это получается... на их компах вообще ещё до нажатия будет формироваться))))))  
 
'!ВЫБИРАЕТ ЧТО КОПИРОВАТЬ И КУДА КОПИРОВАТЬ!  
If Проверка_Условия_ДаНет = "да" And Проверка_Инспектора = SpisInsp.Value Then  
 
'!ОПРЕДЕЛЯЕТ В КАКУЮ ЯЧЕЙКУ ВСТАВЛЯТЬ ЗНАЧНИЕ В ОТЧЁТЕ!  
If ThisWorkbook.Worksheets("Сводный отчёт").Range("I4") = 0 Then  
   Set Первая_Ячейка_в_Отчёте = Range("I4")  
         
       Set Тип_Для_Отчёта_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 4)  
       Set Тип_Для_ЗП_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 5)  
       Set Субсчёт_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 6)  
       Set Процент_Инспектора_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 7)  
       Set Пользователь_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 8)  
       Set Остаток_На_Начало_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 9)  
       Set Передано_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 10)  
       Set Зачтено_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 11)  
       Set Дата_Поступления_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 12)  
       Set Сумма_Поступления_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 13)  
       Set Остаток_На_Конец_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A1").Offset(3 + I, 14)  
         
Else  
     
   Set Первая_Ячейка_в_Отчёте = Range("A4").CurrentRegion.End(xlDown)  
       Set Тип_Для_Отчёта_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 4)  
       Set Тип_Для_ЗП_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A4").Offset(I, 5)  
       Set Субсчёт_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 6)  
       Set Процент_Инспектора_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("A4").Offset(I, 7)  
       Set Пользователь_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 8)  
       Set Остаток_На_Начало_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 9)  
       Set Передано_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 10)  
       Set Зачтено_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 11)  
       Set Дата_Поступления_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 12)  
       Set Сумма_Поступления_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 13)  
       Set Остаток_На_Конец_Ячейка_Куда_Вставляет = ThisWorkbook.Worksheets("Сводный отчёт").Range("a4").Offset(I, 14)  
           
         
End If  
 
Select Case Mes.Value  
         
         
      Case "Декабрь 2011"  
         
       Set Тип_Для_Отчёта_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 104)  
       Set Субсчёт_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 14)  
       Set Процент_Инспектора_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 11)  
       Set Пользователь_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 10)  
         
       Set Остаток_На_Начало_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 417)  
       Set Передано_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 425)  
       Set Зачтено_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 428)  
       Set Дата_Поступления_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 419)  
       Set Сумма_Поступления_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 418)  
       Set Остаток_На_Конец_Ячейка_Откуда_Копирует = ThisWorkbook.Worksheets("Отчёт").Range("A1").Offset(2 + I, 429)  
                 
         
   Тип_Для_Отчёта_Ячейка_Куда_Вставляет.Value = Тип_Для_Отчёта_Ячейка_Откуда_Копирует.Value  
   Субсчёт_Ячейка_Куда_Вставляет.Value = Субсчёт_Ячейка_Откуда_Копирует.Value  
   Процент_Инспектора_Ячейка_Куда_Вставляет.Value = Процент_Инспектора_Ячейка_Откуда_Копирует.Value  
   Остаток_На_Начало_Ячейка_Куда_Вставляет.Value = Остаток_На_Начало_Ячейка_Откуда_Копирует.Value  
   Передано_Ячейка_Куда_Вставляет.Value = Передано_Ячейка_Откуда_Копирует.Value  
   Зачтено_Ячейка_Куда_Вставляет.Value = Зачтено_Ячейка_Откуда_Копирует.Value  
   Дата_Поступления_Ячейка_Куда_Вставляет.Value = Дата_Поступления_Ячейка_Откуда_Копирует.Value  
   Сумма_Поступления_Ячейка_Куда_Вставляет.Value = Сумма_Поступления_Ячейка_Откуда_Копирует.Value  
   Остаток_На_Конец_Ячейка_Куда_Вставляет.Value = Остаток_На_Конец_Ячейка_Откуда_Копирует.Value  
   Пользователь_Ячейка_Куда_Вставляет.Value = Пользователь_Ячейка_Откуда_Копирует.Value
 
Я хотел :(  
Не, ну "стока многа букв" я ещё не видел...  
Подозреваю, что все эти Set можно упразднить.  
Как и ThisWorkbook.Worksheets("Сводный отчёт") написать всего один раз :)
 
А не подскажете как это сделать? На примере парочки сетов и this work book?)))))
 
"Куда вставляет" - это у Вас один неразрывный диапазон, значит туда можно выгрузить один массив.  
Следовательно, можно создать массив нужного размера и заполнить его данными исходя из условия по Mes.Value  
Из одного или другого диапазона, без Set.  
Далее проверяем .Range("I4") = 0 Then и выгружаем его в одно или другое место.  
 
Ну а по this work book так:  
 
with ThisWorkbook.Worksheets("Сводный отчёт")  
If .Range("I4") = 0 Then  
Set Тип_Для_Отчёта_Ячейка_Куда_Вставляет = .Range("A1").Offset(3 + I, 4)  
Set Тип_Для_ЗП_Ячейка_Куда_Вставляет = .Range("A1").Offset(3 + I, 5)  
и т.д....  
end with  
 
Хотя это вероятно уже не будет нужно, если перейти на массив.
 
Паша, ну шок. Так нельзя переменные называть, код просто не читабельный.  
Теперь по порядку:  
1) оператор Set только для объектных переменных, если вы меняете в ячейке только значение, зачем создавать объектную переменную, присваивать ей значение и только потом использовать этого крокодила, чтобы он передал одно единственное значение. Очень не рационально. Можно сразу присваивать соответствующее значение из ячейки листа или создавать переменную соответсвующего типа.  
2) На что стоит обратить внимание - обращение к безадресному диапазону - по умолчанию это ActiveShell со всеми вытекающими проблемами если макрос запущен не там где надо. (Set Первая_Ячейка_в_Отчёте = Range("I4"))  
 
Паша, почитайте на форумах КАК лучше всего оформлять проект. Так нельзя.
 
Ну зачем эти Set ясно - сперва по условию определяем что будем копировать, затем по условию куда. И только потом копируем.  
Но ведь проще сделать иначе - сперва по условию взять те или иные данные в переменные, затем по условию выгрузить в одно или другое место. Без всяких Set и можно без массива (заменив его отдельными переменными, что не меняет сути).
 
Всем огромное спасибо за советы, постараюсь всё учесть)) Огромное спасибо!!!  
Только вот вопрос, всё работает, всё работает очень быстро теперь, 2-5 секунд. Тогда чем плохо что я всё через сет сделал обозвал так переменные и тд?
 
Объектные переменные очень ресурсоемкие в сравнении с переменными одноранговыми. А раз так, то избыточное их количество будет тормозить вычисления при дифиците памяти. В практике программирования необходимо привыкать к минимализму и использовать минимум соответствующих потребностям переменных с обязательно задекларированными типами. В коротких проектах это конечно не критично. НО в случае, если у Вас в расчетах много обращений к объектам и есть циклы, то задержка будет уже заметной.
 
Я не сказал что плохо. Я сказал, что много лишнего, что трудно читается код.  
Ну и на массивах в 40 раз быстрее, чем перебирать ячейки - но не в данном случае.  
Т.к. тут в этом куцем примере нет циклов по тысячам ячеек.  
Но в остальном коде возможно что-то такое есть - раз всё равно 5 сек. набегает.  
Помню, ускорил как-то макрос с 40 минут до 5,5 сек. только заменой перебора ячеек на перебор массива.
 
Из 5 секунд 3 занимает форматирование почему то...  
а где можно почитать про работу с массивами? никогда не сталкивался
 
Вот ссылка на тот код - там вроде всё понятно должно быть: http://www.sql.ru/forum/actualthread.aspx?bid=22&tid=774191&pg=3 Там и файл выше в теме есть, на котором можно код/коды в работе проверить.
 
Это я тогда ещё словари не использовал :)  
Вообще в примере у автора ещё беда с определением последней строки - если исправить, то на 10 сек. его код выходит.
Страницы: 1
Наверх