一万円以下でchatwork連動備品管理システム作ったら喜ばれた

この記事は[Okinawa.rb Advent Calendar 2018](https://qiita.com/advent-calendar/2018/okinawarb)の23日目の記事です。
昨日は @yono@github さんの[Heroku で動かしてる Twitter bot の環境を buildpack から Docker に移行した](https://qiita.com/yono@github/items/923ec75dfe0b9b7dbec0)でした。
明日は @siman さんが何かを書く予定です。


#時代背景
2017年頃、私の会社の総務部では備品管理を紙とペンで行っていた。幾度となくコピーを繰り返して文字が潰れかけている表に

- 貸出物
- 受取者サイン
- 貸出対応者サイン
- 貸出日時
- 返却日時
- 返却者サイン
- 返却対応者サイン

などを記入していた。その表を後日見返す者はもちろんいなかった。

ウェブ部門から総務に転属になった私は隣の席の人に「ピッてやるやつにしてください」と無邪気に言われて「いや、そんなの開発できないし」と素直に答えたけど、ありあわせのものを組み合わせたらピッてやる仕組みがなんとなくできたという話。

#必要なもの
- [google spreadsheet](https://www.google.com/sheets/about/)（無料）
- [chatwork](http://chatwork.com)アカウント（無料でも使える）
- [NFCタグシール](https://www.amazon.co.jp/サンワサプライ-NFCタグ-10枚入り-白-MM-NFCT/dp/B00GXSGL5G/)（20枚で2500円くらい）
- [タグが入るサイズのキーホルダー](https://www.amazon.co.jp/dp/B078JTXB3C/)（20個入り1000円くらい）
- [NFCカードリーダー](https://www.amazon.co.jp/NTTコミュニケーションズ-ICカードリーダライタ-ACR1251CL-NTTCom/dp/B01D0O90N0/)（5000円くらい）
- NFCチップのデータを読み込みソフト[「MANICAコレクタ」](http://www.hayato.info/collector.htm)（当時有料だったのに無料になっている模様。）
    - 適当に検索してて見つけた会社が開発しているWindowsソフト。担当の方がいろんな機器を持ってきて詳しく説明してくれた上に親身に相談に乗ってくれました。ありがとうございました。

> NFC
> 狭義にはNear field communication（NFC）の訳語。NFCはRFID（Radio Frequency IDentification）と呼ばれる無線通信による個体識別の技術の一種で、近距離の無線通信技術を統一化した世界共通の規格である。ICチップを内蔵したNFCタグをNFCのリーダ・ライタ機能を有する機器で読み取ったり書き込んだりする。(wikipedia)

カードリーダーにピッとすれば、チップに内蔵された30桁くらいの一意の文字列（IDm）を読み出せますよ、ということだけわかってればいいと思います。

ちなみに扉の開閉用にNFCタグ入り社員証をすでに導入済みだったので、個人の識別は社員証を使いました。社員証にNFCタグが入ってない場合は上記のNFCタグシールを社員証の裏にでも貼れば同じことができます。


#MANICAコレクタの設定
- カードリーダーを認識させる。
- [キーエミュレートモード](http://www.hayato.info/col_kin.htm)に設定。
- 付加コードは、Tabか右矢印のどちらかだったはず。ピッとした後のカーソル移動の挙動です。

メモ帳などにカーソルが入った状態でタグをピッとしたら、カーソル位置にタグ（IDm）が読み出されるのを確認。


#google spreadsheetで貸出シート作成

##作った列

入力受付列
- 受取者IDm
- 貸出物IDm
- 貸出対応者IDm
- 返却者IDm
- 返却対応者IDm

表示列
- 貸出物名
- 貸出日時
- 受取者名
- 貸出対応者
- 返却日時
- 返却者名
- 返却対応者
- 貸出通知timeStamp
- 返却通知timeStamp

![作った列](https://qiita-image-store.s3.amazonaws.com/0/10505/455097d5-ecc4-8572-6379-accd7fdf8de7.png)

貸出シート https://goo.gl/6mFei4

#google spreadsheetでマスターシート作成

###人マスター
- NFCタグ（社員証の）
- 表示名

![人マスター](https://qiita-image-store.s3.amazonaws.com/0/10505/59540332-c472-70d2-7c3e-76e6ff10e73d.png)


###モノマスター
- NFCタグ（貸出アイテムに付けたNFCラベルの）
- 表示名

![モノマスター](https://qiita-image-store.s3.amazonaws.com/0/10505/74c6cb3e-0e58-7bcc-dd6e-6fa818126bb5.png)

タグデータは読み出しソフトでピッてして入力。

#query関数で管理シートとマスターシートの橋渡し

もうここまで来るとわかると思いますが、IDmの列にピッとタグを入れるとマスターシートに入っている人やモノの名前が表示列に表示されるようにします。

QUERY https://support.google.com/docs/answer/3093343?hl=ja

```
=IF(ISBLANK(A2),,QUERY('モノマスター'!$A$1:$B$999, "select B where A = '"&A2&"'"))
```
という式を入れると以下のようになります。

- 「貸出シートセルA2」が空ではない時に
- 「モノマスターのA列とB列の999行までの範囲」を検索対象として
- 「貸出シートのセルA2」と一致する文字列が「モノマスターのA列」内にあれば
-  その行の「B列」の内容を表示

つまり「item001」の入力があれば「城の鍵01」が表示されます。

#貸出／返却の流れ
###入力インターフェイス
という最大の問題を解決しないことで解決しよう！ということで、もうダイレクトにスプレッドシートのセルにカーソルを入れて「ピッ」とすることにしました。

総務の入口のカウンターにカードリーダーをつなげたwindowsPCを設置。ログオフ時にでかい時計を表示させておくことでカウンターのクール度が少し上がった気がする。
![fliqlo](https://qiita-image-store.s3.amazonaws.com/0/10505/680cf236-fa2a-9a42-a737-7b545bf4ae45.png)
[fliqlo screen saver](https://fliqlo.com/)

貸出時はA列から
1. 貸出者に社員証を「ピッ」としてもらう
2. 貸出アイテムのタグを「ピッ」とする
3. 総務の受付担当者が自分の社員証を「ピッ」とする

返却時は該当行D列から
1. 貸出者に社員証を「ピッ」としてもらう
2. 総務の受付担当者が自分の社員証を「ピッ」とする

#貸出／返却時刻を記録
スクリプトエディタを開いて google apps script 記述。

総務対応者セルに「ピッ」と入力があったら、貸出日時／返却日時の列に入力時間を入れる。

```code.js
// ↑実際の拡張子は.gs

// 総務対応者入力時に対応時間set
function onEdit(e) {
  // 対象範囲
  var editRange= {
    top : 2,
    bottom : 999,
    kashidashiCol : 3,
    henkyakuCol : 5,
  };
  // 日時入れる列のオフセット
  var updateColOffset= {
    kashidashiCol : 4,
    henkyakuCol : 5,
  };  
  
  // シート名チェック
  var activeSheet = e.source.getActiveSheet();
  var sheetName = activeSheet.getName();
  if (sheetName != '貸出表') return;
  
  // 編集セルが対象行チェック（2から999行）
  var range = e.range;
  var thisRow = range.getRow();
  if (thisRow < editRange.top || thisRow > editRange.bottom) return;

  // 編集セルが対象列（対応者ピッ入力列）なら日付入力
  var thisCol = e.range.getColumn();
  if (thisCol == editRange.kashidashiCol) {
    var updateCell = range.offset(0, updateColOffset.kashidashiCol);
    updateCell.setValue(updateTime());
  } else if (thisCol == editRange.henkyakuCol) {
    var updateCell = range.offset(0, updateColOffset.henkyakuCol);
    updateCell.setValue(updateTime());
  }
}

function updateTime() {
  var date = new Date();
  var y = date.getFullYear();
  var m = date.getMonth() + 1;
  var d = date.getDate();
  var hh = date.getHours();
  var mm = date.getMinutes();
  return y + '年' + m + '月' + d + '日' + hh + ':' + mm;
}
```


#chatworkに通知

準備はこちらのわかりやすい記事を参照プリーズ。
[「10分でできる chatwork × Google Apps Script で Hello world!」](https://qiita.com/yamatomo73/items/9168ac844df93da5afa7)

通知用のアカウントを取得してロボットぽい名前をつけて、以下のタイミングで通知

- 新規貸出時
- 返却完了時

未通知アイテムを通知するfunctionを作ってトリガー登録（時計アイコン）。
5分毎にした。

今見たらトリガー登録画面がこんなのに変わってた↓
![トリガー登録](https://qiita-image-store.s3.amazonaws.com/0/10505/e0fc239e-601e-1554-c8ec-3fa5ba7aeacd.png)

こんな感じに通知！（コードは明日元気だったら追記するかもしれません）
![通知](https://qiita-image-store.s3.amazonaws.com/0/10505/92db26bd-923d-5339-c34d-f20d25f4e3da.png)

あと金曜正午に未返却アイテムをまとめて通知、というのもやってました。受取者にメンション飛ばすために、chatwork表示名とto番号のマスターシートが必要でした。

#問題

###たまに変なところに入力されてる問題
- できちゃうのでそうなります。
- 通知内にシートURLを入れて、変な通知が飛んできた時は総務メンバーがすぐ修正（<del>改ざん</del>）できるようにした。
- 操作する人が少なく（総務の数人だけ）教えるコストが低かったので、パソコン苦手な人には丁寧に教えた。
- きちんとインターフェイス作れる人は作ったほうがいい。

###シートが長くなる問題
- 手動対応。100行くらい溜まったら上の方の返却済み行をアーカイブ用のシートにコピーして削除

###シートだらけ問題
- その後、chat通知付きリストを言われるがままに作り続け、いろんな用途のシートとロボット通知が増えた。これってエクセルマクロレガシー的なものと同じじゃないかとある日気づく。
- きちんと引き継ぎして退職した（たぶん）。
- でもみんなエクセル使うような会社だったのもあり、マスター管理インターフェイスとしてのスプレッドシートに違和感感じないらしく、想像以上に受け入れられた。

###備品が近くにない問題
- 名刺フォルダーにNFCタグを貼り付けた名札をストックしてそれを「ピッ」
- 両面使うともちろんうまくいかない。
- ビル管理業者さんなど、定期的に来る外部の人のラベルもこちらに入れておいた。

#まとめ
- タイトルに１万円以下と書いてますが、当時はソフト代がプラス1万円かかりました。
- 「ピッ」とやってるのを見た業者さんから「お金払うので同じものをうちに」と言われたらしく、上司から「これ売れないの？」と言われて嬉しかった。
- 知ってることの組み合わせでなんとかなる、こともある。
- 不完全なツールでも劇的に便利になるというか価値を生み出せる、ことがある。