简体   繁体   English

VBA将大量数据从文本文件加载到Excel

[英]VBA load large data from text file to Excel

I have a problem loading data to Excel from a text file. 我从文本文件加载数据到Excel时遇到问题。 The text file has about 230,000 lines and each line has exactly 130 characters. 文本文件大约有230,000行,每行正好有130个字符。 My goal is to get, from each line, specific data for what I'm trying to load the file into Excel and then retrieve the data I need. 我的目标是从每一行获取特定的数据,以供我尝试将文件加载到Excel中,然后检索所需的数据。

First, I used the following code, but it takes about 7 minutes. 首先,我使用了以下代码,但是大约需要7分钟。

Sub leerTXT()
Dim strArchivo As String 'ruta del archivo
Dim intResultado As Integer 'resultado del dialogo


'---------- RUTA DEL ARCHIVO ----------
'Abrir dialog y preparar
Application.FileDialog(msoFileDialogOpen).AllowMultiSelect = False
intResultado = Application.FileDialog(msoFileDialogOpen).Show

'sólo si hay resultado positivo abrir fichero y leer
If intResultado <> 0 Then
    strArchivo = Application.FileDialog(msoFileDialogOpen).SelectedItems(1)
    On Error GoTo lblError:

Dim strFila As String 'filas que se van a leer
Dim iFila As Long  'numero de fila en la que se esta en el fichero
Dim jFila As Long 'numero de fila en el excel
'posicionarse en la fila 1
iFila = 1
jFila = 1

    'abrir el archivo
    Open strArchivo For Input As #1
    'loop mientras no se ha llegado al final del archivo
    Do Until EOF(1)

        If iFila Mod 70 > 17 Then
            'leer la fila actual
            Line Input #1, strFila

            'leer la linea y copiar a celda
            Cells(jFila, 1) = strFila

            jFila = jFila + 1
        End If

        'incrementar iFila en uno y pasar a la siguiente fila
        iFila = iFila + 1

    'loopear mientras condicion
    Loop

End If

'cerrar el archivo
Close #1

lblError:
If Err.Number <> 0 Then
MsgBox (Err.Number)
MsgBox (Err.Description)
Err.Clear
'cerrar el archivo
Close #1
End If

End Sub

But as I said, that takes too long, so I searched for other ways and I saw something like the following: 但是正如我所说,这花费了太长时间,因此我搜索了其他方法,然后看到了类似以下内容的内容:

Dim FSO As Object, MyFile As Object
Dim FileName As String, Arr As Variant
Dim f As Long

FileName = textfilename
Set FSO = CreateObject("Scripting.FileSystemObject")
Set MyFile = FSO.OpenTextFile(FileName, 1)
Arr = Split(MyFile.ReadAll, vbNewLine) ' Arr is zero-based array

Dim BigGuy(0 To UBound(Arr, 1), 1 To 1) As Long

Dim I As Long
For I = 0 To UBound(Arr)
    BigGuy(I, 1) = I
Next
'For test
'Fill column A from this Array Arr
   'UBound(Arr) + 1 Application.Transpose(
Range("A1:A500") = BigGuy

The clue is to use array and paste range at it seems to be faster, but as the file is too long to transpose, I need to transpose it manually, but UBound(Arr) doesn't work and I don't know how to import the data. 提示是使用数组和粘贴范围似乎更快,但是由于文件太长而无法转置,因此我需要手动进行转置,但是UBound(Arr)不起作用,我也不知道如何导入数据。

And by the way, is there any way of just retrieving specific characters from the file (in an exact position), as every line has exactly the same length? 顺便说一句,由于每一行的长度完全相同,有没有办法从文件中(准确的位置)检索特定字符?

Something like: 就像是:

Dim BigGuy()
Dim numLines As Long
Arr = Split(MyFile.ReadAll, vbNewLine) ' Arr is zero-based array

numLines = UBound(Arr) + 1

ReDim BigGuy(1 To numLines, 1 To 1)


Dim I As Long
For I = 0 To numLines-1
    BigGuy(I+1, 1) = Arr(I)
Next

Range("A1").Resize(numLines, 1) = BigGuy

The array size is limited to 65 536 elements (Integer is 16-bit number). 数组大小限制为65536个元素(整数是16位数字)。 In fact only to 32767 because it is signed number. 实际上只有32767,因为它是带符号的数字。

You can combine first method with second approach reading file in chunks of 32767 elements and fill them by array. 您可以将第一种方法与第二种方法结合起来,以32767个元素的块形式读取文件,并按数组填充它们。

Something like this: 像这样:

Option Explicit
Public Sub test()
Dim strFila As String
Dim i As Integer, j As Long
Dim rng As String

    Dim BigGuy(1 To 32767, 1 To 1)
    i = 1
    j = 1
    Open "c:\temp\data.txt" For Input As #1
    Do Until EOF(1)
        Line Input #1, strFila
        BigGuy(i, 1) = strFila
        i = i + 1
        If i = 32767 Then
            rng = "A" & j & ":A" & j + i - 1
            Range(rng) = BigGuy
            j = j + 32766
            i = 1
        End If
    Loop

    If i > 1 Then
        rng = "A" & j & ":A" & j + i - 2
        Range(rng) = BigGuy
    End If
    Close #1

End Sub

Performance - around 3 sec on my station. 性能-在我的电台上大约3秒。

To extract part of text on well known position use mid$() 要提取已知位置的部分文本,请使用mid$()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM