2014-07-23 16 views
0

有時候我發現自己在填充數組時不必先定尺寸。大多數情況下,我可以通過一個循環來驗證條件已被驗證的次數,ReDim我的數組相應,然後與相同,非常循環用數據填充數組。
這是(尤其是與humongous陣列)非常耗時,並沒有優化。VBA - 將數據插入數組而無需設定尺寸

今天,我發現自己編程「讀書」的文本文件,在其中我不得不驗證行了多少次空單重複之前,無需多少可以有任何線索。我只知道,這樣的線的最小數量爲1

文件看起來是這樣的:

TITLE Very_Much_Potato 
INFO lol? 
FREQUENCY 123456.7 
DEF_DIAG 1 Potato1.TXT 
DEF_DIAG 2 Potato2.TXT 

ELEMENT 1 0.00 0.00 -300.00  0.250 0.0  6.0  1 2 0.00 0.0  0.0  
ELEMENT 2 0.00 0.00 -200.00  0.500 20.0 6.0  1 2 0.00 0.0  0.0  
ELEMENT 3 0.00 0.00 -100.00  0.750 40.0 6.0  1 2 0.00 0.0  0.0  
ELEMENT 4 0.00 0.00 0.00 1.000 60.0 6.0  1 2 0.00 0.0  0.0  
ELEMENT 5 0.00 0.00 100.00 0.750 80.0 6.0  1 2 0.00 0.0  0.0  
ELEMENT 6 0.00 0.00 200.00 0.500 100.0 6.0  1 2 0.00 0.0  0.0  
ELEMENT 7 0.00 0.00 300.00 0.250 120.0 6.0  1 2 0.00 0.0  0.0  

END 

我用下面的代碼來「閱讀」:

Dim i As Integer 
Dim fd As FileDialog, FilePath As String 
Dim fst As Object, StringData As String 
Dim Name As String, Frequency As Double, DefDiag() As String 

Set fd = Application.FileDialog(msoFileDialogFilePicker) 
With fd 
    .Title = "Select the file you would like to import" 
    .AllowMultiSelect = False 
    .Filters.Clear 
    .Filters.Add "Potato File", "*.pot" 
    .FilterIndex = 1 
    If .Show <> -1 Then 
     End 
    End If 
    FilePath = .SelectedItems(1) 
End With 

Set fst = CreateObject("ADODB.Stream") 
fst.Charset = "utf-8" 
fst.lineseparator = 10  ' sets enter as end-of-line separator 
fst.Open 
fst.LoadFromFile FilePath 

StringData = fst.ReadText(-2) ' -2 to read until lineseparator 
Name = Mid(StringData, 7) 
StringData = fst.ReadText(-2) 
StringData = fst.ReadText(-2) 
Frequency = CDbl(Mid(StringData, 11)) 
Do Until fst.ReadText(-2) = "" 
    StringData = fst.ReadText(-2) ' DEF_DIAG 
    DefDiag(i) = Right(StringData, Len(StringData) - InStrRev(StringData, " ")) 
    i = i + 1 
Loop 

自然,停止DefDiag陣列開始填充的位置。任何想法如何不維度?

回答

1

我不認爲這是可能的填充數組沒有VBA的尺寸,但你可以使用ReDim Preserve到REDIM的陣列,同時在循環:

... 

i=1 

Do Until fst.ReadText(-2) = "" 
    StringData = fst.ReadText(-2) ' DEF_DIAG 
    ReDim Preserve DefDiag(i) 
    DefDiag(i) = Right(StringData, Len(StringData) - InStrRev(StringData, " ")) 
    i = i + 1 
Loop 
+0

不錯,順利的把戲!正是我需要的 – Noldor130884

1

我會的;

  • 加載整個文件到內存中,解析成線

    Open FilePath For Input As #1 DefDiag = Split(Input$(LOF(1), #1), ChrW$(10)) Close #1

  • 的陣列分配的第二陣列的大小DefDiag

  • 環路DefDiag做你的處理相同,當需要存儲數值時,添加到第二個數組的下一個索引

  • 當你完成Redim第2個數組截斷其空尾

+0

+1的幫助,但我不喜歡「打開FilePath的輸入爲#1」,也不喜歡我需要使用2個數組的事實。這樣做並不能解決「雙循環」的問題 – Noldor130884

+0

我認爲你擔心效率問題,在這方面IMO很難打敗它的1迴路和3陣列分配,而不是每行分配。也沒有對外部依賴關係的延遲綁定COM調用。 –

+0

那麼你必須加載整個文件在一個數組...這不是一種循環?然後,如果我有更多系列的重複行,我認爲我應該循環多次(特別是當涉及到我的處理過程 - 它會依次構建其他數據)。 此外,我不知道它是否與少數重複行的效率一樣高效:Loop + Redim Preserve應該花費更少的時間。 – Noldor130884