Просто интересно, может ли кто-нибудь предложить какие-либо предложения, которые могли бы улучшить скорость, которую мой код записывает в рабочую книгу.VBA Медленные пишущие массивы, чтобы преуспеть в рабочей книге
Я пишу около 1,9 миллиона строк данных на несколько листов в книге, по одному листу за раз. Пока код завершается, требуется около 18 часов, чтобы написать книгу Excel, которая кажется смехотворно чрезмерной. Вот настройка. Я открыть книгу как таковые:
Dim ExcelAp As Excel.Application
Dim ouputWorkbook As Excel.Workbook
Set ExcelAp = New Excel.Application
Set outputWorkbook = ExcelAp.Workbooks.Open("S:\Some Directory\Template.xlsx")
Тогда у меня есть строки рабочей книги в массивах, загруженных в цикл сбора и ввода через диапазоны в рабочей книге для копирования массивов:
For lonSheetOneCounter = 2 to 999999
outputWorkbook.Worksheets(1).Range(_
outputWorkbook.Worksheets(1).Cells(lonSheetOneCounter, 1).Address & ":" & _
outputWorkbook.Worksheets(1).Cells(lonSheetOneCounter, 21).Address).Value = _
outputCollection.item(lonSheetOneCounter - 1)
Next lonSheetOneCounter
метод копирования одинаковый для других листов. Я сделал книгу и экземпляр excel невидимым, я переключил расчет на руководство для этой книги, и я также отключил обновление экрана, но все равно требуется около 18 часов, чтобы завершить копирование в новую книгу.
Я попытался сделать 2-мерный массив для листа entier, но независимо от метода, который я использую для этого, я получаю ошибку «из памяти» в тот момент, когда я пытаюсь скопировать этот массив в рабочую книгу.
Я не уверен, есть ли что-нибудь еще, что я могу сделать, чтобы получить ошибку и сократить время на копирование, но если у кого-то есть предложение, я все уши. Для чего это стоит, этот макрос размещается в другой книге excel, работающей в отдельном экземпляре excel из рабочей книги, к которой я пытаюсь скопировать.
Редактировать: Незначительное дополнение здесь. Что-то, что я заметил, что я хотел обратить внимание на это, также заставляет меня думать, что возможно ускорить процесс. Я заметил, что макрос замедляется постепенно. Первое число строк X очень быстро записывается, следующие строки, похоже, все больше замедляются по мере записи каждой строки ...
Я собираюсь попробовать эксперимент, в котором я установил свой шаблон для автоматической загрузки таблица с 1 миллионом используемых строк ... вроде подсказываются предложением внизу. Мне интересно, стоит ли excel выделять память для всех дополнительных строк. Возможно, если я начну с шаблона рабочей книги, у которого уже установлено такое количество строк, мне может быть проще.
Редактировать: Мне было указано, что я не знаю, откуда берутся данные, которые я читаю. Эти данные считываются с использованием примитивов VBA из нескольких текстовых файлов. Один из них связан с каналом, две другие запятые, а не то, что схема файлов имеет большое значение.
Что касается заполнения массива, вот фрагмент того, как это происходит. Это выглядит беспорядок, но просто нет другого способа получить данные для соответствия формату трех файлов, которые я сравниваю. Во всяком случае, теперь, когда я помещаю все в большие большие массивы, я собираю эти массивы. Ссылки на arrViLine и arrNonIraLine и arrIraLine просто массивы, что строки файла разобранные в от их исходной трубы и разделенных запятыми форматов:
If arrViLine(2) = arrIraLine(1) Or arrViLine(2) = arrNonIraLine(1) Then
If arrViLine(2) = arrIraLine(1) Then
boolVi = True
boolIra = True
boolNonIra = False
If lonMatchCounter <= 999999 Then
matchOneArray(lonMatchCounter, 1) = arrViLine(1)
matchOneArray(lonMatchCounter, 2) = arrViLine(2)
matchOneArray(lonMatchCounter, 3) = arrIraLine(2)
matchOneArray(lonMatchCounter, 4) = arrIraLine(3)
matchOneArray(lonMatchCounter, 5) = arrViLine(3)
matchOneArray(lonMatchCounter, 6) = arrViLine(4)
matchOneArray(lonMatchCounter, 7) = arrIraLine(4)
matchOneArray(lonMatchCounter, 8) = arrViLine(6)
matchOneArray(lonMatchCounter, 9) = arrViLine(5)
matchOneArray(lonMatchCounter, 10) = arrViLine(7)
matchOneArray(lonMatchCounter, 11) = arrViLine(8)
matchOneArray(lonMatchCounter, 12) = arrViLine(9)
matchOneArray(lonMatchCounter, 13) = arrViLine(10)
matchOneArray(lonMatchCounter, 14) = arrViLine(11)
matchOneArray(lonMatchCounter, 15) = arrViLine(12)
matchOneArray(lonMatchCounter, 16) = arrIraLine(5)
matchOneArray(lonMatchCounter, 17) = arrIraLine(6)
matchOneArray(lonMatchCounter, 18) = arrViLine(13)
matchOneArray(lonMatchCounter, 19) = arrViLine(14)
matchOneArray(lonMatchCounter, 20) = "IRA"
matchOneArray(lonMatchCounter, 21) = arrViLine(15)
lonMatchCounter = lonMatchCounter + 1
Else
lonMatchTwoCounter = lonMatchCounter - 999999
matchTwoArray(lonMatchTwoCounter, 1) = arrViLine(1)
matchTwoArray(lonMatchTwoCounter, 2) = arrViLine(2)
matchTwoArray(lonMatchTwoCounter, 3) = arrIraLine(2)
matchTwoArray(lonMatchTwoCounter, 4) = arrIraLine(3)
matchTwoArray(lonMatchTwoCounter, 5) = arrViLine(3)
matchTwoArray(lonMatchTwoCounter, 6) = arrViLine(4)
matchTwoArray(lonMatchTwoCounter, 7) = arrIraLine(4)
matchTwoArray(lonMatchTwoCounter, 8) = arrViLine(6)
matchTwoArray(lonMatchTwoCounter, 9) = arrViLine(5)
matchTwoArray(lonMatchTwoCounter, 10) = arrViLine(7)
matchTwoArray(lonMatchTwoCounter, 11) = arrViLine(8)
matchTwoArray(lonMatchTwoCounter, 12) = arrViLine(9)
matchTwoArray(lonMatchTwoCounter, 13) = arrViLine(10)
matchTwoArray(lonMatchTwoCounter, 14) = arrViLine(11)
matchTwoArray(lonMatchTwoCounter, 15) = arrViLine(12)
matchTwoArray(lonMatchTwoCounter, 16) = arrIraLine(5)
matchTwoArray(lonMatchTwoCounter, 17) = arrIraLine(6)
matchTwoArray(lonMatchTwoCounter, 18) = arrViLine(13)
matchTwoArray(lonMatchTwoCounter, 19) = arrViLine(14)
matchTwoArray(lonMatchTwoCounter, 20) = "IRA"
matchTwoArray(lonMatchTwoCounter, 21) = arrViLine(15)
lonMatchCounter = lonMatchCounter + 1
End If
Else 'arrViLine(2) must = arrNonIraLine(1)
boolVi = True
boolIra = False
boolNonIra = True
If lonMatchCounter <= 999999 Then
matchOneArray(lonMatchCounter, 1) = arrViLine(1)
matchOneArray(lonMatchCounter, 2) = arrViLine(2)
matchOneArray(lonMatchCounter, 3) = arrNonIraLine(2)
matchOneArray(lonMatchCounter, 4) = arrNonIraLine(3)
matchOneArray(lonMatchCounter, 5) = arrViLine(3)
matchOneArray(lonMatchCounter, 6) = arrViLine(4)
matchOneArray(lonMatchCounter, 7) = arrNonIraLine(5)
matchOneArray(lonMatchCounter, 8) = arrViLine(6)
matchOneArray(lonMatchCounter, 9) = arrViLine(5)
matchOneArray(lonMatchCounter, 10) = arrViLine(7)
matchOneArray(lonMatchCounter, 11) = arrViLine(8)
matchOneArray(lonMatchCounter, 12) = arrViLine(9)
matchOneArray(lonMatchCounter, 13) = arrViLine(10)
matchOneArray(lonMatchCounter, 14) = arrViLine(11)
matchOneArray(lonMatchCounter, 15) = arrViLine(12)
matchOneArray(lonMatchCounter, 16) = arrNonIraLine(4)
matchOneArray(lonMatchCounter, 17) = arrNonIraLine(6)
matchOneArray(lonMatchCounter, 18) = arrViLine(13)
matchOneArray(lonMatchCounter, 19) = arrViLine(14)
matchOneArray(lonMatchCounter, 20) = "IRA"
matchOneArray(lonMatchCounter, 21) = arrViLine(15)
lonMatchCounter = lonMatchCounter + 1
Else
lonMatchTwoCounter = lonMatchCounter - 999999
matchTwoArray(lonMatchTwoCounter, 1) = arrViLine(1)
matchTwoArray(lonMatchTwoCounter, 2) = arrViLine(2)
matchTwoArray(lonMatchTwoCounter, 3) = arrNonIraLine(2)
matchTwoArray(lonMatchTwoCounter, 4) = arrNonIraLine(3)
matchTwoArray(lonMatchTwoCounter, 5) = arrViLine(3)
matchTwoArray(lonMatchTwoCounter, 6) = arrViLine(4)
matchTwoArray(lonMatchTwoCounter, 7) = arrNonIraLine(5)
matchTwoArray(lonMatchTwoCounter, 8) = arrViLine(6)
matchTwoArray(lonMatchTwoCounter, 9) = arrViLine(5)
matchTwoArray(lonMatchTwoCounter, 10) = arrViLine(7)
matchTwoArray(lonMatchTwoCounter, 11) = arrViLine(8)
matchTwoArray(lonMatchTwoCounter, 12) = arrViLine(9)
matchTwoArray(lonMatchTwoCounter, 13) = arrViLine(10)
matchTwoArray(lonMatchTwoCounter, 14) = arrViLine(11)
matchTwoArray(lonMatchTwoCounter, 15) = arrViLine(12)
matchTwoArray(lonMatchTwoCounter, 16) = arrNonIraLine(4)
matchTwoArray(lonMatchTwoCounter, 17) = arrNonIraLine(6)
matchTwoArray(lonMatchTwoCounter, 18) = arrViLine(13)
matchTwoArray(lonMatchTwoCounter, 19) = arrViLine(14)
matchTwoArray(lonMatchTwoCounter, 20) = "Non-IRA"
matchTwoArray(lonMatchTwoCounter, 21) = arrViLine(15)
lonMatchCounter = lonMatchCounter + 1
End If
End If
Вы также можете игнорировать логические переменные, они там перемотать макрос относительно того, следует ли читать следующую строку определенного файла в следующем цикле.
РЕДАКТИРОВАНИЕ: Не то, чтобы он сильно влиял на то, как быстро я пишу данные, чтобы преуспеть, рассмотрите следующие строки как пример формата файлов, с которыми я работаю.
файл "Мастер":
Account Number|ID Number|Int Rate|Cum Int|Agreement|Type
12345|111111|.005|.|"C"|"IRA"
12346|111112|.005|.02345|"A"|"Non-IRA"
12347|111113|.004|.02345|"B"|"Non-IRA"
Match Файл Один:
ID Number|Int Rate|Cum Int|Type
111111|.004|.|"IRA"
Match Файл Два:
ID Number|Int Rate|Cum Int|Type
111113|.004|.02345|"Non-IRA"
Так что это всего лишь небольшой пример того, что я работать с. Текстовые файлы и CSV-файлы, которые перечислены в последовательном порядке по идентификационному номеру. В приведенном выше примере макрос будет соответствовать первой строке мастера, чтобы соответствовать первому файлу и записывать данные из всех полей из обоих файлов в массив, который будет выводиться в таблицу Excel. Затем макрос читает в следующей строке основного файла и сопоставляет файл один, но переносит строку из файла два в следующий цикл. Следующая строка мастера не будет соответствовать и будет записана на отдельном листе книги. Последняя строка мастера соответствует файлу соответствия 2 и записывается в тот же массив, что и первое совпадение.
Вот как работает рутина, тем не менее, реальная проблема, с которой я сталкиваюсь, - это скорость, с которой данные записываются в книгу Excel. В настоящее время я работаю над вырезанием данных в столбцы.
1,9 миллиона! Вы уверены, что Excel - правильный инструмент для этой работы? Вы сделали обычный расчет настроек для «Ручной» и «Экран» на «Ложь»? – Roberto
Вы можете попробовать и объединить массив в меньшие размеры, но это огромный объем данных для набора электронных таблиц, учитывая, что каждый лист действительно способен обрабатывать ~ 65 500 строк эффективно. Это означает, что у вас будет 29 рабочих листов с 1,9 миллионами строк. (В Excel 2007) 2010 год может достигать ~ 1 000 000 строк, но я не думаю, что буду этому доверять, и навсегда откроется. – engineersmnky
@ Roberto К сожалению, Excel - мой единственный вариант. На самом деле это не так уж плохо, это просто сверка выполняется ежеквартально. Мне просто нужно, чтобы занять меньше 20 часов. Я установил вычисление в ручном режиме и вывел значение false. Не знаю, что еще я могу сделать. – MattB