Sub proverka() 'Для проверки Dim i& Dim x(1 To 77777) For i = LBound(x) To UBound(x) x(i) = i Next arToRange x, 1, 1 End Sub
Public Sub arToRange(ByVal arArray, startRow&, startColumn&) 'arArray - входящий массив, _ startRow - строка с которой начать выгрузку, _ startColumn - колонка с которой начать выгрузку Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Dim ar(50000) ' выгружать будем по 50 тысяч Dim tmp 'массив для выгрузки остатка Dim i&, v&, c& ' счетчики Dim delitel& Dim ostatok&
If Not UBound(arArray) - LBound(arArray) + 1 <= 50000 Then 'если входящий массив меньше чем 50к, то выгружаем целиком
startRow = 1 c = 1 For i = 1 To delitel For v = 1 To UBound(ar) ar(v) = arArray(c) c = c + 1 Next Cells(startRow, startColumn).Resize(UBound(ar)) = Application.WorksheetFunction.Transpose(ar) startRow = startRow + UBound(ar) Next
v = 1 If ostatok > 0 Then ReDim tmp(1 To ostatok + 1) For i = c To UBound(arArray) tmp(v) = arArray(i) v = v + 1 Next Cells(startRow, startColumn).Resize(UBound(tmp)) = Application.WorksheetFunction.Transpose(tmp) End If Else Cells(startRow, startColumn).Resize(UBound(arArray) - LBound(arArray) + 1) = Application.WorksheetFunction.Transpose(arArray) End If
Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic End Sub
[/vba]
Процедура выводит одномерный массив на лист через функцию листа Transpose. Подскажите, пожалуйста, как можно этот код улучшить и оптимизировать? Или есть более быстрые варианты? ЗЫ: Планируется выгружать около 1 млн. значений.
Придумал такой алгоритм:
[vba]
Код
Option Base 1 Option Explicit
Sub proverka() 'Для проверки Dim i& Dim x(1 To 77777) For i = LBound(x) To UBound(x) x(i) = i Next arToRange x, 1, 1 End Sub
Public Sub arToRange(ByVal arArray, startRow&, startColumn&) 'arArray - входящий массив, _ startRow - строка с которой начать выгрузку, _ startColumn - колонка с которой начать выгрузку Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Dim ar(50000) ' выгружать будем по 50 тысяч Dim tmp 'массив для выгрузки остатка Dim i&, v&, c& ' счетчики Dim delitel& Dim ostatok&
If Not UBound(arArray) - LBound(arArray) + 1 <= 50000 Then 'если входящий массив меньше чем 50к, то выгружаем целиком
startRow = 1 c = 1 For i = 1 To delitel For v = 1 To UBound(ar) ar(v) = arArray(c) c = c + 1 Next Cells(startRow, startColumn).Resize(UBound(ar)) = Application.WorksheetFunction.Transpose(ar) startRow = startRow + UBound(ar) Next
v = 1 If ostatok > 0 Then ReDim tmp(1 To ostatok + 1) For i = c To UBound(arArray) tmp(v) = arArray(i) v = v + 1 Next Cells(startRow, startColumn).Resize(UBound(tmp)) = Application.WorksheetFunction.Transpose(tmp) End If Else Cells(startRow, startColumn).Resize(UBound(arArray) - LBound(arArray) + 1) = Application.WorksheetFunction.Transpose(arArray) End If
Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic End Sub
[/vba]
Процедура выводит одномерный массив на лист через функцию листа Transpose. Подскажите, пожалуйста, как можно этот код улучшить и оптимизировать? Или есть более быстрые варианты? ЗЫ: Планируется выгружать около 1 млн. значений.SkyPro
skypro1111@gmail.com
Сообщение отредактировал SkyPro - Пятница, 08.11.2013, 02:31
т.к. исходный массив arArray() и массив ar() объявлены как Variant, то выводить можно сразу квадратом, с учетом пустых значений в конце массива ar(), ячейки будут пустыми:
[vba]
Код
Option Explicit
Sub proverka() Dim i& Dim x(1 To 777777) For i = LBound(x) To UBound(x) x(i) = i Next arToRange x, 1, 1 End Sub
Public Sub arToRange(ByVal arArray, startRow&, startColumn&) Application.ScreenUpdating = False Application.Calculation = xlCalculationManual
Dim maxRow&, maxCol&, i&, j&, k& maxRow = 50000 'maxRow = Rows.Count - startRow + 1 maxCol = (UBound(arArray) - LBound(arArray)) \ maxRow + 1 ReDim ar(1 To maxRow, 1 To maxCol) j = 1 For k = LBound(arArray) To UBound(arArray) i = i + 1 If i > maxRow Then i = 1: j = j + 1 ar(i, j) = arArray(k) Next k
Cells(startRow, startColumn).Resize(maxRow, maxCol) = ar
Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic End Sub
[/vba]
т.к. исходный массив arArray() и массив ar() объявлены как Variant, то выводить можно сразу квадратом, с учетом пустых значений в конце массива ar(), ячейки будут пустыми:
[vba]
Код
Option Explicit
Sub proverka() Dim i& Dim x(1 To 777777) For i = LBound(x) To UBound(x) x(i) = i Next arToRange x, 1, 1 End Sub
Public Sub arToRange(ByVal arArray, startRow&, startColumn&) Application.ScreenUpdating = False Application.Calculation = xlCalculationManual
Dim maxRow&, maxCol&, i&, j&, k& maxRow = 50000 'maxRow = Rows.Count - startRow + 1 maxCol = (UBound(arArray) - LBound(arArray)) \ maxRow + 1 ReDim ar(1 To maxRow, 1 To maxCol) j = 1 For k = LBound(arArray) To UBound(arArray) i = i + 1 If i > maxRow Then i = 1: j = j + 1 ar(i, j) = arArray(k) Next k
Cells(startRow, startColumn).Resize(maxRow, maxCol) = ar
Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic End Sub
Насколько я понял - нужен 1 столбец. Так что два цикла, вкупе с Transpose, большаяяя хитрость.
А я даже не обратил на это внимание, думал нужно по столбцам раскидать, макрос ведь не запускал а так, нужно переложить из одномерного массива в двухмерный и выложить целиком на лист,
но в моем варианте есть небольшое плюс, можно массивы более миллиона записей выкладывать, раскидывая их по столбцам
Насколько я понял - нужен 1 столбец. Так что два цикла, вкупе с Transpose, большаяяя хитрость.
А я даже не обратил на это внимание, думал нужно по столбцам раскидать, макрос ведь не запускал а так, нужно переложить из одномерного массива в двухмерный и выложить целиком на лист,
но в моем варианте есть небольшое плюс, можно массивы более миллиона записей выкладывать, раскидывая их по столбцамMCH
Да. Выводить нужно в столбец. Андрей, никак не пойму, как с твоим способом обойтись без транспоза? Александр, чуток уточнить направление поиска "выводить запросами"? Насколько я понял, вы имели ввиду SQL ?
Да. Выводить нужно в столбец. Андрей, никак не пойму, как с твоим способом обойтись без транспоза? Александр, чуток уточнить направление поиска "выводить запросами"? Насколько я понял, вы имели ввиду SQL ?SkyPro
skypro1111@gmail.com
Сообщение отредактировал SkyPro - Пятница, 08.11.2013, 11:09
"дурная голова рукам покоя не дает" Я думал, что массив на лист вывести можно либо циклом по ячейкам (что ооооочень долго), либо транспозом (что быстро). Вот и выбрал быстрый вариант и голову себе вчера ломал. А всего-то нужно было сделать из одномерного массива двумерный =\ Андрей, Михаил, спасибо вам, что просветили
"дурная голова рукам покоя не дает" Я думал, что массив на лист вывести можно либо циклом по ячейкам (что ооооочень долго), либо транспозом (что быстро). Вот и выбрал быстрый вариант и голову себе вчера ломал. А всего-то нужно было сделать из одномерного массива двумерный =\ Андрей, Михаил, спасибо вам, что просветили SkyPro
skypro1111@gmail.com
Сообщение отредактировал SkyPro - Пятница, 08.11.2013, 11:22
Спасибо. В моем случае массив фомируется, а не считывается. Так что вывод проще организовать "обычным" способом. А вашу надстройку, при возможности, обязательно попробую
Спасибо. В моем случае массив фомируется, а не считывается. Так что вывод проще организовать "обычным" способом. А вашу надстройку, при возможности, обязательно попробую SkyPro