【ExcelVBA・マクロ】セルの範囲やシートを画像として保存する方法|CopyPicture・チャートを使ったPNG出力【コピペOK】

ExcelVBA

Excelの表をブログやマニュアル、チャットに貼り付けたいとき、いちいちスクリーンショットを撮っていませんか。VBAを使えば、指定したセル範囲やシート全体をPNG画像として自動で書き出すことができます。この記事では、Range.CopyPictureとチャートオブジェクトを組み合わせて画像出力する方法を、実務で使えるサンプルコード付きで解説します。

スポンサーリンク
スポンサーリンク

なぜチャートを経由するのか

VBAには「セル範囲を直接PNGファイルとして保存する」専用メソッドが存在しません。そこで使われるのが、次のような手順です。

  1. Range.CopyPictureでセル範囲を画像としてクリップボードにコピーする
  2. 一時的に作成したChartObjectにその画像を貼り付ける
  3. Chart.Exportメソッドで画像ファイルとして書き出す
  4. 不要になったチャートを削除する

やや遠回りに見えますが、Chart.ExportはPNG・JPG・GIFなど複数の画像形式に対応しているため、この方法が定番のテクニックとして広く使われています。

セル範囲を画像として保存する方法

まずは基本形として、指定したセル範囲をPNG画像として保存するコードです。

Sub ExportRangeAsImage()
    Dim rng As Range
    Dim tempChart As ChartObject
    Dim savePath As String

    Set rng = ThisWorkbook.Worksheets("Sheet1").Range("A1:D10")
    savePath = ThisWorkbook.Path & "\range_export.png"

    rng.CopyPicture Appearance:=xlScreen, Format:=xlBitmap

    Set tempChart = ThisWorkbook.Worksheets("Sheet1").ChartObjects.Add( _
        Left:=rng.Left, Top:=rng.Top + rng.Height + 20, _
        Width:=rng.Width, Height:=rng.Height)

    tempChart.Chart.Paste
    tempChart.Chart.Export Filename:=savePath, FilterName:="PNG"

    tempChart.Delete

    MsgBox "画像を保存しました: " & savePath
End Sub

ChartObjects.Addで一時的な空のグラフ枠をシート上に作成し、そこに画像を貼り付けてからExportで書き出し、最後にDeleteでグラフ枠を削除しています。実行後もシートの見た目は変わらず、range_export.pngというファイルだけが作成されます。

シート全体を画像として保存する方法

セル範囲の代わりにUsedRange(データが入力されている範囲)を指定すれば、シート全体を1枚の画像として保存できます。

Sub ExportSheetAsImage()
    Dim ws As Worksheet
    Dim rng As Range
    Dim tempChart As ChartObject
    Dim savePath As String

    Set ws = ThisWorkbook.Worksheets("Sheet1")
    Set rng = ws.UsedRange
    savePath = ThisWorkbook.Path & "\" & ws.Name & ".png"

    rng.CopyPicture Appearance:=xlScreen, Format:=xlBitmap

    Set tempChart = ws.ChartObjects.Add( _
        Left:=0, Top:=rng.Height + 20, Width:=rng.Width, Height:=rng.Height)

    tempChart.Chart.Paste
    tempChart.Chart.Export Filename:=savePath, FilterName:="PNG"

    tempChart.Delete

    MsgBox "シート全体を画像として保存しました: " & savePath
End Sub

シート内のデータ量が多い場合は画像サイズも大きくなるため、必要な範囲だけをRangeで明示的に指定する方法と使い分けるとよいでしょう。

保存先フォルダを自動作成する

保存先フォルダが存在しない場合、Chart.Exportはエラーになります。Dir関数でフォルダの有無を確認し、なければMkDirで作成してから保存する処理を入れておくと安全です。

Sub EnsureFolderExists(ByVal folderPath As String)
    If Dir(folderPath, vbDirectory) = "" Then
        MkDir folderPath
    End If
End Sub

Sub ExportRangeToSpecificFolder()
    Dim rng As Range
    Dim tempChart As ChartObject
    Dim folderPath As String
    Dim savePath As String

    folderPath = ThisWorkbook.Path & "\Export"
    EnsureFolderExists folderPath

    Set rng = ThisWorkbook.Worksheets("Sheet1").Range("A1:D10")
    savePath = folderPath & "\range_export.png"

    rng.CopyPicture Appearance:=xlScreen, Format:=xlBitmap

    Set tempChart = ThisWorkbook.Worksheets("Sheet1").ChartObjects.Add( _
        Left:=rng.Left, Top:=rng.Top + rng.Height + 20, _
        Width:=rng.Width, Height:=rng.Height)

    tempChart.Chart.Paste
    tempChart.Chart.Export Filename:=savePath, FilterName:="PNG"

    tempChart.Delete

    MsgBox "画像を保存しました: " & savePath
End Sub

実務での活用例:複数シートをまとめて画像化する

複数のシートを一括でPNG画像化したい場合は、Worksheetsをループしてシートごとに処理します。

Sub ExportAllSheetsAsImages()
    Dim ws As Worksheet
    Dim rng As Range
    Dim tempChart As ChartObject
    Dim folderPath As String
    Dim savePath As String

    folderPath = ThisWorkbook.Path & "\Export"
    If Dir(folderPath, vbDirectory) = "" Then
        MkDir folderPath
    End If

    Application.ScreenUpdating = False

    For Each ws In ThisWorkbook.Worksheets
        Set rng = ws.UsedRange
        If WorksheetFunction.CountA(rng) > 0 Then
            savePath = folderPath & "\" & ws.Name & ".png"

            rng.CopyPicture Appearance:=xlScreen, Format:=xlBitmap

            Set tempChart = ws.ChartObjects.Add( _
                Left:=0, Top:=rng.Height + 20, Width:=rng.Width, Height:=rng.Height)

            tempChart.Chart.Paste
            tempChart.Chart.Export Filename:=savePath, FilterName:="PNG"

            tempChart.Delete
        End If
    Next ws

    Application.ScreenUpdating = True

    MsgBox "全シートの画像化が完了しました。"
End Sub

WorksheetFunction.CountAでシートにデータが入っているかを確認し、空のシートはスキップするようにしています。シート数が多いブックでも、この処理でまとめて画像化できます。

まとめ

  • VBAには範囲を直接画像保存するメソッドがなく、ChartObjectを経由してChart.Exportで書き出すのが定番の方法
  • Range.CopyPictureでクリップボードにコピーし、一時的なチャートに貼り付けてからExportする
  • UsedRangeを使えばシート全体を1枚の画像として保存できる
  • 保存先フォルダはDir関数で存在確認し、なければMkDirで作成しておくとエラーを防げる
  • 複数シートをまとめて画像化する場合はWorksheetsをループして同じ処理を繰り返す

資料作成やブログ執筆、チャットでの共有など、Excelの表を画像として使いたい場面は意外と多いものです。ぜひこのマクロを活用して作業を効率化してみてください。

スポンサーリンク
スポンサーリンク
ExcelVBA
シェアする
いがぴをフォローする

コメント

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