Страницы: 1
RSS
заполнение массива
 
всем здравствуйте  
подскажите, как быстро заполнить массив данными из множества файлов excel.  
задача следующая: все файлы содержат одинаковые таблицы (200 строк, 20 столбцов), нужно создать массив, в котором эти таблицы будут "вставать" одна под другую и, таким образом получиться одна большая таблица.  
интересует именно код записи в массив.  
вариант с циклом не подходит, потому на это уходит слишком много времени (у меня более 300 файлов, хочется чтобы на все про все уходило до 20 мин).  
подскажите, как вставлять данные в массив блоками  
заранее благодарю
 
{quote}{login=The_Prist}{date=19.07.2010 03:16}{thema=}{post}Нельзя блоками.    
 
почему нельзя, можно:  
dim arr()  
arr = Range(Cells(1, 1), Cells(1000, 100))  
только как несколько таких таблиц загнать в массив, я не знаю  
 
про копирование мысль, так просто почему-то даже не подумал)
 
Я думаю, можно и копировать так же через массивы - из одного файла считали в массив за раз, в другой вывалили - за раз. Только всё время iLastRow передвигать... Должно быстро получиться. Но сам не пробовал, гипотеза.
 
Проверил - получилось 0,046875 против 0,359375  
Присвоение через массив против простого копирования.  
А вот присвоение значений одного диапазона другому и впрямь быстрее - 0,03125.
 
спасибо, Hugo  
действительно быстрее  
 
есть еще один вариант, при открытии файла весь usedrange загоняем во временный массив, из которого аккуратно, через цикл укладываем данные в конечный массив, и получаем таблицу нужного вида. при этом excel удивительно быстро это делает с каждым файлом
 
Копируйте блоки данных между массивами одного типа, используя функцию API CopyMemory вместо цикла For...Next:  
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _  
(dest As Any, As Any, ByVal bytes As Long) ' Копируем a() в b() - b() того же типа что и а()  
' Размерность N показывает число копируемых элементов  
CopyMemory b(0), a(0), n * Len(a(0))  
Эту функцию можно использовать для массивов любого типа, за исключением строк переменной длины, объектов и пользовательских типов, их содержащих.
Я сам - дурнее всякого примера! ...
 
Действительно, замена перебора ячеек на перебор массивов даёт удивительный выигрыш по скорости - я недавно так убыстрил с 40 МИНУТ до 5,5 СЕКУНД!  
Причём код принципиально не поменялся - был цикл в цикле по ячейкам, поменял на цикл в цикле по массивам.
 
{quote}{login=KuklP}{date=21.07.2010 10:08}{thema=}{post}Копируйте блоки данных между массивами одного типа, используя функцию API CopyMemory вместо цикла For...Next:  
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _  
(dest As Any, As Any, ByVal bytes As Long) ' Копируем a() в b() - b() того же типа что и а()  
' Размерность N показывает число копируемых элементов  
CopyMemory b(0), a(0), n * Len(a(0))  
Эту функцию можно использовать для массивов любого типа, за исключением строк переменной длины, объектов и пользовательских типов, их содержащих.{/post}{/quote}  
 
а поподробнее бы...  
Ну, что пропущено в аргументах имя переменной (наверное, что-то типа src ?) это понятно...    
А вот где ставить это Declare Sub и где его End Sub, а также фраза CopyMemory b(0), a(0), n * Len(a(0)) - вообще загадка.
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Да, подробнее бы не мешало...  
Нашёл пример:  
эту строку сразу после Option Explicit -    
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Long, ByVal ByteLen As Long)  
 
а остальное в коде, даю целиком функцию -  
 
Public Function GetText() As String  
   Dim hClipMemory As Long  
   Dim lpClipMemory As Long  
   Dim MyString As String  
   Dim lLength As Long  
   Dim RetVal As Long  
     
   If OpenClipboard(0&) = 0 Then  
       MsgBox "Невозможно открыть буфер обмена, " & "Может быть он занят другим приложением"  
       Exit Function  
   End If  
 
   ' получить указатель на блок памяти, с текстом буфера обмена  
   hClipMemory = GetClipboardData(CF_TEXT)  
 
   If IsNull(hClipMemory) Then  
       MsgBox "Невозможно выделить память"  
       GoTo OutOfHere  
   End If  
           
   ' фиксируем блок памяти, чтобы получить указатель на строку  
   lpClipMemory = GlobalLock(hClipMemory)  
   lLength = lstrlen(lpClipMemory)  
 
   If Not IsNull(lpClipMemory) Then  
       MyString = Space$(lLength)  
       CopyMemory ByVal MyString, ByVal lpClipMemory, lLength  
       RetVal = GlobalUnlock(hClipMemory)  
   Else  
       MsgBox "невозможно фиксировать блок памяти"  
   End If  
 
OutOfHere:  
   RetVal = CloseClipboard()  
   GetText = MyString  
End Function
 
Ну, это опять же на тему:"Папа, а ты с кем сейчас говорил?" :-(  
Да и разобраться-протестировать пример невозможно, т.к. в приведённой функции куча не определённых переменных и функций (OpenClipboard, CF_TEXT, GlobalLock, lstrlen, ...), поэтому поставить Private Declare Sub CopyMemory после Option Explicit в том же модуле, где и функция не удастся...
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
Приаттачил вырезку из запасника, вроде я этот код использовал при работе с буфером обмена.
 
The_Prist,  
спасибо за пример.  
Но это байтовые операции, а я до них к сожалению ещё не доуглубился :-)
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
the prist, если вас не затруднит,  
если ли такой пример для двухмерных массивов?
Страницы: 1
Читают тему
Наверх