【Power Automate Desktop】置換リストからテキストを一括置換処理
今回の変換リストからテキストを一括置換処理する方法となりますが、これは実は、鷹尾祥さんの著書「Excelパワークエリ データ収集・整形を自由自在にする本」の第4章7『文字列変換リストを使った一括文字列置換』と同じことをPowerAutomateDesktopを使ってやってみようという試みになります。
- 1.やりたいこと
- 2.事前準備「置換リスト」の作成
- 3.実践① フロー作成 ~ 置換リストの変数設定
- 4.実践② 2つのループ処理を設定
- 5.実践③ エクセルを閉じる(置換後の変換対象ファイルは名前を付けて保存)
- 6.フローの実行
- 7.最後に
1.やりたいこと
下図の通り、事前に「置換リスト」の各組合せをエクセルファイルに設定しておき、選択した「変換対象ファイル」(エクセル)の任意の列の文字列を置換リストの数分、置換処理するものです。
説明が長くなりそうなので全体の流れを要約したものを以下記載しました。
2.事前準備「置換リスト」の作成
下図は今回使用する「置換リスト」の最初と最後のページを横並びにしたものです。これで簡単に説明します。まず、最低限必要なのは「検索Text(A列)」と「置換Text(B列)」となります。下図2行目で例えると、仮に対象テキストが「渋谷109」(0のみ全角)であれば、検索Text 0(全角)を置換Text 0(半角)に置換し、「渋谷109」にすることになります。C、D列の分類と備考はA,B列の説明となりますので無くてもPADフローの動作に影響はありません。分類で分けた通り、置換の分類としては大きく次の通りに分けられます。
00 文字種 ・・ 全角⇔半角、平仮名⇔カタカナ、大文字⇔小文字 の置換等
01 固有テキスト・・その通り固有のテキスト⇔固有テキストの置換
02 削除 ・・ 固有テキストを削除するもの
03 スペース削除・・テキストに含まれる余分な空白を削除するもの
この置換リストでポイントとなるのは上記分類の並び順です。どうゆうことかというと、今回の変換対象ファイルに「WORD WORLD(株)」というテキストがあります。これを下図の置換リストで置換をかけると、リスト順に次の順番で置換されていきます。
WORD WORLD(株) ・・置換前
WORD WORLD(株) ・・D → D (文字種置換)
WORD WORLD(株) ・・ L → L (文字種置換)
WORD WORLD(株) ・・ O → O (文字種置換)
WORD WORLD(株) ・・ R → R (文字種置換)
WORD WORLD(株) ・・ W → W (文字種置換)
WORD WORLD株式会社 ・・ (株) → 株式会社 (固有テキスト置換)
ワード WORLD株式会社 ・・ WORD → ワード (固有テキスト置換)
ワード■WORLD株式会社 ・・ ” ”(半角) → ” "(全角) (スペース置換)
ワード WORLD株式会社 ・・置換後
仮に、92行目の検索Text「WORD」置換Text「ワード」が2行目にあったとしたら、これは置換されず(全角のWORDである為)に最終結果は、「WORD WORLD株式会社」となってしまいます。よって、正しく置換を反映するには固有テキストの前に文字種をセットしたり、半角スペースを一旦、全角スペースに置換してから、その後に全角スペースの調整がなされるようセットする等、工夫が必要です。
その他、94行目のような削除の場合の置換Textは完全なブランクで問題ありません。(パワークエリの場合は「’」とする必要あり)
また、各検索Text、置換Textをエクセルシートに設定するにあたっては、文字列や数値以外の関数(CHAR関数等)の結果であってもフロー実行の置換ではテキストとして扱われます。
3.実践① フロー作成 ~ 置換リストの変数設定
任意の名前を付けて作成ボタンをクリックします。
画面左のアクション一覧からフォルダ→特別なフォルダーを取得 をダブルクリック(又は真ん中のフロー詳細へドラッグ&ドロップ)します。このアクションは以降のファイル選択等の際に「初期フォルダ」を設定するために変数化しておくものです。
ここでは、特別なフォルダ―の名前: デスクトップ を選択します。特別なフォルダーのパス:は自身のデスクトップのパスが自動設定されます。生成された変数はデフォルトの SpecialFolderPath のままとし、保存します。
【置換リストを選択をするためのダイアログ設定】
アクション一覧 → メッセージボックス → ファイルの選択ダイアログを表示 をダブルクリックします。
下図の通り入力し保存します。
ダイアログのタイトル: 置換リストの選択(任意のテキスト)
初期フォルダ:%SpecialFolderPath% (右端の{X}をクリックし、変数名を選択)
ファイルフィルター: *.XLSX* (今回はエクセルファイルに限定するため)
ファイル選択ダイアログ:オン
複数の選択を許可:オフ
ファイルが存在するかどうかを確認:オフ
生成された変数:デフォルトの SelectedFile を ReplaceList_File に変更します。変数名と変更方法は下図(補足)を参照してください。変数ButtonPressedは今回特に使用しませんのでデフォルトのままとします。
今回のフローでは、置換リストと変更対象ファイルを別ファイルとしており、それぞれに対してフローを設定していきますので、
置換リスト関係 = ReplaceList
変更対象ファイル関係 = ConversionSheet
をそれぞれの各変数名に使用して管理することとしますので、頭に入れておいてください。
(補足)
【変更対象ファイルを選択をするためのダイアログ設定】
再び、アクション一覧 → メッセージボックス → ファイルの選択ダイアログを表示 をダブルクリックします。
下図の通り入力し保存します。
ダイアログのタイトル: 変更対象のエクセルファイルを選択(任意のテキスト)
初期フォルダ:%SpecialFolderPath% (右端の{X}をクリックし、変数名を選択)
ファイルフィルター: *.XLSX* (今回はエクセルファイルに限定するため)
ファイル選択ダイアログ:オン
複数の選択を許可:オフ
ファイルが存在するかどうかを確認:オフ
生成された変数:デフォルトの SelectedFile を ConversionSheet_File に変更します。変数ButtonPressed2は今回特に使用しませんのでデフォルトのままとします。
【置換リスト:エクセルの起動】
アクション一覧 → Excel → Excelの起動 をダブルクリックします。
下図の通り入力し保存します。
Excelの起動:次のドキュメントを開く を選択します。
ドキュメントパス:右端の{X}をクリックし、変数ReplaceList_File を選択します。
インスタンスを表示する:オフとします。(起動したエクセル画面を表示するかどうかの設定ですが、置換リストを表示する必要はない為オフ)
読み取り専用として開く:オンにします。
生成された変数名は、ExcelInstanse_ReplaceList に変更します。
【置換リスト:最初の空の列・行(リストの範囲)を取得】
アクション一覧 → Excel → Excelワークシートから最初の空の列や行を取得 をダブルクリックします。
下図の通り入力し保存します。
Excelインスタンス:右端をクリックし、変数ExcelInstanse_ReplaceListを選択します
生成された変数は、FirstFreeColmn_ReplaceList 、FirstFreeRow_ReplaceList に変更します。(ただし、以降のフローで使用するのはFirstFreeRow_ReplaceListのみです)
【変更対象ファイル:エクセルの起動】
アクション一覧 → Excel → Excelの起動 をダブルクリックします。
下図の通り入力し保存します。
Excelの起動:次のドキュメントを開く を選択します。
ドキュメントパス:右端の{X}をクリックし、変数ConversionSheet_File を選択します。
インスタンスを表示する:オンとします。(変更対象ファイルを表示するのは、後の工程で対象の列番号等を目視で確認し入力する想定であること、また実際の置換の動きを画面で確認するためです)
読み取り専用として開く:オフにします。
生成された変数名は、ExcelInstanse_ConversionSheet に変更します。
【変更対象ファイル:最初の空の列・行(リストの範囲)を取得】
アクション一覧 → Excel → Excelワークシートから最初の空の列や行を取得 をダブルクリックします。
下図の通り入力し保存します。
Excelインスタンス:右端をクリックし、変数ExcelInstanse_ConversionSheetを選択します。
生成された変数は、FirstFreeColmn_ConversionSheet 、FirstFreeRow_ConversionSheet に変更します。(ただし、以降のフローで使用するのはFirstFreeRow_ConversionSheetのみです)
【変更対象ファイル:変換対象の列番号をダイアログで入力】
アクション一覧 → メッセージボックス → 入力ダイアログを表示 をダブルクリックします。
下図の通り入力し保存します。
入力ダイアログのタイトル:変更対象ファイルの対象列選択(任意)
入力ダイアログメッセージ:変換対象エクセルファイルの変換対象の列番号を入力してください。(任意)
規定値: ブランク
入力の種類:1行 を選択
入力ダイアログを常に手前に表示する:オン
生成された変数 は、Conversion_Colmn に変更します。ButtonPressed3は使用しない為、デフォルトのままで構いません。
【変更対象ファイル:変換対象列の先頭行番号をダイアログで入力】
再び、アクション一覧 → メッセージボックス → 入力ダイアログを表示 をダブルクリックします。
下図の通り入力し保存します。
入力ダイアログのタイトル:変更対象ファイルの先頭行を選択(任意)
入力ダイアログメッセージ:変換対象エクセルファイルの変換対象列の先頭行番号を入力してください。(任意)
規定値: 2 (先ほどはブランクでしたが、ここは基本的に変更対象ファイルの先頭行は見出しであることを想定し、デフォルト値を 2行目としています。フロー実行時に変更可能です。)
入力の種類:1行 を選択
入力ダイアログを常に手前に表示する:オン
生成された変数 は、Conversion_StartRow に変更します。ButtonPressed4は使用しない為、デフォルトのままで構いません。
【置換リスト:ループ処理用変数の設定】
アクション一覧 → {X}変数の設定 をダブルクリックします。
下図の通り入力し保存します。
設定: ReplaceList_Var とします。(当変数の名前です)
宛先: 2 とします。(この変数は、ループ処理の際に置換リストから読み取る行の初期値となります。置換リストの1行目は見出し(固定)となりますので、初期値が2行目からとなるようにします)
ここまでで、設定したフローは下図の通りとなります。
4.実践② 2つのループ処理を設定
ここで置換をループ処理するためのフローを設定していきます。置換リストの値を読み取るループの中に、変換対象ファイルのテキストを置換するループを入れ子にして、一連の置換ループ処理を作っていきます。(フローの順番に説明していきますので少しわかりずらいところがあるかもしれません)
【置換リストの値を読み取るループ】
アクション一覧 → ループ → ループ条件 をダブルクリックします。
下図の通り入力し保存します。
最初のオペランド: 右端の{X}をクリックし、ReplaceList_Var を選択します。
演算子: と等しくない(<>) を選択します。
2番目のオペランド: 右端の{X}をクリックし、FirstFreeRow_ReplaceList を選択します。
この設定の意味は、ReplaceList_Var (初期値 2)が FirstFreeRow_ReplaceList(置換リスト最終行の次の行) と等しくない限りループ処理を続ける。つまり、置換リストの最初の行から最後の行までループ処理を続けるということです。
【変換対象ファイル:ループ処理用変数の設定】
アクション一覧 → {X}変数の設定 をダブルクリックします。
下図の通り入力し保存します。
設定: ConversionSheet_Var とします。
宛先: 右端の{X}をクリックし、Conversion_StartRow を選択します。
ここで前項の入力ダイアログで取得した変数 Conversion_StartRow を新たな変数としてConversionSheet_Var に設定する理由は、Conversion_StartRowはテキスト型として認識されているためループ処理を回し、この後の変数を大きくするステップで+1をしたときにエラーとなってしまうためです。ここで新たな変数に入れることで数値型となります。
【置換リスト:エクセルから検索Textを読み取る】
アクション一覧 → Excel → Excelワークシートから読み取りをダブルクリックします。
下図の通り入力し保存します。
Excelインスタンス:変数ExcelInstanse_ReplaceList を選択します。
取得: 単一のセルの値 を選択します。
先頭列: 1 を入力します。
先頭行: 右端の{X}をクリックし、ReplaceList_Var を選択します。
生成された変数は、SearchData に変更します。
【置換リスト:エクセルから置換Textを読み取る】
再び、アクション一覧 → Excel → Excelワークシートから読み取りをダブルクリックします。
下図の通り入力し保存します。
Excelインスタンス:変数ExcelInstanse_ReplaceList を選択します。
取得: 単一のセルの値 を選択します。
先頭列: 2 を入力します。
先頭行: 右端の{X}をクリックし、ReplaceList_Var を選択します。
生成された変数は、ReplaceData に変更します。
【変換対象ファイルのテキストを置換するループ】
まだ、最初のループの途中ですがここで置換処理のループを入れます。
アクション一覧 → ループ → ループ条件 をダブルクリックします。
下図の通り入力し保存します。
最初のオペランド: 右端の{X}をクリックし、ConversionSheet_Var を選択します。
演算子: と等しくない(<>) を選択します。
2番目のオペランド: 右端の{X}をクリックし、FirstFreeRow_ConversionSheet を選択します。
この設定の意味は、ConversionSheet_Var (初期値 2)が FirstFreeRow_ConversionSheet(変換対象ファイル最終行の次の行) と等しくない限りループ処理を続ける。つまり、変換対象ファイルの最初の行から最後の行までループ処理を続けるということです。
【変換対象ファイルの対象テキストを読み取る】
アクション一覧 → Excel → Excelワークシートから読み取りをダブルクリックします。
下図の通り入力し保存します。
Excelインスタンス:変数ExcelInstanse_ConversionSheet を選択します。
取得: 単一のセルの値 を選択します。
先頭列:右端の{X}をクリックし、Conversion_Colmn を選択します。
先頭行: 右端の{X}をクリックし、ConversionSheet_Var を選択します。
生成された変数は、TargetData に変更します。
【対象テキストを置換する】
アクション一覧 → テキスト → テキストを置換する をダブルクリックします。
下図の通り入力し保存します。
解析するテキスト: 右端の{X}をクリックし、TargetData を選択します。
検索するテキスト: 右端の{X}をクリックし、SearchData を選択します。
検索と置換に正規表現を使う:オフ
大文字と小文字を区別しない:オフ
置き換え先のテキスト:右端の{X}をクリックし、ReplaceData を選択します。
エスケープシーケンスをアクティブ化:オフ
生成された変数は、デフォルトのReplaced のままとします。
【置換後のテキストに対しトリミングする】
前項の置換だけでは先頭と末尾に余分な空白文字があった場合そのまま残ってしまうため、ここで更にトリミング処理を追加します。
アクション一覧 → テキスト → テキストのトリミング をダブルクリックします。
下図の通り入力し保存します。
トリミングするテキスト:右端の{X}をクリックし、Replaced を選択します。
トリミング対象:先頭と末尾の空白文字 を選択します。
生成された変数は、さきほどの置換時に作成した Replaced とします。
つまり、既にある変数 Replaced を上書きする形となります。
【置換・トリミング後のテキストを変換対象ファイルの元セルへ書き込む】
アクション一覧 → Excel → Excelワークシートに書き込み をダブルクリックします。
下図の通り入力し保存します。
Excelインスタンス:ExcelInstanse_ConversionSheet を選択します。
書き込み値:右端の{X}をクリックし、Replaced を選択します。
書き込みモード:指定したセル上(デフォルトのまま)
列:右端の{X}をクリックし、Conversion_Colmn を選択します。
行:右端の{X}をクリックし、ConversionSheet_Var を選択します。
【次のループ処理の為、変換対象ファイル変数をインクリメントする】
アクション一覧 → 変数 → 変数を大きくする をダブルクリックします。
下図の通り入力し保存します。
変数名:右端の{X}をクリックし、ConversionSheet_Var を選択します。
大きくする数値:1 を入力します。
ここまでで、2つ目のループ処理(置換と書き込み)のフロー設定は完了となります。この2つ目のループ処理のフローを抜き出したのが下図となります。ループ条件とEndの間に設定したアクションが入った状態です。この後、1つ目のループ処理の続きを設定します。
【置換リスト読み取り変数をインクリメントする】
アクション一覧 → 変数 →変数を大きくする をダブルクリックします。
下図の通り入力し保存します。
変数名:右端の{X}をクリックし、ReplaceList_Var を選択します。
大きくする数値: 1 を入力します。
これでループ処理のアクション設定は完了です。2つのループ処理のフロー一覧が下図となります。
最初のループで置換リストの最初の検索Textと置換Textを読み取り →
2つ目のループで変換対象列の行数分の置換処理を実施 →
その後、最初のループ変数をインクリメント →
最初のループの頭に戻って置換リストの2つ目の検索Textと置換Textを読み取り →
これを置換リストの行数分繰り返し処理します。
5.実践③ エクセルを閉じる(置換後の変換対象ファイルは名前を付けて保存)
【置換リスト:エクセルを閉じる】
アクション一覧 → Excel → Excelを閉じる をダブルクリックします。
下図の通り入力し保存します。
Excelインスタンス:ExcelInstanse_ReplaceList を選択します。
Excelを閉じる前:ドキュメントを保存しない を選択します。
【置換後の変換対象ファイルを保存する際の新規ファイル名を作成】
保存するファイル名は元のファイル名の末尾に(Replaced)を追記したファイル名としますので次のアクションでファイル名を作成します。
アクション一覧 → テキスト → テキストを置換する をダブルクリックします。
下図の通り入力し保存します。
解析するテキスト:右端の{X}をクリックし、ConversionSheet_File を選択します。
検索するテキスト:.xlsx と入力します。
検索と置換に正規表現を使う:オフ
大文字と小文字を区別しない:オン(ファイル名の拡張子はどちらもあり得る為)
置き換え先のテキスト: %'(Replaced.xlsx’% と入力します。
エスケープシーケンスをアクティブ化:オフ
生成された変数は、Replaced_FileName とします。
解析するテキストの変数 ConversionSheet_File は元のファイル保存先のパスがすべて含まれていますので、この置換によって変数 Replaced_FileName は元のファイル保存先パスでファイル名の末尾に(Replaced)が追加されたものとなります。
【変換対象ファイル:名前を付けて保存しエクセルを閉じる】
アクション一覧 → Excel → Excelを閉じる をダブルクリックします。
下図の通り入力し保存します。
Excelインスタンス:ExcelInstanse_ConversionSheet を選択します。
Excelを閉じる前:名前を付けてドキュメントを保存 を選択します。
ドキュメント形式:規定(拡張機能から) 【デフォルトのまま】
ドキュメントパス: 右端の{X}をクリックし、Replaced_FileName を選択します。
以上でフローの作成は完了です。作成したフロー全体は次の通りです。
6.フローの実行
詳細設定画面から実行するとデバッグモードで実行され時間が掛かる為、作成したフローを一旦保存後に閉じて、トップ画面から実行します。
置換リスト選択のダイアログが表示されるのでエクセルファイルを選択し、開くをクリックします。
続いて、変換対象のエクセルファイル選択ダイアログが表示されるのでファイルを選択し、開くをクリックします。
変換対象のエクセルファイルが開き、変換対象ファイルの対象列選択ダイアログが表示されるので、対象列を入力してOKをクリックします。
続いて、変換対象ファイルの先頭行を選択ダイアログが表示されます。初期値に設定した 2 が予め入力されていますので、正しければそのままOKをクリックします。その後、置換処理が実行されます。
下図は置換途中の状態です。
置換が完了すると、エクセルが閉じます。元の変換対象ファイル(取引マスタ_202106.xlsx)があった場所を確認すると、「取引マスタ_202106(Replaced).xlsx」という名前のファイルが新たに保存されました。
このファイルを開いてみると、想定通りに置換されたことが確認できました。
7.最後に
想定した通りのフローを作成することができましたが、ひとつ大きな課題が残ってしまいました。それは置換処理にかなりの時間が掛かることです。今回例で実行した置換リスト 98パターン × 取引先マスタ 10件 = 980回の置換処理で掛かった時間が48秒でした。試しに置換リスト 98パターン × 取引先マスタ 100件 = 9800回の置換処理で実行したところ、約10倍以上の9分50秒(590秒)という結果でした。
実務で数千数万件を処理するのにこれでは厳しいです。まずは置換リストのパターンを限定した上で実行すべきかなと思います。また、もっと効率的なフローの書き方があるかも知れませんので今後の課題にしたいと思います。
かなり長くなってしまいましたが、最後まで読んでいただきありがとうございました。