2016-11-25 114 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