我的目标是编写一个将回报转换为价格的函数。 我有一个存储在excel范围内的返回向量,如下所示:
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中使用循环?
非常感谢你的时间 周末很棒答案 0 :(得分:4)
是的,在VBA中直接执行此操作的唯一方法是使用循环。
也可以使用Excel工作表函数间接地在VBA中执行此操作,但实际上通常可以更快地将范围复制到VBA数组中,然后使用循环处理它。
您还可以编写(或查找和下载)具有可调用函数和子例程的库来隐藏循环,但它们仍在执行循环。
正如一条评论所说“学会爱循环”。这就是它在VBA中的运作方式。
具有讽刺意味的是,我认为实现这一目标的实际最快方法是添加一个新列,假设从Z2开始,其中Z2为=B2+1
,其他所有行/单元格为Z * =(B*+1)*Z[*-1]
。
答案 1 :(得分: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
答案 2 :(得分: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