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

このQ&Aのポイント
  • Excel2007のVBAを使用して、セル範囲を画像として保存する方法について教えてください。
  • 指定したシートの指定したセル範囲をPNG形式で保存する方法について教えてください。
  • グラフの場合と同様に、簡単かつ短時間で指定したセル範囲を画像として保存する方法を知りたいです。
回答を見る
  • ベストアンサー

Excel2007のVBAで、セル範囲を指定し

Excel2007のVBAで、セル範囲を指定して画像として保存したいです。 たとえば、 Worksheets("Sheet1").Range("A1:B10").CopyPicture xlScreen, xlBitmap Worksheets("Sheet2").Paste とすれば、別のシートに指定した範囲を画像にすることはでき、 さらにこれを、 With ActiveWorkbook.PublishObjects.Add(xlSourceSheet, "C:\test.html", _ "Sheet2", "", xlHtmlStatic, "image", "") .Publish (True) .AutoRepublish = False End With とすれば、画像を指定した場所に保存することはできると思います。 ただ、これだと無駄な処理をしているような気がしますし、実際時間も数秒必要です。 これが、グラフだと Worksheets("Sheet1").ChartObjects("グラフ1").Chart.Export Filename:="C:\graph.gif", FilterName:="gif" のように簡単に、しかも短時間で出来ます。 できれば、上記グラフのように、指定したSheetの指定したセル範囲を画像として指定した場所にPNGにて保存したいです。 どなたかご教授いただければ幸いです。

質問者が選んだベストアンサー

  • ベストアンサー
  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.4

苦肉の策の中抜き版です。ConvCLSIDに言及してありませんでしたが、コピーされましたでしょうか。 当方では、下記により、Sub testを実行して、選択セルをpngで保存できました。 Private Declare Function IsClipboardFormatAvailable Lib "user32.dll" ( _ Private Declare Function OpenClipboard Lib "user32.dll" ( _ Private Declare Function GetClipboardData Lib "user32.dll" ( _ Private Declare Function CloseClipboard Lib "user32.dll" () As Long Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" ( _ Private Declare Function GdiplusStartup Lib "gdiplus.dll" _ Private Declare Sub GdiplusShutdown Lib "gdiplus.dll" (ByVal token As Long) Private Declare Function GdipCreateBitmapFromHBITMAP Lib "gdiplus.dll" _ Private Declare Function GdipDisposeImage Lib "gdiplus.dll" _ Private Declare Function GdipSaveImageToFile Lib "gdiplus.dll" _ Private Declare Function CLSIDFromString Lib "ole32" _ ' // Types ---------------------------------------------------------- Private Type PictDesc '略 End Type Private Type Guid '略 End Type Public Enum GDIPlusStatusConstants '略 End Enum Private Type UUID '略 End Type Private Type GdiplusStartupInput '略 End Type Private Type EncoderParameter '略 End Type Private Type EncoderParameters '略 End Type ' // Constants ------------------------------------------------------ Private Const CF_BITMAP As Long = 2 Private Const CF_PALETTE As Long = 9 Const CLSID_PNG = "{557CF406-1A04-11D3-9A73-0000F81EF32E}" Sub test() Dim myPicture As StdPicture Selection.Copy Set myPicture = CreatePictureFromClipboard Call SavePicturePng(myPicture, "c:\cells.png") End Sub ' // クリップボードのビットマップデータから Picture オブジェクトを作成 Public Function CreatePictureFromClipboard() As StdPicture '略 End Function Public Function SavePicturePng(ByVal PicObj As IPictureDisp, ByVal FName As String) As GDIPlusStatusConstants '略 End Function Private Function ConvCLSID(ByVal sGuid As String) As UUID '略 End Function

y_r_358
質問者

お礼

大変ご足労おかけしました。 なんの問題もなく出来上がりました。 これからの作業効率を考えると、感謝感謝です。 本当にありがとうございました。

その他の回答 (3)

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.3

#1,2です。 まず、 http://okwave.jp/qa/q2885043.html の、#2の、' // 標準モジュールから、 Public Function CreatePictureFromClipboard() As StdPictureの最後の、 End Functionまでを、コピーして、標準モジュールに貼り付けます。 次いで、 http://hpcgi1.nifty.com/MADIA/VBBBS2/wwwlng.cgi?print+200708/07080012.txt の「ここからコード」というところの次から、 名称 :SavePicturePngの最後の、End Functionまでを貼り付ける訳ですが、 最初に貼り付けたコードの下記の部分に、相当する部分は、それぞれ分類して貼り付けてください。 最初に貼り付けたコードの下に全部貼り付けてしまうと、エラーになってしまうと思います。 ' // Declareations -------------------------------------------------- ' // Types ---------------------------------------------------------- ' // Constants ------------------------------------------------------ 丸ごとコードを載せると、字数制限にとうてい収まりませんし、著作権上の問題も分からないので、控えておきます。 APIというのを用いて、Windowsの機能を使っています。関心を持たれたら、参考URLなどをご覧下さい。

参考URL:
http://www.excellenceweb.net/vba/api/what_windows_api.html
y_r_358
質問者

お礼

ご丁寧にありがとうございます。 書かれていることは、理解しているつもりですが上手く動きません。 私自身のスキルに問題があると感じております。 ありがとうございました。

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.2

#1です。 xl2010、WindowsXPsp3環境で動作確認しましたので、報告しておきます。 実行スピードはあっと言う間です。 (xl2007環境は無いものであしからず) 参考URLから、必要なパーツを、標準モジュールにコピペしてから、実行して下さい。 Sub test() Dim myPicture As StdPicture Selection.Copy Set myPicture = CreatePictureFromClipboard Call SavePicturePng(myPicture, "c:\cells.png") End Sub

y_r_358
質問者

お礼

ご回答ありがとうございます。 >必要なパーツを、標準モジュールにコピペしてから の意味が良くわからず、、、戸惑っていますが がんばってみます。 後ほど、ご報告いたします。

y_r_358
質問者

補足

試してみましたが、私には無理でした。 もしよろしければ、簡単なサンプルを作っていただけませんでしょうか。 厚かましいお願いですみません。

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.1

エクセルでセルをコピーすると、クリップボードには多数の種類のフォーマットでコピーされています。 拡張メタファイル、Picture、ビットマップ、テキスト等々。 ここから、簡単にPNGに変換する方法は存じません。 下記を組み合わせれば出来ると思います。 クリップボードのbitmapからPictureObject生成 http://okwave.jp/qa/q2885043.html 下記の様な使い方で、BMP形式では保存できます。 Sub test() Selection.Copy Call SavePicture(CreatePictureFromClipboard, "c:\cell.bmp") End Sub 残念ながら、SavePictureではBMP(またはEMF)形式でしか保存できないそうなので、 PictureObjectからPNG形式で保存 http://hpcgi1.nifty.com/MADIA/VBBBS2/wwwlng.cgi?print+200708/07080012.txt なお、拡張メタファイルEMF形式での保存なら下記で出来てしまいます。 Vix等のフリーソフトで読み込んでPNGに変換という事もできますが、多量に処理するので無ければご要望には添いませんね。 Const CF_ENHMETAFILE = 14 Private Declare Function OpenClipboard Lib "user32" (ByVal hWndNewOwner As Long) As Long Private Declare Function CloseClipboard Lib "user32" () As Long Private Declare Function GetClipboardData Lib "user32" (ByVal uFormat As Long) As Long Private Declare Function CopyEnhMetaFile Lib "gdi32" Alias "CopyEnhMetaFileA" (ByVal hemfSrc As Long, ByVal lpszFile As String) As Long Private Declare Function DeleteEnhMetaFile Lib "gdi32" (ByVal hEmf As Long) As Long Sub clip2emf() Dim hSrcMetaFile As Long Dim hFileMetaFile As Long Selection.Copy If OpenClipboard(0) Then hSrcMetaFile = GetClipboardData(CF_ENHMETAFILE) hSrcMetaFile = CopyEnhMetaFile(hSrcMetaFile, vbNullString) CloseClipboard End If If hSrcMetaFile = 0 Then MsgBox "emf取得に失敗" Exit Sub End If hFileMetaFile = CopyEnhMetaFile(hSrcMetaFile, "c:\test.emf") DeleteEnhMetaFile hFileMetaFile DeleteEnhMetaFile hSrcMetaFile End Sub

関連するQ&A

  • VBAでのセル範囲指定について

    お世話になります。 私が分からないのは、VBAでのセル範囲指定なのですが、 例えば、シートにデータが有、そのデータの1行目は見出しなので 2行目からデータが入っているセルまでの範囲を指定、コピーして 隣のシートに貼付したいのですが、そのデータの入力される範囲が 毎回違います。「CurrentRegion.Select」としてしまうと、1行目 の見出しまでも範囲指定されてしますので、どうやったら良いのか どなたかお教え頂きたく宜しくお願い申し上げます。

  • VBAで、Excelの選択範囲をWeb形式で保存する方法

    ExcelのVBAで選択範囲(I2:V44)をWeb形式(htm)で保存するプログラムをテキストから写して試してるんですけど(下記貼り付け)、うまく動きません。 どこがおかしいかどなたか教えてくれませんか。どこかのHPでもかまいません。どうぞよろしくお願いします。 Private Sub CmbUPDATE_Click() Set wPage = ActiveWorkbook.PublishObjects.Add _ (SourceType:=xlSourceRange, _ Filename:="C:\Documents and Settings\My Documents\graph1.htm", _ Sheet:="sheet1", _ Source:="I2:V44") 'Title:="GRAPH") wPage.Publish True End Sub

  • Excel:指定したデータ範囲を可変的に取得する方法。

    Excel:指定したデータ範囲を可変的に取得する方法。 現在、個人の労働時間の昨年度と今年度を月ごとに比較するグラフを作っています。 一人ひとりのグラフを新規シートに追加していくのですが、人数が多いのでこれをマクロに したいのです。 【sheet1の表(元データ)】 (A) (B) (C) (D) (E) (F) (G) (P) (1)      1月  2月  3月  4月・・・12月 (2) 1 社員A 20期 20 15.5 22.75 12 27.2 (3)    21期 12 12 26 10 13 (4) 2 社員B 20期 : : : : : (5)    21期 (6) 3 社員C 20期 (7)    21期 (8) 4 社員D 20期      21期 : : 【作りたいマクロ】 例)A2のセル[1]を選択して実行すると、社員Aのデータ範囲(B2~P3までと一行目の月単位行)を グラフ化し、新規シートに追加する。 ・上記例を他社員のデータ範囲にも使えるようにデータ範囲を可変的にしたい。 ・できればそのマクロをボタン化して、A列にそれぞれボタンを挿入したい。 ※A4[2]セルのボタンを押すと、社員Bのグラフが作成される。 下記にわかるところまでのコードを記します。(vba初心者で拙いコードですがお許しください) Sub Macro1() Range(Cells(1, 2), Cells(1, 18)).Select '1月~月平均の列 Range(Cells(2, 2), Cells(3, 18)).Select 'グラフ化する範囲 Cells(2, 2).Activate ActiveSheet.Shapes.AddChart.Select 'グラフ追加 'グラフデータの範囲設定 ActiveChart.SetSourceData Source:=Worksheets("Sheet1").Range(Worksheets("Sheet1").Cells(1, 2), Worksheets("Sheet1").Cells(1, 18)) ActiveChart.SetSourceData Source:=Worksheets("Sheet1").Range(Worksheets("Sheet1").Cells(2, 2), Worksheets("Sheet1").Cells(3, 18)) ActiveChart.ChartType = xlColumnClustered ActiveChart.ApplyLayout (5) ActiveChart.Location Where:=xlLocationAsNewSheet, name:="グラフ" ActiveSheet.Move after:=Worksheets("Sheet1") Sheets("Sheet1").Select End Sub 上記のコードだと範囲指定しているため社員Aのグラフしか作成できません。 範囲を可変的にするために変数を使おうと考えているのですが、 どのように書いてよいのか混乱してしまって・・・ 皆様にご教授願いたいと思いましてこちらに質問させていただきました。 長文および読み辛くなってしまい申し訳ありません。 どうかよろしくお願いいたします。

  • 2本ある折れ線グラフの範囲をVBAで更新したい

    2本ある折れ線グラフの範囲をVBAで更新したいと考えております。 excel2003を使っています。 グラフ1の中に系統がひとつなら以下の内容でうまくいきますが、2本ある場合どうすれば 良いか分からず困っております。 Sub サンプル() Dim myPicture As StdPicture Dim buf As String Dim myR With Worksheets("Sheet1") myR = Application.WorksheetFunction.Count(Worksheets("Sheet1").Range("A5:A100")) End With row1 = "5" row2 = myR col1 = "A" Sheets("Sheet2").Activate ActiveSheet.ChartObjects("グラフ 1").Activate ActiveChart.ChartArea.Select ActiveChart.SetSourceData Source:=Sheets("Sheet1").Range(col1 & row1 & ":" & col1 & row2 + 4), PlotBy:=xlColumns End Sub 系統を増やした場合の書き方をどなたかお教え頂けませんか。 どうぞ、よろしくお願い致します。

  • 数式を使ったセルの範囲指定について(excel 2003)

    数式を使ったセルの範囲指定について(excel 2003)  こんにちは     タイトルの意味が解りづらく申し訳ありません。 excelで数式の結果を用いてセルの範囲指定を行いたいのですが、 範囲指定方法についてご存知の方いらっしゃれば、ご教授頂ければ と思います。  例) =C(E14+15)   (←実際にはうまくいきませんでした。) のようにセルの指定をする際、数式の結果を反映させたいと 考えています。  よろしくお願い致します。

  • Excel2010 VBA グラフのExport

    教えてください。 Excelのシートに表示しているグラフをGIF形式で保存するマクロを組んでいます。 -------------- Dim myRess As Variant ~省略~ myRess = Worksheets("chart_area").ChartObjects("グラフ " & Sheets("master").Range("e" & gyo)) .Chart.Export(chart_Path & Sheets("master").Range("d" & gyo) & "1.gif", "gif", False) -------------- こちらのサイトを参考に作成しました。 http://itpro.nikkeibp.co.jp/article/COLUMN/20100922/352255/ Excel2002の時は問題なく動いていましたが、 Excel2010(64bit)にバージョンアップしたら動かなくなりました。 少し聞いてみたのですが、 Excel2007以降ではExcel2003以前で使用されていたメソッドの一部が隠しメソッドとなっています。 との回答でしたが、どこを修正したらいいのか分かりませんでした。 どのように修正したら動くのか教えてください。 よろしくお願いします。

  • Excel2007で行番号を指定してセル範囲を

    Excel2007で行番号を指定してセル範囲を抜き出したいです。 sheet2のF8に行番号を入れてsheet3のセル範囲(C:T)の値とセル範囲(AB:AS)の値を取り出して sheet2の(A2:AQ2)に入れます。目で分かりやすい様に背景色か色線で4等分したいです。 よろしくお願いいたします。

  • ExcelのVBAの保護をかけた時のグラフについて教えてください。

    グラフにタイトルを設定した後、保護をかけると「ChatクラスのHasTitleプロパティを設定できません」といわれてしまい、.HasTitle=Trueで止まってしまいました。シートの保護をかけても動くようにしたいのですが、どうしたらよいのでしょうか。 (保護しなければ通常に動きます。) 'グラフをオブジェクトで配置 set chartObj=worksheets("Sheet1").ChartObjects.Add(200,0,300,200) chartObj.Chart.SetSourceData Worksheets("Sheet1").range(range("b4").End(xlDown),ActiveCell.end(xlToright)) 'タイトルをつける with worksheets("Sheet1").ChartObjects(1).Chart .HasTitle=True .ChartTitle.Text="タイトル" End with 保護をかけてもグラフの作成ができるのに、タイトル部分で止まってしまうのはなぜでしょうか。 よろしくお願い致します。

  • VBA 範囲指定について

    VBAでシートAの範囲A1:B200までをコピーして シートBの範囲A1:B200にコピペしたいのですが、 範囲のB200のみ変動する可能性があるので、その変動に対応出来るようにしたいです。 例) Worksheets("A").Activate PD = Worksheets("入院費用一覧").Range("A1:B〇〇〇").Value Windows("B").Activate Worksheets("B").Range("A1:B〇〇〇").Value = PD B〇〇〇の所に変動できる数値を関数でC1に行数指定して対応できないかと考えていますが、何かいい方法有りますでしょうか。 宜しくお願い致します。 ※VBAあまり詳しくはありません。

  • VLOOKUPのセル範囲指定

    VLOOKUP(検索値,セル範囲,列番号,検索型) のうち、セル範囲を別の色々なワークシート上のセル範囲として指定したい と思っています。 ワークシート名を書いたセルをT()で参照すればできるかと思ったのですが、 エラーになってしまいました。ワークシートが少数であればIFをつかって 場合わけをしても良いのですが、そこそこ数がある上にこれから増えるかも しれないので、どうにかワークシート名を簡単に変更・指定できる方法が ないか悩んでいます。 なにか知恵があれば教えてください。 よろしくお願いします。

専門家に質問してみよう