コルネの進捗や備忘録が記されたなにか

進捗や成果物や備忘録てきななにかを雑に更新していきます。

Power Apps でSharePoint のドキュメントライブラリを再現する


スポンサードリンク

はじめに

今回はPower Apps でSharePoint のドキュメントライブラリを再現してみようと思います。
完成イメージはこんな感じ。

f:id:koruneko:20210627173823g:plain

"進むボタン"と"戻るボタン"の実装が鬼門ですかね。

PowerApps でSharePoint のドキュメントライブラリを再現する

ドキュメントライブラリの情報を取得する

まずはSharePoint のドキュメントライブラリの情報を取得します。

"データの追加"より”SharePoint”を選択します。

f:id:koruneko:20210627174859p:plain

右にでてきたメニューより、取得したいサイトを選択し、"ドキュメント"を選択します。

f:id:koruneko:20210627175140p:plain

これにより選択したサイトのドキュメントライブラリの情報が取得できます。
中を見てもらえればわかる通り、フォルダ / ファイルの数だけレコードが存在しています。

こちらのデータソースにも他と同様委任問題が発生しますので、コレクションに格納しておきます。

Screen.OnVisible

ClearCollect(documentsLib, ドキュメント);

ドキュメント情報を表示する

先ほど取得した情報をもとに、ドキュメント情報を表示させたいと思います。

ここで、取得した情報はファイル / フォルダーの数だけレコードが存在しているので、そのままギャラリーの Itmes に設定してしまうときちんとした階層で、ファイル / フォルダが表示できません。

そこで、現在表示中のディレクトリのみをフィルタリングして表示するように今回はしたいと思います。

ディレクトリの情報は {Path} に設定されています。

f:id:koruneko:20210627182125p:plain

ただ、Filter 関数などで列を指定するときは {Path} ではなく フォルダーのパス という列名で指定してあげる必要があるので、注意してください。
* 設定が日本語の場合

ギャラリーを設置して、 Items に以下を設定します。

Gallery.Items

Filter(documentsLib, フォルダーのパス = "Shared Documents/")

これにより、ホームディレクトリである、"Shared Documents/" 配下の情報のみがフィルター表示されるようになります。

あとは、ドキュメントライブラリやサンプルのような表示になるように、コントロールを配置して式を設定します。

参考までに列の情報を記載しておきます。

列名 設定内容 使用例
Thumbnail サムネイル
*ドキュメントライブラリで
使われているようなアイコンではありません
ThisItem.Thumbnail.Large
拡張子付きのファイル名 拡張子のついたファイル名
フォルダの場合はフォルダ名
ThisItem.拡張子付きのファイル名
登録日時 ファイル / フォルダを作成した日時 ThisItem.登録日時
登録者 ファイル / フォルダを登録したユーザの情報 ThisItem.登録者.DisplayName
更新日時 ファイル / フォルダを更新した日時 ThisItem.更新日時
更新者 ファイル / フォルダを更新したユーザの情報 ThisItem.更新者.DisplayName
フォルダーである フォルダの場合はTrue ThisItem.フォルダーである

よく使うのはこのぐらいでしょうか。
サムネイルですが、記載している通りSharePoint のドキュメントライブラリで使用されているようなアイコンではないことに注意してください。
文字通りサムネイルです。
Excel であれば、シートのスクショした情報、画像であれば、その画像などが設定されています。

あとは、わかりやすくタイトルのラベルを設定してあげればそれっぽくなりますね。

f:id:koruneko:20210627191435p:plain

ディレクトリを移動できるようにする

続いてディレクトリを移動できるようにします。

ユーザの選択によって、フィルターするパスの条件を変更すれば、ディレクトリを移動しているようにみせることができます。

ユーザのカレントディレクトリを判断する方法ですが、コレクションに設定された情報をごにょごにょすることによって判断しようと思います。
何故テキストで保持するのではなく、わざわざコレクションでディレクトリ情報持つの?というと、進む / 戻るボタンを実装するためです。
詳細は次のセクションで説明します。

ディレクトリ情報を格納するためのコレクションを宣言します。

Screen.OnVisible

ClearCollect(
    selectHistory,
    {id:1, dir:"Shared Documents", isCurrent:true}
)

id は連番、 dirディレクトリの名前、 isCurrent には現在ユーザがそのディレクトリにいるのであれば true を、いないのであれば、 false を設定します。

このコレクションの内容をもとに、ディレクトリのフルパスをラベルに表示させます。
このラベルの内容をもとにフィルターを行うようにしたいので、 {Path} と同じフォーマットで表示させます。

currentDirLbl.Text

Concat(
    Filter(
        selectHistory,
        id <= LookUp(selectHistory, isCurrent = true, id)
    ),
    dir & "/"
)

簡単に説明しますと、ユーザが現在いるディレクトリより前のディレクトリ( id )でフィルタリングして、dir に設定されている、ディレクトリ名を "/" で繋げて1つの文字列としています。

このラベルのテキストをもとに、フィルタリング処理を行いたいので、以下のように設定します。

Gallery.Items

Filter(documentsLib, フォルダーのパス = currentDirLbl.Text)

次にフォルダーを選択したときに、選択したディレクトリ情報をコレクションに設定する処理を記載します。

ユーザがフォルダを選択したときには以下の処理を行う必要があります。

  1. ユーザが選択したディレクトリをコレクションに設定
  2. カレントディレクトリの変更

1の処理はコレクションにレコードを追加してあげればよいです。
2の処理は、先ほどまで isCurrenttrue だったレコードの isCurrentfalse に設定してあげればよいです。

2の処理を実現するために、先ほどまでのカレントディレクトリがどれだったか?
を記憶するための変数が欲しいので、 oldCurrentId を設定します。

Screen.OnVisible

UpdateContext({oldCurrentId:LookUp(selectHistory, isCurrent = true, id)});

これで、1, 2を実装する準備が整いましたのでさっそく実装していきます。

Label.OnSelect

UpdateContext({oldCurrentId:LookUp(selectHistory, isCurrent = true, id)});
Collect(
    selectHistory,
    {
        id:LookUp(selectHistory, isCurrent = true, id) + 1,
        dir:ThisItem.名前,
        isCurrent:true
    }
);
UpdateIf(selectHistory, id = oldCurrentId, {isCurrent:false})

これで、ディレクトリの変更が実装できました!

進む / 戻る機能を実装する

いきなり、実装やロジックを文字で解説する前に簡単にそれぞれのボタンが押されたときの動作を図示したいと思います。

それぞれの操作を行うと、 selectHistory コレクションは以下のような動きになります。

戻るボタンを選択したとき
f:id:koruneko:20210627195838p:plain

進むボタンを選択したとき
f:id:koruneko:20210627195906p:plain

薄い青になっているラベルがユーザのカレントディレクトリです。

図のように、進む / 戻るボタンを押してもレコード数は変化させません。(追加も削除も行わない。)
コレクションのレコード数が変化するのは、ユーザがフォルダーを選択したときだけです。

こうしないと、戻るや進むを選択したときにユーザの選択履歴とは異なる情報が保持されてしまい、正しく機能しなくなってしまいます。

以上を踏まえて、実装を行ていきます。

戻るボタンは、カレントディレクトリを1つ前のものに戻す操作ですので、以下で実現できます。

BackIcon.OnSelect

UpdateContext({oldCurrentId:LookUp(selectHistory, isCurrent = true, id)});
UpdateIf(selectHistory, id = oldCurrentId, {isCurrent:false});
UpdateIf(selectHistory, id = oldCurrentId - 1, {isCurrent:true});

戻るボタンは、カレントディレクトリを1つ先のものにする操作ですので、以下で実現できます。

fowardIcon.OnSelect

UpdateContext({oldCurrentId:LookUp(selectHistory, isCurrent = true, id)});
UpdateIf(selectHistory, id = oldCurrentId, {isCurrent:false});
UpdateIf(selectHistory, id = oldCurrentId + 1, {isCurrent:true});

また、戻るボタン、進むボタンともに、戻る先や進む先がないのに押されてしまうと困ります。
よって、戻る先がないときは戻るボタンを非活性に、進む先がないときは進むボタンを非活性にします。
これは皆さんが普段お使いのブラウザでも同じ動作を行っているはずです。

戻るボタンは、カレントディレクトリのレコードの id ( isCurrenttrue のレコードの id )より、小さい id がなければ、もう戻れる先がないので、非活性にします。

BackIcon.DisplayMode

If(First(Sort(selectHistory, id, Ascending)).id < LookUp(selectHistory, isCurrent = true, id),
    DisplayMode.Edit,
    DisplayMode.Disabled
)

進むボタンはカレントディレクトリーのレコードの id より大きいものがなければ、もう進む先がないので、非活性にします。

fowardIcon.DisplayMode

If(Last(Sort(selectHistory, id, Ascending)).id > LookUp(selectHistory, isCurrent = true, id),
    DisplayMode.Edit,
    DisplayMode.Disabled
)

最後に、戻るボタンを押してそこでユーザがディレクトリを選択したとき。
そのディレクトリよりあとのディレクトリの情報は削除しなくてはならないので、以下の式を設定します。

Label.OnSelect

RemoveIf(selectHistory, id > oldCurrentId);

この式は、新たにレコードを追加する前に行う必要がある( id の連番に整合性をもたせるため)
Collect の前に行います。

Label.OnSelect

UpdateContext({oldCurrentId:LookUp(selectHistory, isCurrent = true, id)});
RemoveIf(selectHistory, id > oldCurrentId);
Collect(
    selectHistory,
    {
        id:LookUp(selectHistory, isCurrent = true, id) + 1,
        dir:ThisItem.名前,
        isCurrent:true
    }
);
UpdateIf(selectHistory, id = oldCurrentId, {isCurrent:false})

以上で、Power Apps でドキュメントライブラリの再現ができました!

おわりに

ちょっと前までは、Power Apps からSharePoint のドキュメントライブラリの情報を取得するのはちょっとめんどうだった(はず)ですが、リストを選択する際に”ドキュメント”を選択すれば簡単に取得できるようになりました。

今度は、Power Apps からSharePoint のドキュメントライブラリへファイルをアップする方法を纏めたいと思います。
業務連絡ですが、Power Apps からアップしたExcel ファイルをPower Apps で表示する(列が可変のもの)というのはちょっと実現できなさそうです。。。

不明点や誤りなどありましたら、遠慮なく指摘してくださいー。


スポンサードリンク