2016-04-11 214 views
2

第一次发布的进口节 - 请温柔:)Excel的VBA - 文本文件(二进制文件的导入)

我有一个大的文本文件(50MB左右),我们的工作服务器上坐着。该文件按升序排序。我想知道是否可以使用二进制搜索来搜索和导入与密钥匹配的文件部分。

例如,代码将占用512kb的文件,并查看我需要的数据是否在文件的该部分,如果不是,则移动到下一个512kb,直到找到我们需要的数据。另外,密钥会有几行(2K)数据,所以代码需要查找密钥的开始和结束点。

我希望在加载文件时只需加载具有用户需要的数据的文件部分即可节省时间。由于服务器速度较慢(特别是在远程连接时(即在家中工作)),每个小时都会生成一个新文件,因此将整个文件加载到报告中需要很长时间。有谁知道这是否可能?

非常感谢

回答

0

不,这是不可能的加载您感兴趣的文件的唯一部分。这主要是由于这样的事实,你不能告诉哪里开始查看文件,你想写什么?开始查看12MB位置附近的50MB文件?

但是,你可以逐行读取文件中的行,而不必将整个文件第一次加载到内存中:

Public Sub ImportToExcel() 

Dim intCounter As Long 
Dim intPointer As Integer 
Dim strFileToImport As String 

'The location of the file you wish to load 
strFileToImport = "C:\tmp\test.csv" 

intPointer = FreeFile() 
Open strFileToImport For Input Access Read Lock Read As #intPointer 

intCounter = 1 
Do Until EOF(intPointer) 
    'Loading row by row from the text file into strLine 
    Line Input #intPointer, strLine 
    'Check if the "KeyYouAreLookingFor" can be found in that line 
    '... if it can be found then copy it to the first sheet 
    If InStr(1, strLine, "KeyYouAreLookingFor") Then 
     Worksheets(1).Cells(intCounter + 1, 1).Value2 = strLine 
     intCounter = intCounter + 1 
    Else 
     'If the key cannot be found but has been found in the past 
     '... then (following your logic that the file is sorted) 
     '... all other rows in the file can be ignored and 
     '... the import is complete: so the program should stop 
     If intCounter > 1 Then Exit Sub 
    End If 
Loop 

Close intPointer 

End Sub 

看一看在更多的解释代码中的注释,让我知道,如果这适合您的需要。

假设你50MB文本文件是,分隔CSV文件,你可以进一步细化上面的代码如下所示:

If InStr(1, Split(strLine, ",")(0), "KeyYouAreLookingFor") Then 

当然,这里假设你的“钥匙”是第一列中每一行。如果没有,只需根据自己的喜好进行适当调整即可。

+0

嗨拉尔夫,感谢您的快速响应。我希望它的工作方式是从中间开始,如果键大于在中间找到的键,则忽略上面的所有内容,然后找到剩余的半个文件的中间>冲洗并重复,直到钥匙已经找到。如果那是不可能的,那就没问题。只是想我会问这个问题。只是关于你的代码的一个简单问题 - 上面的解决方案是否会比“textfile.readall”更快,然后查看每一行以查找所需的数据? – Tabias

+0

简短回答:如果您正在处理大文件(如您的文件),上述解决方案是最好的。大多数文本编辑器甚至无法打开大文本文件(100MB或更大)。只需试试NotePad就可以看到。上面的代码是最好的,因为它只能逐行读入内存。 **不是**立即整个文件。我用上面的代码处理了> 500MB的文件,没有任何问题。如果在那里有支持这一点的工具,你的建议就会有效。但即使使用ODBC连接“SELECT”也需要**整个**文件进行扫描。 – Ralph

+0

嗨Ralph,我刚刚尝试过你的解决方案,大约需要2/3分钟才能执行“Line Input #intPointer,strLine”我假定当excel访问服务器上的整个文件并下载它时。只是为了让你知道它的速度有多慢,在“下载”期间,我的LAN连接只有1%被利用(100mbps)。 – Tabias