PowerAppsからOffice予定表に予定を登録・更新・削除

<iframe width="560" height="400" src="https://www.youtube.com/embed/03nPDoz-MI4?si=-5jB_x8cWAGB_bVm" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
動画でも解説しています

## Office365Outlookコネクタを使用する

左メニューから「データ』→「＋データの追加」
「Office365」で検索して```Office365Outlook```を追加します。

または、新しい画面の追加で「カレンダー」画面を追加すれば自動的にコネクタが追加されます。
![98C0DD54-E9CF-4C99-A93A-55235DEFCD78_1_201_a.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/616fe419-883d-0ba9-83b4-c8a4c5596468.jpeg)
ドロップダウンボックスでは閲覧可能な予定表を選択することができます。
予定表を選択すると変数```_myCalendar```に予定表の情報が格納されます。

カレンダーで予定がある日を選択すると、下にその日の予定の一覧が表示されます。

予定の一覧の件名・タイトルのOnSelectプロパティを見てみると、
```Set(_selectedCalendarEvent, ThisItem)```
が設定されていて、変数```_selectedCalendarEvent```に
イベントIDや件名・開始時間・終了時間等の予定の情報が入るようになっています。

今回は、編集画面に遷移するように```Navigate(EditScreen)```を追加しています。

## 編集画面を準備
新しい画面を追加から、編集画面```EditScreen```を作成しました。
![8183BD51-6F13-4F06-AE9A-27B376700535_1_201_a.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/3a2e88b1-694d-a1b0-10b1-124f8aee134c.jpeg)
上から
ドロップダウンボックス
チェックボックス
日付の選択、ドロップダウンボックス、ドロップダウンボックス
日付の選択、ドロップダウンボックス、ドロップダウンボックス
テキストインプットボックス
リッチテキストエディター
を配置して、

それぞれの規定(Default)に
```_selectedCalendarEvent.〜〜```
で選択した予定の情報が入るようにしています。

一番上のドロップダウンボックスだけは、```_selectedCalendarEvent```から取得できなかったので、```_myCalendar.DisplayName```を規定(Default)に入れています。

または、カレンダー画面の予定件名のOnSelectプロパティを
```javascript
//イベント情報に予定表情報を追加して変数に格納する
Set(_selectedCalendarEvent, 
    AddColumns(ThisItem,calname,_myCalendar));
//編集画面に遷移
Navigate(EditScreen);
```
として、変数```_myCalendar```の情報を、あらかじめ変数_selectedCalendarEventに追加しておけば、
```_selectedCalendarEvent.calname.DisplayName```で予定表の名前
```_selectedCalendarEvent.calname.Name```で予定表ID
が取得できるので、良いかもしれません。

## 開始時刻・終了時刻の作成
予定の追加・更新をする際に、開始時刻と終了時刻は、日時の形式を```"yyyy-mm-ddThh:mm:ss"```のようにテキスト形式で指定します。
予定の追加・更新を行うボタン等のOnSelectプロパティで
初めに変数を作っておくと良いです。
```typescript
//開始日時の文字列を作成する
Set(_start_time,
    If(CheckboxAllday.Value,
        //終日のチェックボックスがtrueの時は0時0分にする。"yyyy-mm-ddTHH:mm:ss"で作成
        Text(event_start.SelectedDate,"yyyy-mm-dd")&"T00:00:00",
        Text(event_start.SelectedDate,"yyyy-mm-ddT")&Text(Value(start_HH.SelectedText.Value),"00:")&Text(Value(start_MM.SelectedText.Value),"00:")&"00")
    );

//終了日時の文字列を作成する
Set(_end_time,
    If(CheckboxAllday.Value,
        //終日のチェックボックスがtrueの時は23時59分にする。"yyyy-mm-ddTHH:mm:ss"で作成
        Text(event_start.SelectedDate,"yyyy-mm-dd")&"T23:59:59",
        Text(event_end.SelectedDate,"yyyy-mm-ddT")&Text(Value(end_HH.SelectedText.Value),"00:")&Text(Value(end_MM.SelectedText.Value),"00:")&"00")
        );
```

終日予定の場合、開始時刻と終了時刻を同じにしてしまうとエラーになります。
終了時刻を翌日00:00:00に指定するか、23:59:59で指定すると大丈夫です。
どちらにしても終日設定にした予定は、0時から翌0時で登録されるようなので好みで選んでください。
この数式では、チェックボックスがtrueの場合は開始時刻を00:00:00にして、終了時刻を23:59:59にしています。


## 予定の追加
予定の追加には以下のコードを先ほどのコードに続けて記載します。
```javascript
Office365Outlook.V4CalendarPostItem(
        DropDownBox_Calendar.Selected.Name,//選択した予定表のID※IDだけどNameで取得
        TextInputBox_title.Text,//件名＊テキスト形式
        _start_time,//開始時刻＊テキスト形式で"yyyy-mm-ddThh:mm:ss"
        _end_time,//終了時刻＊テキスト形式で"yyyy-mm-ddThh:mm:ss"
        "(UTC+09:00) Osaka, Sapporo, Tokyo",//タイムゾーンの指定
        {
            isAllDay:CheckboxAllday.Value, //終日予定の場合はtrue
            body:RichTextEditorBody.HtmlText //予定の詳細・本文 ＊HTMLかテキスト形式
        }
    )
```
第１引数の予定表IDに指定しているドロップダウンボックスのItemsプロパティには
```javascript
Office365Outlook.CalendarGetTables().value
```
が入っており、自分が閲覧できる予定表を選択できるようになっています。
選択した予定表のIDは、ドロップダウンボックス名```.Selected.Name```で取得できます。

第２引数の件名・予定のタイトルはテキスト形式ですので、テキストインプットボックス等からテキスト形式で指定。
第３・４引数が、開始時刻と終了時刻です。先ほど作成した変数を指定しています。

第５引数はタイムゾーンの指定で日本なら上記の通り。

ここまでは、必須の設定です。
波括弧で囲ったテーブル形式の部分はオプションで、終日の設定や予定の詳細・本文を指定することができます。
さらに、必須参加者や任意参加者の指定もできます。


## 予定の更新
予定の更新の場合は、以下のコードを先ほどのコードに続けて記載します。
```javascript
Office365Outlook.V4CalendarPatchItem(
        DropDownBox_Calendar.Selected.Name,//選択した予定表のID※IDだけどNameで取得
        _selectedCalendarEvent.Id,//イベントのID
        TextInputBox_title.Text,//件名＊テキスト形式
        _start_time,//開始時刻＊テキスト形式で"yyyy-mm-ddThh:mm:ss"
        _end_time,//終了時刻＊テキスト形式で"yyyy-mm-ddThh:mm:ss"
        "(UTC+09:00) Osaka, Sapporo, Tokyo",//タイムゾーンの指定
        {
            isAllDay:CheckboxAllday.Value, //終日予定の場合はtrue
            body:RichTextEditorBody.HtmlText //予定の詳細・本文 ＊HTMLかテキスト形式
        }
    )
```
予定の追加との違いは、第２引数のイベントIDのみとなっています。
カレンダー画面などで選択した予定のIDを指定することで、その予定を更新することができます。
## 予定の削除
予定の削除は以下のコードをボタンやアイコンなどのOnselectプロパティに指定します。
``` javascript
Office365Outlook.CalendarDeleteItemV2(
    DropDownBox_Calendar.Selected.Name,//予定表のID
    _selectedCalendarEvent.Id//選択したイベントのID
);
```
指定するのは第１・２引数のみで、予定表IDとイベントIDを指定することでその予定を削除することができます。
例で挙げたように```_selectedCalendarEvent```に予定表情報を追加していれば
```_selectedCalendarEvent.calname.Name```で予定表IDを指定できます。

## バグ？終日予定の開始・終了時刻について
カレンダー画面でOutlook予定表の予定を取得した際に、
終日に設定されている予定の開始時刻が9:00、終了時刻が翌日9:00で取得されてしまいます。
Outlook予定表で終日設定を外すと0:00になり、アプリ側も読み込み直すと0:00になります。

問題となるのは、アプリで終日設定を外して日時を指定する際にデフォルトで表示されるのが9:00〜翌9:00であるため、ユーザーが気付かずに時間だけを変更し、翌日に渡る予定として誤登録してしまう可能性が出てきます。

おそらくバグだと思うのですが、対策としてアプリ側で終日を外した際は、開始の日付と終了の日付が同じになるように手を加える必要がありそうです。