Excel 当VBA代码到达第1048576行时,如何更改目标输出
我试图运行一个代码,当掷8个骰子时显示所有可能的组合。问题是:有将近170万个组合,excel只有1048576行,所以VBA不断给我一个错误(运行时错误“1004”:对象“Range”的方法“Offset”失败)。如何解决此问题 这是我的密码:Excel 当VBA代码到达第1048576行时,如何更改目标输出,excel,vba,Excel,Vba,我试图运行一个代码,当掷8个骰子时显示所有可能的组合。问题是:有将近170万个组合,excel只有1048576行,所以VBA不断给我一个错误(运行时错误“1004”:对象“Range”的方法“Offset”失败)。如何解决此问题 这是我的密码: Sub combinations() Dim c1() As Variant Dim c2() As Variant Dim c3() As Variant Dim c4() As Variant Dim c5() As Variant Dim c6
Sub combinations()
Dim c1() As Variant
Dim c2() As Variant
Dim c3() As Variant
Dim c4() As Variant
Dim c5() As Variant
Dim c6() As Variant
Dim c7() As Variant
Dim c8() As Variant
Dim out() As Variant
Dim j, k, l, m, n, o, p, q, r As Long
Dim col1 As Range
Dim col2 As Range
Dim col3 As Range
Dim col4 As Range
Dim col5 As Range
Dim col6 As Range
Dim col7 As Range
Dim col8 As Range
Dim out1 As Range
Set col1 = Range("A1:A6")
Set col2 = Range("B1:B6")
Set col3 = Range("C1:C6")
Set col4 = Range("D1:D6")
Set col5 = Range("E1:E6")
Set col6 = Range("F1:F6")
Set col7 = Range("G1:G6")
Set col8 = Range("H1:H6")
c1 = col1
c2 = col2
c3 = col3
c4 = col4
c5 = col5
c6 = col6
c7 = col7
c8 = col8
Set out1 = Range("J2", Range("Q2").Offset(UBound(c1) * UBound(c2) * UBound(c3) * UBound(c4) * UBound(c5) * UBound(c6) * UBound(c7) * UBound(c8)))
out = out1
j = 1
k = 1
l = 1
m = 1
n = 1
o = 1
p = 1
q = 1
r = 1
Do While j <= UBound(c1)
Do While k <= UBound(c2)
Do While l <= UBound(c3)
Do While m <= UBound(c4)
Do While n <= UBound(c5)
Do While o <= UBound(c6)
Do While p <= UBound(c7)
Do While q <= UBound(c8)
out(r, 1) = c1(j, 1)
out(r, 2) = c2(k, 1)
out(r, 3) = c3(l, 1)
out(r, 4) = c4(m, 1)
out(r, 5) = c5(n, 1)
out(r, 6) = c6(o, 1)
out(r, 7) = c7(p, 1)
out(r, 8) = c8(q, 1)
r = r + 1
q = q + 1
Loop
q = 1
p = p + 1
Loop
p = 1
o = o + 1
Loop
o = 1
n = n + 1
Loop
n = 1
m = m + 1
Loop
m = 1
l = l + 1
Loop
l = 1
k = k + 1
Loop
k = 1
j = j + 1
out = out1
Loop
out1.Value = out
End Sub
子组合()
Dim c1()作为变量
Dim c2()作为变量
Dim c3()作为变体
Dim c4()作为变体
Dim c5()作为变体
Dim c6()作为变量
Dim c7()作为变量
Dim c8()作为变量
Dim out()作为变量
尺寸j,k,l,m,n,o,p,q,r等于长
Dim col1 As范围
暗淡col2 As范围
变暗col3 As范围
变暗col4 As范围
变暗col5 As范围
Dim col6 As系列
变暗col7 As范围
变暗col8 As范围
变暗1作为范围
设置col1=范围(“A1:A6”)
设置col2=范围(“B1:B6”)
设置col3=范围(“C1:C6”)
设置col4=范围(“D1:D6”)
设置col5=范围(“E1:E6”)
设置col6=范围(“F1:F6”)
设置col7=范围(“G1:G6”)
设置col8=范围(“H1:H6”)
c1=col1
c2=col2
c3=col3
c4=col4
c5=col5
c6=col6
c7=col7
c8=col8
放线1=范围(“J2”,范围(“Q2”)。偏移量(UBound(c1)*UBound(c2)*UBound(c3)*UBound(c4)*UBound(c5)*UBound(c6)*UBound(c7)*UBound(c8)))
out=out1
j=1
k=1
l=1
m=1
n=1
o=1
p=1
q=1
r=1
我建议你尝试下一种方法。无论如何,大数据范围将需要很长时间
它建议使用第二个数组,如果总组合数将超过允许的最大值,则加载该数组。它可以使用相同的数组,将数据丢弃到最大限度,并对新维度进行Redim
,但我担心这个想法的意义可能会被忽略
Sub testCombinations_()
'.......
Dim out2 As Range, outBis As Variant, acceptR As Double
Const maxR As Long = 1048574
acceptR = UBound(c1) * UBound(c2) * UBound(c3) * UBound(c4) * UBound(c5) * UBound(c6) * UBound(c7) * UBound(c8)
If acceptR > maxR Then
Set out1 = Range("J2", Range("Q2").Offset(maxR))
Set out2 = Range("T2", Range("AA2").Offset(acceptR - maxR))
out = out1.value
outBis = out2.value ' only for easy array dimensioning
Else
Set out1 = Range("J2", Range("Q2").Offset(acceptR))
out = out1.value
End If
'follow your code...
'..........
Do While q <= UBound(c8)
If r <= maxR Then
out(r, 1) = c1(j, 1)
out(r, 2) = c2(k, 1)
out(r, 3) = c3(L, 1)
out(r, 4) = c4(m, 1)
out(r, 5) = c5(n, 1)
out(r, 6) = c6(o, 1)
out(r, 7) = c7(p, 1)
out(r, 8) = c8(q, 1)
r = r + 1
q = q + 1
If r = maxR Then r = 1
Else
outBis(r, 1) = c1(j, 1)
outBis(r, 2) = c2(k, 1)
outBis(r, 3) = c3(L, 1)
outBis(r, 4) = c4(m, 1)
outBis(r, 5) = c5(n, 1)
outBis(r, 6) = c6(o, 1)
outBis(r, 7) = c7(p, 1)
outBis(r, 8) = c8(q, 1)
r = r + 1
q = q + 1
End If
Loop
'.........
out1.value = out
If UBound(outBis) > 1 Then out2.value = outBis
End Sub
子测试组合
'.......
调光out2为量程,OUTBI为变型,接受器为双精度
Const maxR长度=1048574
接受者=UBound(c1)*UBound(c2)*UBound(c3)*UBound(c4)*UBound(c5)*UBound(c6)*UBound(c7)*UBound(c8)
如果acceptR>maxR,则
设定值1=范围(“J2”,范围(“Q2”)。偏移量(最大值))
放样2=范围(“T2”,范围(“AA2”)。偏移量(接受-最大)
out=out1.0
outBis=out2.value'仅用于方便的数组尺寸标注
其他的
设定值1=范围(“J2”,范围(“Q2”)。偏移量(接受)
out=out1.0
如果结束
'遵循您的代码。。。
'..........
当q测试时,执行以下操作:
Sub combinations()
Const max_rows As Long = 1000000
Dim c(1 To 8) As Variant
Dim r As Long
Dim i As Long, totRows As Long, out()
Dim x1 As Long, x2 As Long, x3 As Long, x4 As Long
Dim x5 As Long, x6 As Long, x7 As Long, x8 As Long
Dim rngOut As Range
totRows = 1
For i = 1 To 8
c(i) = Range("A1:A6").Offset(0, i - 1).Value
totRows = totRows * UBound(c(i), 1)
Next i
Debug.Print totRows
ReDim out(1 To max_rows, 1 To 8)
Set rngOut = Range("A8")
r = 1
For x1 = 1 To UBound(c(1), 1)
For x2 = 1 To UBound(c(2), 1)
For x3 = 1 To UBound(c(3), 1)
For x4 = 1 To UBound(c(4), 1)
For x5 = 1 To UBound(c(5), 1)
For x6 = 1 To UBound(c(6), 1)
For x7 = 1 To UBound(c(7), 1)
For x8 = 1 To UBound(c(8), 1)
out(r, 1) = c(1)(x1, 1)
out(r, 2) = c(2)(x2, 1)
out(r, 3) = c(3)(x3, 1)
out(r, 4) = c(4)(x4, 1)
out(r, 5) = c(5)(x5, 1)
out(r, 6) = c(6)(x6, 1)
out(r, 7) = c(7)(x7, 1)
out(r, 8) = c(8)(x8, 1)
If r = max_rows Then
'hit row limit: output and move over
rngOut.Resize(max_rows, 8).Value = out
Set rngOut = rngOut.Offset(0, 10)
ReDim out(1 To max_rows, 1 To 8)
r = 0
End If
r = r + 1
Next x8
Next x7
Next x6
Next x5
Next x4
Next x3
Next x2
Next x1
rngOut.Resize(max_rows, 8).Value = out
End Sub
out(r,1)。偏移量(0,z)=c1(j,1)
等。从z=0开始,当r达到100万时,将r重置为1并增加z 10,首先将其写入文本文件。它会更快,否则您的excel会变慢。一旦写入文本文件,然后将该文件加载到内存中,然后分块写入excel文件。如何编写代码,使r在达到100万时重置为1?对不起,我是VBA新手,所以这可能是一个愚蠢的问题。如果r>1000000那么:r=1:z=10:End如果
您真的必须显示这些值吗?您可以将它们存储在内存中,并将其用于任何下游任务?谢谢您的回复。我已经让我的代码工作,所以我没有机会测试这个。谢谢你!