クリップボードのデータのペースト
Excelの操作ではセルのコピペや切り取り+ペーストは利用頻度が多い操作です。VBAでも同じことは可能です。ただ、利用頻度は低いでしょうね。
ペーストはPasteメソッド、または、PasteSpecialメソッドを利用します。
この2つのメソッドはどちらもクリップボードのデータを貼り付ける点は同じですが、貼り付ける際の細かい条件が異なります。
Excel操作での貼り付け(ショートカット:Ctrl + V)にあたるのがPasteメソッド、右クリック+形式を選択して貼り付けにあたるのがPasteSpecialメソッドです。
Pasteメソッドはエラーになりやすい
Pasteメソッドはセルを扱うメソッドの中でも特にエラーが頻発します。
それが嫌なため個人的にはPasteメソッドはまず使いません。
どうしても利用する場合はエラーの回避方法を後述していますので参考にしてください。
構文
Pasteメソッド
1 |
Worksheetオブジェクト.Paste(Destination, Link) |
CutメソッドまたはCopyメソッドで保管されたクリップボードのデータをセルに貼り付けます。引数Destinationと引数Linkは同時に設定できません。
Pasteメソッドを実行する前に、貼り付け先のセル範囲を選択しておく必要があります。
項目 | 説明 |
---|---|
Worksheetオブジェクト | クリップボードのデータを貼り付けるシートを指定します。 |
Destination | 省略可能です。クリップボードに保管されているデータの貼り付け先のセルを指定します。この場合、引数Linkの設定は出来ません。省略した場合は現在選択されているセル範囲が貼り付ける対象になります。 |
Link | 省略可能です。事前に貼り付け先のセル範囲を選択しておく必要があります。元データに対して「=A1」のように数式を設定してリンクします。省略した場合またはFalseの場合はリンクしません。Linkの設定を行う場合は引数Destinationの設定は出来ません。 |
PasteSpecialメソッド
1 |
Rangeオブジェクト.PasteSpecial(Paste, Operation, SkipBlanks, Transpose) |
クリップボードのデータをどういう形式で貼り付けるかを指定してセルに貼り付けます。
Excelの「ホーム」タブ→「クリップボード」→「貼り付け」→「形式を選択して貼り付け」と同じ機能です。
項目 | 説明 | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Rangeオブジェクト | クリップボードのデータを貼り付けるセルを指定します。 | ||||||||||||||||||||||||
Paste | 省略可能です。貼り付ける内容を指定します。指定にはXlPasteType列挙型を利用します。
|
||||||||||||||||||||||||
Operation | 省略可能です。貼り付ける際に加算や減算などの演算を指定します。指定にはXlPasteSpecialOperation列挙型を利用します。
|
||||||||||||||||||||||||
SkipBlanks | 省略可能です。空白セルを貼り付け対象とするかどうかを指定します。Trueは貼り付けません。省略またはFalseは貼り付けます。 | ||||||||||||||||||||||||
Transpose | 省略可能です。行と列を入れ替えるかどうかを指定します。Trueの場合は入れ替えます。省略またはFalseは入れ替えません。 |
サンプルコード
Pasteメソッドのサンプル
A1セルを含むセル範囲をA6セルに貼り付け、A10セルにA1のセル範囲への「=A1」などの数式でのリンクを設定します。
7行目のCutCopyModeにFalseを設定していますが、これはコピーした内容を無効にして、セル範囲を囲う点線表示を消します。
1 2 3 4 5 6 7 8 9 10 11 |
Sub PasteTest() '// A1を含むセル範囲をクリップボードに保持 Range("A1").CurrentRegion.Copy ActiveSheet.Paste Destination:=Range("A6") Application.CutCopyMode = False Range("A10").Select ActiveSheet.Paste Link:=True End Sub |
PasteSpecialメソッドのサンプル
Pasteメソッドとの違いは、上表の条件設定を状況に応じて設定するだけです。Excelの貼り付けオプションを見たほうが分かりやすいと思います。
1 2 3 4 5 |
Sub PasteSpecialTest() Range("A1").CurrentRegion.Copy Range("C10").PasteSpecial Paste:=xlPasteAll End Sub |
Pasteメソッドの注意点
Pasteメソッドを実行する際にエラーが発生することがあります。
エラーの原因には大きく2つあります。
1つはクリップボードにデータが入っていないためで、もう1つは、Link:=True が実行できないセル形式のためです。
クリップボードにデータが無い場合の対応方法
CopyメソッドやCutメソッドなどでのクリップボードのデータ保管漏れが無いか確認します。
ところが、Copyメソッドはちゃんと実装されているのに上記エラーが発生することがあります。
これは、Copyメソッドによるクリップボードへのデータ保管が終わらない状態でPasteメソッドを実行していることが原因です。Copyメソッドが無くクリップボードにも何も無い状態でPasteメソッドを実行すると同じエラーになります。
回避方法には2つあります。
1つは、Copyメソッドの引数Destinationを利用してCopyと同時に貼り付けを行う方法です。こちらの方法をおすすめします。Cutメソッドでも同様のことが可能です。
1 2 3 |
Sub CopyTest() Range("A1").CurrentRegion.Copy Destination:=Range("D1") End Sub |
もう1つは、Copyメソッドによるクリップボードへのデータ保管を待つ方法です。
モジュールの先頭にWin32APIのSleep関数の定義を追加します。
1 2 3 4 5 6 7 |
'// 64bit版 #If VBA7 And Win64 Then Declare PtrSafe Sub Sleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long) '// 32bit版 #Else Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) #End If |
Sleep関数を使ってクリップボードへのデータ保管を待ちます。
1 2 3 4 5 6 7 8 9 10 |
Sub PasteDoEventsTest() '// A1を含むセル範囲をクリップボードに保持 Range("A1").CurrentRegion.Copy DoEvents Call Sleep(100) DoEvents ActiveSheet.Paste Destination:=Range("A6") End Sub |
ただ、個人的にはこの方法はおすすめしません。理由はどれぐらいの時間を待てばいいのか明確でないことと、その待ち時間がもったいないという点です。
リンク貼り付けの場合はコピーできない形式がある
Excelのテーブル機能(挿入タブ→テーブル)を使った表形式のセルをPasteメソッドの引数Link:=Trueで設定しようとするとエラーになります。
このように、Pasteメソッドが有効にならないケースがあります。
そういう場合は以下のように、一度Copyメソッドでコピペしておいて、あとで数式形式に書き換えてしまう方法があります。
Pasteメソッドは何かとエラーが頻発するので私は敬遠していますが、以下のマクロの方法であればPasteメソッドを使わずに貼り付けが実装できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
Sub RangePasteTest() Dim rSelection As Range '// 貼り付け元のセル範囲 Dim r As Range '// セル範囲の各セル Dim rPaste As Range '// 貼り付け先セル Dim iDiffRow '// 貼り付け元と先の行数差 Dim iDiffCol '// 貼り付け元と先の列数差 '// A1を含むセル範囲をクリップボードに保持 Set rSelection = Range("A1").CurrentRegion Set rPaste = Range("C10") '// 貼り付け元と先の差を取得 iDiffRow = rPaste.Row - rSelection.Row iDiffCol = rPaste.Column - rSelection.Column For Each r In rSelection '// 貼り付け元の内容を貼り付け先にコピペ r.Copy Destination:=r.Offset(iDiffRow, iDiffCol) '// 貼り付け元へのリンクを設定 r.Offset(iDiffRow, iDiffCol).Formula = "=" & r.Address(False, False) Next End Sub |