技術関連の覚書

案件でやったり自宅で試したことの覚書

Excelマクロでスクショを取る

自分の仕事は主にSESなので案件によってはテストでExcelにスクショを貼り付けて提出するということを未だにやってるところに当たることがある。 できればそういう作業はやりたくないのでツール化すればよいのだけど(本当はもっと有効なテストをしてスクショ貼りなんてものは法律で禁止してもいいと思ってる) 現状、やらざるをえないところはまだ多いです。

スクショの対象となるツールがブラウザだったり、他のアプリケーションだったりと様々なので完全に一般化することは難しいけど、だいたいこのやり方でできるのではないかということをやってみました。

そして、Excelマクロにした理由は

  • 他のツール(PythonPerlなど)は入れてはいけないところも多い

  • PowershellだとOSの設定によってはファイルから実行できない場合がある

  • Excelにスクショ貼り付けるのでこの場合Excelは確実にインストールされている

送信データの管理などもやりやすいこともあり本来の使い方ではないけれどもExcelを自動スクショ撮りツールにしてみました。

流れは

  1. エビデンスを貼り付けるExcelを作成する

  2. 実行するツールを起動

  3. 何かしらのパラメータを入力項目に設定する

  4. 実行ボタンを押す

  5. 結果が出たらスクショをする

  6. 結果の内容に応じてスクロールして全体を貼り付ける

  7. エビデンスExcelを保存して終了

エビデンスExcelの作成 フォーマットが決まっていればテンプレートを作ってそこに貼り付けて名前を付けて保存する方法が良いと思います。

実行ツールの起動

Dim excel As Workbook

Application.ScreenUpdating = False ' Excelの画面の変化を表示をしないことで高速に実行できる
Set excel = WOrkbooks.Open("template.xlsx")
' テスト用のツール起動
' テスト実施
' スクショコピペ
Application.DisplayAlerts = False ' 上書きする場合にダイアログを出さないようにする
excel.SaveAs "テスト結果.xlsx" ' 提出するファイル名に合わせてください
Application.DisplayAlerts = True ' 上書き時のダイアログ設定を元に戻す
excel.Close
Application.ScreenUpdating = True ' Excelの表示を元に戻す

テスト用ツールの起動

Dim rc As Long

rc = Shell(テストツール, vbMaximizeFocus) ’最大化して起動する。rcはツールにフォーカスする時にこの値を使う
’ この時点ではツールにフォーカスされている。
' 値の設定などはSendKeysを使って値を送ったり、タブ移動などを行うSendKeys "{TAB}" タブ移動
’ SendKeys "{ENTER}" エンターキー押下
' SendKeys "文字列" 文字列を送る
' SendKeys "{UP}" ↑ボタン押下
' SendKeys "{^a}" ctrl+a ^はctrlキーの同時押しになる
' SendKeys "%{F4}" Alt+F4 %はAltキーの同時押しになる、{F数字}はファンクションキー
’ SendKeysでツール上の操作をしたり、Ctrl+AとCtrl+Cでテキストのコピペができたりする
’ 当然、SendKeysで送るのはツールだけでなくエビデンスのExcelにも送るのでフォーカスはExcelとツールを何度も往復することになる
’ Excelへは上記のコードで定義したexcelでexcel.Worksheets("シート名").cells(2,3) = クリップボードの値
' などとすればテキストは貼り付けられる
' 画面のスクショは次のコードで
AppActivate rc ' ツールにフォーカスする
SendKeys "%{F4}" ' Alt+F4でツールを終了する

スクショの貼り付け

ここを参照して作りました。 ExcelVBAでスクリーンショットを取る方法 - Qiita keybd_eventはOSの環境で64ビットか32ビットどちらかを使います。

まずはスクショを撮るためのサブルーチンを定義する。画面を最大化してあるが、ツールバーが入ると嫌なのでAlt+PrtScでツールだけをスクショする。 SendKeysでも送れるようだけども実際にやってみるとうまく行かなかったのでこちらを使いました。 ライブラリの呼び出しについてはここでは書かないので

' こちらは64ビット版、32ビットの場合は上記URLを参照
Private Declare PtrSafe Sub keybd_event Lib "user32" ( _
    ByVal bVk As Byte, _
    ByVal bScan As Byte, _
    ByVal dwFlags As Long, _
    ByVal dwExtraInfo As Long _
        )

Public Sub アクティブ画面を撮る()
    keybd_event &HA4, 0&, &H1, 0& ' &HA4がAltキー、&H1キーを押す
    keybd_event vbKeySnapshot, 0&, &H1, 0& ' vbKeySnapshotがPrtScキー番号は&H2Cらしい
    keybd_event vbKeySnapshot, 0&, &H1 Or &H2, 0& 'PrtScキー &H2でキーを放す
    keybd_event &HA4, 0&, &H1 Or &H2, 0& ' Atlキーを放す
End Sub

これを組み合わせることで大体のスクショはとれるはず