Excel VBAでシート名を変更する方法
今回の目標
「マクロでシート名を変えられない?」や「ブック内のシート名を全て変更できない?」と思ったあなたへ。
この記事では、シート名を変更する方法や、複数のシート名を変更する方法、安全にシート名を変更する方法等を丁寧に解説します!
実務で使える具体例つきです。
目標リスト
- シート名を変更できるようになる
- 他のブックのシート名を変更できるようになる
- エラーを防ぎつつシート名を変更できるようになる
説明
シート名の変更について
Excelでは、シート名を変更できます。
Excel画面上からシート名を変更するなら、シートの見出しをダブルクリックしたり、[ホーム]タブ → [セル]グループ → [書式] → [シート名の変更]を選択する等、変更方法がありますが、マクロで変更することも可能です。
マクロでシート名を変更する場合は、Worksheets オブジェクトの Name プロパティ を使用します。
Worksheets.Name プロパティ
シート名を変更する場合、Worksheets オブジェクトの Name プロパティを使用します。
このプロパティは、変数と同様の扱いで、シート名の取得や代入(変更)が出来ます。
シートの指定方法について
シートの指定方法のおさらいです。
シートの指定は、シート名を指定する方法と、シートのインデックス番号を指定する方法があります。
インデックス番号は内部処理で左のシートから順に、1,2,3… と番号が振られます。
例えば「Worksheets(1)」なら一番左(先頭)のシートになります。
数値で扱うため、For文と併用することで全てのシートを対象とすることができます。
「Worksheets.Count」はブックのシート数を返します。
「Worksheets(Worksheets.Count)」とするとシートの最後尾(一番右)のシートになります。
シートをインデックス番号で指定する際の注意点
インデックス番号で指定する場合の注意点として、非表示のシートも番号が振られていることです。 具体的にはシートの一番左のシート名を取得したつもりが、2番目や3番目のシート名を取得してしまった。 原因を探ったら、「ユーザーが非表示でシートを追加していた」等が起こりえます。
シート名を変更する方法
変更対象のシート名を指定して、シート名を変更する方法です。
Worksheets("変更前のシート名").Name = "変更後のシート名"
変更対象のインデックス番号を指定して、シート名を変更する方法です。
Worksheets(1).Name = "変更後のシート名"
シート名を取得する方法
シート名を指定して、シート名を取得する方法です。
「シート名を指定している時点でシート名が分かっているのでは?」とご意見があると思いますが、その通りです。
一応、紹介します。
Debug.Print Worksheets("Sheet1").Name
シートのインデックス番号を指定して、シート名を取得する方法です。
Debug.Print Worksheets(1).Name
シンプルにシート名を変更する
1.シート名を変更する
シート名を変更するサンプルです。
サンプルコードでは、ブック内のシート ”Sheet2” を ”シート2” に変更します。
サンプルコード
Sub SheetNameChange1_1_1()
'”Sheet2” のシート名を ”シート2” に変更する
Worksheets("Sheet2").name = "シート2"
End Sub
● 実行前
● 実行後
Set を使用して、シート名を変更する方法です。
サンプルコードでは、ブック内のシート ”Sheet2” を ”シート2” に変更します。
サンプルコード
Sub SheetNameChange1_1_2()
Dim ws As Worksheet
'”Sheet2” のシートオブジェクトを参照する
Set ws = Worksheets("Sheet2")
'シートオブジェクトのシート名を ”シート2” に変更する
ws.name = "シート2"
End Sub
● 実行前
● 実行後
2.アクティブなシートのシート名を変更する
アクティブなシートのシート名を変更する方法です。
サンプルコードでは、アクティブなシートのシート名を ”TEST” に変更します。
サンプルコード
Sub SheetNameChange1_2()
'アクティブなシートのシート名を ”TEST” に変更する
ActiveSheet.name = "TEST"
End Sub
● 実行前
● 実行後
3.先頭(一番左)のシートの名前を変更する
先頭(一番左)のシートの名前を変更する方法です。
「Worksheets(1)」とすることで、先頭(一番左)のシートを指定できます。
サンプルコードでは、先頭のシートのシート名を ”先頭のシート” に変更しています。
サンプルコード
Sub SheetNameChange1_3()
'「Worksheets(1)」は先頭(一番左)を指す
Worksheets(1).name = "先頭のシート"
End Sub
● 実行前
● 実行後
4.最後尾(一番右)のシートの名前を変更する
最後尾(一番右)のシートの名前を変更する方法です。
「Worksheets(Worksheets.Count)」とすることで、最後尾(一番右)のシートを指定できます。
「Worksheets.Count」はブックのシート数を返します。
サンプルコードでは、最後尾(一番右)のシート名を ”最後尾のシート” に変更しています。
サンプルコード
Sub SheetNameChange1_4()
'「Worksheets(Worksheets.Count)」は最後尾(一番右)のシートを指す
Worksheets(Worksheets.Count).name = "最後尾のシート"
End Sub
● 実行前
● 実行後
5.他のブックのシート名を変更する
他のブックのシート名を変更する方法です。
マクロを実行しているブックと別のブックのシート名を変更したい場合は、ブックオブジェクトを指定したうえで、シート名を変更します。
サンプルコードでは、例として「Book2.xlsx」を指定しています。この Book2.xlsx の ”Sheet1” を ”シート1” に変更します。
サンプルコード
Sub SheetNameChange1_5()
'Book2.xlsx の "Sheet1" を "シート1" に変更する
Workbooks("Book2.xlsx").Worksheets("Sheet1").name = "シート1"
End Sub
● 実行前
● 実行後
ブック内の複数のシート名を変更する
1.ブック内の全てのシート名を変更する
ブック内の全てのシート名を変更する方法です。
For文 や For Each文を使用することで、ブック内の全てのシートを対象にできます。
サンプルコードでは、For文を使い、「Book2.xlsx」にある ”Sheet1” を ”シート1” に変更します。
サンプルコード
Sub SheetNameChange2_1()
Dim i As Long
For i = 1 To ThisWorkbook.Worksheets.Count
Worksheets(i).name = "Sheet" & i
Next i
End Sub
● 実行前
● 実行後
シートの数字が順番にならない?
場合によっては、下の画像のように数字が飛んでしまう場合があります。
"Sheet3" から "Sheet5" に飛んで、"Sheet4" がありません。
これは "Sheet4" が非表示になっているためです。
表示されているシートのみ、番号を振り直したい場合は次の項目「ブック内の表示されているシート名を全て変更する」を確認してください。
2.ブック内の表示されているシート名を全て変更する
ブック内の表示されているシートのみシート名を変更する方法です。
各シートの表示状態を確認し、表示されているシートだけを対象にします。
サンプルコードでは、For文を使い、「Book2.xlsx」にある ”Sheet1” を ”シート1” に変更します。
サンプルコード
Sub SheetNameChange2_2()
Dim i As Long
Dim num As Long
num = 1
For i = 1 To ThisWorkbook.Worksheets.Count
If Worksheets(i).Visible Then
Worksheets(i).name = "Sheet" & num
num = num + 1
End If
Next i
End Sub
● 実行前
● 実行後
3.選択しているシートのシート名を全て変更する
選択中のシートの名前を全て変更する方法です。
サンプルコードでは、For Each文を使い、選択中のシートの名前の末尾に ”_A” を付けます。
サンプルコード
Sub SheetNameChange2_3()
Dim ws As Worksheet
' "Sheet2" と "Sheet3" を選択する
' ※ 手動で選択しても結果は同じです。
ThisWorkbook.Worksheets(Array("Sheet2", "Sheet3")).Select
'選択中のシートを全て処理する
For Each ws In ThisWorkbook.Windows(1).SelectedSheets
'シート名の末尾に ”_A” を付ける
ws.name = ws.name & "_A"
Next ws
End Sub
● 実行前
● 実行後
エラー対策を行い安全にシート名を変更する
1.エラートラップを行ってからシート名を変更する
エラートラップ(※)を行ってからシート名を変更する方法です。
シート名で使用できない文字を使用したりすると、エラーが発生してプログラムが止まってしまいます。
そのため、安全にシート名を変更するには、エラートラップや変更できるシート名か確認しましょう。
なお、エラートラップとは、プログラムの実行中に発生したエラーを検知して、その内容を受け取ることです。
あわせて、検知したエラーに対して実行する処理(例外処理)を記述することを指す場合もあります。
詳細は次のリンクをお読みください。
・リンク:【例外処理】エラートラップの方法
サンプルコードでは、エラートラップを行ってからシート名を変更しています。
変更するシート名に使用できない文字 "*" が含まれているため、エラーが発生します。
ただし、エラートラップを行っているため、処理が止まらず「ErrorHandler:」に移動します。
サンプルコード
Sub SheetNameChange3_1()
On Error GoTo ErrorHandler
Worksheets(1).name = "Sheet1*"
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました。" & vbNewLine & _
"この画面をキャプチャして、" & vbNewLine & _
"システム管理者にご連絡ください。" & vbNewLine & _
"ーーーーーーーーーーーーーーーー" & vbNewLine & _
Err.Description, vbCritical
End Sub
● 実行後
● エラートラップがないと、次のエラーメッセージになります。
2.チェックを行い安全にシート名を変更する
エラートラップを使用することで、想定外に処理が止まってしまうことはありませんが、詳細なエラー原因が分かりません。
このため、シート名に使用できる名前か1つずつ確認する方が原因を突き止めやすいです。
シート名に使用できる名前は、次の項目の確認が必要です。
リンクは、詳細説明とプログラムへのリンクです。
- 変更対象のシート名のシートは存在するか
- シート名に使用できない文字が含まれていないか
- ブックに同名のシート名が存在していないか
- シート名の文字の長さは、1字~31字 か
- シート名の先頭もしくは末尾が ' でないか
- 変更対象のブックに保護がかかってしまっていないか
サンプルコードでは、上記のチェックをそれぞれ関数化して、真偽を確認しています。 その結果を基準に、なぜシート名にできないかをメッセージボックスに表示します。
サンプルコード
'--------------------------------------------------------------
' 変更可能かチェックを行ってから、シート名を変更する
'--------------------------------------------------------------
Sub SheetNameChange3_2()
Dim oldShNm As String '変更対象のシート名
Dim newShNm As String '変更後のシート名
oldShNm = "Sheet1"
newShNm = "'abcA*" '← 先頭に "'"、使用不可の "*"がある
If SetSheetName(oldShNm, newShNm, ThisWorkbook) Then
'シート名の変更が完了した時の処理
Else
'シート名の変更が出来なかった時の処理
End If
End Sub
'--------------------------------------------------------------
' シート名を変更できる名前か確認してから変更する
' ※ 変更できない場合はメッセージボックスを表示する
' oldShNm:変更したいシート名
' newShNm:変更後のシート名
' wb :名前を変更するシートのブック
' 戻り値:True /シート名の変更が完了した
' False/シート名の変更が出来なかった
'--------------------------------------------------------------
Function SetSheetName(ByVal oldShNm As String, _
ByVal newShNm As String, ByRef wb As Workbook) As Boolean
Dim flag1 As Boolean, flag2 As Boolean
Dim flag3 As Boolean, flag4 As Boolean
Dim flag5 As Boolean, flag6 As Boolean
Dim errMsg As String
errMsg = ""
'oldShNm(変更対象のシート名) のシートは存在するか
flag1 = Not IsSheetNameUsed(ThisWorkbook, oldShNm)
'シート名で使用できない文字が含まれていないか
flag2 = HasForbiddenChars(newShNm)
'ブックに同名のシート名が存在しないか
flag3 = IsSheetNameUsed(ThisWorkbook, newShNm)
'シート名の文字の長さは、1字~31字 か
flag4 = IsInvalidLength(newShNm)
'シート名の先頭もしくは末尾が ' でないか
flag5 = IsEdgeApostrophe(newShNm)
'変更対象のブックに保護がかかってしまっていないか
flag6 = IsProtectBook(ThisWorkbook)
'フラグが1つでも成立していると、シート名にできない
If flag1 Or flag2 Or flag3 Or flag4 Or flag5 Or flag6 Then
'エラーメッセージの生成1
errMsg = "エラーが発生しました。" & vbNewLine & _
"この画面をキャプチャして、" & vbNewLine & _
"システム管理者にご連絡ください。" & vbNewLine & _
"ーーーーーーーーーーーーーーーー" & vbNewLine & _
"シート名を変更できませんでした。" & vbNewLine & _
"(変更前:" & oldShNm & " / " & "変更後:" & newShNm & ")"
'エラーメッセージの生成2
If flag1 Then errMsg = errMsg & vbNewLine & _
"・変更対象のシート名" & oldShNm & "がありません"
If flag2 Then errMsg = errMsg & vbNewLine & _
"・シート名に使用できない文字が含まれています"
If flag3 Then errMsg = errMsg & vbNewLine & _
"・既に[" & newShNm & "]シートが存在しています"
If flag4 Then errMsg = errMsg & vbNewLine & _
"・シート名の長さが、0字または31字を超えています"
If flag5 Then errMsg = errMsg & vbNewLine & _
"・シート名の先頭もしくは末尾が ' です"
If flag6 Then errMsg = errMsg & vbNewLine & _
"・ブックの保護を解除してください"
End If
If errMsg = "" Then
ThisWorkbook.Worksheets(oldShNm).name = newShNm
SetSheetName = True
Else
MsgBox errMsg, vbCritical
SetSheetName = False
End If
End Function
'--------------------------------------------------------------
' シート名で使用できない文字が含まれているかを返す
' newShNm:確認対象のシート名
' 戻り値:True/シート名に使用できない文字が含まれている
'--------------------------------------------------------------
Function HasForbiddenChars(ByVal newShNm As String) As Boolean
Dim forbChars() As Variant 'forb = forbidden
Dim buf As Variant
Dim num As Long
Dim forbStr As String
'シート名に使用できない文字列
forbChars = Array("\", "¥", "/", ":", "*", "?", "[", "]")
'使用できない文字1つずつ、確認する
For Each buf In forbChars
'vbTextCompareを指定して、全角もチェックする
num = InStr(1, newShNm, buf, vbTextCompare)
If 0 < num Then
HasForbiddenChars = True
Exit Function
End If
Next buf
HasForbiddenChars = False
End Function
'--------------------------------------------------------------
' ブックに同名のシート名が既に存在していないか確認する
' wb :確認対象のブック名(シート名を追加/変更するブック)
' newShNm:確認対象のシート名
' 戻り値:True/同名のシート名が存在している
'--------------------------------------------------------------
Function IsSheetNameUsed(ByRef wb As Workbook, ByRef newShNm As String) As Boolean
Dim buf As Worksheet
'ブックのシートを1シートずつ、名前が一致していないか確認する
For Each buf In wb.Worksheets
If buf.name = newShNm Then
IsSheetNameUsed = True
Exit Function
End If
Next buf
IsSheetNameUsed = False
End Function
'--------------------------------------------------------------
' 新しいシート名が1文字~31文字に収まっているか
' newShNm:確認対象のシート名
' 戻り値:True/新しいシート名が0文字もしくは32文字以上
'--------------------------------------------------------------
Function IsInvalidLength(ByRef newShNm As String) As Boolean
Dim flag1 As Boolean
Dim flag2 As Boolean
flag1 = Len(newShNm) = 0
flag2 = Len(newShNm) > 31
IsInvalidLength = (flag1 Or flag2)
End Function
'--------------------------------------------------------------
' シート名の先頭や末尾に ' を使用していないか確認する
' newShNm:確認対象のシート名
' 戻り値:True/新しいシート名の先頭や末尾が ' である
'--------------------------------------------------------------
Function IsEdgeApostrophe(ByRef newShNm As String) As Boolean
Dim flag1 As Boolean
Dim flag2 As Boolean
flag1 = Left(newShNm, 1) = "'"
flag2 = Right(newShNm, 1) = "'"
IsEdgeApostrophe = (flag1 Or flag2)
End Function
'--------------------------------------------------------------
' ブックが保護されているか
' ※ ブックが保護されていると、シート名の変更等 ができない
' wb :確認対象のブック名
' 戻り値:True/ブックが保護されている
'--------------------------------------------------------------
Function IsProtectBook(ByRef wb As Workbook)
IsProtectBook = wb.ProtectStructure
End Function
● 実行後