業務効率化

PAD:ファイルOpen判断フロー

MS系ファイル(ワード、エクセル、パワーポイント)の他、PDFやテキストファイル等を含めてファイルが開いたか判断するPADフローです。空の名前で存在するインスタンスを削除することで、開いているファイル数を適切に判断しています。これによりMS系ファイルに限らず、ファイルを開いた後に処理実行するPowerAutomateフロー作成ができます。

記事の内容

・挙動

・コード

・ポイント機能

挙動

PSを実行し、フロー冒頭時のファイル数、フロー中実行後のファイル数をループで処理し、ループの中でファイル数が増えたかどうかを判断します。ファイルが開かれると変数にTrueが代入されるという流れです。

ループ中ファイル数が増加した場合はFilesOpen変数にTrueが代入されます。これにより、あるアプリからファイルを開くまで待つようなフローを構築することができます。

コード

➤コードはこちら
SET Timecnt TO 0
SET FilesOpen TO 0
IF IsEmpty(Filecount) THEN
    Scripting.RunPowershellScript.RunPowershellScript Script: $'''# 合計カウント用変数
$totalCount = 0

# --- Excel ---
$excel = [Runtime.InteropServices.Marshal]::GetActiveObject(\"Excel.Application\") 2>$null
if ($excel -ne $null) {
    $excelCount = $excel.Workbooks.Count
    $totalCount += $excelCount
}

# --- Word ---
$word = [Runtime.InteropServices.Marshal]::GetActiveObject(\"Word.Application\") 2>$null
if ($word -ne $null) {
    $wordCount = $word.Documents.Count
    $totalCount += $wordCount
}

# --- PowerPoint ---
$powerpoint = [Runtime.InteropServices.Marshal]::GetActiveObject(\"PowerPoint.Application\") 2>$null
if ($powerpoint -ne $null) {
    $powerPointCount = $powerpoint.Presentations.Count
    $totalCount += $powerPointCount
}

# --- PDF ---
# Adobe Reader, Edge, Chromeなど、PDFを開いている可能性のあるプロセスをチェック
$pdfProcesses = @(\"AcroRd32\", \"Acrobat\", \"msedge\", \"chrome\")
$pdfCount = 0
foreach ($procName in $pdfProcesses) {
    $proc = Get-Process -Name $procName -ErrorAction SilentlyContinue
    if ($proc) {
        # プロセス名によってPDF判定を強化したければ、ウィンドウタイトルをチェック
        $titles = ($proc | Where-Object { $_.MainWindowTitle -match \'\\.pdf\' }).Count
        $pdfCount += $titles
    }
}
$totalCount += $pdfCount

# --- TXT ---
# メモ帳(notepad)で開かれているウィンドウ数を数える
$txtCount = (Get-Process notepad -ErrorAction SilentlyContinue | Where-Object { $_.MainWindowTitle -match \'\\.txt\' }).Count
$totalCount += $txtCount

# --- 結果出力 ---
Write-Output $totalCount
''' ScriptOutput=> Filecount
END
SET Filecount2 TO Filecount
# エクセル起動時、タスクマネージャーに一つのエクセルプログラム(タイトルなし)がある場合エクセル数が0となりいくら開いても0のままになる。下記PSスクリプト実行することで、エクセルプログラムを一つのみとして実行させる
Scripting.RunPowershellScript.RunPowershellScript Script: $'''# 対象アプリケーションのプロセス名リスト
$apps = @(\"EXCEL\", \"WINWORD\", \"POWERPNT\")

foreach ($app in $apps) {
    # 対象アプリケーションのプロセスを取得
    Get-Process -Name $app -ErrorAction SilentlyContinue | Where-Object { $_.MainWindowTitle -eq \"\" } | ForEach-Object {
        Write-Output \"終了対象: $($app) プロセス ID $($_.Id)\"
        Stop-Process -Id $_.Id -Force
    }
}
'''
LOOP WHILE (Filecount) >= (Filecount2)
    Scripting.RunPowershellScript.RunPowershellScript Script: $'''# 合計カウント用変数
$totalCount = 0

# --- Excel ---
$excel = [Runtime.InteropServices.Marshal]::GetActiveObject(\"Excel.Application\") 2>$null
if ($excel -ne $null) {
    $excelCount = $excel.Workbooks.Count
    $totalCount += $excelCount
}

# --- Word ---
$word = [Runtime.InteropServices.Marshal]::GetActiveObject(\"Word.Application\") 2>$null
if ($word -ne $null) {
    $wordCount = $word.Documents.Count
    $totalCount += $wordCount
}

# --- PowerPoint ---
$powerpoint = [Runtime.InteropServices.Marshal]::GetActiveObject(\"PowerPoint.Application\") 2>$null
if ($powerpoint -ne $null) {
    $powerPointCount = $powerpoint.Presentations.Count
    $totalCount += $powerPointCount
}

# --- PDF ---
# Adobe Reader, Edge, Chromeなど、PDFを開いている可能性のあるプロセスをチェック
$pdfProcesses = @(\"AcroRd32\", \"Acrobat\", \"msedge\", \"chrome\")
$pdfCount = 0
foreach ($procName in $pdfProcesses) {
    $proc = Get-Process -Name $procName -ErrorAction SilentlyContinue
    if ($proc) {
        # プロセス名によってPDF判定を強化したければ、ウィンドウタイトルをチェック
        $titles = ($proc | Where-Object { $_.MainWindowTitle -match \'\\.pdf\' }).Count
        $pdfCount += $titles
    }
}
$totalCount += $pdfCount

# --- TXT ---
# メモ帳(notepad)で開かれているウィンドウ数を数える
$txtCount = (Get-Process notepad -ErrorAction SilentlyContinue | Where-Object { $_.MainWindowTitle -match \'\\.txt\' }).Count
$totalCount += $txtCount

# --- 結果出力 ---
Write-Output $totalCount
''' ScriptOutput=> Filecount2
    DISABLE WAIT 0.1
    Variables.IncreaseVariable Value: Timecnt IncrementValue: 1
    IF Timecnt >= 5 THEN
        SET FilesOpen TO $'''False'''
        EXIT LOOP
    END
END
IF Filecount >= Filecount2 THEN
    SET FilesOpen TO $'''False'''
ELSE
    SET FilesOpen TO $'''True'''
END

ポイント機能

・PowerShellによる開いているファイル数取得

・ファイル数誤判定防止処理

PowerShellによる開いているファイル数取得

スクリプトを実行からPSスクリプト実行を利用し、現在開いているMS系ファイル(ワード、PPT、エクセル)の数を数えます。

このスクリプトをファイル開く前と開いた後に実行し、ファイル数を変数に代入します。まずフロー実行時のファイル数をFilecountに、フロー実行してファイル開いた後をFilecount2に代入し、二つの変数の値=ファイル数を比べます。

今フローではファイル数が同じである場合はループをして、ファイルが開くまで処理を続けます。ファイル数が増えれば、ファイルが開いたことになり、FilesOpen変数にTrue,Falseが代入されます。ループにてループインデックスが5になった場合はループを終了させています。

ファイル数が増減に応じてTrue,Falseが代入
ループカウントが5以上で終了させる。

なおループにて待機メソッドは入れていません。PowerShellスクリプトによる実行である程度の遅延があるためです。より遅延させたい場合は遅延メソッドを有効化します。

ファイル数誤判定防止処理

タスクマネージャーから確認できますが、其々のファイルは一つのインスタンスを親にしていることが分かります。基本的には1ファイルに1にタスクが存在していますが、エクセル等MSファイルではまれに空白のタスクが存在し、2つのインスタンスが存在する場合があります。

上記PSでは一つのプログラムの中でのファイル数を判断するため、この状況だとファイル数の判定が正しく取得できない場合があります。そこでPSで空白のエクセル等プロセスがあった場合は終了させます。

PDFについては、Acrobatの構造上ファイル数の把握が難しいです。複数ファイルを開いても同じアプリ内のタブが増えるという仕様のため、MSファイルのように数の判断ができません。もしPDFが開いたか判断が必要な場合は、PADメソッドのアクティブウィンドウを取得し、ウィンドウがアクロバットかどうかで判断するとよいでしょう。

-業務効率化