这里我对Excel中的VBA有一些复杂的组合问题。 我有n个变量由起始值,停止值和步骤定义。 N个变量是双值,基本上如下所示。
Var1, Var2, Var3, .... VarN
start: 20, 1, 0.1, ....
stop : 100, 10, 1.0, ....
step : 10, 1, 0.1, ....
如下所示,生成每个变量组合的最有效(快速)方法是什么:
20, 1, 0.1
20, 1, 0.2
20, 1, 0.3
...
...
...
100, 10, 0.8
100, 10, 0.9
100, 10, 1.0
我认为这种情况下有900种组合(= 9x10x10)。
更具挑战性的部分是我需要使用像这样的双数组的N变量案例更灵活的解决方案(不涉及任何工作表公式):
Private startValue() As Double ' start value of each variable
Private stopValue() As Double ' stop value of each variable
Private stepValue() As Double ' step value of each variable
Private combination() as double 'combination of all N variable
Private n as integer ' number of variable = N
ReDim startValue(1 To 1, 1 To n) As Double
ReDim stopValue(1 To 1, 1 To n) As Double
ReDim stepValue(1 To 1, 1 To n) As Double
我非常感谢您的帮助。
亲切的问候。
答案 0 :(得分:0)
如果你想要3个数组用于startValue,stopValue和stepValue,为什么你需要2维数组。或者,您只能使用一个二维数组
ReDim arrValue(0 To 2, 0 To n-1) As Double
其中索引0 =开始,1 =停止,2 =步骤
答案 1 :(得分:0)
您可以通过为变量指定范围(即Excel
)来让arrMyValues = Range("A2:C4")
完成工作,而不是创建数组然后为其指定值。但是在你的情况下,我们不知道最后一栏,我们首先必须得到最后一栏。我们可以通过以下方式得到这个:
oWS.Cells(1, Columns.Count).End(xlToLeft).Column
这将返回工作表中使用的列数。但是,在这种情况下,我们需要最后一列的名称。为此,我们首先得到最后一列地址:
oWS.Cells(1, Columns.Count).End(xlToLeft).Address
然后我们将这个地址拆分成一个数组,以便我们得到列名:
arrColAddress = Split(oWS.Cells(1, Columns.Count).End(xlToLeft).Address, "$")
现在我们有了最后一列的名称,我们可以使用带行数的名称将范围传递给我们的变量。要获取工作表的行数,我们可以使用:
oWS.Cells(Rows.Count, "B").End(xlUp).Row
如果我们把所有这些放在一起(我添加的只是一个工作表对象),我们得到:
Dim oWS as Worksheet : Set oWS = Worksheets("your worksheet name")
arrColAddress = Split(oWS.Cells(1, Columns.Count).End(xlToLeft).Address, "$")
arrMyValues = oWS.Range("A2:" & arrColAddress(1) & oWS.Cells(Rows.Count, "B").End(xlUp).Row)
代码基于您提供的表格
答案 2 :(得分:0)
这是一个适用于任意数量变量的解决方案:
'The following takes a 1-based variant area with 3 rows
'And n columns, where n is the number of variables
'The first row are start values, the second is stop, and the
'third is step-size.
'It returns a variant array consisting of all combos
Function MakeCombos(Vals As Variant) As Variant
Dim i As Long, j As Long, n As Long
Dim numCombos As Long
Dim combos As Variant, levels As Variant
Dim var As Double, varStep As Double, colStep As Long
If TypeName(Vals) = "Range" Then Vals = Vals.Value 'make into a VBA array if passed a range
n = UBound(Vals, 2)
ReDim levels(1 To n)
'first find the *number* of levels for each variable
numCombos = 1
For i = 1 To n
levels(i) = 1 + Round((Vals(2, i) - Vals(1, i)) / Vals(3, i))
numCombos = numCombos * levels(i)
Next i
ReDim combos(1 To numCombos, 1 To n)
'Now -- just fill in column by column in reverse order with some modular arithmetic
colStep = 1 'how often value is changed in column
For j = n To 1 Step -1
var = Vals(1, j)
varStep = Vals(3, j)
combos(1, j) = var
For i = 1 To numCombos - 1
combos(i + 1, j) = var + (Int(i / colStep) Mod levels(j)) * varStep
Next i
'before next pass theough outer loop, increase colStep so that
'in the next column will step more slowly
colStep = colStep * levels(j)
Next j
MakeCombos = combos
End Function
为了测试它,我开始使用一个看起来像的电子表格:
然后运行此代码:
Sub test()
Range("F1:H900").Value = MakeCombos(Range("B2:D4"))
End Sub
之后,F:H列中的数据以:
开头和900行结束时: