フランチャイザーのシステムがアレなので手書き書類を無くすべく超低コスト超小規模事務処理システムを開発した

#はじめに
　むかしむかし、あるところで……

　これはあるフランチャイズ店の~~不甲斐ないフランチャイザーの代わりに~~ITによる働き方改革をしたお話。

　これはシステム開発記録であり、ある友人の為に書いたものです。
　その為、一部内容を省略していたり、かなり個人的な偏見などに満ちた内容になっています。
　コードは少ないのですが、技術の選定理由・時短術・実際の活用など、参考になる部分はあるかもしれません。

#開発の動機

　その店にはある一つの悩みがあった
　それは

　***事務処理が鬼のように時間を食う***

　ということであった……。

　客先を周り、ようやく帰ってきた我々の前に現れる作らなくてはならない書類の山。
　平均一時間半、吸い取られていく時間に、我々はなすすべも無いのであった。

##なぜ時間を食うか

　なぜそんなに時間がかかるのか。
　事務員が居ないというのはあるが（零細なので）、この事務処理、純粋に極端に非効率なのである。

　この事務処理は、フランチャイザー（フランチャイズを提供する側。所謂フランチャイズ本部）の指定する手順によるもので、以下のような内容である。

* 顧客情報をPCで一度入力
* 三回（予定表、指示書、受付記録）フルに手書き
* 二枚管理用の一覧を作る（売上票、指示書一覧）

　一つ一つはたしかに必要な書類やデータなのだが、どういうわけかまったく同じ内容を別のフォーマットに４回も移し替えている。
　そしてそれを管理する為の書類が二枚も必要である。
　つまり***同じ内容を６度も転機している！***

　同一内容を複数記載することにどれほどの価値があるのだろう。
　ある時フランチャイザーは言った。
　「同じ内容を転機することで間違いは減る」
　私は思った。手書きするほど間違えるはずだと。

　恐ろしく非効率な事務処理により、時間は無駄に消耗される。
　帰りは遅くなる、お客様は待たせる、疲労は貯まる、心の余裕はなくなる、お肌は荒れる。良いとこ無しだ。
<div align="center">
<img height=350 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455236/fe5f7e03-10e9-e839-081f-9678e05ff476.png">
</div>


　２１世紀にもなってこの仕組みはもはや異常なので、フランチャイザーの連中にも何度か文句を言ったのだが『僕らもそう思うんですけどねぇなかなかねぇ』という回答しか得られない。
　***そこを変えるのが君らの仕事じゃないんか？***

　何年も文句をいい続けたが変化無し。
　プログラマ三大美徳の一つ***怠惰***が爆発したのも当然である。
　~~というか早く帰りたかった（みなし残業制なので）~~

#前提条件
　システムをつくる前に、前提条件を整理しよう。
　当時の職場の環境はこんな感じだった。

* 零細企業なので、フットワークは軽い

* 書類に関連する人員
　私
　もう一人の正社員（５０代）
　入金管理をする人
<img height="150" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455236/2bcaed28-c861-5d77-7ca3-cf5b29f81d26.png">

* 私以外はITシステムよくわからん人々である

* え、私？
　プライベートではLinuxデスクトップを使うWeb系ばかり詳しい怪しいおっさん。
　JavaScript歴12年、Linux歴12年。関数型言語大好き。CとかJavaも一応使える。マクロありのLisp処理系を最近作った。
　いつも触っているのはエディタはVIM。
　Windowsアプリなんて作ったことは大学時代の授業ぐらいでよく知らない。

* 事務処理に使えるマシンは数台、サーバなどというものは無い
　マシンの数は足りている。
　無線APにファイルサーバ機能がある。

* フランチャイザーが提供しているシステムは糞レガシー

　** フランチャイザーが提供している事務処理システムは、VBScriptを使ったIE専用システム（！）
　**  何故かレジストリ内のキーを参照する意味不明なセキュリティ。
　** よってwgetなどで自動処理はできそうな雰囲気では無い。
　** 顧客情報などの検索・管理は行える。
　** ありがたいことに検索結果をCSVで拾える。
　（しかしデータを検証するとDB内２つのテーブル間の連携キーは見せてくれない仕様。データを店に渡すつもりは無いらしい~~そんな小細工あったところでどうにでもなるけど~~）

#で、何が必要か
　とにかく事務処理で時間を食っているのは帳票の作成
　つまり
　***我々に必要なのは重複入力を避けた自動帳票作成・管理のシステム***

##帳票システムを作るにあたって考慮しなければならない事

###システムわからん勢の割合が高い。
　手順の多い操作や複雑度の高い操作は極力減らしたい。
　運用に関しても、せいぜいファイルをあっちからこっちに動かす程度で済ませたい。
　（私がいなくてもどうにでもできる程度のシステムにしたい）

###時間が無さそう
　無さそう。と曖昧な表現なのは、最初の段階で本当にわからなかった為。
　いくら暇な時期とはいえ、仕事は入ってくる事もあるため、いつ時間が取れるかわからなかった。
　また、あんまりシステム開発にかまけてると、あいつ仕事しとらんのちゃう？みたいな雰囲気になってくるので。そういう意味でも時間は無駄にできない。~~ヘタレ~~


#技術選定
　上記の前提条件からシステムを作るにあたり以下の技術を選定した。

##Windowsデスクトップアプリ
　Webアプリも検討したが。というかWebアプリなら目をつむっていても始められるが、今回はデスクトップアプリにした。
　デスクトップアプリであれば考えることは少ないし、こういった事務所理系アプリ作成の情報も多い。よって、生産性が段違いである。

##C♯
　Windowsデスクトップアプリということで選択肢はほぼこれ一択である。生産性も高い言語と聞いていたので選択。
　情報も多そうである。~~知らない言語を覚えるのは楽しいし~~
####C♯での開発経験は無いが
　C言語もJavaScriptもCommonLispも使える俺様。C♯のごとき***モダンJavaもどき恐るるに足りず！***
　という具合にプログラマ三大美徳のうちの一つである***傲慢***さを発揮した。

##SQLite
　SQLiteはサーバの不要なDBである。必要なのはファイルだけ。
　サーバを立てる手間及び~~DB鯖ぐらいならすぐ立てれるけども~~、運用の手間を避けたい為にSQLiteを採用した。サーバを立てれるのも運用するのも私しかできない、サーバの予算もない。
　管理人の居ない砂漠に機械式の井戸を掘ってはいけないので、サーバは一旦諦める。

　SQLiteであれば、WindowsからDBファイルが見えていればそれだけで利用できる。無線APの機能であるファイルサーバだけで済む。
　ファイルだけで管理できるので簡単。バックアップもファイルをコピーするだけである。
　規模が小規模なので、SQLiteの機能で十分だし、クエリーが衝突することも無い。
　NuGet（VisualStudio用パッケージ管理システム、Ubuntuで言うapt）で拾ったAPIを使うので、いざと慣れば他の本格的なDBにもすぐ移植可能。

##Excel (ClosedXML)
　印刷については悩みの種だった。
　柔軟に変更したい。枠からのはみ出しなどを考慮しなければならない。印刷周りはそれ意外も考慮しなければ鳴らないことが多い。
　~~面白くなさそうなところに工数をかけたくない。~~
　Excelをそのまま利用できれば便利なのになーと思って調べてみたらClosedXMLなるものがあるのを発見した。ClosedXMLはExcelファイルを読み込み、セルの内容などを更新し、Excelファイルを出力できるライブラリである。
　渡りに船だ。

　NuGetで取得できるClosedXMLを利用し、Excelのテンプレートファイルから出力用ファイルを生成する形にした。
　エンドユーザでも帳票を編集できる。帳票がExcelファイルとして残る。印刷の仕組みはよく練り込まれた（そして枯れた）Excelの資産を利用できる。

##開発手法
　どれだけ時間が取れるかわからない。そもそもどのくらい有用かもわからない。確実に途中で調整が必要になる。
　というわけでアジャイル一択である。設計書はプレインテキスト。

##テスト
　テストも作っていられないので、基本的にユニットテストである。
　小規模開発のメリットを活用し、ある程度完成したらドックフードを食べる（開発したシステムを自分たちで利用してバグを出すこと）。

##コーディング
　コーディングに際してはちょっとしたコードを書くにもネットで調べてから行う事にした。
<img height=200 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455236/c7dab25e-5794-d15b-1052-a248c785cd35.png">

　C♯は開発効率の良い言語と言われている。それを活かすには ~~よくレガシーJavaプログラマーがやらかすように~~ 自分の得意な言語の常識をそのままC♯世界に持ち込んではいけない。C♯なのにJavaScriptのようなコードを書いてはいけないのである。

　***郷に入れば郷に従え***

　まずは徹底してC♯の流儀というものを検証し、活用する。最初こそ時間はかかるかもしれないが、これが開発効率を左右する。自分の流儀はそれから出しても遅くはない。

###○○志向、○○型
　UIを扱うからにはオブジェクト志向は必須である。
　データをストリーミング処理するからには関数型プログラミングが圧倒的にフィットする。
　一つの手法に囚われず、適材適所で動的に作成してゆく。


#設計
　システムを設計に当たってはUnixシェルスクリプトの如く、組み合わせによる省力化を行った。使えるものはなんでも使うの精神である。

　よって基本的なデータの流れは下のようになる。

　***レガシーWebシステム → CSV → 新規システム → Excelファイル***

　帳票管理や、通し番号の付加の為にDBが必要になる。
　また、バックアップも必要になる為ので、以下のような関係性となる。

　***新規システム***
　　　↑↓
　　　***DB***　→　DBファイルをローカルにバックアップ

　新規システム内のUIとしては

　***CSVデータ管理画面***　指示書作成／受付記録/売上票／粗利管理表出力ボタン付き
　　　↓　　　　　　　　↓　　　　　　　↓
　***指示書管理画面　　入金管理画面　　仕入管理画面***

　最終的に予定表のみ手書きになった（ただし簡易化）。手書きの方がかえって楽な部分もあるものである。


#変遷
　ここからは実際の開発の流れをざっくり見てゆく。

##見切り発車
　上記の設計だが、開発を始めた段階では一切細部を煮詰めていなかった。
　前記したとおり、とにかくどこまで時間があるか。不明だったのである。
　とりあえず一部でも作成すれば作業効率バク上げ必死だったので見切り発車した。

##CSVデータ一覧
　最初に行った事はレガシーシステムから出力されたCSVファイルを読み取り、表示する部分である。上記のCSVデータ管理画面に当たる。
　最も時間のかかる書類作成に関して、必ず必要になるフェイズの為、最初に作成を行った。

　レガシーシステムの出力するCSVは注文・受注が記録されたデータで、まずはこれを表示する。表示に関してはGridViewを仕様した。
　もちろんWindowsアプリの作成は大学時代以来なのでGridViewの仕様などワカラナイ。GridViewはリストや配列を関連付けて表示及び変更できるViewである。配列の処理は関数型言語使いには朝飯前である。LINQを使ってサラサラっと処理が行える。
　ファイルを読み込むAPIも、そのためにドラッグアンドドロップするAPIも、ググればすぐに出てきた。ただ、CSVを読み出すライブラリは標準ライブラリに見当たらなかったので、自作する。
　GridView内の列に出力可否のbool値を入れる事で、チェックボックスを使えるようにした。
　ここまで作成したことで、使えるシステムになりそうな感覚がつかめてくる。

##まず作成したもの
　事務処理で手間のかかるのが指示書の作成である。次にこれを作成していく。
　Excelでテンプレートとなるファイルを作成し、ClosedXMLで読み込み。CSVから取得した注文データを流し込む。
　Excelを利用したことで、驚くほど短時間に指示書のレイアウトを作成でき、さらにClosedXMLのおかげで、簡単に書類を量産できた。なんでも調べて使ってみるものだ。
　次いで、売上票作成機能も作成する。
　ClosedXMLを使ってはいるが、基本的には配列の処理である。ストリーム処理は状態を持たないので関数型プログラミングの得意とするところ（最後の出力のみ別）で、細かく関数を作成してゆく。LINQもしくはforeachを使い、ループ内処理内の副作用を排除し極力関数にすることで、読みやすさを重視した。
　このあたりからC♯に関する理解が深まってくる。モダンなJavaという感じだが、ユーザの流儀はもう少しラフだ。他言語の知識も役立つ。難しい要素は無い。
　ここあたりから、テストを書く時間も無いので、ひたすらユニットテストを行っていく。

##DB
　指示書の作成、売上票作成機能には必要なものがある。
　指示書番号（連番）の管理と、売上票に記載する指示書番号（及び内容の判定）の管理だ。DBの出番である。
　もともとWeb屋なのでDBは使ったことがある。SQLは結合の基礎程度はわかるし、特にSQLiteは十八番だ。しかし業務用システムの開発は初めてだ。DBの設計には頭を悩ませた。
　DBはテーブルを扱う機能である。テーブルはJSONのような自由度の高いデータ構造と違い、後から変更が効きにくい。最初にきっちり設計しなければならない。
　と思い込んでいたのだが、実際は違った。DB設計は幾度と無く変更された。最初１つだったテーブルが２つになり、３つになった。その度に列が変更になった。運用を始めてからさえ、変更があった。
　その度にテストは必要になったが、変更は効いた。私はDBに対する認識を改めた。

##指示書及び売上票作成機能完成
　DB設計及びDBを管理する機能を作った（DBは状態を持つのでオブジェクトで管理、Actionで抽象化）為。指示書及び売上票の作成機能が完成する。
　この段階で既に役立ちそうではあったが、時間がまだありそうだったのと、指示書等の一覧（管理）無しでは不便なので開発を続行する。

##リファクタリングの嵐
　さて、ここまでの開発の中で私は都度つどリファクタリングに努めた。リファクタリングはコードのみならず、設計、DB設計、帳票のデザインなどに及んだ。
　リファクタリングにはコストがかかる。しかし、結果論になるが、都度リファクタリングを行ったのは迅速な改良の際に大いに助けとなった。
　コードのリファクタリングの回数が増えたのは、私がC♯の書き方というものを知らなかったからだ。それは文法やシンタックスシュガー、そしてC♯利用者の一般的な書き方、及び最新の手法に及ぶ。また、VisualStudioをよく知らなかったというのも大きい（いつもVimなので）。回数は増えたが、しっかりとリファクタリングを行った事でコードはすっきりとした。また、何度も見直す中で、どこで何が起きているかよく把握することができた。
　リファクタリングに際しては、ドラスティックに改変（設計レベルから見直す）事も行った。小さいバグを生むリスクはあったが、後々には役立った。この際にC♯が強い静的型付け言語であることが役立った。一部引数の仕様を変えたりすると影響を受ける箇所が一目瞭然になる。これは動的言語ではできない芸当であり、強い静的型付け言語はアジャイルやボトムアッププログラミングに向かないという思い込みを打ち破るには十分な力があった。
　また名前にも気を使った。良い名前はコメントよりも雄弁に語るからだ。

##指示書一覧/入金管理
　指示書を管理・確認する為にそれぞれの一覧表示機能を作った。DBもあり、VisualStuioにも慣れてきていたので簡単だった……。
　と言いたいところだが、機能を別アプリにすべきかひとしきり悩んだ。

##仕入管理/粗利管理
　DBを導入したので色々できるようになり、ついでに作成。地味に時間を使っていた作業を簡略化。

##仮運用開始
　ここまでで必要な機能はひととおり揃った。テストを繰り返した後、
　運用開始はかなり慎重に、私だけのワンマン営業日に、ひっそりとシステムを使い始めた。
　恐ろしくスムースに運用は開始できてしまい、次の日からはシステム無しなど考えられなくなった。
　DBのバックアップ機能がまだ無かったので、作成した。

##手順書作成
　僕がいなくても使えるように、手順書はちゃんと作りました。
　ものすごく丁寧にわかりやすく作ったのだが、結論から言うと不要だった。使う人たちがすぐに覚えてしまったのである。別の人が使い始める事を考慮しても、もっと簡単な手順書でも良かった。

##運用開始
　別の社員にも使い始めてもらう。特に問題無し。要望として全部チェックするボタンくれと言われたので実装した。要望としてはそれだけだった
　たまに改良を行ったが、会社のPCはクラウドで同期しているので、最新版の配布はビルドしてコピペ一発で済むようになっていて便利（小学生なみの感想）。

##受付票管理
　また時間が出来たので、この機能を作った。あっという間に作ったが効果は絶大だった。

#結果
　事務処理時間が45分程度（人数や内容にもよるが、平均）で終わるようになった。以前の半分程度である。
　開発期間は二ヶ月半。しかし、合間の時間を利用して作成していたので実質開発時間は二週間だった。

#最後に
　システムは毎日利用中。毎日、作った自分に感謝するくらい事務処理が早く終わる。IT革命ってこういうことかとちょっと感動したぐらい。

　ところでここで費用対効果を考えてみよう。

　システム作成にかかった時間：　   7時間 x 14日（二週間） = 98時間
　システムにより節約した時間：　0.75時間 x 利用日数　　 = 節約した時間

　システムを利用し始めてから５ヶ月。つまり

　0.75時間 x 30日 x 5ヶ月 = 112.5時間

　かなりいい加減な計算だが、元は取ったと思う。これからはひたすらプラスになる。
　金銭的なコストとしてもせいぜい無線APに接続したUSBメモリ代とVisualStudioの商用利用可能ライセンス代くらいだ。

　しかし世の中の経営者の方々へ、この開発記録はコスト削減のアテにならないので注意して頂きたい。属人化したフルスタックエンジニア（と自称するコンピュータオタク）がたまたま転がっていなければできない。テストもドキュメントも作成していない。これだけの品質ができたのは単に運が良かったとしか言いようがない。
　システムの開発とはコストがかかるものなのだ。

　さて、そんなこんなでシステムは完成した。
　我々の手元には節約した時間が残っている。

　そのあまった時間をどうするかって？ ***帰るんスよ！***
![family_happy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455236/a396343f-3a5a-9f6b-a861-148a1473b2b6.png)
　~~もともと残業過多だったし、みなし残業制なので~~

　まぁ、見積もりとかすることに、結局はなるんですけども。

　なにはともあれ、めでたしめでたし！！

<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>



　しかしアレですね。フランチャイザーは何やってるんですかね。全店舗で４５分ずつ節約したらドエライ経済効果だと思いますけども。