【VBA】グラフが重複生成される問題の防止策(既存削除など)

VBAでグラフ作成マクロを実行する際、毎回新しいグラフが追加されてしまい、同じシートにグラフが大量に増えるというトラブルはよく発生します。

これは、

  • 「既存のグラフを削除しない」
  • 「同じ名前のグラフが複数作られる」
  • 「位置や条件で既存グラフを判別していない」

などが原因です。

本記事では、実務で使える重複生成を防止するためのコードパターンをまとめます。


1. 最もシンプル:事前に全グラフを削除してから作り直す

同じシートに常に 1 つのグラフだけ置きたい場合は、
作り始める前に既存のグラフをすべて削除するのが最も確実です。

● コード例:既存のグラフ削除 → 再作成

Sub CreateChart_ClearOld()

    Dim ws As Worksheet
    Set ws = Sheet1

    '既存グラフを削除
    Dim obj As ChartObject
    For Each obj In ws.ChartObjects
        obj.Delete
    Next obj

    '新しいグラフを作成
    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 newCht As ChartObject
    Set newCht = ws.ChartObjects.Add(Left:=200, Top:=50, Width:=400, Height:=300)

    newCht.Chart.SetSourceData dataRange
End Sub

用途
→「常に最新のグラフだけ置きたい」ケースに最適


2. グラフ名(Name)で特定のグラフだけを削除する

シートに複数のグラフがある場合、
目標のグラフだけを削除または更新したいこともあります。

そんなときはグラフ名を付けて管理すると便利です。

● 特定の名前のグラフだけ削除する

Sub DeleteTargetChart()
    Dim ws As Worksheet
    Set ws = Sheet1

    Dim obj As ChartObject
    For Each obj In ws.ChartObjects
        If obj.Name = "売上グラフ" Then
            obj.Delete
            Exit For
        End If
    Next obj
End Sub

● グラフ作成時に名前をつける(管理しやすい)

newCht.Name = "売上グラフ"

用途
→「複数グラフがある環境で、目的のグラフだけ更新したい」


3. 既存のグラフがある場合は再利用し、なければ新規作成する

削除せず、同じグラフを更新するだけの方が効率的です。

● コード例:存在チェック → 更新処理

Sub CreateOrUpdateChart()
    Dim ws As Worksheet
    Set ws = Sheet1

    Dim chtObj As ChartObject
    Dim found As Boolean
    found = False

    '既存グラフがあるか確認
    For Each chtObj In ws.ChartObjects
        If chtObj.Name = "売上グラフ" Then
            found = True
            Exit For
        End If
    Next chtObj

    'なければ新規作成
    If Not found Then
        Set chtObj = ws.ChartObjects.Add(Left:=200, Top:=50, Width:=400, Height:=300)
        chtObj.Name = "売上グラフ"
    End If

    'データ更新
    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)

    chtObj.Chart.SetSourceData dataRange
End Sub

用途
→「毎回グラフを作り直す必要はない、更新だけで十分」場合


4. グラフの位置・サイズで既存グラフを判断する方法

名前管理が難しい場合、
座標(Top、Left など)で既存グラフを見つける方法もあります。

● 例:指定座標にグラフがあったらそれを再利用

Sub UpdateChart_ByPosition()
    Dim ws As Worksheet
    Set ws = Sheet1

    Dim targetTop As Double: targetTop = 50
    Dim targetLeft As Double: targetLeft = 200

    Dim chtObj As ChartObject
    Dim found As Boolean: found = False

    For Each chtObj In ws.ChartObjects
        If chtObj.Top = targetTop And chtObj.Left = targetLeft Then
            found = True
            Exit For
        End If
    Next chtObj

    If Not found Then
        Set chtObj = ws.ChartObjects.Add(Left:=targetLeft, Top:=targetTop, Width:=400, Height:=300)
    End If
End Sub

用途
→「名前をつけるほどではないが、特定位置のグラフだけ更新したい」


5. 実務で使える:重複防止の最適パターン(テンプレート)

最も実務で安定するのは “名前つき+存在すれば更新” のパターンです。

Sub CreateChart_NoDuplicate()
    Dim ws As Worksheet
    Set ws = Sheet1

    Dim chtObj As ChartObject
    Dim exists As Boolean: exists = False

    '既存グラフ検索
    For Each chtObj In ws.ChartObjects
        If chtObj.Name = "DynamicChart" Then
            exists = True
            Exit For
        End If
    Next chtObj

    'なければ作る
    If Not exists Then
        Set chtObj = ws.ChartObjects.Add(Left:=250, Top:=100, Width:=400, Height:=300)
        chtObj.Name = "DynamicChart"
    End If

    'データ更新
    Dim last As Long
    last = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

    chtObj.Chart.SetSourceData ws.Range("A1:B" & last)
End Sub

重複しない・高速・管理しやすい
という3拍子揃った方法です。


6. まとめ

方法目的特徴
全削除 → 再作成常に1つの最新グラフだけ必要最も簡単・確実
名前で管理して特定のグラフだけ削除/更新複数グラフを使う環境実務で最も推奨
位置で判別する名前管理できない場合座標が一致すれば再利用
事前チェックして更新のみ最も高速で効率的余計な描画が減る

コメント

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