我正在尝试通过使用两个数据集进行插值来构建收益曲线:一系列到期日,以及另一个利率范围。
我在VBA上有一个UDF,可以对利率进行插值。它使用用户在excel工作表上选择的两个单元格区域作为参数。
我知道Excel要求这些范围必须由连续的单元格组成。 我想做的是在工作表中选择不连续的单元格,并将其值用作UDF参数的范围。
更具体地说,我有两列数据用作范围。但是有时候我需要在每列上跳过一个值,然后将剩余的值用作UDF的范围。
我尝试在UDF中再包含两个范围参数,并使用union方法将两个范围合并为一个,以便在代码中使用结果范围。没用。
****编辑
克里斯, 感谢您指出手表和即时Windows。经过多次尝试,该代码最终按我的预期工作,但是仅对DC_1和taxas_1范围使用单独的循环。 奇怪的是,如果我从循环内部删除“ If k> 1 Then”语句,它将无法正常工作。所以我需要保留它并使它什么也不做。
我注意到间接函数无法与(A1:A3,C2:C5)之类的参数一起使用,因此我不能将indirect((A1:A3,C2:C5))用作UDF的参数。但是,这是一个小问题。
如果有人遇到类似问题,这是我正在使用的代码。
Public Function Interplin_union(ByVal taxas_1 As Range, ByVal DC_1 As Range, ByVal dias As Integer) As Double
Dim tam1 As Long
Dim taxa1 As Double, taxa2 As Double, alfa As Double, d1 As Double, d2 As Double
Dim k As Long
Dim taxas As Variant
Dim DC As Variant
tam1 = taxas_1.Cells.Count
ReDim taxas(1 To tam1)
ReDim DC(1 To tam1)
Interplin_union = -1
Dim c As Range
k = 1
For Each c In DC_1
'taxas(k) = taxas_1(k)
DC(k) = c
If k > 1 Then
'Debug.Print DC(k)
If DC(k - 1) > DC(k) Then
Interplin_union = CVErr(xlErrNA)
Exit Function
End If
End If
k = k + 1
Next
k = 1
For Each c In taxas_1
taxas(k) = c
If k > 1 Then
'Debug.Print DC(k), taxas(k)
End If
k = k + 1
Next
For k = 1 To (tam1 - 1)
If ((DC(k) < dias) And (DC(k + 1) >= dias)) Then
taxa1 = taxas(k)
taxa2 = taxas(k + 1)
alfa = (taxa2 - taxa1) / (DC(k + 1) - DC(k))
Interplin_union = taxa1 + (alfa * (dias - DC(k)))
End If
Next k
If (dias <= DC(1)) Then
Interplin_union = taxas(1)
ElseIf dias > DC(tam1) Then
Interplin_union = taxas(tam1)
End If
End Function
答案 0 :(得分:1)
您可以实际上在不连续范围内的单元格上循环。
也就是说,许多Range属性在应用于不连续范围时,会返回第一个连续子范围的属性值。
演示:
left
那么,如何将其应用于您的情况?我建议两件事:
1的演示
Dim cl as Range, SomeDiscontiguousRange as Range
Dim Rpt as String
Set SomeDiscontiguousRange = [A1:A3, C2:C5]
For each cl in SomeDiscontiguousRange
'Do something with cl, eg
Rpt = Rpt & "," & cl.Address
Next
Debug.Print Rpt 'returns the 7 cell addresses
Debug.Print SomeDiscontiguousRange.Rows.Count 'returns 3, the rows in the first sub-range
在这样的单元格中使用:Function Demo(r as range) as Variant
Demo = r.Address
End Function
请注意双括号,这告诉Excel将=Demo((A1:A3,C2:C5))
视为单个参数。
您的代码经过重构以应用这些方法(以及其他一些优化方法)
(A1:A3,C2:C5)
旁注:
要访问不连续范围的每个范围的属性,请先在Area上循环,然后在每个Area的单元格上循环。例如
Public Function Interplin_union(ByVal taxas_1 As Range, ByVal DC_1 As Range, ByVal dias As Integer) As Double
Dim tam1 As Long
Dim taxa1 As Double, taxa2 As Double, alfa As Double, d1 As Double, d2 As Double
Dim k As Long
Dim taxas As Variant
Dim DC As Variant
tam1 = taxas_1.Cells.Count
ReDim taxas(1 To tam1)
ReDim DC(1 To tam1)
Interplin_union = -1
Dim c As Range
k = 1
For Each c In DC_1
taxas(k) = taxas_1(k)
DC(k) = c
If k > 1 Then
Debug.Print DC(k - 1), DC(k)
If DC(k - 1) > DC(k) Then
Interplin_union = CVErr(xlErrNA)
Exit Function
End If
End If
k = k + 1
Next
For k = 1 To (tam1 - 1)
If ((DC(k) < dias) And (DC(k + 1) >= dias)) Then
taxa1 = taxas(k)
taxa2 = taxas(k + 1)
alfa = (taxa2 - taxa1) / (DC(k + 1) - DC(k))
Interplin_union = taxa1 + (alfa * (dias - DC(k)))
End If
Next k
If (dias <= DC(1)) Then
Interplin_union = taxas(1)
ElseIf dias > DC(tam1) Then
Interplin_union = taxas(tam1)
End If
End Function
Excels Formula Union运算符为Dim Arr as Range, Cl as Range
For Each Arr in SomeDiscontiguousRange.Areas
Debug.Print Arr.Rows.Count
For Each Cl in Arr.Cells
Debug.Print Cl.Address
Next
Next
,交集运算符为,
(空格)。
尝试来了解我的意思。 See this - "Under Reference operators" heading