いやー。解決策が分からずにハマりました。1時間半くらい悩んでしまいました。もうこれ以上悩まないために、メモを残しておきます。
Power Automate のクラウドフロー作成中に、Outlook の予定表から「イベントの取得 (V4)」アクションを利用し、特定のイベントアイテムを取得しようとしました。イベントアイテムを特定するために「フィルタークエリ」の設定を利用して、アイテムの件名を用いて絞り込みを行います。しかしこのとき、取得したいアイテムの件名に「’(シングルクォート)」が含まれていると、どうしても「Invalid filter clause」のエラーになり上手く動きませんでした。
シングルクォートの罠
こうした特殊な記号を含んだフィルターをしようとしたときのエラーは、ほとんどの場合がエンコード絡みです。ネットを検索しても、シングルクォートは「%27」にエンコードできるよという情報があります。そんなわけで次のように修正してみました。
元の ODATA フィルタークエリの指定がこちら。(この例はまったくの間違い)
subject eq 'Masaru's Meeting'
修正後がこちら。
subject eq 'Masaru%27 Meeting'
これでうまく行きそうに思えましたが、まるで解決には至りませんでした。引続き「Invalid filter clause」のエラーが発生します。
シングルクォートはシングルクォート x2 に置換
広大なネットの海をさまよっていると、「Power Automate の ODATA フィルタ―クエリでは、シングルクォートは、2 個のシングルクォートとして扱うんだよ」という情報がありました。
つまりこういうことですね。
subject eq 'Masaru''s Meeting'
なるほど。このように指定した場合は、たしかにエラーが発生せずにイベントアイテムを取得できました。
replace 関数で置換する
さて、フローで自動化するために、replace
関数で置換するように書き換えましょう。と、ここで話がさらにややこしくなってきます。例えば、単純に考えて次のように replace
関数を書きます。
replace('Masaru's Meeting', ''', '''')
しかし、この関数は明らかに正しくないですね。「Masaru’s」に含まれるシングルクォートが、引数の文字列を囲むシングルクォートと競合して、引数の値を正しく識別できないからです。つまり、「Masaru’s」のような引数の文字列では、シングルクォートをエスケープする必要があります。
そしてさらにややこしくさせるのが、シングルクォートをエスケープするためには、シングルクォートを利用するという点です。つまり、「’」は「”」とシングルクォート x2 で表記するわけですね。先ほどの replace
関数は次のようになります。
replace('Masaru''s Meeting', '''', '''''')
これはややこしい…。特に最後の引数は、シングルクォート x6 です。パッと見では何をしているのか分かりませんね……。
最終的に ODATA フィルタークエリに指定した式
と、ここまででシングルクォートの課題は解決できました。しかし、いくつかのパターンで ODATA フィルタークエリを利用していると、フィルター条件の文字列に「&」や「#」が含まれている場合もエラーになることがわかりました。これらの文字列は URL エンコードする必要があり、「&」は「%26」に「#」は「%23」に置換しなければなりません。
Power Automate では、こうした文字列を URL エンコードするための uriComponent
関数があります。シングルクォートをシングルクォート x2 に置き換えた文字列を、uriComponent
関数でエンコードしておくことで、「&」や「#」が含まれた場合にも対応できます。
uriComponent(replace('Masaru''s Meeting', '''', ''''''))
これで完璧。ODATA フィルタークエリには、次のように設定します。replace
関数のひとつめの引数には、フィルター条件に利用したい元の文字列を指定します。変数や動的コンテンツに含まれる文字列ではシングルクォートのエスケープは考える必要がありませんので、そのまま引数に指定するだけです。
uriComponent(replace(variables('フィルター件名'), '''', ''''''))
こんな感じ。
subject eq '@{uriComponent(replace(variables('フィルター件名'), '''', ''''''))}'
こうしておけば、どんな文字列でもエラーにはならずに実行できると思います。
さいごに
ODATA フィルタークエリを利用するときに、条件に文字列を利用するときは注意ですね。特に、シングルクォートの扱いにはハマりました。