• ベストアンサー

コピー貼り付けのマクロの処理時間の早い方法を教えてください。

ある表の中から部分的にセルを指定して抜き出して、 別の表を作成しています。 コピーする範囲のセルが連続して繋がっていないので、 セルを一つづつ指定してコピーして貼り付ける動作をマクロの自動記録で登録しました。 コピー貼り付けの回数が100セル分ほどあるので、処理時間が遅いです。 目で見て順番にデータがコピーされて行くのが分かるくらいです。 この動作をもっと速くするマクロを教えてください。 実際の表ではコピー元(sheet1)のA5→コピー先(sheet2)C1、 以下同じくコピー元は全て(sheet1)でコピー先は(sheet2)です。 A8→C2、A11→C3、A14→C4、A17→C5,・・・・ B2→D1、B12→D2、B22→D3、B32→D4,・・・・ このような感じでコピーします。 *コピー元のsheet1の指定セルは毎回同じ場所です。 コピー先も毎回同じセルです。 宜しくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.4

PCの性能にもよるのでスピードは何ともいえませんが、必要外の命令を省くこと、画面のアップデートをさせないことなどでスピードアップが図れます。100回のコピーでそれほど時間がかかるとも思えません。(単純コピーで試してみましたが、こちらのマシンでは10,000回で約6秒でした) さて、コピーには規則性があるものとして、(A列は3行おき、B列は10行おきと仮定)終りの行はともに50行、コピー先はC、D列とも1行目から記入されていくものとすれば、以下のようなものでいかがでしょうか? (仮定したシート名、行番号などは、適宜修正してください。) Sub test()  Dim ss As Worksheet, ds As Worksheet  Dim i As Long, r As Long  Set ss = Worksheets("Sheet1")   '←コピー元のシート  Set ds = Worksheets("Sheet2")   '←コピー先のシート   '//A列のコピー(スタート行番号、最大行番号、間隔)  r = 1  For i = 5 To 50 Step 3   ds.Cells(r, 3).Value = ss.Cells(i, 1).Value   r = r + 1  Next i   '//B列のコピー(スタート行番号、最大行番号、間隔)  r = 1  For i = 2 To 50 Step 10   ds.Cells(r, 4).Value = ss.Cells(i, 2).Value   r = r + 1  Next i End Sub

fightman11
質問者

補足

回答ありがとうございます。 この方法もかなり早いですね。 これのアレンジで形式を選択して貼り付け(値のみ)の場合はどのように変更したら良いですか?

その他の回答 (4)

  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.5

#4です。 >選択して貼り付け(値のみ)の場合はどのように変更したら良いですか? 実は、もともと意図的に値のみ貼り付けにしてあります。 (dest.value = sorce.value という記述なので値だけ入力している。) たいていの場合セルのコピーをする時には、罫線をコピーしたくない場合が多いので、勝手にそのように考えて作成しました。 それなので、逆に言えば、式をそのままコピーしたい場合や、文字の色、リンクなども、このままだとコピーされません。 ご質問文から想像するに、値だけコピーできれば(できるほうが)意図に合うであろうと判断させていただきました。

fightman11
質問者

お礼

試したデータも数値だけのデータだったので気付きませんでした。 ありがとうございました。

  • pkh4989
  • ベストアンサー率62% (162/260)
回答No.3

こんにちは。 ワークテーブルを利用しましょう。 以下のようにコピー元とコピー先の範囲をワークへ設定してから ワークへ移動するように試してみてください。Rangeは必ず "A1: から Sub Copy()   Dim wVal    As Variant   Dim wVal2    As Variant   '   'コピー元   wVal = Worksheets("Sheet1").Range("A1:Z100")  '→wVal(100,26)の2次元テーブルになる   '→wVal(100,26)の2次元テーブルにRange("A1:Z100")の内容が設定される   'コピー先   wVal2 = Worksheets("Sheet2").Range("A1:Z100")   '   'A8→C2   wVal2(2, 3) = wVal(8, 1)   'A11→C3   wVal2(3, 3) = wVal(11, 1)   'A14→C4   wVal2(4, 3) = wVal(14, 1)   'A17→C5   wVal2(5, 3) = wVal(17, 1)   '   '↓   'ワークテーブルの内容をシートへ設定   Worksheets("Sheet2").Range("A1:Z100") = wVal2   '又は   Worksheets("Sheet2").Range("A1").Resize(100, 26) = wVal2 End Sub

fightman11
質問者

お礼

回答ありがとうございます。 速いですね~。 勉強になります。

  • hana-hana3
  • ベストアンサー率31% (4940/15541)
回答No.2

単純なコピーならこれ。 Sub test1() Sheets("Sheet1").Range("A8,A11,A14,A17,A20,A23,A26").Copy Sheets("Sheet2").Range("C1") End Sub 法則があるならVBAらしくこれ。 Sub test2() Dim i As Long For i = 0 To 30 With Sheets("Sheet1") .Range("A8").Offset(i * 3).Copy Sheets("Sheet2").Range("C1").Offset(i) .Range("B2").Offset(i * 10).Copy Sheets("Sheet2").Range("D1").Offset(i) End With Next End Sub

fightman11
質問者

お礼

単純なコピーが意外と速かったです。 ありがとうございました。

fightman11
質問者

補足

回答ありがとうございます。 法則がある場合で、コピー元の表の50行目までだけを対象とする場合はどうすれば良いのですか?(51行目以降も入力されたセルがあるが、それはコピーしない)

  • n-jun
  • ベストアンサー率33% (959/2873)
回答No.1

コードの提示がないので憶測です。 Application.ScreenUpdating = False '~処理~ Application.ScreenUpdating = True としてますか。

fightman11
質問者

お礼

回答ありがとうございました。 参考にさせていただきます。

関連するQ&A