[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『マクロで指定した回数だけ別シートへコピー』(h,n)
いつも大変参考にさせて頂いております。
以下の通りコピー元の行を、指定した回数別シートへコピーするマクロを作成しました。
正常に動作はしておりますが、コピー元のデータが多く、マクロ完了までにかなりの時間を要しております。
もう少し時間短縮出来るようなコードが御座いましたら、参考したく
質問させて頂きます。
Dim g As Long
Dim y As Long
Dim b As Long
Dim t As Long
Dim u As Long
Sheets("作業場").Select ’コピー元のシート
t = Sheets("作業場").Cells(Rows.Count, 2).End(xlUp).Row
Application.ScreenUpdating = False
For u = 2 To t 'コピー元の行1万行程あります ’2行目から最終行まで1行づつ指定した回数だけシート3へコピー ’シート3へはおおよそ10万行以上のデータがコピーされます。
y = Cells(u, 1).Value '指定した回数の取得
For i = 1 To y
g = Sheets("sheet3").Cells(Rows.Count, 1).End(xlUp).Row + 1
Range(Cells(u, 1), Cells(u, 20)).Copy Sheets("Sheet3").Cells(g, 1) Next i cntRec = cntRec + 1 Application.StatusBar = "処理実行中....(" & t & " 件中 現在 " & cntRec & "件)"
Next u
Application.StatusBar = False
'MsgBox "処理終了しました。(処理件数=" & cntRec & "件)"
Application.ScreenUpdating = True
End Sub
< 使用 Excel:Office365、使用 OS:Windows10 >
こんばんは ^^ コピーされていますけど、写し方を拝見するに、数式等では無いですよね 値だけで良いのであれば比較的簡単に。。。配列を使うのも一案かもですね。 コピー元のa列にコピー回数が入力されているのですね。← あれ!間違ってます? ^^; (隠居じーさん) 2020/12/18(金) 17:24
■2
標準モジュールでシートの指定を省略するとActiveSheetを指定したとみなされるきまりです。
よって、複数のブックやセルをまたぐ処理を考えているなら「■1」と合わせて、きちんと対象のオブジェクトを明示したほうがよいとおもいます。
■3
踏まえて整理するとこんな感じですよね?
Sub ななしのまくろ() Dim t As Long, u As Long, i As Long, cntRec As Long
With Sheets("作業場") 'コピー元のシート t = .Cells(.Rows.Count, 2).End(xlUp).Row
For u = 2 To t 'コピー元の行1万行程あります For i = 1 To .Cells(u, 1).Value Intersect(.Rows(u), .Range("A:T")).Copy Sheets("sheet3").Cells(Rows.Count, 1).End(xlUp).Offset(1) Next i
cntRec = cntRec + 1 Application.StatusBar = "処理実行中....(" & t & " 件中 現在 " & cntRec & "件)" Next u End With
Application.StatusBar = False End Sub
画面更新の抑制もされてますし、現状の2重ループで1行ずつコピーするというアプローチだとこれ以上の手はないような気がします。
■4
こちらで同じ環境が用意できないので試していませんが、別案として貼り付け先をResizeしてみるのはどうでしょうか?
Sub 別案() Dim dstRNG As Range Dim i As Long
Set dstRNG = Sheets("sheet3").Cells(Rows.Count, 1).End(xlUp)
With Sheets("作業場") For i = 2 To .Cells(.Rows.Count, "B").End(xlUp).Row If .Cells(i, "A").Value > 0 Then Intersect(.Rows(i), .Range("A:T")).Copy dstRNG.Resize(.Cells(i, "A").Value) Set dstRNG = dstRNG.Offset(.Cells(i, "A").Value) End If Next i End With End Sub
(もこな2 ) 2020/12/18(金) 18:07
独学で最近覚えたばかりで、大変参考になります。
私にはまだ高度すぎて、ご質問に対してお答えできませんが、
時間短縮出来る気がしてきました。
■3 を試してみたいと思います、比較的わかりやすいコードでしたので。
このようなサイトがあり、いつも感謝しております、大変ありがとうございました。
(h,n) 2020/12/18(金) 18:40
■3 のコードですと、私の作成したコードと同じくらいの処理速度でした。
■4 ですが、すごいです、びっくりするくらい早いです!
Resizeの勉強致します、大変ありがとうございました。
(h,n) 2020/12/18(金) 19:16
既にご案内があったよぉですが、言い出しっぺの配列案など。。。 処理件数が大量になると、すこ〜しは速いと思いますです。^^; 値貼付けモードです。。。m(_ _)m Sub OneInstanceM() Dim i As Long Dim j As Long Dim y As Long Dim x As Long Dim mTx() As Variant Dim tAr() As Variant Dim iMax As Long Dim r As Range Dim t As Double t = Timer With Worksheets("作業場") tAr = .Cells(1, 1).CurrentRegion.Value Set r = Intersect(.Range("A:A"), .UsedRange) Set r = r.Offset(1).Resize(r.Rows.Count - 1, 1) iMax = Application.Sum(r) Set r = Nothing End With ReDim mTx(1 To iMax, 1 To 20) y = 1 For i = 2 To UBound(tAr, 1) For j = 1 To tAr(i, 1) For x = 1 To 20 mTx(y, x) = tAr(i, x) Next x y = y + 1 Next j If i Mod 12800 = 0 And i >= 12800 Then DoEvents Next With Worksheets("Sheet3") .UsedRange.Clear .Cells(2, 1).Resize(UBound(mTx, 1), UBound(mTx, 2)) = mTx .Activate End With Erase mTx, tAr MsgBox "終了 " & Format(Int(Timer - t) / 24 / 60 / 60, "hh : mm : ss") & _ Format((Timer - t) - Int(Timer - t), ".000") & " 秒" End Sub (隠居じーさん) 2020/12/18(金) 22:04
If i Mod 12800 = 0 And i >= 12800 Then DoEvents
↑
失敗、失敗。。。両方1280に修正を。。。(◎_◎;)。。お願い いたします。やたら動かすととても重くなりそぉなので工夫した つもりが。。。あはは。。。ぜんぜんDoEventsやらないで終了し ていましたね。。。(^◇^;)。。(T_T) m(__)mすみませんでした。 (隠居じーさん) 2020/12/18(金) 22:19
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.