スポンサーリンク

画面のスクリーンショットを,Excelブック内に自動的に保存するバッチ


画面のスクリーンショット(キャプチャ)を,バッチで自動的に取得しよう。

そしてExcelブック内に,自動的に保存する。


開発プロジェクトで,画面定義書などのドキュメントを効率的に作成するために利用可能。


使う技術は

  • Excel VBA
  • WSH

の2点。


(1)Excel側でキャプチャするコード

まずExcel側のVBAマクロ。

標準モジュールの中の「Module1」に,下記の関数を作成。

Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, _
    ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)

Private Const KEYEVENTF_EXTENDEDKEY As Long = &H1
Private Const KEYEVENTF_KEYUP As Long = &H2
Private Const fKEYDOWN = KEYEVENTF_EXTENDEDKEY
Private Const fKEYUP = KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP


' 現在のスクリーンキャプチャ画像を,特定のシートに貼り付けます。
Sub my_cap(sheet_name)
    ' シート内の全画像を削除
    Sheets(sheet_name).Activate
    For Each pic In ActiveSheet.Pictures
        pic.Delete
    Next

    ' キャプチャ実行
    keybd_event vbKeySnapshot, 0&, fKEYDOWN, 0&
    keybd_event vbKeySnapshot, 0&, fKEYUP, 0&
    
    '貼り付け処理
    Sheets(sheet_name).Activate
    Range("A1").Select
        'SendKeys "+(^V)", True
    ActiveSheet.Paste

End Sub

' PrintScreenの自動実行について
' http://www.asahi-net.or.jp/~zn3y-ngi/YNxv9d342.html


このマクロが実行されると,

  • (PrintScreenキーを押下したのと同じ効果で)スクリーンショットが取得され,
  • 指定したシートのA1セルに左端が来るように,キャプチャ画像がペーストされる。

したがって,このマクロを

  • 外部のバッチから,
  • Excelを非表示のままで

実行すればよい。

(2)Excelのマクロを外部から呼び出すバッチ

そのために,以下のバッチを作成。(cap.jsなどの名前で保存)


// 設定項目(保存対象となるExcelブックのパス)
var file_name = "cap.xlsm";
var file_path = "D:\\temp\\" + file_name;

// excelを陰ながら起動
var excel = WScript.CreateObject("Excel.Application");
var book = excel.Workbooks.Open( file_path );
	//excel.Visible = true;

// キャプチャ実行
excel.Run( file_name + "!my_cap", "Sheet1" );

// ブックを保存
excel.DisplayAlerts = false; // 既存ファイルがあっても上書きする
book.SaveAs( file_path );


// Excelを閉じて終了
excel.Quit();
excel = null;
WScript.Echo("キャプチャしました。"); 

あとは,

  • このバッチをダブルクリックするか,
  • もしくは,コマンドラインから cscript cap.js として実行する。


こうすれば,ペイントなどのツールを使わずに「コマンドラインからキャプチャ」できる。

補足:別の方法

以前,古い方法として,「ペイント」の自動化によりキャプチャを保存する手を掲載した。

画面をコマンドラインからキャプチャする方法 (WSHバッチでPrintScreen)
http://language-and-engineering.hatenablog.jp/entry/20081121/1227203100


上記のエントリでは,やはり,Excelの機能をうまいこと利用している。

WSHからExecuteExcel4Macroを使い,user32.dllを呼び出して,キーボードイベントを発生させている。



今回のエントリでは,ExecuteExcel4Macroを使わずに,Excel内部でuser32.dllを読み込んでいる。

結局,キャプチャのためにExcelを使っている。



どうしてExcelが必要になるかというと,

WSHには制限がいろいろあり,PrintScreenの押下を自動化できないからだ。



そこで,発想を変える。

WSHに制限があるのは仕方ない。

ならば,かわりに制限のないアプリケーション基盤を見つけて,WSHからコールして利用すればよい。


そのために最適なのは,Excel VBAではなかろうか?

魅力は,

  • Windows APIを自在に組み込めるプログラミング環境であること。
  • ドキュメントという成果物に対して,非常に近いポジションに存在すること。

など。


特に,前者はでかい。

わざわざC言語で,バッチ呼び出し専用のDLLを作ったりしなくて済むのだ。


※わざわざバッチ用のDLLを自作している例としては,下記のエントリを参照。

コマンドラインからマウスを操作する方法 (rundll32.exeで動くDLLの作成法)
http://language-and-engineering.hatenablog.jp/entry/20081117/1226943698


「WSHから,あるいはバッチから,Windowsのディープな部分を操作したい」という場合,

このようにExcel VBAを経由するのが最も手っ取り早いかもしれない。


ついでに言うと,Web屋がWindowsプログラミングに足を踏み入れる第一歩としても,やはりExcel VBAが最適なのでは。