2014-07-23 71 views
0

我很熟悉MATLAB,但現在在VBA中工作,因爲MATLAB對我來說不太方便,我努力嘗試在VBA(如矢量化)可以很容易地在MATLAB中處理。在VBA內存中使用數組並避免使用矢量化的循環

可以說我有一個數據表中以下格式的Excel:

record startDate endDate count 
1 100 103 10 
2 98 102 5 
3 101 104 4 

我願做內存我所有的處理(避免環路),然後看起來像這樣的輸出結果文件:

1 2 3 Sum 
98 0 5 0 5 
99 0 5 0 5 
100 10 5 0 15 
101 10 5 4 19 
102 10 5 4 19 
103 10 0 4 14 
104 0 0 4 4 

基本上,我開始通過最新的日期最早的日期和循環,然後檢查是否每一個日期被包括在每條記錄的日期窗口,如果它是我申請的記錄數的那一天,然後總結它們。

我使用簡單的工作表函數創建了包含的輸出,但我希望能夠在VBA中複製該過程,特別是避免循環至少減少到1循環而不是嵌入循環。

如果我在MATLAB我會找到符合條件的邏輯陣列,例如:

numDays = 7; 
numRecords = 3; 
startDate = [100; 98; 101]; 
endDate = [103; 102; 104]; 
dateVector = [98; 99; 100; 101; 102; 103; 104]; 
count = [10; 5; 4]; 
dateLogic = logical(numDays,numRecords); 
for d = 1:numDays 
    dateLogic(d,:) = dateVector(d) >= startDate(:,1) & dateVector(d) <= endDate(:,1) 
end 
countMatrix = dateLogix * count'; 
Sum = sum(countMatrix,2); 

這會給我,我可以計數矢量乘跨到零和一的邏輯矩陣得到我的數量,最終我的總和向量。我相信我甚至可以在幾天內使用bsxfun來刪除循環。

請原諒任何潛在的語法錯誤,因爲我現在無法訪問MATLAB。

無論如何,我如何在VBA中做類似的事情。是否有一個等效的冒號表示法來引用數組中的整個列或行的範圍。我將應用於大數據集,因此效率是至關重要的。在粘貼更好之前,我可以在記憶中做的越多。

在此先感謝。

+2

您需要使用一些自定義函數來切片數組。使用2d矩陣數組很容易構建一個'GetRow'函數或'GetColumn'函數。這裏還有大量有用的幫助功能:www.cpearson.com/excel/array.htm –

+0

爲什麼不使用Octave? – RowanC

+0

雖然我想避免學習另一種語言(八度),但兩個很好的線索。所提供的鏈接上的數組函數有可能支持我所需要的。 –

回答

1

以下是一種可能性,請嘗試使用新工作簿的A1:A4中的sampe數據。

Sub NewTable() 

Set Table = Sheet1.[a2:d4] 

With Application 

    Record = .Transpose(.Index(Table, , 1)) 
    FirstDate = .Transpose(.Index(Table, , 2)) 
    LastDate = .Transpose(.Index(Table, , 3)) 
    Count = .Transpose(.Index(Table, , 4)) 

    Dates = .Evaluate("row(" & .Min(FirstDate) & ":" & .Max(LastDate) & ")") 
    Values = .PV(, Count, .PV(, .GeStep(Dates, FirstDate), .GeStep(LastDate, Dates))) 
    Sum = .MMult(Values, .Power(.Transpose(Record), 0)) 

End With 

Sheet1.[F1].Offset(, 1).Resize(, UBound(Values, 2)) = Record 
Sheet1.[F2].Resize(UBound(Dates)) = Dates 
Sheet1.[G2].Resize(UBound(Values), UBound(Values, 2)) = Values 
Sheet1.[G2].Offset(, UBound(Values, 2)).Resize(UBound(Dates)) = Sum 

End Sub