この記事でできること
「毎朝、入力シートから報告シートに手作業でコピペ。30行もあると、どこまで貼ったか分からなくなって1行ズレてやり直し…」 そんな経験はないだろうか。この記事のコードをコピペして実行すれば、ボタン1つで転記が完了し、行ズレ・貼り忘れのミスがゼロになる。VBAの経験がなくても、コードをそのまま貼るだけで動くので安心してほしい。
- VBAでセルの値を別シートに自動転記できる
- 転記先の最終行を自動検出し、データを追記できる(行数が増えても対応)
- 毎日の手作業コピペが不要になる
対象: Excel 2016以降 / Microsoft 365、Windows 10/11
毎日の報告データを別シートに手作業でコピペしていた。行がズレて上書きしてしまったことがある。VBAで自動転記にしてからは、ミスゼロで毎朝5分の作業が消えた。
どんな場面で使う?
セルの転記を自動化すると効果が大きいのは、たとえばこんな場面です。
- 毎朝の日報・報告データの集約 — 入力シートに記入したデータを報告シートにまとめる作業。手作業だと行がずれて上書きしがち
- 受注データの蓄積 — 受注入力フォームから受注台帳シートへ1件ずつ追記していく。最終行を取得する方法と組み合わせれば、追記位置を自動で判定できる
- 月次集計の元データ準備 — 各部門のシートからデータを1つのシートに集めて集計する前処理
- マスタデータの更新 — 新しいマスタ情報を入力シートに入れたら、マスタシートに自動で反映させたい
- 経費精算のワークフロー — 申請シートに入力した経費データを承認シートにコピーし、承認後に確定シートへ転記する多段階の処理
手作業のコピペは「どこまで貼ったか」を目で確認する必要があり、件数が増えるほどミスが増えます。VBAで自動化すれば、どんなデータ量でも正確に転記できます。
—
完成イメージ(Before / After)
Before(手動コピペ):
- 入力シートのデータ範囲を選択
- Ctrl+C でコピー
- 報告シートに切り替え
- 貼り付け位置を探してCtrl+V
- 30行あれば範囲を間違えてやり直し
After(VBAで自動転記):
- マクロを実行(またはボタンをクリック)
- 入力シートのデータが報告シートに自動転記される
- 完了メッセージが表示される
—
自分も毎朝、入力シートから報告シートへ30行分のデータを手作業でコピペしていた。毎日30分かかるうえに、1行ずれて転記ミスしたことがあって冷や汗をかいた。VBAで転記を自動化してからは、朝の30分が5秒で終わるようになった。転記ミスもゼロ。同じコピペ地獄を抱えている人に、この記事で自動化を体験してほしい。
手作業のコピペは、件数が増えるほどミスが増える。VBAに任せれば速くて正確。
なお、「全シートに同じ処理を一括適用する」のとは別のテーマ。全シート一括処理は「【VBA】複数シートに同じ処理を一括実行する方法」を参照。
—
実行前の準備
バックアップを取る
転記先のシートに既存データがある場合、上書きされる可能性がある。 必ずファイルのコピーを別フォルダに保存してから実行する。
Excelをマクロ有効ブック(.xlsm)で保存する
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
シート構成を確認する
このコードは以下のシート構成を前提としている:
- 入力シート: シート名「入力」— 転記元のデータがある
- 報告シート: シート名「報告」— 転記先
自分のシート名が異なる場合は、コード内のシート名を書き換える。
—
手順(コピペ → 実行まで約5分)
VBE(コードを書く画面)を開く
- Excelで
Alt + F11を押す
標準モジュールを挿入する
- VBEのメニュー →「挿入」→「標準モジュール」
コードを貼り付けて実行する
- コードウィンドウに、下のコードをそのままコピペする
Alt + F8→ マクロ名を選んで「実行」
ボタンに割り当てれば毎回Alt+F8を押さなくて済む。方法は「【VBA】マクロをボタン1つで実行する方法」を参照。
—
コード(最小版)– 同一ブック内の別シートへ転記
'============================================================
' ■ セルの値を別シートに転記(最小版)
' → 入力シートの A1:D10 を報告シートの A1 から貼り付け
'============================================================
Sub TransferDataMinimal()
'--- ★書き換えポイント ---
Dim srcSheet As String
srcSheet = "入力" '← 転記元のシート名
Dim destSheet As String
destSheet = "報告" '← 転記先のシート名
Dim srcRange As String
srcRange = "A1:D10" '← 転記する範囲
Dim destCell As String
destCell = "A1" '← 転記先の開始セル
'--- ★ここまで ---
'--- 値を転記(書式はコピーしない。値だけ)
' Resize = 転記先の範囲を転記元と同じ行数・列数に自動調整
Worksheets(destSheet).Range(destCell).Resize( _
Worksheets(srcSheet).Range(srcRange).Rows.Count, _
Worksheets(srcSheet).Range(srcRange).Columns.Count _
).Value = Worksheets(srcSheet).Range(srcRange).Value
MsgBox "転記が完了しました。", vbInformation
End Sub
書き換えポイント
| 変数 | 説明 | 初期値 |
|---|---|---|
srcSheet |
転記元のシート名 | "入力" |
destSheet |
転記先のシート名 | "報告" |
srcRange |
転記する範囲 | "A1:D10" |
destCell |
転記先の開始セル | "A1" |
重要: Worksheets("報告") のようにシート名を明示すること。省略するとアクティブシートが対象になり、意図しないシートに書き込む原因になる。
コードの仕組み:
このコードは .Value = .Value という代入で転記を行っています。Range.Copy + Range.Paste を使う方法もありますが、値だけを転記する場合は .Value による直接代入のほうが高速で、クリップボードを汚さないメリットがあります。Resize メソッドで転記先の範囲を転記元と同じサイズに自動調整しているため、転記元の行数や列数が変わっても、コードを修正する必要がありません。
転記するデータを条件で絞り込みたい場合は 複数条件でデータを抽出してまとめる方法 も参考にしてほしい。
—
コード(実務版)– 最終行を自動検出して別シートに追記
実務では「毎日データが増えるシートに、追記していく」パターンが多い。最終行を自動検出して、その次の行に転記する。
最終行を自動取得する方法を覚えてからは、毎日データが増えても追記位置がずれない。手動で行番号を数える必要がなくなった。毎朝30分かかっていた転記作業が5秒で終わるようになり、朝イチのストレスが完全に消えた。色分け(「セルの値に応じて行を自動色分けする方法」)と組み合わせれば、転記後の報告シートが一目で分かりやすくなる。最終行の取得テクニックについて詳しく知りたい場合は データの最終行・最終列を正確に取得する方法 も参考になる。
転記するデータ量が多い場合は 配列を使ってVBAの処理速度を10倍にする方法 で高速化できる。複数シートに同じ転記処理を適用したい場合は 複数シートを一括処理する方法 を参照。
'============================================================
' ■ 最終行を自動検出して別シートに追記(実務版)
' → 転記元の最終行を取得し、転記先の最終行の次に追記
' → ヘッダー行(1行目)はスキップ
'============================================================
Sub TransferDataAdvanced()
'--- ★書き換えポイント ---
Dim srcSheet As String
srcSheet = "入力" '← 転記元のシート名
Dim destSheet As String
destSheet = "報告" '← 転記先のシート名
Dim srcStartCol As String
srcStartCol = "A" '← 転記するデータの開始列
Dim srcEndCol As String
srcEndCol = "D" '← 転記するデータの終了列
Dim headerRows As Long
headerRows = 1 '← ヘッダー行数(スキップする行数)
'--- ★ここまで ---
Dim wsSrc As Worksheet
Set wsSrc = ThisWorkbook.Worksheets(srcSheet)
Dim wsDest As Worksheet
Set wsDest = ThisWorkbook.Worksheets(destSheet)
'--- 転記元の最終行を取得(A列で判定)
Dim srcLastRow As Long
srcLastRow = wsSrc.Cells(wsSrc.Rows.Count, srcStartCol).End(xlUp).Row
'--- 転記するデータがあるか確認
If srcLastRow <= headerRows Then
MsgBox "転記するデータがありません。", vbExclamation
Exit Sub
End If
'--- 転記先の最終行を取得し、次の行を追記位置にする
Dim destNextRow As Long
destNextRow = wsDest.Cells(wsDest.Rows.Count, srcStartCol).End(xlUp).Row + 1
'--- 転記範囲を設定(ヘッダーの次の行からデータ最終行まで)
Dim srcData As Range
Set srcData = wsSrc.Range( _
srcStartCol & (headerRows + 1) & ":" & srcEndCol & srcLastRow)
'--- 値を転記
wsDest.Range(srcStartCol & destNextRow).Resize( _
srcData.Rows.Count, srcData.Columns.Count _
).Value = srcData.Value
MsgBox srcData.Rows.Count & " 行のデータを転記しました。" & vbCrLf & _
"転記先: " & destSheet & "シートの" & destNextRow & "行目〜", vbInformation
End Sub
書き換えポイント
| 変数 | 説明 | 初期値 |
|---|---|---|
srcSheet |
転記元のシート名 | "入力" |
destSheet |
転記先のシート名 | "報告" |
srcStartCol / srcEndCol |
転記するデータの列範囲 | "A" 〜 "D" |
headerRows |
スキップするヘッダー行数 | 1 |
転記マクロをボタン(「マクロをボタン1つで実行する方法」)に割り当てれば、毎朝ボタン1つで転記が完了する。
—
よくある落とし穴5選
1. シート名の指定ミスで「インデックスが有効範囲にありません」エラー
原因: シート名が実際と違う。対策: シートタブから正確な名前をコピペ。
2. 転記先シートの指定忘れで、自分自身に上書きしてしまう
自分もこれで痛い目にあった。転記先のシートを指定し忘れて、入力シートのデータを入力シート自身に上書きしてしまった。元データが消えて焦った。対策: 必ず wsDest.Range(...) のようにシート変数を付ける。
3. 最終行が正しく取れない(途中に空白行がある)
原因: 判定列に空白があると正しくない場合がある。
自分も最初、A列で最終行を判定していたが、A列に空白行があったせいで途中のデータまでしか転記されなかった。500行あるはずのデータが200行しか転記されず、残り300行を見落としていた。
対策: 必ずデータが入っている列で判定する。空白行が混在するデータの場合は、最終行・最終列を正確に取得する方法で紹介している UsedRange による取得方法も検討してみてください。また、転記前に空白行を削除しておくのも有効な対策です。
4. PasteSpecial で書式までコピーされた
原因: Range.Copy + Range.Paste だと書式もコピー。対策: 実務版は .Value = .Value で値だけ転記。
5. 転記先の既存データが上書きされた
原因: 開始位置を固定にしていた。対策: End(xlUp).Row + 1 で最終行の次に追記。なお、転記先シートが完全に空の場合、End(xlUp).Row は1を返すため、destNextRow が2になる。ヘッダー行が1行目にある前提のコードなら問題ないが、ヘッダーがない場合は1行目から書き込まれる点に注意。
VBAでセルの転記をしたのに値が入らないときの対処法
「マクロを実行したのに転記先のセルが空のまま」という場合、原因はシート名の指定ミスか、転記元の範囲に実際のデータがないことが多い。Worksheets("報告") のようにシート名をハードコーディングしている場合、実際のシート名とスペルや全角半角が1文字でも違うと「インデックスが有効範囲にありません」エラーになる。エラーが出ずに値も入らない場合は、転記元の最終行が1以下(データなし)になっていないかを確認すること。自分もシート名を「Sheet1」と「sheet1」で間違えてハマったことがある。
VBAのコピー・貼り付けがうまくいかないときの対処法
「Range.Copyで転記したら書式まで変わってしまった」「PasteSpecialでエラーが出る」という場合、原因はCopyメソッドが値だけでなく書式・数式・罫線もまとめてコピーする仕様だからだ。値だけ転記したいなら .Value = .Value の直接代入を使うのが最もシンプルで高速。PasteSpecialでエラーが出る場合は、Copyの後に別のセル操作を挟んでクリップボードが消えている可能性がある。CopyとPasteSpecialは連続で記述し、間に他の処理を入れないようにすること。
—
FAQ
Q1: 値だけでなく書式もコピーしたい
wsSrc.Range("A2:D" & srcLastRow).Copy
wsDest.Range("A" & destNextRow).PasteSpecial xlPasteAll
Application.CutCopyMode = False
Q2: 別ブックに転記したい
Dim wb As Workbook
Set wb = Workbooks.Open("C:\報告書\月次報告.xlsm") '← パスは自分の環境に合わせて変更
wb.Worksheets("報告").Range("A1").Value = ThisWorkbook.Worksheets("入力").Range("A1").Value
wb.Save
wb.Close
Q3: 転記後に元データを消したい
Dim ans As VbMsgBoxResult
ans = MsgBox("転記元のデータを消去しますか?", vbYesNo + vbQuestion)
If ans = vbYes Then
wsSrc.Range("A2:D" & srcLastRow).ClearContents
End If
Q4: 複数ファイルのデータを1つに統合したい
「【VBA】複数Excelファイルを1つに統合する方法」を参照。
Q5: ボタン1つで転記を実行したい
「【VBA】マクロをボタン1つで実行する方法」で TransferDataAdvanced をボタンに割り当てる。
—
まとめ
.Value = .Valueで値だけを別シートに転記できる(最小版)Cells(Rows.Count, "A").End(xlUp).Rowで最終行を自動検出し、追記できる(実務版)- シート名の指定忘れが最大の落とし穴。必ずシート変数を付ける
- 転記先の既存データを守るには、最終行+1に追記する方式にする
セルの転記はVBA自動化の中でも最も基本的な操作のひとつです。「入力 → 転記 → 蓄積」の流れを一度作ってしまえば、日報の集約から月次集計まで、さまざまな業務の土台として使い回せます。まずは最小版で動作を確認し、慣れてきたら実務版に切り替えて、最終行の自動検出と追記を使いこなしてみてください。転記の仕組みを理解しておくと、空白行の削除やCSV書出など、他の自動化処理と組み合わせるときにもスムーズに進められます。自分の経験上、転記マクロを最初に作ると「VBAでここまで楽になるのか」と実感しやすく、次の自動化に取り組むモチベーションにもつながる。実務版のコードは受注台帳や在庫管理など、データが日々蓄積されていく業務と相性が良いので、まずは身近な転記作業から試してみてほしい。
関連記事
- 【VBA】複数シートに同じ処理を一括実行する方法 — 全シートへの一括処理はこちら
- 【VBA】複数Excelファイルを1つに統合する方法 — 複数ファイルの統合はこちら
- 【VBA】マクロをボタン1つで実行する方法 — 転記マクロをボタンに割り当て
—
次にやりたくなること
- 配列を使ってVBAの処理速度を10倍にする方法 — 転記する行数が数百〜数千行になったとき、配列を使えば処理時間を劇的に短縮できる
- データの最終行・最終列を正確に取得する方法 — 転記先の最終行を正確に取得するテクニックを深掘りしたい場合に。空白行が混在するケースにも対応
- 【VBA】複数シートに同じ処理を一括実行する方法 — 転記先が複数シートにまたがる場合、一括で処理したいときに
- 【VBA】複数Excelファイルを1つに統合する方法 — 複数ファイルのデータを1つに集約して転記したい場合に
—


コメント