2016-04-11 152 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