Share pointリストにJSONデータを格納しテーブルとして扱う方法

## やりたいこと
SharepointリストをDBとしたアプリ開発で、列を増やす事なくデータを可変に管理したい。
行が増える事を想定したり、行が増えるたびにメンテするなどをやりたくない

例
ユーザ毎に個人専用のリンク集を設定するアプリを作成する。
構成は、
・登録ユーザアドレス
・リンクタイトル
・リンク


## 実現方法
Sharepointリストの複数業にJson形式で値を格納する。

### なぜ？　
簡単なのと複数行テキストに63999文字も格納できるから
※文字数制限があるので格納天井がある事を理解した上で活用する


以下、Microsoft公式から上限の引用や、その他今回使う引用関係
MAXで63399文字格納できるらしい。
>[Sharepointリスト　複数行テキストに格納できる文字数上限](https://support.microsoft.com/ja-jp/office/%E3%83%AA%E3%82%B9%E3%83%88%E3%81%8A%E3%82%88%E3%81%B3%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE%E5%88%97%E3%81%AE%E7%A8%AE%E9%A1%9E%E3%81%A8%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3-0d8ddb7b-7dc7-414d-a283-ee9dca891df7#:~:text=%E3%83%AA%E3%82%B9%E3%83%88%E3%81%BE%E3%81%9F%E3%81%AF%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%A7%E6%9B%B8%E5%BC%8F,%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82)

>[Power AppsでのJSON。リスト登録時に使う](https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-json)

>[Parse Json。リストのJSONデータをAppsで使用する際に使う](https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-parsejson)

## 実際に作ってみる
### SPOリストを作成する
リスト名：CustomLinkMaster
| 列名 | 列プロパティ |列用途  |
|:-:|:-:|:-:|
|UserEmail| 1行テキスト  | アドレスでユーザを特定する(ユニークな値ならOK）  |
|LinkJson | 複数行テキスト|  リンクタイトル、リンクをJSON形式で格納する |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645607/df69e111-bffb-815b-9328-baaea896c3ba.png)


### Appsからリストへ登録時
テキストインプットを二個用意する。
登録用のボタンでチェックボックスを用意


以下画像の様にリンクタイトル、リンク、チェックボックスを用意し、JSON登録する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645607/b252c658-54e5-ef87-7ea8-ddf34aac7c15.png)

チェックボックスのoncheckプロパティで以下コード記述
最初のSplit結果は冗長なので、短縮して書くことをお勧めします。
コード修正後記事に反映します。。。

※Jsonformatの部分でcompactを指定すると、値を詰めてくれるので、文字数を最低限にする際に使用する事を勧めます。
```swift
//初期設定。変更前のリンクタイトル、リンクをJSONで取得し、[]以外の文字列にする
Set(jsondatatext,LookUp(CustomLinkMaster,UserEmail = User().Email,LInkJson));
Set(firstcut, Split(jsondatatext,"["));
Set(cutdate,Concatenate(Last(FirstN(firstcut,2)).Value));
Set(lastcut,Split(cutdate,"]"));
Set(splitdate,Concatenate(First(lastcut).Value));


//結合するJSONを作成する
Set(
    AddJson,
    JSON(
        {
//TにタイトルをLにリンクをセットする
            L: TextInputCusLink_4.Text,
            T: TextInputCusLinkTitle_4.Text
           
        },
        JSONFormat.IndentFour
    )
);

//受けとったデータを元にpathdate変数に結合する
Set(pathdate,
    Concatenate("[" , splitdate,",",AddJson,"]")
);
//↓↓以下コードはアプリでコレクションデータを表示する為使用する。使わなければ削除可
    Collect(ParsedDataindex,
        {
            リンクタイトル:TextInputCusLinkTitle_4.Text,
            リンク:TextInputCusLink_4.Text,
            index:CountRows(ParsedDataindex)+1
        }
    );
//↑↑↑    

//最終的にデータソースを書き換える。
If(IsEmpty(ParsedDataindex),
    Patch(CustomLinkMaster,
        {
            LInkJson:pathdate,
            UserEmail:User().Email
        }
    ),
    Patch(CustomLinkMaster,
        LookUp(CustomLinkMaster,UserEmail = User().Email),
        {
            LInkJson:pathdate
        }
    )
);


//テキストインプットをクリアする
Reset(TextInputCusLink_4);
Reset(TextInputCusLinkTitle_4);
Reset(Checkbox2_7)
```


### Appsからリスト参照時

画面のonvisibleに以下を記述して、リストのJsonデータを解析する。
index番号を振ったコレクションを作成することによって、任意のレコード削除、更新へ対応する。

```swift

//自分専用のカスタムリンクを取得するコレクションにemail＝でフィルタリング
ClearCollect(UserSubmitLinkcol,Filter(CustomLinkMaster,UserEmail = User().Email));

//編集前自分のデータを定義アドレス＝で
Set(colJson,LookUp(CustomLinkMaster,UserEmail = User().Email,LInkJson));
Set(UserCus, Table(ParseJSON(colJson)));

Set(jsondatatext,LookUp(CustomLinkMaster,UserEmail = User().Email,LInkJson));


//コレクション化
ClearCollect(  
    ParsedData,  
    ForAll(
        ParseJSON(jsondatatext),
        {
            リンクタイトル:ThisRecord.T,
            リンク:ThisRecord.L
        }
    )
);

Clear(ParsedDataindex);
//連番を振る削除キーとする為
ForAll(ParsedData,
    Collect(ParsedDataindex,
        {
            リンクタイトル:Text(ThisRecord.リンクタイトル),
            リンク:Text(ThisRecord.リンク),
            index:CountRows(ParsedDataindex)
        }
    )
);
```

## 纏め
この仕組みは一度理解してしまえば色んな場所で使いまわせそうなのが良い。
コード自体は必要最低限のみ記述したので、中身を更に知りたい等あれば連絡してください。

今回の実装とは異なりますが、複数行テキストで2進数を使用し、フラグで膨大な情報を管理する事例をやってるユーザもいたので、
発想は色々あるなと思いました。