在VBA

时间:2016-11-10 15:10:13

标签: arrays vba loops for-loop nested-loops

为资产A,B,C,D构建投资组合资产分配器,并希望将其扩展为n资产。有四个资产,可以运行四个嵌套循环。问题是创建n个嵌套循环,然后应用下面详述的约束和中间嵌套,它将数组分配给当前资产分布。约束是(A + B + C + ... + n)<> 100即所有资产的100%分配。

资产步长是任意的(5或1),但每个n资产都有最小和最大界限。

资产总和为100约束会导致许多迭代失败。

在这个问题中有趣的是,AllocArray需要每个{A,B,C,...,nAsset}的位置,即每个嵌套循环的位置。我认为这是一个令人兴奋的难题。

下面是nAssets = 4,即{A,B,C,D}:

MinMaxStepParam = Range("A1:C4")
   Min Max Step
A    5 100 5
B    5 100 5
C    5 100 5
D    5 100 5


Dim Sim As Long: Sim = 1

Dim AllocArray() As Variant
ReDim AllocArray(1 To nSim, 1 To nAsset + 1)

Dim A As Double
Dim B As Double
Dim C As Double
Dim D As Double

For A = AMin To AMax Step AStep
    For B = BMin To BMax Step BStep
    'If (A + B) > 100 Then GoTo endB ' not required as middle nest bound catches all
        For C = CMin To CMax Step CStep
        'If (A + B + C) > 100 Then GoTo endC ' ditto
            For D = DMin To DMax Step DStep
                        'Constraints
                        If (A + B + C + D) <> 100 Then GoTo endD
                        Debug.Print Sim; A; B; C; D
                        AllocArray(Sim, 1) = Sim
                        AllocArray(Sim, 2) = A
                        AllocArray(Sim, 3) = B
                        AllocArray(Sim, 4) = C
                        AllocArray(Sim, 5) = D
                        Sim = Sim + 1
endD:
            Next D
endC:
        Next C
endB:
    Next B
Next A

PrintArray AllocArray, ActiveWorkbook.Worksheets("Output").[A1]

Sub PrintArray(Data As Variant, Cl As Range)
    Cl.Resize(UBound(Data, 1), UBound(Data, 2)) = Data
End Sub

我已将其作为动态循环生成,但存在错误。 VBA可以使用数组位置处理循环的最小值,最大值和步长吗?还有其他选择吗?

Sub ConfigureArrayDylan()

Dim Param() As Variant: Param = Range("M3:O6")  ' a 4x3 with...Min Max Step... {5 100 5; 5 100 5; 5 100 5; 5 100 5}.
Dim nAsset As Long: nAsset = UBound(Param) ' Count {A, B, ... , D } = 4
Debug.Print nAsset

Dim Asset As Double
Dim Value As Double
Dim Sim As Long: Sim = 1

Dim nSim As Long: nSim = 1
Dim nSimStep As Long
For i = 1 To nAsset Step 1
    nSimStep = (1 + (Param(i, 2) - Param(i, 1)) / Param(i, 3))  '(1 + (AMax - AMin) / AStep) *
    Debug.Print i; nSimStep
    nSim = nSim * nSimStep
Next i
Debug.Print nSim

Dim AllocArray() As Variant
ReDim AllocArray(1 To nSim, 1 To nAsset + 1)

For Asset = 1 To nAssets Step 1
    For Value = Param(Asset, 1) To Param(Asset, 2) Step Param(Asset, 3)
        Debug.Print Value; ' FAILURE HERE
        AllocArray(Sim, Asset) = Value
        Sim = Sim + 1
    Next Value
Next Asset
Debug.Print Sim;

PrintArray AllocArray, ActiveWorkbook.Worksheets("Test").[L18]
'Range("D30").Resize(NumRows, NumCols).Value = AllocArray

End Sub

0 个答案:

没有答案