1次元配列をワークシートに高速で転記する方法について質問します。
1次元配列をワークシートに高速で転記する方法について質問します。
エクセル2000です。
1000万までの範囲で素数を抽出したいと思いました。
そこで下記のようなコードを書きました。
最初は配列にいれず一個ずつセルに転記させたところ664,579個の素数抽出に1分37秒かかったので、配列を用意して下記のようにしたところ1分15秒まで短縮されました。
質問1:配列を使った割には劇的に短縮されないのはなぜでしょうか?
質問2:下記のコードでは最初に取り込んだ1次元外配列をシートに貼るために2次元に変換する際、2次元方向(列)は256で固定、1次元方向(行)は計算で求めたのですが、その結果、要素数が合わず、後の方のデータがない部分が0とシートに出てしまいます。
こうならない方法がありますか?
質問3:一次元配列をワークシートに配置するため二次元配列に変換するのに、もっと良い方法があったらご教示ください。
質問4:配列をワークシートに転記する場合
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
はあってもなくとも速度に変化がありませんでした。このような貼り付け(配列から一度に転記)には不要なのでしょうか?
たくさん質問して申し訳ありません。
宜しくお願いいたします。
Sub test()
Dim t As Date
Dim a As Long, b As Long, c As Long, Num As Long, r As Long, i As Long, x As Long, y As Long
Dim buf As Boolean
Dim myPrm() As Long, myRng() As Long
t = Now()
c = 0
For Num = 2 To 10000000
a = Int(Sqr(Num)) '平方根算出
buf = True
For b = 2 To a '除数
If Num Mod b = 0 Then '割切れたら
buf = False '素数じゃない
Exit For
End If
Next b
If buf Then '割切れなかったら
ReDim Preserve myPrm(c) '添字追加
myPrm(c) = Num
c = c + 1 '素数カウント
End If
Next Num
r = Application.WorksheetFunction.RoundUp((UBound(myPrm) + 1) / 256, 0) '必要行数取得
ReDim myRng(1 To r, 1 To 256) '2次元配列のサイズ変更
For i = LBound(myPrm) To UBound(myPrm) '2次元配列に格納
x = IIf((i + 1) Mod 256 = 0, 256, (i + 1) Mod 256)
y = Application.WorksheetFunction.RoundUp((i + 1) / 256, 0)
myRng(y, x) = myPrm(i)
Next i
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Cells(1, 1).Resize(r, 256).Value = myRng() 'セル範囲に転記
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
MsgBox c & "個抽出しました。" & vbNewLine & "所要時間:" & Format(Now() - t, "hh:mm:ss")
End Sub
お礼
有難うございました。 そんなに高速で計算できるのかと思い、よくよく確認をしたところ、計算そのものではなくベクトルへの代入(正確には、代入する値の取得)に時間が掛かっていることが分かりました。お騒がせいたしました。