Power Appsから覗いてみるSharePoint Listsの添付ファイルの「AbsoluteUri」

# [SubmitForm](https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-form#submitform)後の添付ファイルの取得

言わずもがなな部分もありますが、Power Appsにおける編集フォームは自分が思っているよりも高性能です。

ユーザーがデータを追加、更新するときに使用する関数という認識ですが、
1. フィールドごとのエラーチェック
    - エラーの場合、`ErrorKind`プロパティが設定され、`OnFailure`式が実行
1. データ検証後に、データをデータソースに更新 `SubmitForm`
    - 成功した場合、Errorプロパティをクリア
    - `OnSuccess`式が実行される
    - 送信失敗の場合、Errorプロパティに問題の説明を設定
    - 同時更新を防ぐべく`ErrorKind.Conflict`というErrorKindを持つ
1. `Unsaved`プロパティで未保存の変更が失われるのを防ぐ

などなど、機能がモリモリ。

https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/controls/control-form-detail

その中でも`LastSubmit`は、正常に送信されたレコードを返す非常に便利なプロパティです。
**登録後に一意の値である`ID`を含め、レコードを丸々取得できます。**

さて、SharePoint Listsをデータソースにしていて、添付ファイルが有効である場合、
SubmitFormでは、Listsに添付ファイルをアップロードすることができます。

Power Appsの豊富な機能でも、*Power Appsのみ*の機能で、添付ファイルをアップロードすることは方法が限られます。

**アップロード先がListsの添付ファイル列ですが、複数のファイルをまとめてアップロードできる`SubmitForm`** は、それだけでも魅力的な機能といえます。

## Form.LastSubmit.添付ファイル
フォームコントロールの名前が`Form`の場合、
`「Form.LastSubmit.添付ファイル」`こちらから添付ファイルの一覧を取得できるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/3865f0c7-883b-139a-563c-628a247d7e15.png)

|列名|データ型|詳細|
|---|---|---|
|AbsoluteUri|`string`文字列|添付ファイルのリンク|
|DisplayName|`string`文字列|拡張子付きのファイル名|
|Id|`string`文字列|識別子|
|Value|`string`文字列|コントロールからファイルが保存がされる場所|

`テーブル型`のデータですので、`ギャラリー コントロール`で参照できそうだなと思います。

### ギャラリー コントロールを`Form.LastSubmit.添付ファイル`を表示できない

ところが面白いことに、`ギャラリー コントロール`の`Items`に`Form.LastSubmit.添付ファイル`を設定しても値は参照できません。なぜでしょうね。

 - カーソルを合わせると値の参照できるが
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/a50ff3b4-5c3f-058d-c9d4-a07d31630be4.png)

 - テキストラベルで値が参照できない（無効となる）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/708e5568-0dd3-b002-2cb1-5282fdcc0017.png)

:::note warn
私が、2024.06.10にキャンバスアプリで検証した結果
:::

### コレクションに格納しても表現できない。
`ClearCollect(colFiles, Form.LastSubmit.添付ファイル);`を使って、コレクション(colFiles)を`Items`に設定したらどうなるでしょうか。

おもしろいことに`colFiles`は、真っ白！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/32f652a6-f4a4-1170-86f0-2d2ee978d9f8.png)

### テーブル コントロールの場合
👆上がモダン、👇下がクラシックの`テーブル コントロール`です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/13c4fcd9-3c08-7a68-8f0e-71b51cf4f7ec.png)

- モダンは普通に表示される！
- クラシックはErrorを出しながら出力する

非常に謎な現象が発生します。

## とりま[ParseJSON 関数](https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-parsejson)で対処する

このままだと平行線ですので、[JSON 関数](https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-json)を用いて、値をJSON文字列にできるか試してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/9823ad7d-126d-6ca2-c451-cffdd9594f3a.png)

無事できました。

これから[ParseJSON 関数](https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-parsejson)を介して値を取得できそうです。

```plaintext:Items
// jsonObj: JSON(Form.LastSubmit.添付ファイル)をあらかじめ実行
Table(ParseJSON(jsonObj))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/1adfccba-0bf7-9368-c5d8-8ed3eb460fc0.png)

テキストラベルは
- `ThisItem.Value.DisplayName`
- `ThisItem.Value.Id`
- `ThisItem.Value.AbsoluteUri`

上記を指定しています。

## AbsoluteUri
`AbsoluteUri`を用いるとアップロードした添付ファイルが開けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/235386e2-a8cc-572e-242c-7bc1215df844.png)

AbsoluteUriは、`https://{SharePoint Site}/Lists/{Lists Name}/Attachments/{Listの行ID}/{File name}`と組み立てられます。アップロードしたあと、ファイル名はURLエンコードされます。
しかし前述で表現している`AbsoluteUri`や`DisplayName`は、エンコード前の文字が表示されます。

`ChatGPT`でありえないファイル名をいくつか作ってもらい、

```plaintext:プロンプト
誤作動の要因となるファイル名を複数のパターンから提案してください。
拡張子は全て.pdfとします。
```

```plaintext:GPTの回答
誤作動の要因となる可能性のあるファイル名のパターンを以下に提案します。これらのパターンは、システムやソフトウェアが適切に処理できない場合があります。

1. **特殊文字を含むファイル名**
   - `document?.pdf`
   - `report#.pdf`
   - `data<analysis>.pdf`

2. **非常に長いファイル名**
   - `this_is_a_very_long_file_name_that_might_cause_errors_in_some_systems_due_to_length_constraints.pdf`

3. **空白やタブを含むファイル名**
   - `report .pdf`
   - `file	 name.pdf`

4. **制御文字を含むファイル名**
   - `file\nname.pdf` (改行文字)
   - `file\tname.pdf` (タブ文字)

5. **システム予約語を含むファイル名**
   - `CON.pdf`
   - `PRN.pdf`
   - `AUX.pdf`
   - `NUL.pdf`

6. **異なる言語やエンコードを含むファイル名**
   - `ファイル名.pdf`
   - `файл.pdf`
   - `文件.pdf`

7. **拡張子が連続するファイル名**
   - `document..pdf`
   - `report.final.pdf`

これらのパターンは、特定のシステムやソフトウェア環境で誤作動を引き起こす可能性があります。テストや運用環境での使用にあたっては、注意が必要です。
```
- `document?.pdf`
- `data<analysis>.pdf`
- `file\nname.pdf` (改行文字)
- `file\tname.pdf` (タブ文字)

GUIで設定できないため、まずつく名前ではないだろう、ということで除外
将来を見越して`🐟ほうこく★📃.pdf`のような名前も使ってアップロードしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/2c729cb2-a173-3eb4-fa31-4339d58814ae.png)

アップロードしてみたところ、一部ﾀﾆにましたが、大体生きていますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/d361b80f-f613-d7bd-0f34-34a988de4a8d.png)

- 🙆 файл.pdf
- 🙆 ファイル名.pdf
- 🙆 🐟ほうこく★📃.pdf
- 🙆 文件.pdf
- ❌ NUL.pdf
- ❌ PRN.pdf
- 🙆 report .pdf
- ❌(リンク切れ) report#.pdf
- 🙆 report.final.pdf
- 🙆 this_is_a_very_long_file_name_that_might_cause_errors_in_some_systems_due_to_length_constraints.pdf
- 🙆 document..pdf
- 🙆 document.pdf.pdf
- 🙆 filename.pdf
- 🙆 filetname.pdf
- AUX.pdf
- CON.pdf
- ❌ dataanalysis.pdf

PCの予約語以外いけましたね。`AbsoluteUri`は絵文字であろうと空白を含んでいようと、そのまま評価されていることがわかりますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/e29c805d-9fc2-f575-660e-69827fb7b72e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/b1aee1d5-f764-abd8-30b3-a9de67efe6c9.png)

ちなみに`何も記載がないテキストファイルなどは、アップロードができません。`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/36e28ba4-22b8-3fbe-37bb-7d41481a18cd.png)

■ 何も残らない・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/bdd376df-8989-d667-ae70-9ca1cd7a7e99.png)

### Power Automateの`添付ファイルの取得`アクションで、リストの添付ファイル名を覗いてみると・・・

おいおい・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/fba2f2f9-c65b-30d1-db6a-771bba07d932.png)

まじかよ・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/0e8ac3b7-6a49-7976-5f03-0e673b1a99a6.png)

不思議だ・・・。

## こんな小技ができそう
これが何の役に立つか・・・あんまり日の目を帯びなそうですが、下記のシナリオが考えられます。

1. `SharePoint Lists`に`SubmitForm`で添付ファイルを登録する
1. `Concat関数`で`HTML文字列`から、`リンク付きファイル名`を作成する
1. (2)の`HTML文字列`を、`Power Automate`に渡す
1. `Power Automate`で、添付ファイルを`ドキュメント ライブラリ`に移動
1. (3)で`ファイルのリンク`を取得し、(2)のリンクと置き換え
1. Listの`HTMLテキスト`列に反映

といったシナリオ・・・・？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/9c71b4ce-4dd6-b574-bf36-47abe21319f4.png)

:::note warn
このような運用は決して推奨しません。
:::

### Form.LastSubmit.添付ファイルから、リンク付き文字列をつくる
`HTML テキスト`コントロールに下記の式を設定します。

```plaintext:HtmlText
Concat(
    Form.LastSubmit.添付ファイル,
    $"<p><a href='{AbsoluteUri}'>{DisplayName}</a></p>"
)
```
なぜかはわかりませんが、これも上手くいきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/87948180-987e-7144-c376-5b5964313635.png)

この`AbsoluteUri`を、
1. 添付ファイルのコンテンツの取得
1. ドキュメントライブラリにファイルをコピー
1. ファイルのプロパティの取得
上記から取得できる`アイテムへのリンクから置き換えてみます。`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/ae5e3eca-b49e-fb8f-349b-933943d53735.png)

**果たしてうまくいくでしょうか。**

# 結論 大体うまくいってしまう
`report#.pdf`のようなリンク切れを起こすファイル名でない限り、この変な技は成立します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/edf896e1-e13a-cdae-3a92-87388095d6a3.png)

赤枠から`ドキュメントライブラリに遷移`します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734332/d6741479-25e6-3531-aa5a-4050a47d9916.png)

いやー、誰かに怒られそうな実験ですね。