今から新しいExcel連携業務改善アプリを請けるときの設計と見積と炎上回避ポイント

という名の、ある人に宛てたお手紙です。

先日、とある戦友が異郷の地で、少ない経験ながらWPFを使って「業務改善のデスクトップアプリを作る」プロジェクトを任されたと聞きました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129567/d3d3e0f4-a8b4-4946-a356-81eaa7a1b647.png)

それだけだと良いチャレンジだねとなるのですが、よく聞いてみるとちょこっとした社内アプリじゃなくて割とちゃんとした案件のようで、従来Excel方眼紙でなんやかんややってたのを効率化したいのでアプリを作りたいという、ありがちな要求だけどアプリとしてはそこそこの仕立てが必要そうなヤツでした。

別の会社の案件なので当然詳しく内容を聞けるものではありませんが、こういった案件もいくつかやってきた小職は相談の端々から次のような情報を読み取り、

- WPFの経験者が居ない
- デスクトップアプリの経験も少ない
- なので見積もり精度が低い
- 数カ月の短い工期
- 少数精鋭ではなく少数初心者
- 開発者の立場が弱い
- WPFというイニシャル学習コスト高めのフレームワーク
- WPFのDataGridという魔物とExcelぽくできるという幻想

というような特徴から破局的炎上の気配を察しまして、外野から説教じみたおせっかいかつ厚かましくも、あなたの心が心配になりプロジェクトの計画見直しとそれにあたり取るべき行動を具申するものであります。

:::note info
なおこの案件はこの記事を書き上げたあたりで丁度、見直しの話が挙がったそうです。そのためこの記事は、ついでに記事数を稼ぐかという浅ましい業にポエムという言い訳を付けて0と1の世界の隅を汚すものと成ります。
:::

## クライアントの業務を知り要求を獲得する

まずこのアプリでやることリスト（WBS: Work Breakdown Structure）を作るもっともっと前段から首を突っ込んだ方がよさそうです。クライアントの業務のできるだけ全容を学び、このアプリ解決するのはどの範囲なのかをあなたの言葉で説明できるようにしましょう。

これは仕様書でもREADMEでもよいのですけど目立つ場所や文書の先頭に、見やすいように書いておき、クライアントと合意しておきましょう。最低限ですが例えば次のような感じです。

```
このアプリケーションは2024年まで手動で運用していた「XXXX管理Excelブックファイル」に対する定型的な作業を自動化するためのシステムです。
バージョン1.0.0ではXXXX業務にまつわる次の作業を自動化します。
- XXXX登録
- XXXX検証
- XXXXレポート作成
```

しっかり開発プロセスを持っているところだと、プロジェクト計画書のような文書の一番先頭に書くと思います。

これは工期中にクライアントからの何気ない追加要望からあなたを守るための責任範囲です。こと「業務効率化」はアプリの責任範囲がふわっとしがちなので、ナアナアにすると炎上ポイントが上がります。

さてこのフェーズはおそらく、あなたもまた苦手としているかもしれない、コミュニケーション能力が重視される仕事です。しかしこのフェーズをおろそかにして出来上がったアプリは微妙な仕上がりになることが多いです。

- 「自動テストシステムを作る」ことになっていたのに、実はクライアントは監視システムが欲しかった
- クライアントの業界や業務の流れを学ばなかったため、いわゆるドメイン駆動開発的なプラクティスを汲めず、ツギハギだらけでメンテ不可能になった

こういったことは私もやらかしましたし、他社がやらかしたアプリをリプレースしたりと、実際に何度も目にしました。

業務を理解している開発者が協力してくれるのは、クライアントにとっても非常に心強いことです。例えば、あなたはゲームプログラミングが得意ですね。60FPSという制約を守るために、日々効率のよいコーディングを欠かしません。そんなところへ現れた新しいメンバーが、イミュータブルな関数型プログラミングの方が優れてるんッスよとか言って、「それを知っててあえて今のコードにしてるんだよ」というこちらの考えをよそに毎フレーム遠慮なくデカいメモリアロケーションをしまくるコードをコミットしてきたら殺意を向けたくもなるでしょう。

なおここでいうコミュニケーション能力とはもちろん陽気にワイガヤできる素質ではなく、ビジネスをするために言葉だけではなく絵や文字その他を駆使して誤解のない合意を達成するスキルのことです。表現方法さえ押さえれば、これは本来エンジニアが得意とする事であると、私は考えています。今後のAI活用ではより重要となるスキルでしょう。考え方を変えれば、それを鍛えるよい機会かもしれません。

## フレームワークを選定する

Excel関係でなんやかんやすると聞き及びまして、私はこの手のアプリ開発は次のどちらかが無難だと考えています。

- A. [Excelアドイン] + [GUIをWPFまたはWinForms]
- B. [WPFまたはWinForms] + [ClosedXML]

A案は、既に運用されている Excel ブックファイルを引き続き使用しつつ部分的に自動化したい場合の、現状の最適解だと思っています。Excel操作は Microsoft.Office.Interop.Excel で行い、リボンメニューは xml で構築でき、GUI は WPF でも WinForms でもどちらでも使えます。Excelとシームレスに統合できるためユーザーが新しいアプリを覚える負担がすくないのと、自動操作中はなんか Excel が動いて見えるので、姑息ですが「自動化している感」がよく見えてユーザーの満足に繋がりやすいです。

B案は、これから全く新しいフォーマットの Excel ブックファイルを作れる場合に有用です。ClosedXML は (Interop.Excelと比べて) 軽量・手軽で Excel アプリの動作に引っ張られることが無く安定感が魅力です。しかし凝った数式やマクロが使われている既存の Excel ブックファイルを使う場合、サポートが無いことがあるため注意が必要です。

なお B案を採用する場合、Excelワークシートの画面をGUIアプリで再現するのは避けるよう、強く、強く、とても強く進言いたします。強大な資本で以って開発され世界中で使われている優秀なUI/UXを持ったExcelで目の肥えているユーザーからは常に比較され、「結局Excel使った方が使いやすいじゃん！」に落ち着く無茶な要求や不条理な評価を受けることが多いためです。それでも、という場合は有償コンポーネントをお勧めします。

### WPF vs WinForms

基本は WPF 推奨で、次の場合は WinForms が選択肢に入ります。

- アプリは大きな拡張の予定が無い（初動はWinFormsの方が簡単で早く作れる）
- クライアントがGUIの見た目にそれほど関心が無い（WinFormsの方が簡単だけど見た目のカスタマイズはXAMLと比べて辛い）
- DataGrid 中心のアプリを作りたい（WPFのDataGridは落とし穴。WinFormsのDataGridの方が多少マシ）

[WPF vs WinForms] とかで調べてみるとわかると思いますが、 GUI の表現力は WPF の方がずっと大きく、 WinForms はもしかしたらユーザーの期待に追いつけなくなる可能性があります。また WinForms は MVVM や MVP といったアーキテクチャパターンの学習機会を奪う可能性が高く、View層にあらゆる処理を書いちゃうなどアンチパターンを踏みメンテ困難になることが多いです。

### WPF の DataGrid は避けたほうがいいかも

特に Excel 連係・移行を目的とした使用は避けるべきと強く意見します。

気を付けポイントは [【WPF】DataGridをMVVMで使うなら変えておくべきプロパティ](https://threeshark3.com/datagrid-often-use-property/#google_vignette) がよくまとめられていると思います。

付け加えると、次のような問題を感じています。

- フォーカスの仕組みがかなり独特だったりするので、 Excel の操作感に慣れていると不具合として指摘される事が多い。それに対して開発者が取れる対策は頭を下げることがほとんど。
- 中途半端に Excel に似ていることが、開発者とユーザー双方に誤解と期待を与えがち。例えば Excel と同じようなフィルタはそれなりの規模の開発となる。 Excel 使った方が安いし早いし慣れてる。

WinForms の DataGrid も拡張し辛いという点では WPF とそれほど変わらないと考えていますが、少なくとも WPF の DataGrid よりは安定した操作感があるので、DataGrid だけを強く前面に出していきたいという場合は一考の余地があると思います。

### 「.NET Framework」 ではなく「.NET」

C#初心者にはとても分かりにくい違いなので注意です。

- 「.NET Framework」 は 4.8.1 が最終バージョンで、そのうえで動く C# 言語バージョンもアップデートされていません。
- 「.NET」 は現在のメインストリームです。Null安全性など、コンパイラ自体が静的解析のような機能を備えていますので、単純にこちらの方が不具合削減に効果があります。


## 要求を洗い出して見積もる

この作業は苦手な人が普通だと思いますし、あなたもまた苦手としていると思います。

- [プログラミングで一番難しいのは「見積もり」だと思う](https://qiita.com/yuno_miyako/items/8678cd542fbb7050e40e)

見積を出せるエンジニアの価値についての説明は今更不要だと思いますが、不確実な数字に対して予防線を張りつつも責任を持つというのはある種の「勇気」が必要です。しかし物事をロジカルに進めたい我々エンジニアにとってはぞれ自体が持つストレスと、あいまいなのにGoしなければならない理不尽はそれを容易に打ち砕いてきます。苦手とするのも無理もないことだとおもいます。

ですが乱暴な意見かもしれませんが、見積から逃げて、アジャイルなどを都合よく解釈して責任範囲の合意なく楽しいプログラミング作業に移ってしまうエンジニアは、私の知る範囲では炎上案件を抱え続けることが多いです。私自身もそうでした。

さて、私が業務系デスクトップアプリを作るときによく見積に盛り込むタスクを挙げてみます。参考にしてください。

- Gitリポジトリの準備
- VisualStudioのプロジェクト準備
- ユニットテストプロジェクト準備
- できれば、CIでテスト回す準備
- アプリ動作ログの記録
- 例外のグローバルハンドリング
- バージョンダイアログ
- インストール手順・マニュアル作成
- 静的解析準備
- 実行ファイルの署名
- 国際化・翻訳作業
- 多重起動防止
- ユーザーデータのバックアップ
- Undo/Redo
- 配布方法検討（インストーラ作成やランタイム配布方法など）
- リリースノート作成

### WBS項目の粒度

機能やタスクをどの程度まで細かく出せばよいのかは無限に悩ましいところです。多分正解は無いと思います。

私は0.5日～5日（1週間）の範囲で割るようにしています。機能とかいう曖昧なものではなく、数字で表す工数で割るのがポイントです。

例えば「ログファイルを出力する」という機能が2日くらいで作れそうと見積もったなら、そのままこれで行きます。一方でログをサイズや日付で分割したいとか、バックアップしたいとか、何か特別なメタデータを埋め込みたいとか色々要求が出てきて、5日を超えそうだと判断したら「条件付きで分割しつつログファイルを出力する:3日」「ログファイルをバックアップできるようにする:3日」「ログファイルにメタデータを仕込む: 1日」といった感じの見出しに分割して、各々が5日を超えないようにします。

これは [アジャイルな見積りと計画づくり](https://amzn.asia/d/4akFDxB) を参考にした粒度です。

私の個人的な感覚もありますが、1週間以内程度であれば人はわりと正確に予測ができます。2週間はギリギリですが怪しくなる感じがします。1カ月を超えると、私はちょっと信用しきれません。数カ月にもなると、真面目に考えてるの？ってなります。

現場によってはさらに「設計」「実装」「検証（ユニットテスト）」と細かくすることもありますが、これを全て同じ人が行う場合は「検証に30%時間をかける」みたいな機械的な導出になることが多いため、私は基本的にフェーズでは分けません。また項目数が多くなるため「やってる感」が出るのですが、このリストを見る他の人にとってはノイズや暴力に感じることが多く、重要な項目を見落としてしまう可能性が高いためです。このリスクも先ほどの「アジャイルな見積りと計画づくり」の中で触れられています。

なおクライアントやチームメンバーの間で認識の共有がしやすいなら、ストーリーポイント法にしておくと、プランニングポーカーなどでもうちょっと効率的に見積もれるかもしれません。ただ私も以前チャレンジしてみましたが、私の仕事のステークホルダは日数や時間の方が説明しやすいのと、ぶっちゃけ私自身も日数が一番考えやすいなと思ったので、このような方法をとっています。

## 交渉してスケジュールを引く

後で記事にするかもですが、1年くらい前にあなたに教えた2点見積、あるいはそれを発展させたやつ――規模（日数等）とリスクレベルの掛け算で見積もる方法を取ると、クライアントにあなたやメンバーのスキルレベルや不安度も共有できて、納得してもらいやすいかもしれません。

注意点として、見積もった「工数（請求額）」と「工期（いつ頃納品できるのか）」は別物として説明しましょう。あなたが1日に8時間フルコミットできるのは稀だと思います。見積もりテクニックとしてよく挙げられますが、割り込みの業務や体調不良を考慮して、1日平均6時間くらいの開発速度で工期を説明しましょう。

もし何らかの方法でここ半年くらいのあなたの稼働率が求められるなら、6時間と言わずそれをベースにすると、もう少し精度が上がるかもしれません。またもしプロジェクトを掛け持ちしている場合はパワー配分の割合も減じましょう。

### 長くても3カ月くらいで一時納品

数年にもわたる大きなプロジェクトが炎上したという話は枚挙にいとまがありません。それらの反省をうけてか、アジャイルでもウォーターフォールでも、定期的に現物で出来具合を確認しようという雰囲気は、ここ最近私の周りの案件でよく感じられます。

例えば、次のような感じです。

- まずは100万で何ができそうか教えて
- 見積りの中でまずは3カ月でできるところまでやってみて

このようにお金や期間の制約が課されると、じゃあさっき出したWBSの中からどれを対応しようか、という話になっていきますので、ここでも数字が役に立ちます。ここで議論が発散したりダラダラしないよう、「こんなこともあろうかと！」みたいに松竹梅プランを出してスムーズに誘導できると、コイツ仕事できるなってなるかもしれません。

なおアジャイルの手法の中には毎週とか隔週でデモする方法もありますが、開発側もクライアント側の負担もけっこう大きくなるので、毎月～3カ月（四半期）がちょうどいいのかな、と思っています。※私は BtoC の経験はほとんど無いので、例えば自社開発の BtoC アプリではまた違ってくるかもしれません。

もしクライアント側からこのような提案が無かった場合、あなたは自分から「定期的に方針の認識合わせをしながら進めたいです」と発信しましょう。最初はただ仕事を増やすだけの面倒なことに感じられるかもしれませんが、変化の速い昨今、開発期間中でも新たな知見から認識のずれは起こってきます。これもまた、あなたを炎上から守るテクニックのひとつだと信じています。

## さいごに

あなたとは週末にゲームを遊ぶ約束をしました。無事にこの無茶な計画を何とかして、一緒にシド星を炎上できることを願っています。