- ベストアンサー
ExcelVBAでの配列処理について
- ExcelVBAで配列処理を利用したい場合、処理速度の向上が期待できます。しかし、配列をシートに書き出す際に起こる問題に悩んでいます。
- 10000行×2列の乱数表データを配列として作成し、A列に1万行、D列に1万行書き出したいと考えています。
- 処理速度向上のため、ループ処理ではなく一気に書き出したいです。解決方法を教えてください。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
最初から列毎に分けて処理する事をお勧めします。(B,C列が0になってしまって良いなら別ですが) まとめて書き込んでいるので、Application云々の必要性は不明ですが、ご参考まで。 Sub test() Dim aa As Variant, ad As Variant Dim rngA As Range, rngD As Range Dim i As Long Const maxNo As Long = 10000 Randomize (Time) Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Set rngA = Range("A1").Resize(maxNo, 1) Set rngD = Range("D1").Resize(maxNo, 1) aa = rngA ad = rngD For i = 1 To 10000 aa(i, 1) = Rnd() ad(i, 1) = Rnd() Next i rngA = aa rngD = ad Application.Calculation = xlCalculationAutomatic Application.ScreenUpdating = True End Sub
その他の回答 (5)
- mitarashi
- ベストアンサー率59% (574/965)
#2です。 列数が可変なら、どうせ一列ずつの処理ですので、自分なら次の様な関数にして、列毎に処理します。ここでは、先頭のセルと、データ数を渡す様にしてみました。 ご参考まで。 Sub test3(startCell As Range, maxNo As Long) Dim aa As Variant Dim rngA As Range Dim i As Long Randomize (Time) Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Set rngA = startCell.Resize(maxNo, 1) aa = rngA For i = 1 To maxNo aa(i, 1) = Rnd() Next i rngA = aa Application.Calculation = xlCalculationAutomatic Application.ScreenUpdating = True End Sub
- imogasi
- ベストアンサー率27% (4737/17070)
確かにエクセルは、普通は画面のセルの値を修正を伴うのですが、それを Application.ScreenUpdating = False で抑止すれば、どちら(配列もセルも)もメモリへ書き込む処理になって、ForNextで書き込む(2列に分けてになる)のと、大きな差は無いのではないですか。自己満足ではないですかね。よく検証してみてください。結果的にセルの値を後ほどセットするならなおさら。 >処理速度を向上させたいので、なんていっているが質問者はプログラムのベテランですか?観念的な考えで左右されないように、テストでもして、実証しつつ、考えられんことを。 私はInsideエクセルのことは知りませんが(普通の人はこの点勉強して無いでしょう)。
お礼
当然こういったサイトに技術的なことを質問しているぐらいですからベテランではありませんよ。 皆様のおかげて処理速度が速くなりました。 ありがとうございました。
- mitarashi
- ベストアンサー率59% (574/965)
#2です。 #3さんの手がありましたね。.Value=.Valueを入れないで、再計算に入り悲惨な目にあった事を思い出しました。 試みに、60000行にして処理時間を計測してみました。当方PentiumM1.33Gという古いマシン、xl2000です。 #2のコードで、実行2~6回目の平均時間が448msec、改造して#3さんの方法を取り入れたもので、511msecと、配列による方法も満更でもない結果でした。 ところで、For i = 1 to 10000 のところは、to maxNo の直し損ねですので、言わずもがなですがお知らせしておきます。(恥)
- hallo-2007
- ベストアンサー率41% (888/2115)
お役にたてるかどうかですが >処理速度を向上させたいので、またFor分処理するのではなく、一気に書き出したいと思っています。 With Range("A2:A10000") .FormulaR1C1 = "=RAND()" .Value = .Value End With With Range("D2:D10000") .FormulaR1C1 = "=RAND()" .Value = .Value End With といった方法では如何でしょうか。
お礼
ありがとうございます。 これは早いですね。 こんなやり方があったとは知りませんでした。 この方法でも検討してみます。
- D-Matsu
- ベストアンサー率45% (1080/2394)
私なら一次配列に入れ直すか、最初から10000x4の配列を使って1と4だけ値を入れることを考えます。 後者の場合、こんな感じになりますか。 Dim aa(10000, 4) as double for i = 1 to 10000 for j = 1 to 4 step 3 aa(i, j) = Rnd() next j next i メモリをバカ食いするので配列サイズによっては不可能ですが、これくらいならたぶんなんとか。
お礼
ありがとうございます。 1次配列に入れ直す方法も教えてもらえると助かります。
お礼
ありがとうございます。 かなり高速に処理できそうです。 ただ、列数も可変の場合はもっとややこしいですよね。 教えていただいた方法で工夫すればできそうですが、別途ご教授していただけると助かります。