はじめに
SI 業界で度々話題になるExcelスクショ問題について、今年も新人さんが言及し始めたようなので、知見を残そうと思います。2016 年度版です。
対処例
2016 年現在、さすがにエクセルスクショ職人のパソコンも Windows7 が主流かと思います。ただしフリーソフトの導入は厳禁かと思います。
では対処例を。
Excel といえば VBA ですが、今回は Powershell を使います。
とりあえず以下の様なスクリプトを用意しました。Create-ExcelEvidence.ps1
など適当な名前で保存してください。
※最新のソースコードは github から取得してください。
Create-ExcelEvidence.ps1
param($Path)
function logger($msg) {
$msg = (Get-Date -Format "u") + "`t" + $msg
Write-Host $msg
}
logger "Processing..."
Add-Type -AssemblyName System.Windows.Forms
$Excel = New-Object -ComObject Excel.Application
$Excel.Visible = $true
logger "Connected to Excel."
if ($path) {
try {
$Excel.Workbooks.Open($Path) > $null
logger "Open $Path"
} catch {
logger "File Open Failed. => $Path"
$Excel.Quit()
return;
}
} else {
$Excel.Workbooks.Add() > $null
}
# qiita bug?
# [System.Windows.Forms.Clipboard]::SetDataObject("")
# logger "Clear Clipboard."
while($true){
if ([system.windows.forms.Clipboard]::ContainsImage()) {
$Excel.ActiveCell.Value2 = Get-Date -Format "\'yyyy/MM/dd HH:mm:ss"
$Excel.ActiveCell.Offset(1, 0).Select() > $null
$Excel.ActiveSheet.Paste()
$Graphic = $Excel.Selection
$Offset = $Excel.ActiveCell.Top + $Graphic.Height
measure-command {
$Caption = $Excel.Caption
$Excel.Caption = "Pasting..."
$cell = $Excel.ActiveCell
while ($cell.Top -lt $Offset) {
$cell = $cell.Offset(5,0) # speed up
}
while ($cell.Top -gt $Offset) {
$cell = $cell.Offset(-1,0) # rewind...
}
$cell.Offset(2,0).Select() > $null
$Excel.Caption = $Caption
} | % { logger $_.TotalMilliseconds.toString("#####.000ms").padleft(10) }
[System.Windows.Forms.Clipboard]::SetDataObject("")
}
if ($Excel.Visible -eq $False) {
logger "Excel Closed."
break
}
Start-Sleep -Milliseconds 100
}
logger "Terminating..."
Powershell
はデフォルトでスクリプト実行が制限されていますので、使い方にはコツが必要です。
コマンドプロンプトで以下のように。
C:> PowerShell -sta -ExecutionPolicy Bypass .\Create-ExcelEvidence.ps1
長いコマンドにアレルギーがある人でなければ、上記の方法で問題ないはずです。
ただ、外部から操作しているせいか内側のループがやたら遅いです。スクショ貼るごとに 1~2 秒は CPU 1 コアを占有しているようです。スペックの低いパソコンだと問題になるかもしれません。
おわりに
知見を残すだけのつもりが、普通に使えそうなスクリプトができてしまった。