Excel VBAでシート全体をコピーしたい場面は、実務で非常に多くあります。
たとえば、集計シートの内容を別シートへ保存したい場合や、数式が入った帳票を「結果だけ残す形」でバックアップしたい場合です。
しかし、通常のシートコピーを使うと、数式・書式・列幅・図形・条件付き書式なども含めてコピーされるため、目的によっては扱いづらくなることがあります。
特に「数式ではなく、表示されている結果だけを残したい」という場合は、値貼り付けの考え方が重要です。
この記事では、VBAでシート全体を値貼り付けする方法を、実務で使いやすいコードとあわせて解説します。
目次
- ✅ VBAでシート全体を値貼り付けする基本の考え方
- ・シート全体コピーと値貼り付けは目的が違う
- ・実務で多いのは「コピー後に値へ固定する」処理
- ・シート全体を値にする場合はUsedRangeを使う
- ✅ VBAでシート全体をコピーして値貼り付けする方法
- ・シートをコピーして数式を値に変換する基本コード
- ・なぜコピー後に値変換するのか
- ・ActiveSheetを使うときの注意点
- ✅ VBAでシート全体を値だけ別シートへコピーする方法
- ・UsedRangeの値だけを別シートへコピーするコード
- ・この方法が向いているケース
- ・値だけコピーでは書式が引き継がれない
- ✅ VBAでシート全体を値貼り付けするときにUsedRangeを使う理由
- ・UsedRangeで使用範囲だけを対象にする
- ・Cells全体を対象にしない方がよい理由
- ・UsedRangeが広がりすぎることもある
- ✅ VBAでシート全体を値貼り付けする実務向けコード
- ・日付時刻付きでコピーシートを作成するコード
- ・日付時刻付きにするメリット
- ・シート名に使えない文字に注意する
- ✅ VBAで値貼り付け後に数式が残っていないか確認する方法
- ・数式セルが残っているか確認するコード
- ・SpecialCells使用時にエラー対策が必要な理由
- ・外部提出用データでは確認処理が役立つ
- ✅ VBAでシート全体を値貼り付けするときの注意点
- ・元シートを直接値に変換しない
- ・数式を残すべきシートでは使わない
- ・保護シートではエラーになることがある
- ✅ まとめ:VBAでシート全体を値貼り付けするならコピー後に値変換しよう
✅ VBAでシート全体を値貼り付けする基本の考え方
シート全体をコピーすると聞くと、Worksheet.Copy を使えばよいと思うかもしれません。
確かに、シートを丸ごと複製したいだけなら Copy メソッドで対応できます。
しかし、実務では「シートの見た目は残したいが、数式は値に変えたい」というケースがよくあります。
この場合、単純なシートコピーだけでは、コピー先にも数式が残ってしまいます。
元データを変更したときにコピー先の結果まで変わってしまうと、保存用の資料としては危険です。
そのため、シート全体をコピーした後に、使用範囲を値へ変換する設計が重要になります。
・シート全体コピーと値貼り付けは目的が違う
シート全体コピーは、シートそのものを複製する処理です。
一方、値貼り付けは、セルに入っている数式や参照ではなく、表示されている結果だけを残す処理です。
たとえば、次のような数式が入っているセルがあるとします。
=A1+B1
通常コピーでは、この数式もコピーされます。
しかし、値貼り付けでは計算結果だけがコピー先に残ります。
つまり、実務では次のように使い分けます。
- シートの構造ごと複製したい:シートコピー
- 数式結果だけ固定したい:値貼り付け
- 書式も残しつつ数式だけ値にしたい:シートコピー後に値変換
・実務で多いのは「コピー後に値へ固定する」処理
実務では、次のような目的で使われます。
- 月次集計シートを保存用に残す
- 帳票の数式結果だけを確定版にする
- 報告用シートを元データと切り離す
- 外部提出用に数式を消す
- 誤って数式が変更されるリスクを減らす
特に、請求書・売上集計・勤怠集計・在庫管理表などでは、「その時点の結果を固定する」ことが重要になります。
・シート全体を値にする場合はUsedRangeを使う
シート全体といっても、Excelには100万行以上の行があります。
そのため、すべてのセルを対象にして処理すると非常に重くなります。
実務では、実際に使われている範囲だけを対象にするため、UsedRange を使うのが基本です。
✅ VBAでシート全体をコピーして値貼り付けする方法
シート全体を値貼り付けしたい場合、まず元シートをコピーし、そのコピーしたシートの使用範囲を値に変換する方法が使いやすいです。
この方法なら、列幅や書式、罫線などの見た目を残しながら、数式だけを値に変換できます。
いきなり値だけを別シートへ代入すると、書式や列幅はコピーされません。
そのため、帳票や報告資料のように見た目も重要なシートでは、先にシートを複製する方が自然です。
ただし、コピー後にどのシートを操作しているのかを曖昧にすると、別のシートを値変換してしまう危険があります。
実務では、コピー後のシートを変数で明確に管理することが重要です。
・シートをコピーして数式を値に変換する基本コード
Sub CopySheetAndConvertToValues()
Dim sourceWorksheet As Worksheet
Dim copiedWorksheet As Worksheet
' コピー元シートを明確に指定する
Set sourceWorksheet = ThisWorkbook.Worksheets("集計表")
' コピー元シートを末尾に複製する
sourceWorksheet.Copy After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count)
' コピー直後のアクティブシートをコピー先として取得する
Set copiedWorksheet = ActiveSheet
' コピー先シート名を設定する
copiedWorksheet.Name = "集計表_値貼り付け"
' 使用されている範囲の数式を値に変換する
With copiedWorksheet.UsedRange
.Value = .Value
End With
End Sub
このコードでは、「集計表」シートをコピーし、コピー後のシート内にある数式を値へ変換しています。
・なぜコピー後に値変換するのか
この方法のメリットは、見た目を保ったまま数式だけを消せることです。
通常の値代入だけで別シートへ転記すると、書式や罫線、列幅までは引き継がれません。
しかし、先にシートをコピーしておけば、次のような要素を残せます。
- セルの色
- 罫線
- 表示形式
- 列幅
- 行の高さ
- 印刷設定
- ページレイアウト
そのうえで、UsedRange.Value = UsedRange.Value とすることで、数式だけを値へ固定できます。
・ActiveSheetを使うときの注意点
このコードでは、シートコピー直後に ActiveSheet を使っています。
通常、Worksheet.Copy を実行すると、コピーされたシートがアクティブになります。
そのため、直後に Set copiedWorksheet = ActiveSheet とすれば、コピー先シートを取得できます。
ただし、実務では ActiveSheet に依存しすぎるのは危険です。
このコードでは、コピー直後だけに限定して使っているため、意図が明確です。
だらだらと ActiveSheet.Range(...) のように書き続けるのではなく、すぐに変数へ格納して以降は copiedWorksheet を使うのが安全です。
今回のコードでは、シートコピー直後の ActiveSheet を取得して処理を行っています。アクティブシートの安全な扱い方や、シート名取得・値参照の考え方については、【VBA】アクティブシートの指定・変更・シート名取得・値参照の記事で詳しく解説しています。
✅ VBAでシート全体を値だけ別シートへコピーする方法
場合によっては、書式や列幅は不要で、値だけを別シートへ出力したいこともあります。
この場合は、シートコピーではなく、使用範囲の値を別シートへ直接代入する方法が向いています。
ただし、値だけをコピーする場合は、貼り付け先の範囲サイズをコピー元と合わせる必要があります。
範囲サイズがずれていると、一部しか転記されなかったり、意図しない結果になったりします。
また、貼り付け先に古いデータが残ることもあるため、事前にクリアする設計も大切です。
ここでは、値だけを別シートへコピーする実務向けの書き方を確認します。
・UsedRangeの値だけを別シートへコピーするコード
Sub CopySheetValuesOnlyToAnotherSheet()
Dim sourceWorksheet As Worksheet
Dim destinationWorksheet As Worksheet
Dim sourceRange As Range
Dim destinationTopLeftCell As Range
Set sourceWorksheet = ThisWorkbook.Worksheets("集計表")
Set destinationWorksheet = ThisWorkbook.Worksheets("値出力")
Set sourceRange = sourceWorksheet.UsedRange
Set destinationTopLeftCell = destinationWorksheet.Range("A1")
' 貼り付け先の既存データを削除する
destinationWorksheet.Cells.ClearContents
' コピー元と同じサイズに貼り付け先を広げて値を代入する
destinationTopLeftCell.Resize(sourceRange.Rows.Count, sourceRange.Columns.Count).Value = sourceRange.Value
End Sub
このコードでは、「集計表」の使用範囲を「値出力」シートのA1から値のみで出力しています。
・この方法が向いているケース
この方法は、次のような場面に向いています。
- 値だけ一覧として出力したい
- 書式は不要
- CSV出力前のデータを作りたい
- 集計結果だけ別シートにまとめたい
- 軽い処理で済ませたい
書式や印刷設定まで必要ない場合は、シート全体コピーよりもシンプルです。
・値だけコピーでは書式が引き継がれない
この方法では、コピーされるのは値だけです。
そのため、以下はコピーされません。
- セルの色
- 罫線
- 列幅
- 行の高さ
- 表示形式
- 条件付き書式
帳票としてそのまま使いたい場合は、先にシートをコピーしてから値変換する方法の方が適しています。
一方、データ加工用の出力なら、値だけコピーの方が余計な情報を持たないため扱いやすくなります。
値だけを別シートへ出力すると、罫線や表レイアウトは引き継がれません。出力後に見やすい表へ整える方法については、【VBA】罫線を範囲指定の変数で引く方法|Range変数で崩れない表を作る実務設計の記事で詳しく解説しています。
✅ VBAでシート全体を値貼り付けするときにUsedRangeを使う理由
シート全体を値貼り付けするとき、初心者の方は Cells.Value = Cells.Value のように書きたくなるかもしれません。
しかし、Excelの全セルを対象にすると、処理が非常に重くなる可能性があります。
また、不要な空白セルまで処理対象になるため、マクロの実行時間が長くなります。
実務では、処理対象を必要な範囲に絞ることが非常に重要です。
そのため、実際にデータが入っている範囲を示す UsedRange を使います。
ただし、UsedRange にも癖があるため、過信しすぎないことも大切です。
・UsedRangeで使用範囲だけを対象にする
UsedRange は、そのシートで使用されている範囲を取得します。
たとえば、A1からF100までデータや書式がある場合、UsedRange はその範囲を対象にします。
値変換は次のように書けます。
With Worksheets("集計表").UsedRange
.Value = .Value
End With
この処理により、使用範囲内の数式が値に変わります。
・Cells全体を対象にしない方がよい理由
次のようなコードは避けた方が安全です。
Worksheets("集計表").Cells.Value = Worksheets("集計表").Cells.Value
この書き方は、シート全体のセルを対象にしようとするため、非常に重くなる可能性があります。
実務では、使用している範囲だけを処理する方が安定します。
・UsedRangeが広がりすぎることもある
UsedRange は便利ですが、過去に書式を設定したセルも使用範囲として残ることがあります。
たとえば、以前にZ列や10000行目に書式を付けていた場合、見た目には空白でも使用範囲が広くなることがあります。
その場合、値変換の対象も広がり、処理が遅くなる可能性があります。
実務では、必要に応じて不要な行や列を削除し、使用範囲を整理しておくことも大切です。
✅ VBAでシート全体を値貼り付けする実務向けコード
実務で使う場合は、単純にコピーするだけでなく、同名シートが存在する場合への対策も必要です。
たとえば、「集計表_値貼り付け」というシートがすでに存在していると、同じ名前を付けようとしてエラーになります。
また、何度も実行するマクロでは、古い出力シートを削除するのか、日付付きで残すのかを決める必要があります。
この設計を曖昧にすると、シートが増えすぎたり、逆に必要な履歴を上書きしてしまったりします。
実務では、出力シート名の付け方も含めて考えることが重要です。
ここでは、日付時刻を付けて保存用シートを作る例を紹介します。
・日付時刻付きでコピーシートを作成するコード
Sub CopySheetAsValuesWithTimestamp()
Dim sourceWorksheet As Worksheet
Dim copiedWorksheet As Worksheet
Dim newSheetName As String
Set sourceWorksheet = ThisWorkbook.Worksheets("集計表")
' シート名に使える形式で日時を作成する
newSheetName = "集計表_値_" & Format(Now, "yyyymmdd_hhmmss")
' コピー元シートをブックの末尾にコピーする
sourceWorksheet.Copy After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count)
Set copiedWorksheet = ActiveSheet
copiedWorksheet.Name = newSheetName
' 数式を値に変換する
With copiedWorksheet.UsedRange
.Value = .Value
End With
MsgBox "値貼り付け済みシートを作成しました。" & vbCrLf & newSheetName, vbInformation
End Sub
このコードでは、コピー先シート名に日付時刻を付けています。
そのため、同じ名前のシートが存在していても重複しにくくなります。
・日付時刻付きにするメリット
日付時刻付きのシート名にすると、次のようなメリットがあります。
- 履歴として残しやすい
- 上書きミスを防げる
- いつ作成したシートか分かる
- 月次・日次の保存に使いやすい
実務では、集計結果を「その時点の確定版」として残すことがあります。
その場合、毎回同じシート名で上書きするよりも、日時付きで残した方が安全です。
・シート名に使えない文字に注意する
Excelのシート名には、使えない文字があります。
たとえば、次のような文字は使えません。
:\/?*[]
そのため、時刻をシート名に入れる場合は、hh:mm:ss のようにコロンを含む形式は避ける必要があります。
今回のコードでは、yyyymmdd_hhmmss の形式にしているため、シート名として安全に使えます。
今回のように、日時付きでシートを自動生成する処理では「シート名の管理ルール」が非常に重要になります。シート名の変更・参照・命名ルールについては、【Excel】シート名の活用完全ガイド|変更・参照・管理・命名ルールまで徹底解説の記事で詳しく解説しています。
✅ VBAで値貼り付け後に数式が残っていないか確認する方法
シート全体を値貼り付けしたつもりでも、対象範囲の指定ミスによって数式が残ることがあります。
特に、UsedRangeが想定と違う場合や、図形・テーブル・外部参照が含まれる場合は注意が必要です。
実務では、マクロ実行後に「本当に数式が消えているか」を確認できると安心です。
保存用シートや外部提出用資料では、数式が残っていると元データの構造が見えてしまうこともあります。
そのため、必要に応じて数式セルの有無をチェックする処理を入れておくと安全です。
ここでは、コピー後のシートに数式が残っていないか確認する簡単な方法を紹介します。
・数式セルが残っているか確認するコード
Sub CheckFormulaCellsInSheet()
Dim targetWorksheet As Worksheet
Dim formulaRange As Range
Set targetWorksheet = ThisWorkbook.Worksheets("集計表_値貼り付け")
On Error Resume Next
Set formulaRange = targetWorksheet.UsedRange.SpecialCells(xlCellTypeFormulas)
On Error GoTo 0
If formulaRange Is Nothing Then
MsgBox "数式は残っていません。", vbInformation
Else
MsgBox "数式が残っているセルがあります。確認してください。", vbExclamation
formulaRange.Select
End If
End Sub
このコードでは、対象シートの使用範囲から数式セルを探しています。
数式が残っていなければメッセージを表示し、残っていれば該当セルを選択します。
・SpecialCells使用時にエラー対策が必要な理由
SpecialCells(xlCellTypeFormulas) は、該当するセルがない場合にエラーになることがあります。
そのため、次のように一時的にエラーを回避しています。
On Error Resume Next
Set formulaRange = targetWorksheet.UsedRange.SpecialCells(xlCellTypeFormulas)
On Error GoTo 0
この処理を入れないと、数式がない正常な状態なのにマクロが止まってしまう可能性があります。
実務では、「該当なし」も正常な結果として扱えるようにしておくことが大切です。
・外部提出用データでは確認処理が役立つ
外部に提出する資料や、他部署へ共有するファイルでは、数式が残っていないか確認する価値があります。
数式が残っていると、次のような問題が起きる可能性があります。
- 元データ参照が切れてエラーになる
- 外部参照が残る
- 編集時に計算結果が変わる
- 見せたくない参照構造が残る
単なる社内作業なら不要な場合もありますが、提出用データではチェック処理を入れておくと安心です。
今回のように、数式セルだけを抽出して確認したい場合は、SpecialCells メソッドが非常に便利です。特定セルを一括取得する実務的な活用方法については、【VBA】SpecialCellsメソッドで特定のセルを一括抽出する実務活用ガイドの記事で詳しく解説しています。
✅ VBAでシート全体を値貼り付けするときの注意点
シート全体の値貼り付けは便利ですが、何でも値に変換すればよいわけではありません。
数式を値に変えると、後から再計算できなくなります。
つまり、保存用や提出用には向いていますが、編集を続ける作業用シートには向かない場合があります。
また、条件付き書式やデータ入力規則などは、値変換だけでは削除されません。
「何を残して、何を消すのか」を事前に決めておくことが重要です。
実務では、コピー前の元シートを必ず残しておく設計にすると安全です。
・元シートを直接値に変換しない
次のようなコードは、元シートの数式を直接値に変えてしまいます。
With Worksheets("集計表").UsedRange
.Value = .Value
End With
これは便利ですが、元シートの数式が失われます。
間違えて実行すると、元に戻せない場合があります。
そのため、基本的にはコピーしたシートに対して値変換を行う方が安全です。
・数式を残すべきシートでは使わない
次のようなシートでは、値変換に注意が必要です。
- 計算用シート
- 入力に応じて自動更新する管理表
- 月次で使い回すテンプレート
- 他シート参照が必要な集計表
これらを値にしてしまうと、次回以降の更新ができなくなります。
値貼り付けは「確定版を作る処理」と考えると、使いどころを間違えにくくなります。
・保護シートではエラーになることがある
シートが保護されている場合、値変換ができずにエラーになることがあります。
その場合は、事前に保護を解除する必要があります。
ただし、保護解除にはパスワード管理の問題もあるため、むやみにコードへパスワードを直接書くのは避けた方が安全です。
実務では、保護解除が必要かどうかを運用ルールとして確認しておきましょう。
シート保護が有効になっている場合、値貼り付け処理が正常に実行できないことがあります。Unprotect メソッドを使ったシート・ブック保護解除の方法については、【VBA】Unprotectメソッド:ブック・シートの保護解除の記事で詳しく解説しています。
✅ まとめ:VBAでシート全体を値貼り付けするならコピー後に値変換しよう
今回は、VBAでシート全体を値貼り付けする方法について解説しました。
シート全体を値として残したい場合は、単純にセル範囲をコピーするだけでなく、シートをコピーした後に使用範囲を値へ変換する方法が実務では使いやすいです。
特に、書式や列幅、印刷設定を残したまま数式だけを値にしたい場合は、今回紹介した方法が役立ちます。
今回のポイントを整理すると、以下の通りです。
- シートコピーと値貼り付けは目的が違う
- 見た目を残したい場合は、シートコピー後に値変換する
- 値だけ別シートへ出力するなら
Value代入が使いやすい - シート全体ではなく
UsedRangeを対象にすると処理が軽くなる - 日付時刻付きのシート名にすると履歴管理しやすい
- 外部提出用では数式が残っていないか確認すると安全
- 元シートを直接値に変換すると、数式が失われるため注意が必要
- 実務では「保存用」「提出用」「確定版」として使うのが向いている
VBAでシート全体を値貼り付けできるようになると、月次集計表の保存、報告資料の作成、提出用データの固定化など、多くの業務に応用できます。
まずは元シートを直接変更せず、コピーしたシートを値に変換する安全な方法から使ってみるのがおすすめです。