« 2023年2月 | トップページ | 2023年5月 »

2023年3月

Power Automate / SharePoint のメモ

■ SharePointのファイルの取得(プロパティのみ)

これで得られるフルパスは、https:から始まるパスではなく、ファイルの取得で指定したライブラリ名からのパスのようです。

Microsoft365 E3では、フィルタークエリにstartswith(Title,'A')が使えないようです。出力に"Title"が出ません。開発者プログラムのMicrosoft365 E5では、出力に"Title"が出るので、startswith(Title,'A')が使用できます。(2023/03/31時点)

設定の改ページをオンにしてしきい値に大きな数値を設定しているときに、上から順に取得に数値を設定しても、その数で出力が制限されないようです。設定のしきい値の数の出力数になるようです。(2023/03/31時点)

フルパスはURLに使用できない文字(例:"#",",","&"など)もデコードされて取得されるのですが、このフルパスをSharePointのリストのハイパーリンクに入れると、ブラウザがエンコードできず、リンク切れになります。また、ライブラリのフォルダ作成アクションでは、URLに使用できない文字がエンコードされず、エラーになります。手動だとURLに使用できないフォルダ名も作成できます。URLのコードの自動変換に一貫性が無いようです。

■ SharePointの複数の項目の取得のフィルター クエリの文字列変数

文字列変数の比較をするときは文字列変数を''で括る必要がありそうです。

■ SharePointのハイパーリンク項目の作成

項目の作成でハイパーリンクに空白文字を入れようとするとエラーになります。nullならエラーになりません。
if(empty(items('Apply_to_each')?['URL']),null,items('Apply_to_each')?['URL'])

ExcelのデータをSharePointのリストのハイパーリンクに書き込む場合、Excel側はテキストで良いようです。Excelでハイパーリンクが設定されていても表示文字が使用されると思います? なので、表示文字がURLである必要があると思います?

日付も空白文字だとエラーになるようです。nullならエラーにならないようです。
if(empty(items('Apply_to_each')?['Date']), null, items('Apply_to_each')?['Date'])

■ SharePointのファイルの取得 (プロパティのみ)で取得したLink

SharePointのファイルの取得 (プロパティのみ)で取得したLink をSharePointのリストのハイパーリンクに書き込むとエラーになります。入力データを直接ブラウザに入れるとLinkは正しいのですが、原因不明です。
items('Apply_to_each')?['{Link}']はError

サイトアドレスとFullPathを結合すると書き込めます。
concat(variables('SiteAddr'),'/',items('Apply_to_each_Folder')?['{FullPath}'])はOK

■ SharePointのサイトやリスト名を変数で設定

SharePointの項目の更新などでサイトのアドレスやリスト名を動的に変数で与えると、Power Automateのデザイナーがリストの項目を取得できなくなります。下記方法でOKな時とNGの時があり、正しい方法が良く分かりません。

1) 実態のサイト名やリスト名などを設定し、項目を設定する。(関数を書くときはFxに書く。Fxだと動的な値の選択肢にbodyやvalueやApply to eachの現在の値しか出ないので、?['xxx']で項目を書き加える。)
2) 生成されたJSONをコピーし、メモ帳に貼り付け、不要な部分を削除しする。(Power Automateの編集画面の項目やFxに貼って編集するのはNG。)
"parameters": {
"item/Title": "@replace(items('Apply_to_each')?['Title'],decodeUriComponent('%0B',''),items('Apply_to_each')?['Title'])",
"item/Date": "@if(empty(items('Apply_to_each')?['Date']),null,items('Apply_to_each')?['Date'])",
"item/Dep": "@variables('Dep')"
},
3) "@を{、"を}に置換し、"item/Title"になっていたら、item/を消す。
{
"Title": @{replace(items('Apply_to_each')?['Title'],decodeUriComponent('%0B',''),items('Apply_to_each')?['Title'])},
"Date": @{if(empty(items('Apply_to_each')?['Date']), null, items('Apply_to_each')?['Date'])},
"Dep": @{variables('Dep')}
}
4) サイト名やリスト名をカスタム値=変数に戻す。
5) 項目にメモ帳で編集したJSONを貼り付ける。
6) 右辺の動的な値や式はエディタの機能で選択しなおした方が良いかもしれない。選択肢に動的な値が出ない場合は、式の編集画面で「現在のアイテム」など親を選び、?['xxx']を追加する。

■ Excelの「表内に存在する行を一覧表示」のフィルタークエリ

単一の 'eq'、'ne'、'contains'、'startswith'、'endswith' のみがサポートされているそうです。(2023/03/21時点)

■ アクションの名前の変更は最初に行う

アクションを作成したときに変更したほうが良いです。
後にアクションのパラメータを参照する式を書き、その後にアクションの名前を変えると、参照式が元のアクション名のままなのでエラーになります。

名前を後から変更したときに、Enterを押しても名前が確定できない場合は、Escキーを押すと確定できます。変更した名前を参照している部分は自動的には変わらないので、手動で修正が必要です。

■ Do Untilループ内のエラー

Do Untilなどのループ内でエラーが起きると、Do Untilの終了条件に影響するアクションがスキップされ、無限ループになることがあります。
1) 終了条件に影響するアクションをエラーでも実行するように実行条件の構成を変更する。
2) 実行条件の構成をエラー時にした並列処理を追加して、ループを抜ける条件を設定するアクションを追加する。

■ Power Automateの実行回数制限

https://learn.microsoft.com/ja-jp/power-automate/limits-and-config
Microsoft365だと"低"なのでかなり少ないです。
無限ループを放っておくと回数を無駄に消費するので、実行履歴画面の右上のキャンセルをクリックして強制終了します。

データの移行など一時的に多くのデータを取り扱う場合は、処理レコード数をカウントし、1日の制限に掛かる前に処理IDや処理数を保存してから終了し、翌日続きから実行するなどの処理が必要です。

Microsoft E3の制限は10Kアクション/日ですが、1~7割程度のオーバーでは止まらないようです。ExcelのテーブルをSharePointのリストにコピーするフローの実行時間は30分/日くらいでした。

■ テストの10分タイムオーバー表示

10分のタイムオーバーが表示されても止まっていないようです。なので、無限ループになっている疑いがある場合は、キャンセルしたほうが良さそうです。

■ テスト実行直後のアクションの出力のダウンロード

テスト実行直後はアクションの出力が表示されずダウンロードのリンクが表示されます。これをクリックすると生データが表示されます。Firefoxでは内蔵されているJSONの表示機能で、JSON、生データ、ヘッダーの3つのタブが表示され、JSONでは折り畳みや展開表示ができるので便利です。Edgeの場合はアドオンが必要ですが、FirefoxのJSON表示機能のようなアドオンを発見できてません。

■ 2023/03/21の仕様変更?

SharePointの複数の項目の取得でリスト名などを変数で設定すると、変数名が表示されず、「カスタム値」と表示されるようになり、変数名が分からなくなりました。編集画面で確認する必要があります。
値の設定などで式の入力エディタから選んで(例:true)式を入力してアクションに戻ると、表示がUndefined(...)とかvariable(...)などの表示になり中身が分からなくなります。保存したり再編集すると正しくなります。
式の編集部分の行数が増えました。(ここにPower Fxのように複数の処理を書けるともっと良いのですが。設定だけでなく、アクションもコードで書けた方が条件が複雑になったとき横に広がらず読みやすいと思うのですが?)
Fxの中から選べる動的な値の選択肢が増えました。これは便利です。

■ アクションの検索言語

「Power Automate を使用してシーケンシャル承認を管理する」を試そうと思ったのですが、get managerでGet manager (V2)/Office 365 Usersが表示されません。
https://learn.microsoft.com/ja-jp/power-automate/sequential-modern-approvals

上司で検索すると表示されました。英語のmanagerですね。

ワークフローニーズが多いのですが、連続承認、並列承認、質問、回答、却下、修正依頼、再承認依頼、配信のみ、承認ルートの選択、承認者の選択、等処理が複雑なので、Microsft365で作るのは難しそうです。

■ 余談

Power Platformは初心者用の書籍や情報が少ないです。Microsoft Learnは機械翻訳で分かりにくいし、クラウドフローにはアクションのリファレンスがありません。SharePointは「戻り値:この操作の出力は状況に応じて変わります。」としか書いていないものがあり、初心者には意味不明です。

Power Platformではデータソースを変数で与えることが難しいので、データソースの切り替えが難しいです。なのでデータソースを分割することが難しく、データソースが大きくなり、クラウドの負荷が増える、という印象があります。

※ 当方はIT関係者でもプログラマでも無いMS-Officeアプリユーザーですので、間違いがあると思います。

| | コメント (0)

Power Apps / SharePoint のメモ

■ SharePointのリストを切り替える

Power Apps Formの参照データソースを動的に切り替える
https://zezeze.hateblo.jp/entry/2020/06/08/233157
何故か変数方式ではデータソースを切り替えることができませんでした。変数にデータソース型ってあるのでしょうか?

//NGコード:無効な引数が含まれていますとのエラーが出ます。
UpdateContext({locDs:cmbDs.Selected.Ds});
Patch(locDs,Defaults(locDs),{Title:locTitle});

テキストだから駄目なのかなと思い、データソースの配列を作ってLookupで抽出してもダメでした。
//NGコード
ClearCollect(dsDBs,{Sgn:"D01",dsDB:D01},{Sgn:"D02",dsDB:D02},...,{Sgn:"D99",dsDB:D99})
Patch(LookUp(dsDBs,Sgn=locDs,dsDB),Defaults(LookUp(dsDBs,Sgn=locDs,dsDB)),{Title:locTitle});

仕方がないので、Switchで切り替えました。リストの数だけ書くので間抜けで酷いコードです。

//多分OKだと思うコード
Switch(locDs,
"D01",Patch(D01,Defaults(D01),{Title:locTitle}),
"D02",Patch(D02,Defaults(D02),{Title:locTitle}),
...
"D99",Patch(D99,Defaults(D99),{Title:locTitle})
)

切り替えができるコントロールは一部です。
Patchとギャラリー(Item)は、Switchが使えました。
フォームとテーブルは、Switchで切り替えることができないようです。残念。

Global variable to store data source · Community (powerapps.com)

■ If()やSwitch()でリストの切り替えが可能な機能

1) 切り替え可能な機能

  • ギャラリー
  • Patch()

2) 切り替え不可能な機能

  • フォーム
  • データテーブル
  • Set()、UpdateContext()の中

 

■ SharePointのリストの項目名

SharePointのリストの項目名は少なくとも3つあるようです。
1) リスト表示画面で追加、変更できる表示名
2) リストの設定で表示、変更できる表示名
3) リストの設定でURLのFieldに表示される内部名

Power Appsで1つのSharePointリストを使用している場合は、表示名でコードを書きます。
Power Appsで複数の同じ項目名のリストを切り替える場合は、内部名でコードを書く必要がありそうです。なので、複数のデータソースを切り替える場合は、内部名=表示名にしておく必要がありそうです。

内部名に使用できる文字は半角アルファベットのみのようです。半角数字はNGです。アンダースコアは使えました。スペースやドットは使えません。
内部名は作成時に決まり、後から変更できません。

Excelからインポートしたリストの内部項目名は、最初の項目名がTitleになり、以降はField数字の形式になります。表示名はExcelの表示名になります。何故かExcelの項目名"Type"はインポートできません。しかし、SharePointのリストで項目名に"Type"は使用できます。内部名も"Type"は使用できます。Excelの日付をインポートするとSharePoint側の日付書式が変わります。変わる書式は一定ではありません。謎です。好みの書式にするには、JSONで設定する必要がありそうですが、この書式マニュアルの所在が不明です。

■ SharePointのリストのレコードの削除

レコード数が500を超えてくると、とても時間がかかります。

■ SharePointのリストにExcelのデータをコピー&ペーストで貼り付ける

レコード数が500を超えてくると、とても時間がかかります。一度にコピーするレコード数は100位にしておいた方が良さそうです。
Excel側の日付表示形式をSharePointの形式に合わせておく必要があります。また、Power Automateは日付&時刻を文字列で処理するようなので、時刻も表示しておいたほうが良さそうです。
調べていないのですが、もしかするとタイムゾーンの違いによる9時間ずれが発生するかも知れません??

Excelデータに問題が無くても、文字列に0x0Bがあるとのエラーで止まることがあります。この場合、0x0Bを示す□文字を消せば処理が再開されますが、エディタが非常に遅く1文字消すだけでも時間がかかります。

Excelデータに問題が無くても、日付のエラーで止まることがあります。

以上のことから大きなExcelのデータをコピー&ペーストでSharePointのリストに貼り付けるのは困難です。対策としては、Power Automateでコピーするフローを作成します。

Power AutomateでExcelからSharePointへ値を転記する際の対応方針(1):Excelのテーブル編
https://artisan.jp.net/blog/convert-excel-to-sharepoint-1/

■ 承認ワークフロー

Power Appsで承認ワークフローを検索すると、Power Automateの承認コントロールを使用するが多くヒットします。しかし、この方法では以下の欠点があるかもしれません。

(1) 30日を超えるとタイムアウトでワークフローが停止します。下記対応が示されていますが、Common Data Service connectorを使用するのでPremiumライセンス費用が必要です。
長期にわたる承認とその他の改善点:https://learn.microsoft.com/ja-jp/business-applications-release-notes/april19/microsoft-flow/long-lived-approvals-other-approval-improvements

(2) 承認待ちの数が52に制限されます。例えば平均承認期間が14日の場合、52/14=3.7件/日しか承認依頼を発行できません。
承認コネクタ利用に関する思わぬ落とし穴!?:https://tana-techlog.net/?p=334

上記欠点を考えると「Power Apps キャンバスアプリ上から承認/拒否を実施」の方が良いかもしれません。
Power Apps キャンバスアプリ:承認機能の設計方針:https://artisan.jp.net/blog/power-apps-canvas-app-approval/

■ リッチテキストエディタの書式

Power AutomateではなくPower Appsで承認フローを作るには、承認依頼メールに承認アプリのリンクを貼る必要があります。この為にはリッチテキストエディタで本文を作成する必要がありますが、Power Appsのリッチテキストの書き方の情報を発見できていません。試行錯誤した結果、リッチテキストコントロールのDefaultに以下を記述します。注意点は、href=の後のURLを"で囲んではだめで、'で囲む必要があるということです。

"<p>1. 下記の文書の確認をお願いします。<br/>
文書格納場所:<a href='" & gblUrl & "'>" & gblUrl & "</a></p>
<p>2. 下記のリンクの承認システムで承認処理をしてください。<br/>
承認システム:<a href='" & gblAppr & "'>" & gblAppr & "</a></p>"

下記ではリッチテキストコントロール上ではリンクになりますが、送ったメールがリンクになりません。
文書格納場所:<a href=&quot;" & gblUrl & "&quot;>" & gblUrl & "</a></p>
承認システム:<a href=&quot;" & gblAppr & "&quot;>" & gblAppr & "</a></p>"

■ SharePointの参照列をLookUpの条件式に入れる方法

参照列は値が入っているのではなく親のIDが入っているようです。なので、直接値の比較ができません。よって、親の値をLookUpで比較します。
SharePointの親リスト:Code,Model,Price,Weight
SharePointの子リスト:Code(参照列),Code:Model(参照で追加した列),Person,Qty,Date
Set(gblCode,"A0001");
LookUp(子,Code.Id=LookUp(親,Code=gblCode,ID),Person)

■ SharePointの参照列に値を書き込む方法

参照先には値ではなく参照元のIDを書き込みます。
Patch(参照先データソース,Defaults(参照先データソース),{Title:gblTitle,
参照列名:{'@odata.type':"#Microsoft.Azure.Connectors.SharePoint.SPListExpandedReference",
Id:LookUp(参照元データソース,参照列名=値).ID,Value:ダミー値}}

■ ParseJSON()をコレクションに変換する方法

ParseJSON()は型指定されていないテーブルを返すので、コレクションを操作する関数が使えません。そこで、下記方法によりコレクションに変換します。

PowerApps Parse JSON examples
https://devoworx.net/powerapps-parse-json-examples/
You can use the for all function to loop in your JSON string and collect the rows in your collection as shown in the bellow code.

これによりSharePointのリストの項目を固定したまま、可変長のテーブルやコレクションをJSON()でSharePointのリストに格納し、それを読み取りPower Appsのコレクション関係の関数で操作をすることができます。

入れ子の配列は次のように2重のForAllで型付のコレクションに変換します。

//元の入れ子の配列を持つコレクション
Set(NameA,"A");Set(NameB,"B");Set(NoA,1);Set(NoB,2);
//ClearCollect(colA,[1,2]); // DataAの初期値
//ClearCollect(colB,[3,4]); // DataBの初期値
ClearCollect(colA,[{Value:1},{Value:2}]); // DataAの初期値
ClearCollect(colB,[{Value:3},{Value:4}]); // DataBの初期値
ClearCollect(colJ,{Name:NameA,No:NoA,Data:colA});
Collect(colJ,{Name:NameB,No:NoB,Data:colB});

//コレクションをJSONに変換
Set(jsn,JSON(colJ)); //これをSharePointのリストの複数行テキストに保存します。jsnは次のようになります。
//[{"Data":[{"Value":1},{"Value":2}],"Name":"A","No":1},{"Data":[{"Value":3},{"Value":4}],"Name":"B","No":2}]
//([{"Data":[1,2],...のようにはならず、JSON()ではValueが付加されます。)

//ParseJSONからコレクションに変換
ClearCollect(colJ2,ForAll(Table(ParseJSON(jsn)),{Name:Text(Value.Name),No:Value(Value.No),Data:ForAll(Table(Value.Data),{Value:Value(ThisRecord.Value.Value)})})); //SharePointリストの複数行テキストからJSONを呼び出し、型付のコレクションに変換します。
Set(jsn2,JSON(colJ2)); //再びJSONにしてSharepointに戻すことができます。


■ 入れ子の配列を抜き出す方法

表colJ2のNo:1のレコードのData列に入っている1次元配列をcolA2に代入する方法
Clear(colA2);ForAll(LookUp(colJ2,No=1,Data) As Tmp,Collect(colA2,{Value:Tmp.Value}));

■ コンボボックスの初期値にアプリを起動しているOffice365ユーザーを初期値に設定する方法

DefaultSelectedItmesに下記を設定します。
{DisplayName:User().FullName,Claims:"office365Users.SearchUser" & Lower(User().Email),Department:"",Email:User().Email,JobTitle:"",Picture:""}

下記ではだめでした。
First(Office365ユーザー.SearchUserV2({SearchTerm:User().Email}).value)
Office365ユーザー.SearchUserV2({SearchTerm:User().Email}).value

コンボボックスのDefaultSelectedItemsは、Itemsと同じデータソースである必要があります。同じ値の変数などを設定するとコンボボックスに表示されるので、一見選択できているような表示になりますが、内容を読み出すと空になり選択できていません。この選択されていない初期値をコンボボックスから取得する方法を発見できていません。なので、コンボボックスからの値の取得は、以下のようにすることが考えられます。

1) 初期値を変数に保存。
2) IsBlank(.Selected.Feild)=falseなら、変数に.Selected.Feildを代入。
3) 2)ではなく、IsBlank(.SearchText)=falseなら、変数に.SearchTextを代入。
4) 2)3)ではなく、IsBlank(.SelectedItems) || IsEmpty(.SelectedItems) = trueなら、変数にBlank()を代入。

■ SharePointのドキュメントライブラリのコンテンツ数制限

2024年にSharePointのコンテンツ数が約4万を超えたところでPower Automate DPAのSPOアクションが数%失敗しました。リトライを入れてもダメです。暫く時間を置かないと成功しません。なので、1ライブラリのコンテンツ数を2万または5千以下で使うのが安全です。NASの様に自由にSharePointにファイルを入れるとコンテンツ数の削減が難しくなり危険です。Teamsのファイルも同じです。Power Platformは、速度とコンテンツ数については要注意です。キャッシュの更新は遅いです。

※ 当方はIT関係でもプログラマでも無いExcelユーザーですので、間違いがあると思います。

| | コメント (0)

« 2023年2月 | トップページ | 2023年5月 »