業務効率化

PAD:MS系ファイルOpen判断関数

Powerautomate for desktop におけるPDFファイルやエクセル等マイクロソフト系ファイルを開いたかどうかを判断する関数です。従来開いたかどうかを判断する直接的なメソッドはなく、スクリプトで新たに作成するなどの必要がありました。今回の関数では現状の開いているファイル数及び、PDFアプリがアクティブになったかどうかを判断することで両ファイルが開いたかどうかを判断できます。

PADでアプリ操作をしてファイル取得保管を含むフローを作成したい場合に応用できます。

記事の内容

・挙動

・コード

・ポイント機能

挙動

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

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

コード

下記コートをPADのフローにコピペしてください。

➤コードはこちら
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
    #Write-Output \"Excel: $excelCount ブックが開かれています。\"
    $totalCount += $excelCount
} else {
    #Write-Output \"Excelは現在起動していません。\"
}

# Wordのカウント
$word = [Runtime.InteropServices.Marshal]::GetActiveObject(\"Word.Application\") 2>$null
if ($word -ne $null) {
    $wordCount = $word.Documents.Count
    #Write-Output \"Word: $wordCount ドキュメントが開かれています。\"
    $totalCount += $wordCount
} else {
    #Write-Output \"Wordは現在起動していません。\"
}

# PowerPointのカウント
$powerpoint = [Runtime.InteropServices.Marshal]::GetActiveObject(\"PowerPoint.Application\") 2>$null
if ($powerpoint -ne $null) {
    $powerPointCount = $powerpoint.Presentations.Count
    #Write-Output \"PowerPoint: $powerPointCount プレゼンテーションが開かれています。\"
    $totalCount += $powerPointCount
} else {
    #Write-Output \"PowerPointは現在起動していません。\"
}

# 合計を表示
Write-Output $totalCount
''' ScriptOutput=> Filecount
    DISABLE Scripting.RunPowershellScript.RunPowershellScript Script: $'''# ExcelアプリケーションのCOMオブジェクトを取得
$excel = [Runtime.InteropServices.Marshal]::GetActiveObject(\"Excel.Application\") 2>$null

if ($excel -ne $null) {
    # 開いているブックの数を取得
    $workbookCount = $excel.Workbooks.Count
    Write-Output $workbookCount
} else {
    Write-Output \"Excelは現在起動していません。\"
}''' ScriptOutput=> Filecount
END
SET Filecount2 TO Filecount
# エクセル起動時、タスクマネージャーに一つのエクセルプログラム(タイトルなし)がある場合エクセル数が0となりいくら開いても0のままになる。下記PSスクリプト実行することで、エクセルプログラムを一つのみとして実行させる 20250622確認
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)
    DISABLE Scripting.RunPowershellScript.RunPowershellScript Script: $'''# Excel プロセスを取得
$excelProcesses = Get-Process -Name EXCEL -ErrorAction SilentlyContinue

if ($excelProcesses) {
    Write-Output \"現在起動している Excel プロセス:\"
    foreach ($proc in $excelProcesses) {
        Write-Output \"-----------------------------\"
        Write-Output \"プロセス ID: $($proc.Id)\"
        Write-Output \"開始時間: $($proc.StartTime)\"
        Write-Output \"メモリ使用量: $([math]::Round($proc.WorkingSet64 / 1MB, 2)) MB\"
        Write-Output \"ウィンドウタイトル: $($proc.MainWindowTitle)\"
    }
} else {
    Write-Output \"Excel プロセスは起動していません。\"
}
''' ScriptOutput=> 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
    #Write-Output \"Excel: $excelCount ブックが開かれています。\"
    $totalCount += $excelCount
} else {
    #Write-Output \"Excelは現在起動していません。\"
}

# Wordのカウント
$word = [Runtime.InteropServices.Marshal]::GetActiveObject(\"Word.Application\") 2>$null
if ($word -ne $null) {
    $wordCount = $word.Documents.Count
    #Write-Output \"Word: $wordCount ドキュメントが開かれています。\"
    $totalCount += $wordCount
} else {
    #Write-Output \"Wordは現在起動していません。\"
}

# PowerPointのカウント
$powerpoint = [Runtime.InteropServices.Marshal]::GetActiveObject(\"PowerPoint.Application\") 2>$null
if ($powerpoint -ne $null) {
    $powerPointCount = $powerpoint.Presentations.Count
    #Write-Output \"PowerPoint: $powerPointCount プレゼンテーションが開かれています。\"
    $totalCount += $powerPointCount
} else {
    #Write-Output \"PowerPointは現在起動していません。\"
}

# 合計を表示
Write-Output $totalCount
''' ScriptOutput=> Filecount2
    DISABLE Scripting.RunPowershellScript.RunPowershellScript Script: $'''# ウィンドウタイトルが空の Excel プロセスだけを取得して終了
Get-Process -Name EXCEL | Where-Object { $_.MainWindowTitle -eq \"\" } | ForEach-Object {
    Write-Output \"終了対象: プロセス ID $($_.Id)\"
    Stop-Process -Id $_.Id -Force
}
'''
    DISABLE Scripting.RunPowershellScript.RunPowershellScript Script: $'''# ExcelアプリケーションのCOMオブジェクトを取得
$excel = [Runtime.InteropServices.Marshal]::GetActiveObject(\"Excel.Application\") 2>$null

if ($excel -ne $null) {
    # 開いているブックの数を取得
    $workbookCount = $excel.Workbooks.Count
    Write-Output $workbookCount
} else {
    Write-Output \"Excelは現在起動していません。\"
}
''' ScriptOutput=> Filecount2
    WAIT 1
    Variables.IncreaseVariable Value: timestop IncrementValue: 1
    IF timestop >= 5 THEN
        EXIT LOOP
    END
END
IF Filecount >= Filecount2 THEN
    SET MSFilesOpen TO $'''False'''
ELSE
    SET MSFilesOpen TO $'''True'''
END

ポイント機能

・PowerShellによるMSファイル数取得

・誤判定防止のための空ネームプログラムの停止

PowerShellによるMSファイル数取得

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

このスクリプトをファイル開く前と開いた後に実行することで、ファイル数の変化を監視します。ファイル開く前をFilecountに、ファイル開いた後をFilecount2に代入し、二つの変数の値=ファイル数を比べます。今フローではファイル数が同じである場合はループをして、ファイルが開くまで処理を続けます。ファイル数が増えれば、ファイルが開いたことになり、MSFilesOpen変数にTrue,Falseが代入されます。

ファイル数が増減に応じてTrue,Falseが代入

誤判定防止のための空ネームプログラムの停止

タスクマネージャーから確認できますが、其々のファイルは一つのインスタンスを親にしていることが分かります。それぞれのファイルごとに一つのタスクが存在していることが殆どですが、エクセルではまれに空白のタスクが存在し、二つのアプリインスタンスが存在する場合があります。その際はファイル数の判定が正しく取得できない場合があります。

そこでPSで空白のエクセルプロセスがあった場合は終了させます。

-業務効率化