シートをコピーする
大事なのは「どこに」「どの名前で」「安全に」複製するか。初心者でも迷わないように、動くコードと使い回せるテンプレートで、実務の落とし穴も一緒に潰します。
基本:Worksheet.Copyで丸ごと複製する
Sub CopySheet_Basic()
Worksheets("Template").Copy After:=Worksheets(Worksheets.Count) '末尾に複製
End Sub
VB- ポイント:
Worksheet.Copyで、書式・数式・オブジェクトを含めて「シート全体」を複製します。BeforeまたはAfterを使って挿入位置を指定します(同時指定は不可)。 - 最短応用:
Worksheets("Template").Copyとだけ書くと、テンプレートだけを入れた新規ブックが作成されます。
位置指定と命名:複製直後の新シートに名前を付ける
Sub CopyAndRename_After()
Worksheets("Template").Copy After:=Worksheets(Worksheets.Count)
ActiveSheet.Name = "月次レポート" '複製直後は新シートがアクティブ
End Sub
VB- ポイント: 複製直後は新しいシートがアクティブなので、
ActiveSheet.Nameで命名できます。Before:=Worksheets(1)で先頭に、After:=Worksheets(Worksheets.Count)で末尾に配置するのが定番です。 - 注意: 同名はエラー。禁止文字(: / \ ? * [ ])と31文字上限にも注意しましょう。
他ブックへコピー:新規ブック/既存ブックへの複製
新規ブックにコピー(最短)
Sub CopyToNewWorkbook()
Worksheets("Template").Copy '新規ブックにTemplateが1枚だけ入る
End Sub
VB- ポイント: 引数なしの
Copyは新規ブック作成。テンプレートから派生ブックを作る場面で便利です。
既存ブックにコピー(参照して挿入)
Sub CopyToExistingWorkbook()
Dim src As Worksheet, dstWb As Workbook
Set src = ThisWorkbook.Worksheets("Template")
Set dstWb = Workbooks("集計.xlsm") '既に開いているブック
src.Copy After:=dstWb.Worksheets(dstWb.Worksheets.Count)
dstWb.ActiveSheet.Name = "集計_レポート"
End Sub
VB- ポイント:
CopyのBefore/Afterに「相手ブックのシート」を渡せば、既存ブックの好きな位置に複製できます。
安全テンプレート:重複回避・禁止文字対応・警告制御
Function SanitizeSheetName(rawName As String) As String
Dim s As String: s = rawName
s = Replace(s, ":", "_"): s = Replace(s, "/", "_")
s = Replace(s, "\", "_"): s = Replace(s, "?", "_")
s = Replace(s, "*", "_"): s = Replace(s, "[", "_")
s = Replace(s, "]", "_")
If Len(s) > 31 Then s = Left$(s, 31)
SanitizeSheetName = s
End Function
Function UniqueSheetName(baseName As String, wb As Workbook) As String
Dim name As String: name = SanitizeSheetName(baseName)
Dim i As Long: i = 1
Do While SheetExists(name, wb)
i = i + 1
name = SanitizeSheetName(baseName & "_" & CStr(i))
Loop
UniqueSheetName = name
End Function
Function SheetExists(sheetName As String, wb As Workbook) As Boolean
Dim t As Worksheet
On Error Resume Next
Set t = wb.Worksheets(sheetName)
SheetExists = Not t Is Nothing
On Error GoTo 0
End Function
Sub CopyTemplate_Safe(newName As String)
Dim targetName As String
targetName = UniqueSheetName(newName, ThisWorkbook)
Application.DisplayAlerts = False '命名時の警告を抑止
Worksheets("Template").Copy After:=Worksheets(Worksheets.Count)
ActiveSheet.Name = targetName
Application.DisplayAlerts = True
End Sub
VB- ポイント: 命名は「禁止文字除去」「31文字制限」「重複なら連番」で安全運用。
DisplayAlertsを一時オフにすると、命名衝突時のダイアログを抑えられます。
例題:月次・週次の量産、値のみコピーの応用
例題1:月次レポートをテンプレートから量産
Sub CreateMonthlyReportFromTemplate()
Dim nm As String
nm = Format(Date, "yyyy-mm") & "_レポート"
CopyTemplate_Safe nm
With ActiveSheet
.Range("A1").Value = "作成日"
.Range("B1").Value = Date
.Range("A2").Value = "担当"
.Range("B2").Value = Environ$("Username")
End With
End Sub
VB- ポイント: テンプレートを丸ごと複製→命名→初期値セットという鉄板パターン。毎月の定型作業がワンクリックになります。
例題2:週報を5枚まとめて複製・命名
Sub CreateWeeklyReports()
Dim i As Long, nm As String
For i = 1 To 5
nm = "週報_" & CStr(i)
CopyTemplate_Safe nm
ActiveSheet.Range("A1").Value = "週番号"
ActiveSheet.Range("B1").Value = i
Next
End Sub
VB- ポイント: 連番命名+初期化をループで一気に。重複も安全に回避します。
例題3:見た目だけ複製(値貼り付け)
Sub CopyValuesOnly_FromTemplate()
Dim src As Worksheet, dst As Worksheet
Set src = Worksheets("Template")
src.Copy After:=Worksheets(Worksheets.Count)
Set dst = ActiveSheet
dst.Name = UniqueSheetName("レポート_値のみ", ThisWorkbook)
'すべて値に変換(数式リンクを断つ)
With dst.UsedRange
.Value = .Value
End With
End Sub
VB- ポイント:
Copyで丸ごと複製してからUsedRange.Value = UsedRange.Valueで値化すれば、式や外部参照を断ち切った「見た目だけ」版が作れます。
よくある落とし穴と対策
- 同名エラー: 既存と重複すると命名でエラー。安全命名関数か、
DisplayAlertsでダイアログ抑止+連番付与をセットにするのが安心。 - 挿入位置の誤指定:
Before/Afterはどちらか一方のみ。相手が別ブックなら、そのブックのシート参照を正しく渡すこと。 - Copy直後の参照: 新シートはアクティブになる。命名・初期化は
ActiveSheetか、Worksheets(Worksheets.Count)など位置で参照。 - 新規ブックになる仕様: 引数なし
Copyは新規ブック作成。既存ブックに入れたいときは必ずBefore/Afterで挿入先を指定。 - グラフ・特殊オブジェクト:
Sheetsはグラフシートも対象。通常はWorksheetsを使うと混乱が少ない。
次の一歩(小課題)
- 課題1:
InputBoxで受け取った名前を安全化(禁止文字・重複回避)してテンプレートを複製。 - 課題2: 既存の「集計.xlsm」を開き、その末尾に「Template」を複製して「集計_YYYYMM」命名。
- 課題3: 複製後にセル範囲A1:D20だけ値化、それ以外は数式維持する初期化ロジックを追加。
