2016-09-29 2 views
0

Я написал код ниже, чтобы ввести текущее значение ячеек в массив строк. Есть 52k + строки и при запуске в режиме отладки, если я помещаю перерыв во втором «Do», код работает очень быстро (в секундах) после нажатия F5. Если перерыв не вводится, это занимает очень много времени (6-8 минут).VBA excel code время работы

Кто-нибудь есть идеи, почему это происходит и как это можно исправить?

Бест, Nasos

Do 
    ProjectIDPub(i, 0) = Cells(3 + i, 13).Value & " - " & Cells(3 + i, 3).Value 
    ProjectIDPub(i, 1) = Cells(3 + i, 7).Value 
    i = i + 1 
Loop Until i = numberRowsAXProjectsSheetPub 

i = 0 
Do 
    Cells(3 + i, 14).Value = ProjectIDPub(i, 0) 
    Cells(3 + i, 15).Value = ProjectIDPub(i, 1) 
    i = i + 1 
Loop Until i = numberRowsAXProjectsSheetPub 
i = 0 
+0

Я не понимаю. Почему ты не делаешь этого сразу? –

+1

Если у вас есть рабочий код, который просто нуждается в улучшениях, вы, вероятно, не в том месте с этим сообщением. [Обзор кода] (http://codereview.stackexchange.com/) - это то, где они обрабатывают существующий/рабочий код и делают все возможное, чтобы улучшить его с точки зрения скорости, безопасности, устойчивости и долговечности, включая лучшие практики. Попробуйте. Они хороши! – Ralph

ответ

3

Предполагая, что numberRowsAXProjectsSheetPub это число строк в массиве ProjectIDPub, весь второй цикл может быть заменен

Range(Cells(3,14),Cells(3 + numberRowsAXProjectsSheetPub - 1,15)).Value = ProjectIDPub 

Это почти всегда гораздо быстрее передать массив на лист в одной уступки, а чем в цикле.

+0

Большое вам спасибо, что я немного скорректировал ваш код, и это сработало отлично – Nasos

+0

Привет, Джон, я пробовал тот же метод с одномерным массивом, и он только перенял первый элемент из линий 30k. 'code Range (Ячейки (3, 4), Ячейки (3 + numberRowsEcosSheetPub - 1, 4)). Value = projectIDPub' – Nasos

+0

@Nasos В Excel диапазоны соответствуют двумерным массивам, даже если они имеют только 1 столбец. Это известная досада. Существует работа, связанная с использованием функции рабочего листа «Transpose», но я не думаю, что она работает с линиями 30k. Самое простое решение - всегда использовать 2-мерные массивы, даже если 1 измерение является поддельным: просто объявите 'projectIDPub', например. 'Dim projectIDPub (от 1 до 30000, от 1 до 1)' и просто используйте 'projectID (i, 1)' вместо 'projectID (i)'. Это утомительно, но иногда это лучший способ справиться с диапазонами из 1 колонки в качестве массивов VBA. Если это так, назначение будет работать так, как есть. –

1

Вы пробовали запуска этих петель с обновлением экрана отключен?

Application.ScreenUpdating = False 
Do 
ProjectIDPub(i, 0) = Cells(3 + i, 13).Value & " - " & Cells(3 + i, 3).Value 
ProjectIDPub(i, 1) = Cells(3 + i, 7).Value 
i = i + 1 

Loop Until i = numberRowsAXProjectsSheetPub 
i = 0 
Do 
    Cells(3 + i, 14).Value = ProjectIDPub(i, 0) 
    Cells(3 + i, 15).Value = ProjectIDPub(i, 1) 
    i = i + 1 
Loop Until i = numberRowsAXProjectsSheetPub 
i = 0 
Application.ScreenUpdating = True 

И как @ ali-srn спросил, почему вам нужно запустить ту же петлю дважды? Если второй цикл доступа к некоторым данным, которые должны быть созданы первым, вы должны иметь возможность изменить его с некоторым смещением для i, если необходимо, и просто запустить один раз.

+0

Я пробовал с отключенным экраном. Я также попытался запустить его за один раз, но это никак не повлияло на время, необходимое для завершения операции. – Nasos

+0

Это странно, что отключение обновления экрана до изменения ячеек не повлияло на время выполнения. Я всегда нахожу это обязательным при переходе через множество ячеек и изменении их содержимого. – Pav

Смежные вопросы