業務の隙間を埋める技術メモ。

「それ、作れるか?」より 「それ、作って大丈夫か?」を考えたい。 業務で“ちゃんと使える”かどうかを、 実際に手を動かして確かめたログを残しています。

世紀末オフィスを救え。 椅子取り合戦を終わらせるため、Power Platformだけで座席予約アプリを作ってみた話

 

きっかけ:静かなオフィス、荒ぶる全社会議の日

普段のオフィスは、正直がらんどう。
固定席もないし、来客も少ない。
「今日はどこ座ろうかな」くらいの、のどかな世界。

ところが全社会議の日。

リモート勤務のメンバーが一斉に出社し、
開場と同時に始まる椅子取り合戦

  • 電源が近い席は即消滅

  • 画面が見やすい席も即消滅

  • 出遅れた人は「空いてるけど微妙」な席へ…

誰が悪いわけでもないけど、
なんとなく殺伐とするこの空気、どうにかしたい。

「だったら予約制にすればいいのでは?」
→ でも専用ツールを入れるほどでもない
→ じゃあ Power Platformで作ってみるか

という流れで、座席予約アプリを作ることにしました。

めざせマルス!(いやいやそこまでは目指しません、あしからず。)

 


ゴール設定(あくまで控えめに)

最初から立派なものは目指さず、ゴールはこれだけ。

  • スマホ・PCから座席を予約できる

  • 誰がどこを使うか“なんとなく”見える

  • 管理者が死なない(運用が楽)

優雅なオフィス改革とか言いつつ、
実態は「当日の無言の圧を減らしたい」だけです。


全体構成:Power Platform縛り

使ったのはこれだけ。

  • SharePoint List:データ置き場

  • Power Apps(Canvas:予約画面

  • Power Automate:通知用(おまけ)

Dataverseも使わず、
Microsoft 365契約があればだいたいある構成」です。


データ設計(まずは素直に)

座席マスタ(Seats)

列名 内容
Title 1行テキスト 座席名(A-1など)
Area 選択肢 エリア
HasPower Yes/No 電源あり?

予約テーブル(Reservations)

列名 内容
Seat 参照 Seats
ReservedBy ユーザー 予約者
ReserveDate 日付 利用日

この時点では
「時間帯」は割り切って入れませんでした
午前午後で揉める未来が見えたので…。


Power Apps:画面は3つだけ

① 座席一覧画面

ギャラリーに Seats を並べます。

Seats

予約済みかどうかは、
その日の予約が存在するかで判定。

If(
    CountRows(
        Filter(
            Reservations,
            Seat.Id = ThisItem.ID &&
            ReserveDate = Today()
        )
    ) > 0,
    RGBA(200,200,200,1),
    RGBA(255,255,255,1)
)

グレー=埋まってる
これだけでだいぶ平和になります。


② 予約ボタン

空いている席だけ予約可能に。

If(
    CountRows(
        Filter(
            Reservations,
            Seat.Id = ThisItem.ID &&
            ReserveDate = Today()
        )
    ) = 0,
    Patch(
        Reservations,
        Defaults(Reservations),
        {
            Seat: ThisItem,
            ReservedBy: User(),
            ReserveDate: Today()
        }
    )
)

押せたら予約完了。
エラーハンドリング? 最初はありませんでした。


③ 自分の予約確認画面

Filter(
    Reservations,
    ReservedBy.Email = User().Email &&
    ReserveDate = Today()
)

「今日はここ座ります」が一目で分かるだけで、
朝の精神的コストが激減しました。


Power Automate(おまけ)

予約完了時に Teams に通知。

  • トリガー:SharePoint「アイテム作成時」

  • アクション:Teams に投稿

正直、これはなくても成立します。
でも「予約した感」が出てちょっと楽しい。


実際に使ってみて良かった点

  • 朝の無言の圧が消えた

  • 席を探してウロウロする人が減った

  • 「あ、そこ◯◯さんなんだ」が分かる安心感

殺伐さはかなり軽減されました。
オフィス、ちょっとだけ優雅。


反省点・ハマりどころ(重要)

① 同時押し問題

ほぼ同時に2人が予約 → 両方成功するケースあり。

さすがに放置できず、疑似排他制御を入れた

 

最初に作った版では、
ほぼ同時に2人が「予約」ボタンを押すと、両方成功してしまうという問題がありました。

デモなら笑って済むけど、
実運用ではさすがにまずい。

とはいえ、

…を持ち出すほどでもない。

そこで今回は
Power Apps × SharePointでできる範囲の疑似排他制御
という割り切った方法を使いました。


考え方:予約前に「仮押さえ」フラグを立てる

やったことはシンプルです。

  1. 座席マスタに「ロック用の列」を追加

  2. 予約処理の最初でロックを取る

  3. ロックが取れなければ予約中止

Seats に追加した列

列名 用途
IsLocking Yes/No 予約処理中かどうか
LockTime 日時 ロック開始時刻

「誰が取ったか」までは持たず、
短時間だけロックする前提にしました。


実装①:ロック取得(最初の関門)

予約ボタンを押したら、まずこれを実行します。

If(
    ThisItem.IsLocking,
    Notify("他の人が予約処理中です。少し待ってください。", NotificationType.Error),
    Patch(
        Seats,
        ThisItem,
        {
            IsLocking: true,
            LockTime: Now()
        }
    )
)

ここでポイントなのは、

  • ロック取得だけを先にやる

  • 予約登録はまだしない

という点。

これで「ほぼ同時押し」でも
後から来た人は弾かれるようになります。


実装②:予約登録(再チェック付き)

ロック取得後、あらためて予約済みチェック。

If(
    CountRows(
        Filter(
            Reservations,
            Seat.Id = ThisItem.ID &&
            ReserveDate = Today()
        )
    ) = 0,
    Patch(
        Reservations,
        Defaults(Reservations),
        {
            Seat: ThisItem,
            ReservedBy: User(),
            ReserveDate: Today()
        }
    ),
    Notify("すでに予約されています。", NotificationType.Error)
)

ロックを取っていても油断しない
というのが地味に大事でした。


実装③:ロック解除(忘れると事故る)

予約が成功しても失敗しても、
最後に必ずロック解除。

Patch(
    Seats,
    ThisItem,
    {
        IsLocking: false,
        LockTime: Blank()
    }
)

これを忘れると
永久に予約できない座席が誕生します。
実際、一度やらかしました。


念のため:ロックの自然死も入れておく

アプリが落ちた、通信が切れた、などを考慮して
「一定時間たったロックは無効」としました。

If(
    ThisItem.IsLocking && DateDiff(ThisItem.LockTime, Now(), Seconds) > 30,
    Patch(
        Seats,
        ThisItem,
        {
            IsLocking: false,
            LockTime: Blank()
        }
    )
)

30秒は完全に感覚値ですが、
人が押して考えて戻る時間としては十分でした。

 


② 日付の扱い

Today() 基準だと、

という地味な罠。
後から「予約日選択」を追加しました。


③ 座席レイアウト欲が出る

途中から
「オフィス図面を背景に置きたい」
「色分けしたい」
と欲が暴走。

まずは一覧で十分だったな、という反省。


まとめ:完璧じゃないけど、今すぐできる

このアプリ、

  • 設計はシンプル

  • コードも短い

  • 失敗しても業務が止まらない

という、Power Platformの練習題材としてちょうどいい感じでした。

「オフィスの小さなストレス」を
大げさなDXにせず、
自分たちで雑に直す

そんなノリでも、
意外と現場は救われます。

 

同じように椅子取り合戦で心をすり減らしている方の
参考になれば幸いです。