2016-11-25 112 views
1

我的目標是編寫一個將回報轉換爲價格的函數。 我有一個存儲範圍之內Excel中像這樣的回報的向量:避免在VBA中循環數組?

r1 
r2 
... 
rn 

現在假設這些收益都存儲在B列中 在VBA中寫了下面的代碼

Dim r As Range 

Set r = ThisWorkbook.Sheets("Foglio1").Range("B2:B" & _ 
ThisWorkbook.Sheets("Foglio1").Range("B" & Rows.Count).End(xlUp).Row) 

Dim temp() As Variant 
temp = r 

所以我成功將值r1,r2,...,rn分配給我稱爲temp的數組

現在,如果我是在R或MATLAB我會做以下,以轉換回價格:

temp = cumprod(1 + temp) 

與命令的一條線,我會轉換返回到價格

(1 + TEMP)應總結1至數組的每個元素和cumprod應該返回我的向量與所述累積產物。

是否有可能達到相同的結果,我不得不在VBA中使用循環?

非常感謝您的寶貴時間 有一個偉大的週末

+3

除了使用循環以外,沒有其他方法可以實現這一點。在某些語言中,循環可能比其他語言隱藏在語法糖後面,在VBA中它根本不隱藏,您必須享受它。如果你想要一些糖,創建一個接受Variant數組和一個參數來添加的函數。 – GSerg

+0

你可以在沒有的情況下使用數學公式使用數組公式EXP(SUM(LN(B2:B30)))不知道這是否有幫助? –

回答

4

是直接做在VBA是循環的唯一方法。

也可以通過使用Excel工作表函數在VBA中間接執行它,但實際上通常更快地將範圍複製到VBA數組中,然後使用循環處理它。

您也可以編寫(或查找和下載)具有可調用函數和子例程的庫來隱藏循環,但它們仍在循環中。

正如一條評論所言:「學會愛上循環」。這就是它在VBA中的工作原理。


諷刺的是,我認爲實際的最快的方式做到這一點是添加一個新列,比方說在開始那Z2 Z2了和=B2+1每隔一行/細胞是Z * =(B*+1)*Z[*-1]

+1

我喜歡用循環工作..我只是想知道是否有更有效的方式來做到這一點......非常感謝您的答案! –

+0

實際上有其他避免循環的方法(請參閱其他答案)。不知道哪個是最高效的 – user3598756

+0

@ user3598756我*我確信哪個是最有效率的,因爲我已經嘗試過所有這些。正如我上面所說的,*通常*最快的方法是1)陣列 - 將單元格複製到vba數組,2)循環,然後3)將數組粘貼到單元格中(這是OP正在做的事情)。在某些情況下,vba中的工作表函數(甚至只是公式wo VBA)可能會更快,但它需要在功能和您要實現的功能之間進行非常好的直接匹配。 – RBarryYoung

0

你可以用SQL來做?

這個工作對我的測試

Public Function PRODUCT_FUNCTION(strRange As String) 

Dim c As ADODB.Connection 
Dim r As ADODB.Recordset 

strInputFile = ThisWorkbook.FullName 
Set c = New ADODB.Connection 

strConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strInputFile & ";" & _ 
          "Extended Properties=""Excel 12.0 Xml;HDR=No"";" 

c.ConnectionString = strConnectionString 
c.Open 

strsql = "Select Exp(Sum(Log([F1]))) from [Sheet1$" & strRange & "]" 

Set r = New ADODB.Recordset 

r.Open strsql, c, 1 

PRODUCT_FUNCTION = r.Fields(0).Value 

r.Close 
c.Close 

Set r = Nothing 
Set c = Nothing 

End Function 
0

實際上有一種方法利用Range對象PasteSpecial()方法和WorksheetFunction.Product()方法:

Function CumulativeDiscount(discountsRng As Range) As Double 
    With discountsRng 
     .Copy 
     With .Offset(, .Parent.UsedRange.Columns.Count) 
      .Value = 1 
      .PasteSpecial , Operation:=xlPasteSpecialOperationAdd 
      Application.CutCopyMode = False 
      CumulativeDiscount = WorksheetFunction.Product(Application.Transpose(.Cells)) 
      .ClearContents 
     End With 
    End With 
End Function 

,你可以在你的「主」的代碼按如下方式使用:

Sub main() 
    With ThisWorkbook.Sheets("Foglio1") 
     MsgBox CumulativeDiscount(.Range("B2", .Cells(.Rows.Count, "B").End(xlUp))) 
    End With 
End Sub 

唯一限制作爲WorksheetFunction.Product()最多可接受30 自變量,即要乘以的最大折扣數量爲30