教材

【RPA入門】Power Automate Desktopの使い方6~複数の受信メールからのデータ抽出(正規表現)

pad extract mail

RPAの入門として、Power Automate Desktopの使い方を紹介していきます。今回は、複数の受信メールから指定したデータを抽出する処理を自動化したいと思います。データの抽出には正規表現(パターンマッチング)を使用します。

1. Power Automate Desktopの初期設定

【RPA入門】Power Automate Desktopの使い方1~Webデータ取得(テキスト編)」の記事の【Step.1】から【Step2】までを実行してください。

 

2. 受信メールの作成

先ずは、下記のようなメールを受信トレイに3つ用意します。各メールで、予約内容のデータを適当に変更しておいてください。今回は、メール本文から以下のデータを抽出することにします。

  • 予約番号
  • 日付
  • 開始時刻
  • 終了時刻
  • 利用料金

sample mail

 

■メールの本文

「会議室」をご利用頂き、ありがとうございます。
以下の内容でご予約を承りました。

-------------------------
【予約内容】
●予約番号:14321
●日時  :2020/8/7 13:00~15:00
●会議室 :大会議室
●利用人数:5名
●利用料金:¥15,000(税込)
-------------------------

株式会社First

 

受信トレイにはダミーメールも2つ入れておきます。なお、メール本文はHTMLメールではなく、テキストメール(プレーンテキスト)にしてください。

sample mail inbox

 

3. 出力ファイルの作成

メールから抽出したデータを保存するために、下記のようなExcelファイルを作成しておきます。ファイル名は「リスト.xlsx」、シート名は「リスト」としました。

output file

 

4. Power Automate Desktopのフロー構築

【Step.1】Outlookを起動する

受信メールを取得するために、Outlookを起動するアクションを追加します。画面左側のアクション検索窓に「outlook」と入力します。「Outlookを起動します」アクションをフロー内にドラッグ&ドロップします。

open outlook

 

すると、プロパティ設定の画面が開きます。「生成された変数」に「%OutlookInstance%」が設定されていることを確認して、そのまま「保存」ボタンをクリックします。

set property of open-outlook

 

【Step.2】受信メールを取得する

受信トレイにあるメール(複数)を取得します。「Outlookからメールメッセージを取得します」アクションを、「Outlookを起動します」アクションの直下にドラッグ&ドロップします。

get mail list

 

すると、プロパティ設定の画面が開きます。下表の通りに各プロパティの値を編集します。続けて、「生成された変数」をクリックして、変数名が「%RetrievedEmails%」になっていることを確認します。「生成された変数」には、取得したメール(複数)のデータが格納されます。基本的に、変数名はその中身を推測できる名称をつけるべきです。今回は、「%mailList%」に変更します。

set property of get-mail

 

No. プロパティ項目 設定する値
1 アカウント あなたのメールアドレスです。xxxxには適切な値を入力してください。
2 メールフォルダー 取得先のフォルダを指定します。デフォルトの受信トレイの場合は「受信トレイ」を指定します。

 

【Step.3】Outlookを閉じる

Outlookを閉じるアクションを追加します。「Outlookを閉じます」アクションを、「Outlookからメールメッセージを取得します」アクションの直下にドラッグ&ドロップします。

close outlook

 

すると、プロパティ設定の画面が開きます。「Outlookインスタンス」に「%OutlookInstance%」が設定されていることが確認できます。「%OutlookInstance%」は、【Step.1】で起動したOutlookのインスタンス名です。

set property of close-outlook

 

【Step.4】受信メールを1件ずつ処理

受信メールを1件ずつ取り出して、順にデータを抽出していきたいです。変数mailListに保存されたメールを1件ずつ取り出すために、「For each」アクションを使用します。画面左側のアクション検索窓に「for」と入力します。「For each」アクションを、フロー内の「Outlookを閉じます」アクションの直下にドラッグ&ドロップします。

for each

 

すると、プロパティ設定の画面が開きます。「反復処理を行う値」に「%mailList%」を入力します。このプロパティでは、繰り返し処理を行う対象として、リスト型やテーブル型の変数を指定します。

set property of for-each

 

【Step.5】受信メールリストの確認

下図を見てください。

sample for-each

 

「For each」アクションでは、各メールが変数CurrentItemに代入されます。各メールの題名や本文などを取得するには、下記のように記述します。

送信者 → CurrentItem.From
題名  → CurrentItem.Subject
本文  → CurrentItem.Body

 

【Step.6】メールの題名を取得

各メールの題名を取得するには、「CurrentItem.Subject」と記述します。以降の処理で、このメールの題名を何度も使用する場合は、変数を新規作成して、題名を保存しておくことを勧めます。また、適切な名前の変数に保存することで、フローの可読性を高めることもできます。

変数を新規作成して、何かしらの値を保存するには、「変数の設定」アクションを使用します。画面左側のアクション検索窓に「変数」と入力します。「変数の設定」アクションを、「For each」アクションの内部にドラッグ&ドロップします。

variable of mail-title

 

すると、プロパティ設定の画面が開きます。「設定」を「%mailTitle%」に変更して、「宛先」には「CurrentItem.Subject」と入力します。

set property of mail-title

 

【Step.7】受信メールの条件分岐

今回は、メールの題名が「会議室の予約完了のお知らせ」に完全一致したメールのみ処理します。ダミーメールは処理しません。処理を条件分岐させるには、「If」アクションを使用します。画面左側のアクション検索窓に「if」と入力します。「If」アクションを、「変数の設定」アクションの直下にドラッグ&ドロップします。

if

 

すると、プロパティ設定の画面が開きます。下表の通りに各プロパティの値を編集します。今回は、条件式を満たすメールのデータを抽出します。従って、以降では、データを抽出する処理を「if」アクションの内部に追加していきます。

set property of if

 

No. プロパティ項目 設定する値
1 最初のオペランド %mailTitle%
2 演算子 と等しい(=)
3 2番目のオペランド 会議室の予約完了のお知らせ

 

【Step.8】メールの本文を取得

各メールの本文を取得するには、「CurrentItem.Body」と記述します。メールの題名と同様に、変数に保存しておきましょう。画面左側のアクション検索窓に「変数」と入力します。「変数の設定」アクションを、「if」アクションの内部にドラッグ&ドロップします。

variable of mail-body

 

すると、プロパティ設定の画面が開きます。「設定」を「%mailText%」に変更して、「宛先」には「CurrentItem.Body」と入力します。

set property of mail-body

 

【Step.9】「予約番号」の抽出

メールの本文から「予約番号」を抽出します。フローが長くなると可読性が下がるため、処理の区切りに「コメント」を追加します。画面左側のアクション検索窓に「コメント」と入力します。「コメント」アクションを、「変数の設定」アクションの直下にドラッグ&ドロップします。

comment for number

 

すると、プロパティ設定の画面が開きます。「コメント」に「▼予約番号の取得」と入力します。

set property of comment-number

 

【Step.9-1】テキストブロックの抽出(正規表現)

正規表現を使って、メールの本文から「予約番号」を含むテキストブロックを抽出します。画面左側のアクション検索窓に「解析」と入力します。「テキストの解析」アクションを、「コメント」アクションの直下にドラッグ&ドロップします。

match for number

 

すると、プロパティ設定の画面が開きます。下表の通りに各プロパティの値を編集します。「生成された変数」には、取得したテキストブロックが格納されます。基本的に、変数名はその中身を推測できる名称をつけるべきです。今回は、「%number%」に変更します。

set property of match-number

 

No. プロパティ項目 設定する値
1 解析するテキスト %mailText%
2 検索するテキスト \r\n●予約番号:.*\r\n
3 正規表現である ON
4 解析の開始位置 0

 

下図を見てください。メール本文の予約番号は、「\r\n●予約番号:.*\r\n」というパターンで取得できます。

pattern of number

 

正規表現のマッチングの精度を上げるために、検索対象(●予約番号:xxxxx)の前後に改行文字が存在すると考えて取り扱います。正規表現ではWindows環境の改行文字は「\r\n」と表記します。予約番号の数字は、各メールによって変化します。そこで、これらの数字は、任意の文字が0個以上連続する文字列「.*」と表記します。「.」は任意の1文字を表します。「*」は直前の文字が0個以上連続する文字列を表します。

実際に取得されるテキストブロックは下記のようになります。よく確認すると、テキストブロックの前後に改行が入り、「●予約番号:」のテキストが含まれることが分かります。これらの余分な内容を削除する必要があります。

extracted number

 

【Step.9-2】改行の削除(トリミング)

テキストブロックの前後の改行を削除(トリミング)します。画面左側のアクション検索窓に「トリミング」と入力します。「テキストのトリミング」アクションを、「テキストの解析」アクションの直下にドラッグ&ドロップします。

trim for number

 

すると、プロパティ設定の画面が開きます。「トリミングするテキスト」に「%number%」を入力します。「生成された変数」には、トリミング後のテキストが格納されます。変数の値が上書きされるように「%number%」に変更します。

set property of trim-number

 

【Step.9-3】余分なテキストの削除

テキストブロック内の「●予約番号:」を削除します。文字列の削除は、対象の文字列を空白文字に置換することで実現します。画面左側のアクション検索窓に「置換」と入力します。「テキストを置換する」アクションを、「テキストのトリミング」アクションの直下にドラッグ&ドロップします。

replace for number

 

すると、プロパティ設定の画面が開きます。下表の通りに各プロパティの値を編集します。「生成された変数」には、置換後のテキストが格納されます。変数の値が上書きされるように「%number%」に変更します。

set property of replace-number

 

No. プロパティ項目 設定する値
1 解析するテキスト %number%
2 検索するテキスト ●予約番号:
3 置き換え先のテキスト %''%
※空白の文字を指定します。ただし、未入力だと設定エラーになるようなので、代わりに空の文字列の評価式を書いておきます。

 

【Step.10】「日時」の抽出

メールの本文から「日時」を抽出します。フローが長くなると可読性が下がるため、処理の区切りに「コメント」を追加します。画面左側のアクション検索窓に「コメント」と入力します。「コメント」アクションを、「テキストを置換する」アクションの直下にドラッグ&ドロップします。

comment for date

 

すると、プロパティ設定の画面が開きます。「コメント」に「▼日時の取得」と入力します。

set property of comment-date

 

【Step.10-1】テキストブロックの抽出(正規表現)

正規表現を使って、メールの本文から「日時」を含むテキストブロックを抽出します。画面左側のアクション検索窓に「解析」と入力します。「テキストの解析」アクションを、「コメント」アクションの直下にドラッグ&ドロップします。

match for date

 

すると、プロパティ設定の画面が開きます。下表の通りに各プロパティの値を編集します。「生成された変数」には、取得したテキストブロックが格納されます。基本的に、変数名はその中身を推測できる名称をつけるべきです。今回は、「%dateTime%」に変更します。

set property of match-date

 

No. プロパティ項目 設定する値
1 解析するテキスト %mailText%
2 検索するテキスト \r\n●日時  :.*\r\n
3 正規表現である ON
4 解析の開始位置 0

 

下図を見てください。メール本文の日時に関する情報は、「\r\n●日時  :.*\r\n」というパターンで取得できます(※全角空白を含む)。

pattern of date

 

実際に取得されるテキストブロックは下記のようになります。よく確認すると、テキストブロックの前後に改行が入り、「●日時  :」のテキストが含まれることが分かります。これらの余分な内容を削除する必要があります。また、「日付」「開始時刻」「終了時刻」を分割する必要もあります。

extracted date

 

【Step.10-2】改行の削除(トリミング)

テキストブロックの前後の改行を削除(トリミング)します。画面左側のアクション検索窓に「トリミング」と入力します。「テキストのトリミング」アクションを、「テキストの解析」アクションの直下にドラッグ&ドロップします。

trim for date

 

すると、プロパティ設定の画面が開きます。「トリミングするテキスト」に「%dateTime%」を入力します。「生成された変数」には、トリミング後のテキストが格納されます。変数の値が上書きされるように「%dateTime%」に変更します。

set property of trim-date

 

【Step.10-3】余分なテキストの削除

テキストブロック内の「●日時  :」を削除します。文字列の削除は、対象の文字列を空白文字に置換することで実現します。画面左側のアクション検索窓に「置換」と入力します。「テキストを置換する」アクションを、「テキストのトリミング」アクションの直下にドラッグ&ドロップします。

replace for date

 

すると、プロパティ設定の画面が開きます。下表の通りに各プロパティの値を編集します。「生成された変数」には、置換後のテキストが格納されます。変数の値が上書きされるように「%dateTime%」に変更します。

set property of replace-date

 

No. プロパティ項目 設定する値
1 解析するテキスト %dateTime%
2 検索するテキスト ●日時  :
3 置き換え先のテキスト %''%
※空白の文字を指定します。ただし、未入力だと設定エラーになるようなので、代わりに空の文字列の評価式を書いておきます。

 

【Step.10-4】テキストの分割

「テキストの分割」アクションを使って、下図のように「日付」「開始時刻」「終了時刻」を分割します。

sample split

 

先ずは、半角空白を区切り文字として、「日付」と「時刻」に分割します。画面左側のアクション検索窓に「分割」と入力します。「テキストの分割」アクションを、「テキストを置換する」アクションの直下にドラッグ&ドロップします。

split date-time

 

すると、プロパティ設定の画面が開きます。下表の通りに各プロパティの値を編集します。「生成された変数」には、分割されたテキストが格納されます。変数名は「%dateTimeList%」に変更します。

set property of split-date

 

No. プロパティ項目 設定する値
1 分割するテキスト %dateTime%
2 区切り記号の種類 標準
3 標準の区切り記号 スペース

 

次は、「~」を区切り文字として、「開始時刻」と「終了時刻」に分割します。再度、「テキストの分割」アクションを、フロー内にドラッグ&ドロップします。

split time

 

すると、プロパティ設定の画面が開きます。下表の通りに各プロパティの値を編集します。「生成された変数」には、分割されたテキストが格納されます。変数名は「%timeList%」に変更します。

set property of split-time

 

No. プロパティ項目 設定する値
1 分割するテキスト %dateTimeList[1]%
2 区切り記号の種類 カスタム
3 標準の区切り記号

 

【Step.11】「料金」の抽出

メールの本文から「料金」を抽出します。フローが長くなると可読性が下がるため、処理の区切りに「コメント」を追加します。画面左側のアクション検索窓に「コメント」と入力します。「コメント」アクションを、「テキストの分割」アクションの直下にドラッグ&ドロップします。

comment for price

 

すると、プロパティ設定の画面が開きます。「コメント」に「▼料金の取得」と入力します。

set property of comment-price

 

【Step.11-1】テキストブロックの抽出(正規表現)

正規表現を使って、メールの本文から「料金」を含むテキストブロックを抽出します。画面左側のアクション検索窓に「解析」と入力します。「テキストの解析」アクションを、「コメント」アクションの直下にドラッグ&ドロップします。

match for price

 

すると、プロパティ設定の画面が開きます。下表の通りに各プロパティの値を編集します。「生成された変数」には、取得したテキストブロックが格納されます。基本的に、変数名はその中身を推測できる名称をつけるべきです。今回は、「%price%」に変更します。

set property of match-price

 

No. プロパティ項目 設定する値
1 解析するテキスト %mailText%
2 検索するテキスト \r\n●利用料金:¥.*(税込)\r\n
3 正規表現である ON
4 解析の開始位置 0

 

下図を見てください。メール本文の利用料金は、「\r\n●利用料金:¥.*(税込)\r\n」というパターンで取得できます。

pattern of price

 

実際に取得されるテキストブロックは下記のようになります。よく確認すると、テキストブロックの前後に改行が入り、「●利用料金:¥」と「(税込)」のテキストが含まれることが分かります。これらの余分な内容を削除する必要があります。

extracted price

 

【Step.11-2】改行の削除(トリミング)

テキストブロックの前後の改行を削除(トリミング)します。画面左側のアクション検索窓に「トリミング」と入力します。「テキストのトリミング」アクションを、「テキストの解析」アクションの直下にドラッグ&ドロップします。

trim for price

 

すると、プロパティ設定の画面が開きます。「トリミングするテキスト」に「%price%」を入力します。「生成された変数」には、トリミング後のテキストが格納されます。変数の値が上書きされるように「%price%」に変更します。

set property of trim-price

 

【Step.11-3】余分なテキストの削除

テキストブロック内の「●利用料金:¥」と「(税込)」をそれぞれ削除します。文字列の削除は、対象の文字列を空白文字に置換することで実現します。画面左側のアクション検索窓に「置換」と入力します。「テキストを置換する」アクションを、「テキストのトリミング」アクションの直下にドラッグ&ドロップします。

replace for price

 

すると、プロパティ設定の画面が開きます。下表の通りに各プロパティの値を編集します。「生成された変数」には、置換後のテキストが格納されます。変数の値が上書きされるように「%price%」に変更します。

set property of replace-price

 

No. プロパティ項目 設定する値
1 解析するテキスト %price%
2 検索するテキスト ●利用料金:¥
3 置き換え先のテキスト %''%
※空白の文字を指定します。ただし、未入力だと設定エラーになるようなので、代わりに空の文字列の評価式を書いておきます。

 

再度、「テキストを置換する」アクションを、フロー内にドラッグ&ドロップします。

replace for price2

 

すると、プロパティ設定の画面が開きます。下表の通りに各プロパティの値を編集します。「生成された変数」には、置換後のテキストが格納されます。変数の値が上書きされるように「%price%」に変更します。

set property of replace-price2

 

No. プロパティ項目 設定する値
1 解析するテキスト %price%
2 検索するテキスト (税込)
3 置き換え先のテキスト %''%
※空白の文字を指定します。ただし、未入力だと設定エラーになるようなので、代わりに空の文字列の評価式を書いておきます。

 

【Step.12】出力用のテーブルの作成

メール本文から必要なデータを抽出することができました。最後に、これらのデータを出力ファイルに書き込みます。ただし、データの数が多いため、セルに一つずつ書き込むと結構な時間がかかってしまいます。そこで、事前に出力用のテーブルを作成しておき、一括でファイルに書き込めるようにしたいと思います。

フローが長くなると可読性が下がるため、処理の区切りに「コメント」を追加します。画面左側のアクション検索窓に「コメント」と入力します。「コメント」アクションを、「テキストを置換する」アクションの直下にドラッグ&ドロップします。

comment for output

 

すると、プロパティ設定の画面が開きます。「コメント」に「▼ファイルへの出力」と入力します。

set property of comment-output

 

テーブルの作成には「変数の設定」アクションを使います。画面左側のアクション検索窓に「変数」と入力します。「変数の設定」アクションを、「コメント」アクションの直下にドラッグ&ドロップします。

variable of table

 

すると、プロパティ設定の画面が開きます。「設定」を「%table%」に変更して、「宛先」には下記の式を入力します。これで、1行×5列の二次元配列のテーブルを作成することができます。

%{[number, dateTimeList[0], timeList[0], timeList[1], price]}%

 

set property of table

 

実際に作成されるテーブルは下記のようになります。

sample table

 

【Step.13】Excelの起動

事前に作成した出力ファイル(リスト.xlsx)を開くために、アクションを追加します。画面左側のアクション検索窓に「excel」と入力します。「Excelの起動」アクションを、「For each」アクションの直前にドラッグ&ドロップします。Excelの起動自体は一回でよいので、繰り返し処理に入る前に実行します。

open excel

 

すると、プロパティ設定の画面が開きます。「Excelの起動」には「次のドキュメントを開く」を指定して、「ドキュメントパス」には、Excelリストのファイルパスを入力します。

set property of open-excel

 

【Step.14】Excelリストの範囲情報の取得

Excelリストの範囲情報を取得します。「Excelワークシートから最初の空の列や行を取得」アクションを、フロー内の「Excelの起動」アクションの直下にドラッグ&ドロップします。

get range

 

すると、プロパティ設定の画面が開きます。「Excelインスタンス」に「%ExcelInstance%」が設定されていることが確認できます。「%ExcelInstance%」は、【Step.13】で起動したExcelのインスタンス名です。生成された変数には、「FirstFreeColumn」と「FirstFreeRow」が設定されています。これらの変数には、Excelのシート内で最初に空となる列数と行数の値がそれぞれ格納されています。

set property of get-range

 

【Step.15】カウンタ変数の作成

各メールから抽出したデータを、Excelリストに行数をずらしながら順に書き込んでいくために、カウンタ変数を作成します。画面左側のアクション検索窓に「変数」と入力します。「変数の設定」アクションを、フロー内の「For each」アクションの直前にドラッグ&ドロップします。

variable of counter

 

すると、プロパティ設定の画面が開きます。「設定」を「%count%」に変更して、「宛先」には「%FirstFreeRow%」と入力します。これで、変数countが作成されました。初期値を「%FirstFreeRow%」にした理由は、Excelリストの最終行の下からデータを書き込むためです。

set property of counter

 

【Step.16】出力ファイルへのテーブル書き込み

出力ファイル(リスト.xlsx)に【Step.12】で作成したテーブルを書き込む処理を追加します。画面左側のアクション検索窓に「excel」と入力します。「Excelワークシートに書き込み」アクションを、「if」アクションの「End」の直前にドラッグ&ドロップします。

write range

 

すると、プロパティ設定の画面が開きます。下表の通りに各プロパティの値を編集します。

set property of write-range

 

No. プロパティ項目 設定する値
1 書き込む値 %table%
2 書き込みモード 指定したセル上
3 1
4 %count%

 

【Step.17】カウンタ変数のインクリメント

出力ファイルへのテーブル書き込みが実行される度に、カウンタ変数の値を1増やす(インクリメント)必要があります。画面左側のアクション検索窓に「変数」と入力します。「変数を大きくする」アクションを、フロー内の「Excelワークシートに書き込み」アクションの直下にドラッグ&ドロップします。

increment counter

 

すると、プロパティ設定の画面が開きます。「変数名」には「%count%」と入力して、「大きくする数値」には「1」と入力します。

set property of increment

 

【Step.18】Excelリストを閉じる

最後にExcelリストを閉じます。画面左側のアクション検索窓に「excel」と入力します。「Excelを閉じる」アクションを、フロー内の一番下にドラッグ&ドロップします。

close excel

 

すると、プロパティ設定の画面が開きます。「Excelインスタンス」に「%ExcelInstance%」が設定されていることが確認できます。「%ExcelInstance%」は、【Step.13】で起動したExcelのインスタンス名です。「Excelを閉じる前」を「ドキュメントを保存」に変更します。

set property of close-excel

 

【Step.19】フローの実行

上部の「実行」アイコンをクリックし、このフローを実行してみましょう。なお、フローの作成画面から実行すると、「デバッグモード」で実行されるようで、処理速度が遅いです。実際の運用時には、管理画面から実行ボタンをクリックしてフローを実行しましょう。

run flow

 

受信トレイ内の各メールのデータが出力ファイルに書き込まれました。データが正しく抽出できていることが確認できます。

result

 

5. まとめ

今回は、複数の受信メールから指定したデータを抽出する処理を自動化しました。下記の点を理解して、他の業務にも応用できるようにしましょう。

  • Outlookによる受信メールの取得
  • 「For each」を使った繰り返し処理
  • 「If」を使った条件分岐
  • 正規表現によるテキスト検索
  • テキストデータのトリミング
  • テキストデータの置き換え
  • テキストデータの分割
  • テーブルの作成
  • Excelへの書き込み

より深く「RPA」を学びたい方は、スクールでオンライン講義もやっていますので、良かったらこちらの記事もご覧ください。