Excel VBAでセルをコピーするマクロを作成した際、見た目では同じ値を貼り付けたいのに、数式までコピーされてしまうことがあります。特に集計用のマクロやデータ保存用の処理では、計算式ではなく計算結果だけを記録したい場面が多くあります。
この記事では、Excel VBAでセルの値だけを貼り付ける方法、数式がコピーされる理由、さらにコードを簡潔にする改善ポイントについて解説します。
Excel VBAのCopyでは数式も一緒にコピーされる
Excel VBAのCopyメソッドは、セルの内容をそのまま複製する処理です。そのため、コピー元のセルに数式が入力されている場合、計算結果ではなく数式そのものが貼り付けられます。
例えばA1に「=2*3」と入力されている場合、通常のCopyでは貼り付け先にも「=2*3」が入ります。Excel上では表示が「6」になっているため分かりにくいですが、セルの中身は数式のままです。
今回のようにA1:C1の結果である「6、4、9」を記録したい場合は、コピーではなく「値のみ貼り付け」の処理を指定する必要があります。
VBAで値だけを貼り付ける方法
値のみ貼り付けを行う場合は、PasteSpecialメソッドのxlPasteValuesを使用します。
以下のように変更すると、数式ではなく計算後の値だけが貼り付けられます。
Sub マクロ名()
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
Range("A1:C1").Copy
Range("A" & lastRow + 1).PasteSpecial Paste:=xlPasteValues
End Sub
この場合、A1に「=2*3」が入力されていても、貼り付け先には「6」という値だけが保存されます。
値として保存されるため、後から元の数式が変更されても、貼り付けたデータには影響しません。
Copyを使わずにさらに簡単に値貼り付けする方法
実は、コピーとPasteSpecialを使わなくても、RangeのValueプロパティを利用すると、よりシンプルに値だけを転記できます。
例えば以下のようなコードでも同じ処理が可能です。
Sub マクロ名()
Dim lastRow As Long
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
Range("A" & lastRow + 1 & ":C" & lastRow + 1).Value = Range("A1:C1").Value
End Sub
この方法ではクリップボードを使用しないため、Copy後の貼り付け処理も不要になります。処理速度も速く、データ転記用のマクロではよく使われる書き方です。
最終行を取得するコードの改善ポイント
元のコードでは以下のように最終行を取得しています。
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
この書き方自体は一般的で問題ありません。ただし、対象となるシートを指定していないため、複数のシートがある場合は意図しないシートを参照する可能性があります。
より安全にする場合は、Worksheetを明示します。
lastRow = Worksheets("Sheet1").Cells(Rows.Count, "A").End(xlUp).Row
特に業務で使うマクロでは、どのシートを操作するのか明確に指定しておくことで、予期せぬエラーを防げます。
VBAで値貼り付けをするときによくある注意点
値貼り付けを行う場合でも、コピー元と貼り付け先の範囲サイズが違うとエラーになることがあります。例えば3列分コピーする場合は、貼り付け先も3列分の範囲を指定する必要があります。
また、A列を基準に最終行を取得している場合、A列だけ空白になっているデータでは正しい位置を取得できない場合があります。
データによっては、A列ではなく必ず入力される列を基準に最終行を取得するなど、表の構造に合わせて調整すると安定したマクロになります。
まとめ
Excel VBAでCopyを使うと、セルの値だけではなく数式や書式もコピーされます。そのため、計算結果だけを保存したい場合はPasteSpecialのxlPasteValuesを使用する必要があります。
また、単純なデータ転記であればRange.Valueを使った代入方法の方がコードが短く、処理も高速です。
マクロでは「何をコピーしたいのか」を明確にすることが重要です。数式を残したい場合はCopy、結果だけを保存したい場合はValueやxlPasteValuesを使い分けることで、目的に合った処理を作成できます。

コメント