Лучший способ прочитать очень большой массив в листе Excel - PullRequest
0 голосов
/ 13 февраля 2019

Мне нужно импортировать несколько текстовых файлов в Excel и добавить каждый текстовый файл на новый лист.Количество строк в некоторых файлах превышает 350 000.Циклы занимают так много времени, что это не очень удобно для пользователя.Я пытался использовать это, чтобы быстро прочитать данные

Dim arrLines() As String
Dim lineValue As String

lineValue = ts.ReadAll
DoEvents
arrLines() = Split(lineValue, vbCrLf)


Dim Destination As Range
Set Destination = Worksheets(WorksheetName).Range("A2")
Set Destination = Destination.Resize(UBound(arrLines), 1)
Destination.Value = Application.Transpose(arrLines)

, но это приводит к тому, что каждое значение ПОСЛЕ строки 41243 просто имеет значение "# N / A".Я думал использовать Application.Index для разбиения массива на меньшие массивы, но вам нужно дать функции индекса массив строк, которые вы хотите создать новый массив, и это будет означать создание цикла для выполнения черезчисла 1-41000, затем 41001-82000 и т. д. На данный момент я делаю цикл для создания массивов, это не очень быстро.цикл по файлу построчно также слишком медленный.Какой хороший способ чтения в таком большом количестве строк, не заканчивая пропущенными значениями?

Ответы [ 3 ]

0 голосов
/ 13 февраля 2019

Матье Гиндон получил именно то решение, на которое я надеялся.Устранение транспонирования решило проблему со значениями # N / A.Спасибо!

Редактировать:

Код просто зацикливает массивированные данные во второй раз в двумерный массив и затем отправляет их в диапазон без эффекта транспонирования.Это немного медленнее, чем старый способ (занимает около двух минут или дольше), но все равно довольно быстро и дает желаемые результаты.Код выглядит следующим образом:

    lineValue = ts.ReadAll
DoEvents
arrLines() = Split(lineValue, vbCrLf)
Dim arrBetween() As Variant
ReDim arrBetween(UBound(arrLines), 0)

LoopLength = UBound(arrLines) - 1

For i = 0 To LoopLength
    arrBetween(i, 0) = arrLines(i)

    DoEvents

    If i Mod 2500 = 0 Or i = LoopLength Then
        Application.StatusBar = "Importing " & WorksheetName & " " & (i) & " ."
    End If
Next i

Dim Destination As Range
Set Destination = Worksheets(WorksheetName).Range("A2:A" & UBound(arrLines))

Destination.Value = arrBetween
0 голосов
/ 13 февраля 2019

Копировать текстовые файлы в Excel

Кредиты simple-solution для предложения (в комментариях) открыть текстовые файлы с Workbooks.Open.

Код

Sub CopyTextFilesToExcel()

    ' Search Folder Path
    Const cStrPath As String _
            = "D:\Excel\MyDocuments\StackOverflow\"
    Const cStrExt As String = "*.txt"       ' File Extension
    Const cFolderPicker As Boolean = False  ' True to enable FolderPicker

    Dim wb As Workbook          ' Current File
    Dim strPath As String       ' Path of Search Folder (Incl. "\" at the end.)
    Dim strFileName As String   ' Current File Name

    With Application
        .ScreenUpdating = False
        .DisplayAlerts = False
    End With

    On Error GoTo ProcedureExit

    ' Determine Search Path ("\" Issue)
    If cFolderPicker Then
        With Application.FileDialog(msoFileDialogFolderPicker)
            If .Show = False Then Exit Sub
            strPath = .SelectedItems(1) & "\"
        End With
      Else
        If Right(cStrPath, 1) <> "\" Then
            strPath = cStrPath & "\"
          Else
            strPath = cStrPath
        End If
    End If

    ' Determine first Current File Name.
    strFileName = Dir(strPath & cStrExt)

    With ThisWorkbook ' Target Workbook
        ' Loop through files in folder.
        Do While strFileName <> ""
            ' Create a reference to the Current File.
            Set wb = Workbooks.Open(cStrPath & strFileName)
            ' Copy first worksheet of Current File after the last sheet
            ' (.Sheets.Count) in Target Workbook.
            wb.Worksheets(1).Copy After:=.Worksheets(.Sheets.Count)
            ' Close Current File without saving changes (False).
            wb.Close False
            ' Find next File(name).
            strFileName = Dir()
        Loop
    End With

    MsgBox "All files copied!"

ProcedureExit:

  With Application
      .ScreenUpdating = True
      .DisplayAlerts = True
  End With

End Sub
0 голосов
/ 13 февраля 2019

Вы можете использовать и автоматизировать мастер «Данные» -> «Из текста / CSV» в Excel.

Используя макрос-рекордер, вы получите следующее, что должно стать хорошим началом:

ActiveWorkbook.Queries.Add Name:="MyFile", Formula:="let" & Chr(13) & "" & Chr(10) & "    Source = Table.FromColumns({Lines.FromBinary(File.Contents(""C:\Path\MyFile.txt""), null, null, 1252)})" & Chr(13) & "" & Chr(10) & "in" & Chr(13) & "" & Chr(10) & "    Source"
ActiveWorkbook.Worksheets.Add
With ActiveSheet.ListObjects.Add(SourceType:=0, Source:="OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=""MyFile"";Extended Properties=""""", Destination:=Range("$A$1")).QueryTable
    .CommandType = xlCmdSql
    .CommandText = Array("SELECT * FROM [MyFile]")
    .RowNumbers = False
    .FillAdjacentFormulas = False
    .PreserveFormatting = True
    .RefreshOnFileOpen = False
    .BackgroundQuery = True
    .RefreshStyle = xlInsertDeleteCells
    .SavePassword = False
    .SaveData = True
    .AdjustColumnWidth = True
    .RefreshPeriod = 0
    .PreserveColumnInfo = True
    .ListObject.DisplayName = "MyFile"
    .Refresh BackgroundQuery:=False
End With
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...