【VBA】シート名変更による参照切れに対応するコーディング法

グラフを作成する際、もっとも多いトラブルの1つが**「シート名を変更したことで参照が切れてしまう」**という問題です。
VBAで "Worksheets("データ")" のように名前でシートを参照している場合、シート名変更でコードが動かなくなり、実行時エラー9(Subscript out of range) が発生します。

本記事では、シート名が変更されても壊れない「参照切れ防止テクニック」をまとめます。


1. コードネーム(CodeName)で参照する方法【最強で推奨】

ワークシートには「コードネーム」があり、
シート名が変わっても絶対に変わりません。

VBAのプロパティウィンドウで次のように表示されます:

  • 左側:コードネーム(例:Sheet1
  • 右側:シート名(例:売上データ

シート名は自由に変更可能ですが、コードネームはユーザーが変更しない限り固定です。

● コードネームを使った参照例

Sub Sample()
    Sheet1.Range("A1").Value = "OK"
End Sub

上記の Sheet1 はシート名ではなく「コードネーム」。
ユーザーがシート名を「売上表」「DataSheet」などに変更してもコードは壊れません。

● グラフ作成時もコードネームを使う

Sub CreateChart_CodeName()
    Dim ws As Worksheet
    Set ws = Sheet1 '← 変更されない参照

    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

    Dim dataRange As Range
    Set dataRange = ws.Range("A1:B" & lastRow)

    Dim chtObj As ChartObject
    Set chtObj = ws.ChartObjects.Add(Left:=300, Top:=50, Width:=400, Height:=300)

    chtObj.Chart.SetSourceData dataRange
End Sub

これが最も安定します。


2. シート名ではなく Worksheets(Index) で参照する方法

コードネームが使えない場合は、インデックス番号で参照する方法も有効です。

Set ws = Worksheets(1)

ただし、

  • シートの並び順が変わると壊れる
  • 新しいシート挿入で番号がズレる

といったリスクがあります。

コードネーム>インデックス>シート名 の順で安全です。


3. シート名を変えられても自動で見つける方法(Name検索)

どうしてもシート名を使いたい場合、
存在チェックをしてから参照する ことでエラーを回避できます。

● シート存在チェック関数

Function ExistsSheet(sheetName As String) As Boolean
    Dim ws As Worksheet
    For Each ws In ThisWorkbook.Worksheets
        If ws.Name = sheetName Then
            ExistsSheet = True
            Exit Function
        End If
    Next ws
    ExistsSheet = False
End Function

● 使用例(存在しなければ終了)

Sub SafeSheetReference()
    Dim targetName As String
    targetName = "データ"

    If Not ExistsSheet(targetName) Then
        MsgBox "シート名「" & targetName & "」が見つかりません。", vbExclamation
        Exit Sub
    End If

    Dim ws As Worksheet
    Set ws = Worksheets(targetName)
End Sub

※ これは「参照切れ防止」にはなるものの、
シート名が変わった場合は処理自体は止まるので 完全な対策ではない ことに注意。


4. グラフの元データがシート名変更で壊れる問題への対策

グラフが内部で参照しているデータ範囲には
シート名が文字列として含まれるため、変更すると壊れます。

例:
=Sheet1!$A$1:$B$10

これがシート名変更時に無効になります。

● VBAでグラフ系列の参照を再設定する

Sub ResetChartSeries()
    Dim ws As Worksheet
    Set ws = Sheet1 'コードネーム

    Dim cht As Chart
    Set cht = ws.ChartObjects(1).Chart

    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

    cht.SetSourceData ws.Range("A1:B" & lastRow)
End Sub

コードネームとの併用で参照切れを完全に回避できます。


5. 実務向け:シート名依存を完全になくすテンプレート

Sub CreateChart_NoSheetNameRisk()
    'シート名ではなくコードネームを使用
    Dim ws As Worksheet
    Set ws = Sheet1

    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

    If lastRow < 2 Then
        MsgBox "データが不足しています。", vbExclamation
        Exit Sub
    End If

    Dim dataRange As Range
    Set dataRange = ws.Range("A1:B" & lastRow)

    Dim chtObj As ChartObject

    '既存グラフ削除(重複防止)
    For Each chtObj In ws.ChartObjects

        chtObj.Delete
    Next chtObj

    'グラフ作成
    Set chtObj = ws.ChartObjects.Add(Left:=300, Top:=50, Width:=400, Height:=300)
    chtObj.Chart.SetSourceData dataRange
End Sub

6. ポイントまとめ

方法安定度特徴
コードネーム参照(最強)★★★★★シート名変更の影響ゼロ
Worksheets(Index)★★★☆☆並び順変更で壊れる
Worksheets(“名前”)★★☆☆☆名称変更でエラー
存在チェック関数★★★☆☆例外処理として有効

コメント

タイトルとURLをコピーしました