初めてRPAツールを触る方や基本的なプログラミング学習向けに、Power Automate Desktop(PAD)をつかってフォルダー配下のすべてのサブフォルダーやファイルの情報を取得する方法について解説しています。ご自身の環境で動作可能なフローのテンプレートも共有して説明していますので、Power Automate Desktopを使った自動化フローを作る際の参考にしてみてください。
マイクロソフトの無償RPA(自動化ツール)である「Power Automate Desktop(PAD)」で、フォルダー階層を辿ってすべてのサブフォルダーやファイルの情報を取得する方法について解説します。
自動化フローで複数のファイルやフォルダーを対象とすることも多いと思いますが、環境により異なるフォルダー構成などを読み取って処理をするにはいくつかポイントがあります。
また、このような場合にフォルダ階層を取得するための一般的なプログラミング手法があるのですが、PADではその方法がそのまま使えないため、ちょっとしたコツが必要となります。
今回はこれらのポイントやコツを踏まえたフォルダー情報の取得方法についてご説明します。
無料自動化ツールの「Microsoft Power Automate Desktop」について、そもそもの解説や導入方法については「はじめてのPower Automate Desktop – 使い方・解説記事まとめ」からお読みいただくと基本的な使い方などが確認できます。
あるフォルダの中のサブフォルダを取得する方法
PowerAutomateDesktopでは「フォルダー内のサブフォルダーを取得」アクションを使ってあるフォルダーの中のサブフォルダーを一覧で取得することができます。
もし、このサブフォルダーの中にさらにフォルダーがあるような場合、ループアクションを使うことで階層を掘り下げて子や孫のフォルダーを取得することも可能です。
このような形で、ループを単純に増やしていけばより深い階層のフォルダーまで辿ることもできますが、仮に自動化をしたいフォルダの構成が3階層などと決められたものでなく、10階層だった場合や実行する環境やタイミングによって変わってしまう可能性がある場合はどうでしょうか。
そのような場合、単純にループを増やしていくことはあまりスマートではありません。
再帰処理を使う
前項のような不特定なフォルダの階層を辿るような処理を効率よく行う方法のひとつとして「再帰処理」と呼ばれるものがあります。
これは、プログラムなどのある処理のかたまりの中で、さらに同じ処理を行うプログラム(自分自身)を呼び出すような処理のことで、自分自身を呼び出す関数などを「再帰関数」などと呼んでいます。
この再帰の考え方を使うと、新しいフォルダが見つからなくなるまで子、孫フォルダの中を探し続けるといったような特殊な繰り返しフローが作成できます。
PADでの再帰処理のイメージ
Power Automate Desktopで再帰処理を行おうとした場合、ちょっとした問題が発生します。
まずは実際の動作をイメージするために、再帰処理の理想的なフローをご紹介すると以下のようなフローになります。
- サブフロー名「Subflow_1」
- フォルダー内のサブフォルダーを取得
%CurrentItem%
内のサブフォルダーを取得し、%Folders%
に保存する。 - For each
%CurrentItem%
in%Folders%
- 項目をリストに追加
%CurrentItem%
をリスト%FolderList%
に追加 - サブフローの実行
サブフロー「Subflow_1」を実行する - End
- フォルダー内のサブフォルダーを取得
フローのスクリーンショットのイメージは以下のような感じです。
このようにできれば、フォルダーの中のサブフォルダーを取得した後、各サブフォルダーに対するループの中で再度自分自身のサブフローである「Subflow_1」が呼び出され、そのサブフローの中でサブフォルダーの中のサブサブフォルダーを取得し、そのループの中で「Subflow_1」が呼び出され……というような処理が実現でき、サブフォルダが無くなるまで階層を辿ってフォルダを取得することができます。
しかしながら、Power Automate Desktopでは実際にこのようなサブフローを作ることはできません。
サブフローの中に「サブフローの実行」アクションを配置した場合、「サブフローの実行」ドロップダウンの一覧から自分自身のサブフローを選ぶことができず、エラーとなってしまいます。
他の一般的なプログラミングの関数であれば、このフローのような動作を作ることができるのですが、PADのサブフローは関数と異なり再帰的な呼び出しが認められていないため、上記のようなフローを作ろうとしても実際に動作させることができません。
PADでフォルダー配下のすべての子、孫サブフォルダーやファイルを取得するサンプルフロー
そこで、ちょっと面倒なやり方ではありますが、代わりの方法で再帰処理風のフローを作ることができます。
考え方はシンプルで、自分自身を再帰的に呼び出すことができない代わりに、同じ処理を行うサブフローを2つ作成し、それらをお互いに呼び出すような形で処理させます。
ここではフォルダー配下のすべての子、孫サブフォルダーやファイルを取得するサンプルフローをご紹介します。
サンプルはフォルダやファイルの一覧を取得してメッセージボックスに表示するだけのものですが、取得したフォルダやファイルの一覧を使ってループアクションを追加すれば、特定のフォルダ配下にあるすべてのファイルに対して自動処理を行うなどの自動化フローのテンプレートとして利用することも可能です。
サンプルフロー
以下はサンプルフローのスクリーンショットです。
今回のサンプルは1つのメインフローと2つのサブフローで構成されています。実際に動作を行ってみる際はそれぞれを作成してください。
メインフロー(Main)
サブフロー1(Subflow_1)
サブフロー2(Subflow_2)
サブフロー1とサブフロー2は同じアクションで構成されていますが、ステップ4の「サブフローの実行」アクションでそれぞれ他方のサブフローを呼び出すように指定します。
Robinソースコード
サンプルフローのRobin言語ソースコードです。
コピー&ペーストで貼り付けることで、お手元のPower Automate Desktopで動作を確認することができます。
メインフロー(Main)
Display.SelectFolder Description: $'''フォルダを選択''' IsTopMost: False SelectedFolder=> CurrentItem ButtonPressed=> ButtonPressed
Variables.CreateNewList List=> FolderList
CALL Subflow_1
Display.ShowMessage Title: $'''フォルダー一覧''' Message: FolderList Icon: Display.Icon.None Buttons: Display.Buttons.OK DefaultButton: Display.DefaultButton.Button1 IsTopMost: False ButtonPressed=> ButtonPressed2
Variables.CreateNewList List=> FileList
LOOP FOREACH CurrentFolder IN FolderList
Folder.GetFiles Folder: CurrentFolder FileFilter: $'''*''' IncludeSubfolders: False FailOnAccessDenied: True SortBy1: Folder.SortBy.NoSort SortDescending1: False SortBy2: Folder.SortBy.NoSort SortDescending2: False SortBy3: Folder.SortBy.NoSort SortDescending3: False Files=> Files
IF IsNotEmpty(Files) THEN
Variables.MergeLists FirstList: Files SecondList: FileList OutputList=> FileList
END
END
Display.ShowMessage Title: $'''ファイル一覧''' Message: FileList Icon: Display.Icon.None Buttons: Display.Buttons.OK DefaultButton: Display.DefaultButton.Button1 IsTopMost: False ButtonPressed=> ButtonPressed3
サブフロー1(Subflow_1)
Folder.GetSubfolders Folder: CurrentItem FolderFilter: $'''*''' IncludeSubfolders: False FailOnAccessDenied: True SortBy1: Folder.SortBy.NoSort SortDescending1: False SortBy2: Folder.SortBy.NoSort SortDescending2: False SortBy3: Folder.SortBy.NoSort SortDescending3: False Subfolders=> Folders
LOOP FOREACH CurrentItem IN Folders
Variables.AddItemToList Item: CurrentItem List: FolderList NewList=> FolderList
CALL Subflow_2
END
サブフロー2(Subflow_2)
Folder.GetSubfolders Folder: CurrentItem FolderFilter: $'''*''' IncludeSubfolders: False FailOnAccessDenied: True SortBy1: Folder.SortBy.NoSort SortDescending1: False SortBy2: Folder.SortBy.NoSort SortDescending2: False SortBy3: Folder.SortBy.NoSort SortDescending3: False Subfolders=> Folders
LOOP FOREACH CurrentItem IN Folders
Variables.AddItemToList Item: CurrentItem List: FolderList NewList=> FolderList
CALL Subflow_1
END
フローの共有、共有されたコードの利用の詳細については作成したフローを他のユーザーに共有する方法でも解説しているので、併せてご参照ください。
アクション解説
各アクションの設定について解説します。
起点となるフォルダーの指定
まず、階層を辿る起点となるフォルダーの指定を行うために「フォルダーの選択ダイアログを表示」アクションを配置します。
ここで指定したフォルダーは %CurrentItem%
という変数に保管されるように指定しておきます。この変数は再帰処理の中でも使われる変数となるため同じ名前にしておいてください。
リスト変数の設定
取得したフォルダー一覧を格納していくリストを「新しいリストの作成」アクションを使って作ります。
ここでは %FolderList%
という変数名を指定します。
サブフロー内でサブフォルダーを取得する
Subflow_1およびSubflow_2では、初めに %CurrentItem%
の変数を基にサブフォルダの取得を行います。取得したサブフォルダーの変数名は %Folders%
としておきます。
この %CurrentItem%
変数はメインフローから受け渡されるフォルダ名としてだけでなく、再帰的に呼び出されたサブフロー内で変更され、より下層のサブフォルダを取得することができます。
ループと再帰(風)呼び出し
「フォルダー内のサブフォルダーを取得」アクションで取得した %Folders%
は、「For each」アクションを使ってひとつひとつのフォルダに対するループ処理を行います。
ここで処理対象となるフォルダー変数を %CurrentItem%
として次のサブフローを呼び出すことで、呼び出されたサブフローはサブフォルダー(子フォルダ)で置き換えられた %CurrentItem%
を起点としたサブサブフォルダ(孫フォルダ)を取得するように動作します。
これを繰り返し、サブフォルダーのループ処理対象が存在しなくなるまで再帰処理を繰り返すことで、すべての階層のディレクトリを %FolderList%
変数に格納することができます。
まとめ
再帰処理はプログラムにおいてよく使われる手法のひとつですが、その典型的な方法である自分自身の処理を呼び出すようなフローはPower Automate Desktopで作ることができません。
今回のようなフローの構成は似たようなアクションで作られているためあまり理想的な方法ではないかもしれませんが、応用次第で再帰処理風の自動化フローを作ることも可能です。
また、こういった再帰処理を想定しておくことで不特定な状況にも対応できる自動化フローを構築することができるため、考え方を覚えておくだけでも今後のフロー設計に役立つのではないかと思います。
実際にPower Automate Desktopで動作させてみて、どのようなデータが取得できるかや変数の状態の変化などをチェックしてみてください。
コメント
「サブフォルダーを含める」のチェックをONにするだけで良いのでは?