記事ID: 069
タイトル: 【VBA】シート名の取得・一括変更・存在チェックする方法(コピペOK)
カテゴリ: シート操作
一次キーワード: VBA シート名 取得 変更
二次キーワード: VBA シート名 一覧, VBA シート名 存在チェック, VBA シート名 一括変更, VBA シート名 禁止文字
想定読者: 月次レポートで12枚のシート名を毎月手動で変更している事務・管理職
検索意図: VBAでシート名を取得・変更・一覧表示・存在チェックする方法を知りたい
読者の悩み: 12枚のシートをダブルクリックして1枚ずつ名前を変えるのが地味に面倒。しかも禁止文字でエラーになった
読了後にできること: VBAでシート名の取得・一括変更・存在チェック・一覧作成をコピペで自動化できる
前提条件:
- Excel版: Excel 2016以降 / Microsoft 365
- OS: Windows 10/11
- 保存形式: .xlsm(マクロ有効ブック)
- 貼り付け場所: 標準モジュール
- 実行方法: マクロ実行(F5)またはボタン割り当て
メタディスクリプション: VBAでシート名を取得・変更・一覧表示・存在チェックする方法を解説。全シート名の一括取得、月次テンプレートのシート名一括変更、シート名のルール(禁止文字・文字数制限)まで。コピペOK。
更新日: 2026-04-15
この記事でできること
月次レポートのExcelファイルに「Sheet1」「Sheet2」…とシートが12枚ある。毎月これを「2026年1月」「2026年2月」…に手動で1枚ずつダブルクリックして名前を変更する。12回ダブルクリック → 入力 → Enter。地味に面倒だ。
しかも一度、シート名に「/」を入れてしまってエラーになった。「2026/01」と入力したら「実行時エラー 1004」。Excelのシート名には使えない文字があるなんて、誰も教えてくれなかった。
VBAで一括変更するようにしてからは、ボタン1つで12枚のシート名が一瞬で変わる。 禁止文字のチェックも、同名シートの存在確認も、コードに組み込めば二度とエラーに悩まされない。
この記事では、VBAでシート名の取得・一括変更・存在チェックする方法を、コピペで動くコード付きで解説する。
- 対象:シート名を手動で1枚ずつ変更している人
- 所要時間:コピペ → 実行まで3分
—
完成イメージ(Before / After)
Before(手作業で12回ダブルクリック)

| 操作 | 内容 | 時間 |
|---|---|---|
| 1枚目 | Sheet1 → ダブルクリック → 「2026年1月」入力 → Enter | 約15秒 |
| 2枚目 | Sheet2 → ダブルクリック → 「2026年2月」入力 → Enter | 約15秒 |
| … | 同じ作業を繰り返す | … |
| 12枚目 | Sheet12 → ダブルクリック → 「2026年12月」入力 → Enter | 約15秒 |
| 合計 | 12回のダブルクリック + 入力 + Enter | 約3分 |
After(VBAで一括変更)

| シート番号 | 変更前 | 変更後 |
|---|---|---|
| 1 | Sheet1 | 2026年1月 |
| 2 | Sheet2 | 2026年2月 |
| 3 | Sheet3 | 2026年3月 |
| … | … | … |
| 12 | Sheet12 | 2026年12月 |
| 合計 | F5キーを1回押すだけ | 1秒 |
—
どんな場面で使う?
自分がシート名の操作をVBAで自動化したのは、以下のような場面で「手作業の限界」を感じたから。
- 月次レポートのテンプレートを毎月作成する — 12枚のシートを「2026年1月」〜「2026年12月」と名前を付ける作業を毎年やっていた。手作業だと3分、VBAなら1秒
- 他部署から受け取ったブックのシート構成を確認する — 「このシート入ってる?」をいちいち目視で確認する代わりに、SheetExists 関数で一発チェック
- 大量のシートがあるブックを整理する — 20枚以上のシートがあるファイルで、シート名を一覧化してExcelの別シートに出力すると全体像が掴みやすい
- マクロの中で「シートがなければ新規作成、あればそのまま使う」の分岐を入れる — 存在チェックなしだとエラー9(インデックスが有効範囲にありません)が頻発する
- シート名にルール(禁止文字・文字数制限)があることを知らずにハマった経験がある人 — 自分も
2026/01と付けようとして初めて禁止文字の存在を知った
—
基本:シート名を取得する
まずはシート名を取得する基本コードです。
アクティブシートの名前を取得する
Sub アクティブシート名を取得()
MsgBox "アクティブシートの名前は「" & ActiveSheet.Name & "」です"
End Sub
ポイント:
ActiveSheet.Nameで、今選択しているシートの名前を取得できます- 取得した名前は文字列(String型)で返ります
- どのシートがアクティブかはユーザーの操作次第で変わるため、特定のシートを確実に操作したい場合はシート名やコードネームで指定するほうが安全です
インデックス番号でシート名を取得する
Sub インデックスでシート名を取得()
' 左から1番目のシート名を取得
MsgBox "1番目のシートは「" & Worksheets(1).Name & "」です"
End Sub
ポイント:
Worksheets(1)は左から1番目のシート- シートの並び順を変えるとインデックス番号も変わるので注意
Worksheets("Sheet1")のように名前で指定するほうが安全です
—
シート名を変更する
シート名を変更するには、Name プロパティに新しい名前を代入します。
Sub シート名を変更する()
Worksheets("Sheet1").Name = "売上データ"
End Sub
ポイント:
Worksheets("旧名前").Name = "新しい名前"が基本形- 変更前のシート名が存在しないとエラーになります(→ 後述の存在チェックで対策)
- シートが保護されている場合は変更できません(→ シート保護・解除の方法を参照)
アクティブシートの名前を変更する
Sub アクティブシート名を変更する()
ActiveSheet.Name = "売上データ"
End Sub
ポイント:
- 今選択しているシートの名前を変更します
- どのシートがアクティブかを意識してから実行してください
なお、シート名の変更は「代入するだけ」なのでコードは単純だが、変更前に存在チェックをしないとエラーの原因になる。Worksheets("Sheet1") の「Sheet1」が存在しなければエラー9が出るし、変更先の名前が既に使われていればエラー1004が出る。実務では後述の SheetExists 関数と組み合わせて使うのが鉄則。
—
シート名の一覧を取得する
ブック内の全シート名を一覧で取得するコードです。全シートをFor Eachでループして処理します。For Eachループの基本は複数シートを一括処理する方法で詳しく解説しています。
MsgBoxで一覧表示する(最小版)
Sub 全シート名を一覧表示()
Dim ws As Worksheet
Dim msg As String
For Each ws In ThisWorkbook.Worksheets
msg = msg & ws.Name & vbCrLf
Next ws
MsgBox msg, vbInformation, "シート名一覧"
End Sub
実行結果:
┌──────────────────────┐
│ シート名一覧 │
│ │
│ 1月データ │
│ 2月データ │
│ 3月データ │
│ 集計 │
│ マスタ │
│ │
│ [OK] │
└──────────────────────┘
ポイント:
For Each ws In ThisWorkbook.Worksheetsで全シートを1枚ずつ処理vbCrLfは改行コード。シート名が1行ずつ表示されますThisWorkbookは「このマクロが書かれているブック」を指します
セルに一覧を書き出す
シート名の一覧をセルに書き出すこともできます。データの最終行を正確に取得する方法は最終行・最終列を取得する方法を参照してください。
Sub シート名をセルに書き出す()
Dim ws As Worksheet
Dim i As Long
' 書き出し先のシート(ここでは1番目のシート)
Dim outSheet As Worksheet
Set outSheet = ThisWorkbook.Worksheets(1)
' 見出し
outSheet.Cells(1, 1).Value = "No"
outSheet.Cells(1, 2).Value = "シート名"
i = 2 ' 2行目からデータ
For Each ws In ThisWorkbook.Worksheets
outSheet.Cells(i, 1).Value = i - 1
outSheet.Cells(i, 2).Value = ws.Name
i = i + 1
Next ws
MsgBox "シート名の一覧を書き出しました(" & ThisWorkbook.Worksheets.Count & "枚)"
End Sub
ポイント:
ThisWorkbook.Worksheets.Countでシートの総数を取得できます- 見出し行を1行目に入れて、2行目からデータを書き出すと見やすくなります
このコードでは For Each ws In ThisWorkbook.Worksheets のループ内でカウンタ変数 i を手動でインクリメントしている。For Eachループは自動でカウンタが回らないため、セルの行番号を管理するにはこのように自前の変数が必要になる。書き出し先を1番目のシート(Worksheets(1))に固定しているが、自分の環境に合わせて変更してほしい。他のシートのデータを集約する応用はセルのデータを別シート・別ブックに転記する方法で詳しく解説している。
—
シートが存在するかチェックする
シート名を指定して操作する前に、そのシートが存在するかチェックしましょう。存在しないシート名を指定すると「実行時エラー 9: インデックスが有効範囲にありません」が発生します。
SheetExists関数(汎用版)
Function SheetExists(sheetName As String) As Boolean
Dim ws As Worksheet
On Error Resume Next
Set ws = ThisWorkbook.Worksheets(sheetName)
On Error GoTo 0
SheetExists = Not ws Is Nothing
End Function
ポイント:
On Error Resume Nextでエラーを一時的に無視して、シートを取得できるか試します。存在しないシート名を指定するとエラーが発生するが、Resume Next でそのエラーを握り潰している- 取得できれば
wsにシートがセットされ、取得できなければNothingのまま。Not ws Is Nothingで「Nothing ではない = シートが存在する」と判定している On Error GoTo 0で通常のエラー処理に戻すのを忘れずに。これを書かないと、以降のコードでエラーが全部無視されてしまう(→ エラー処理で止まらないマクロを作る方法を参照)- この関数は何度でも使い回せるので、標準モジュールに入れておくと便利です。自分はどのプロジェクトでもまずこの関数を用意している
SheetExists関数の使い方
Sub 存在チェックの使用例()
If SheetExists("売上データ") Then
MsgBox "「売上データ」シートは存在します"
Else
MsgBox "「売上データ」シートは存在しません"
End If
End Sub
存在チェック付きでシートを操作する
Sub 安全にシートを操作する()
Dim targetName As String
targetName = "売上データ"
If SheetExists(targetName) Then
' シートが存在する場合のみ操作
Worksheets(targetName).Select
MsgBox targetName & " シートを選択しました"
Else
MsgBox targetName & " シートが見つかりません", vbExclamation
End If
End Sub
—
実務版:月次テンプレートのシート名を一括変更する
ここからが実務で使えるコードです。12枚のシートの名前を「2026年1月」〜「2026年12月」に一括変更します。既に同名シートがある場合はスキップするので安全です。
※ シート名の変更はCtrl+Zで元に戻せません。念のためブックのバックアップを取ってから実行してください。
※ シート名に禁止文字(: \ / [ ] * ?)を含む形式にカスタマイズする場合は、落とし穴1のCleanSheetName関数で除去してください。
'============================================
' 月次テンプレートのシート名を一括変更する
'============================================
' ● やること:
' 12枚のシート名を「2026年1月」〜「2026年12月」に変更
' ● 前提:
' - ブックに12枚以上のシートがあること
' - .xlsm で保存されていること
' - 標準モジュールに貼り付けること
' ● 注意:
' - 13枚目以降のシートは変更されません
' - カスタマイズ時は禁止文字に注意(落とし穴1参照)
'============================================
Sub 月次シート名を一括変更()
Dim i As Long
Dim newName As String
Dim yearNum As Long
Dim changeCount As Long
Dim skipCount As Long
yearNum = 2026 ' ← 年を変更する場合はここを書き換え
' --- シート数チェック ---
If ThisWorkbook.Worksheets.Count < 12 Then
MsgBox "シートが12枚未満です。" & vbCrLf & _
"現在のシート数: " & ThisWorkbook.Worksheets.Count, _
vbExclamation, "エラー"
Exit Sub
End If
' --- 一括変更 ---
For i = 1 To 12
newName = yearNum & "年" & i & "月"
' 既に同名シートがあればスキップ
If SheetExists(newName) Then
skipCount = skipCount + 1
Else
ThisWorkbook.Worksheets(i).Name = newName
changeCount = changeCount + 1
End If
Next i
' --- 結果表示 ---
MsgBox "完了しました。" & vbCrLf & _
"変更: " & changeCount & "枚" & vbCrLf & _
"スキップ: " & skipCount & "枚", _
vbInformation, "シート名一括変更"
End Sub
'============================================
' シート存在チェック関数(上のコードで使用)
'============================================
Function SheetExists(sheetName As String) As Boolean
Dim ws As Worksheet
On Error Resume Next
Set ws = ThisWorkbook.Worksheets(sheetName)
On Error GoTo 0
SheetExists = Not ws Is Nothing
End Function
コードの流れ
- 年の設定:
yearNum = 2026を変更すれば、任意の年に対応 - シート数チェック: 12枚未満なら処理を中断してエラー表示
- ループで一括変更: 1〜12月のシート名を順番に変更
- 存在チェック: 既に同名シートがあればスキップ(エラー防止)
- 結果表示: 変更枚数とスキップ枚数をMsgBoxで表示
実務版コードの詳細解説
このコードのキモは「安全策を二重にかけている」点。まず ThisWorkbook.Worksheets.Count < 12 でシート数の事前チェックをしている。12枚のシートに名前を付けるマクロなのに、ブックに12枚未満しかシートがなければ当然エラーになる。この種の前提条件チェックを入れておくと、「なぜエラーになったか」がユーザーに即座に伝わる。
次に SheetExists(newName) で同名シートの存在チェック。Excelでは同じブック内に同名シートを作れないため、既に「2026年1月」というシートがある状態で別のシートを同じ名前に変更しようとするとエラー1004になる。存在チェックでスキップすることで、マクロを何度実行しても安全に動作する「冪等性(べきとうせい)」を確保している。
changeCount と skipCount で変更枚数とスキップ枚数をカウントしているのも実務的なポイント。処理結果を数値で表示することで、「本当に変更されたのか」「何枚スキップされたのか」が一目で分かる。
カスタマイズ例
年を自動で取得する場合は、yearNum = 2026 を以下に変更してください:
yearNum = Year(Date) ' 実行時の年を自動取得
シート名のフォーマットを変えたい場合:
' 「2026_01」形式にしたい場合
newName = yearNum & "_" & Format(i, "00")
' 「1月度」形式にしたい場合
newName = i & "月度"
---
落とし穴
落とし穴1: シート名に禁止文字を使ってエラーになる
シート名には使えない文字があります。以下の7文字です:
: \ / [ ] * ?
これらを含む名前を付けようとすると「実行時エラー 1004」が発生します。
自分もシート名に「2026/01」と付けようとしてエラーになった。/ はシート名に使えない文字だった。「2026年01月」や「2026_01」のように、禁止文字を避けた形式にすればOK。
対策: 禁止文字をReplace関数で除去してから変更する。
Function CleanSheetName(name As String) As String
Dim result As String
result = name
Dim ch As Variant
For Each ch In Array(":", "\", "/", "[", "]", "*", "?")
result = Replace(result, ch, "")
Next ch
' 31文字を超えたら切り詰め
If Len(result) > 31 Then result = Left(result, 31)
CleanSheetName = result
End Function
落とし穴2: 同名シートが存在してエラーになる
同じブック内に同じ名前のシートは作れません。既に「2026年1月」というシートがあるのに、別のシートの名前も「2026年1月」にしようとするとエラーです。
対策: SheetExists 関数で事前に存在チェックする(実務版コードでは対応済み)。
落とし穴3: シート名が31文字を超えてエラーになる
シート名は31文字が上限です。全角・半角を問わず31文字です。
' これはエラー(32文字以上)
ws.Name = "あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみ"
対策: Len(newName) > 31 で事前にチェックするか、Left(newName, 31) で切り詰める。
落とし穴4: シートが保護されていて変更できない
シートが保護されている状態では、シート名を変更できません(「実行時エラー 1004」)。
対策: シート名を変更する前にシート保護を解除する。詳しくはシート保護・解除の方法を参照。
' パスワード付きで保護されている場合
ws.Unprotect Password:="パスワード" ' 保護解除
ws.Name = "新しい名前" ' シート名変更
ws.Protect Password:="パスワード" ' 再度保護
' パスワードなしで保護されている場合
ws.Unprotect ' これだけでOK
ws.Name = "新しい名前"
ws.Protect
落とし穴5: VBAコード内のシート参照が壊れる
Excelの数式はシート名変更に自動で追従しますが、VBAコード内で Worksheets("旧名前") とハードコーディングしている場合は自動で変わりません。
対策: VBAコード内でシート名をハードコーディングせず、コードネーム(Sheet1 等)で参照する。
' NG: シート名が変わると動かなくなる
Worksheets("売上データ").Range("A1").Value = 100
' OK: コードネームならシート名が変わっても動く
Sheet1.Range("A1").Value = 100
VBAでシート名を変更しようとしてエラーが出るときの対処法
「Worksheets("Sheet1").Name = "新しい名前" を実行したらエラー1004が出る」という場合、原因は大きく2つある。1つは変更先の名前が既に他のシートで使われている場合(同名不可)。もう1つはシート名に禁止文字(: \ / [ ] * ?)が含まれている場合。対処法は、変更前に SheetExists 関数で同名シートがないか確認し、CleanSheetName 関数で禁止文字を除去してから代入すること。自分も 2026/01 と付けようとしてエラーになった経験がある。
VBAでシートの存在確認をする方法がわからないときの対処法
「シートがあるかどうかVBAでチェックしたいけど方法が分からない」という場合、On Error Resume Next を使って Worksheets("シート名") を取得し、結果が Nothing かどうかで判定するのが定番パターン。本記事の SheetExists 関数をそのまま使えばOK。この関数を標準モジュールに入れておけば、どのマクロからでも If SheetExists("売上データ") Then で存在チェックできる。自分はどのプロジェクトでもまずこの関数を用意するようにしている。
VBAでシート名変更後にマクロが動かなくなるときの対処法
「シート名を変更したら、他のマクロで『インデックスが有効範囲にありません』のエラーが出るようになった」という場合、原因はVBAコード内で旧シート名をハードコーディングしていること。Excelの数式はシート名変更に自動追従するが、VBAの Worksheets("旧名前") は自動で変わらない。対処法は、VBAコード内でシート名を直接書かず、コードネーム(Sheet1 等)で参照すること。コードネームはVBEのプロパティウィンドウで確認できる。
---
FAQ
Q1: Worksheets と Sheets の違いは?
Worksheets はワークシート(通常のシート)のみを指します。Sheets はワークシートに加えて、グラフシートやマクロシートなどすべてのシートを含みます。
通常のExcelファイルではグラフシートを使うことは少ないので、Worksheets を使えば問題ありません。
Q2: シート名の変更をCtrl+Zで元に戻せる?
VBAで変更したシート名はCtrl+Zで元に戻せません。元に戻したい場合は、変更前のシート名を配列に保存しておき、復元するコードを用意しましょう。
' --- 変更前のシート名を保存 ---
Dim oldNames() As String
ReDim oldNames(1 To ThisWorkbook.Worksheets.Count)
Dim j As Long
For j = 1 To ThisWorkbook.Worksheets.Count
oldNames(j) = ThisWorkbook.Worksheets(j).Name
Next j
' --- 復元する場合(上の保存処理の後に使う) ---
Sub シート名を復元する()
Dim k As Long
For k = 1 To UBound(oldNames)
ThisWorkbook.Worksheets(k).Name = oldNames(k)
Next k
MsgBox "シート名を元に戻しました"
End Sub
Q3: シート名に使える最大文字数は?
31文字です。全角・半角を問わず31文字が上限です。32文字以上のシート名を付けようとすると「実行時エラー 1004」が発生します。
Q4: 全シート名をイミディエイトウィンドウに出力する最短コードは?
Sub 最短版()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets: Debug.Print ws.Name: Next ws
End Sub
Ctrl + G でイミディエイトウィンドウを開いてから実行すると、全シート名が出力されます。
Q5: 特定の文字を含むシートだけ処理するには?
InStr 関数でシート名に特定の文字が含まれるかチェックできます。
Sub 特定シートだけ処理()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If InStr(ws.Name, "月") > 0 Then
' 「月」を含むシートだけ処理
Debug.Print ws.Name
End If
Next ws
End Sub
For Eachでのシート処理の応用は複数シートを一括処理する方法を参照してください。
---
まとめ
この記事では、VBAでシート名を取得・変更・一覧表示・存在チェックする方法を解説しました。
| やりたいこと | コード |
|---|---|
| アクティブシート名を取得 | ActiveSheet.Name |
| シート名を変更 | Worksheets("旧名前").Name = "新名前" |
| 全シート名を一覧取得 | For Each ws In ThisWorkbook.Worksheets |
| シートの存在チェック | SheetExists 関数(On Error方式) |
| 月次シート名を一括変更 | 実務版コード(本記事) |
シート名のルールも押さえておきましょう:
- 31文字以内
- 禁止文字:
: \ / [ ] * ? - 空文字不可・同名不可
シート名の操作は「たかがシート名」と思われがちだが、月次処理や年次処理では毎回発生する定型作業。一度マクロ化しておけば、毎月の手間がゼロになる。SheetExists 関数は他のマクロでも頻繁に使うので、標準モジュールに入れておいて損はない。
シートを別ブックにコピーして活用する方法はシートを別ブックにコピー・移動する方法で解説しています。シート名でフォルダを振り分ける方法はフォルダ作成・振り分けの方法も参考にしてください。シート名に含まれる文字列を抽出・加工したい場合は文字列から必要な部分だけ抽出する方法、シート名の置換にはセルの文字列を一括置換する方法の Replace 関数が応用できます。エラー処理を入れてより堅牢にしたい場合はエラー処理の応用パターン(リトライ・ログ・通知)を実装する方法も参照してください。
次にやりたくなること
- 複数シートをまとめて処理したい → 複数シートを一括処理する方法
- シートを別ブックにコピーしたい → シートを別ブックにコピー・移動する方法
- シート名に含まれる文字列を加工したい → 文字列から必要な部分だけ抽出する方法
- マクロのエラー処理を強化したい → エラー処理の応用パターンを実装する方法


コメント