表をつくる上での、重視したい考え

# はじめに

DMM WEBCAMP Advent Calendar 2020、7日目を担当します！私はよく社内で、グーグルのスプレッドシートとGASを組み合わせてツールを作成することが多いのですが、ツールや表を作る時に考えていることをお伝えできればと思っていますー。

# そもそも
表をつくるときって、いつも突然に作る必要に駆られますよね。あ、3時間後の会議にこの表があったほうがいいなとか、この表がないと後々火山が爆発して文明が滅ぶなぁ…とか、というか文明が滅びかけのときだったりして、後の祭り状態で書くこともしばしば…。

そういうときって

1. 表の仕様を設定する(各行にはどんな情報がある？各列にはどんな情報がある？)
2. レイアウトを決める
3. 関数(数式)を設定する

という流れが多いと思いますが、たいてい3のところにしわ寄せが訪れます。でも3番の関数を設定するところって一番自由が聞かないところなんですよね。グーグルで調べてもどのサイトを見ればいいかわからないし、そもそも参考になるかどうかわからないし…。悩んでぐるぐるしている中で、迫る会議の開始時間、送付されるzoomのリンク、発表を始める同僚…。

私もそういう経験が無限に（サラリーマン人生3年くらい）繰り返されて、そうして1つのことに気づきました。そう、まるで青天の霹靂、プロジェクトXで言う中盤の盛り上がりのところみたいにね！全ては関数から物事を考えればよかったんです！

そもそも、例えば旅行に行くときに、スーツケースの中に入るものを取捨選択して、持っていくものを決めるはずです。旅慣れた人ほど持っていくものを絞りますよね。私たちは不自由な点を集中して考え、計画しているはずです。

すなわち、考える順序として
1. 表の仕様を設定する(各行にはどんな情報がある？各列にはどんな情報がある？)
2. 関数を設定する
3. レイアウトを決める

の順番で考えてみます。実は1番のところでも影響を受けることがありますが、とりあえず表のイメージを固めて、そこからは関数に積極的に介入させます。

# 関数はなぜ不自由なのか
例えばvloolupに苦戦した(またはしている)方も多いと思います。あれやばいですよね。[vlookup](https://support.google.com/docs/answer/3093318?hl=ja)とは

- 検索キー
- 範囲
- 番号
- 並べ替え済み
  - ここは省略可

を受け取って、結果を返すっていう関数です。

ユーザID|名前|性別
:--:|:--:|:--:
75691|田中|女性
19623|野間|女性
85315|佐藤|男性

のような表があったとして、
=vlookup(75691, A:B(ここではユーザーIDと名前の列の範囲を指定しています), 2(検索キーから何列目の情報を持ってくるかの指定ですね), false(これで完全一致を指定しています。分かりづら…))
とvlookupに()で情報を渡してあげれば、田中という情報が返ってきます。

でも不自由なのが、田中という名前からユーザーIDは持ってこれないんですよね。
検索キーは左でないとうまくいきません。なぜなら指定している番号というのが、（検索キーから見て右に）2番目の列からとってくる、という数字だからです。田中という名前から性別は持ってこれますが、検索キーの左の情報は持ってくることができません。

ここが人と関数の違う、面白いところで、人って

都道府県|名前|性別
:--:|:--:|:--:
大阪|田中|女性
大阪|野間|女性
新潟|佐藤|男性

というような表をつくって、「大阪には何人いるねー」というのをひと目でわかるようにしていることが多いですが、関数的には

名前|都道府県|性別
:--:|:--:|:--:
田中|大阪|女性
野間|大阪|女性
佐藤|新潟|男性

が正しかったりします。人は分類を左に持っていきがちですが、関数としては、分類などは右にあったほう望ましいんですよね（というより、行を特定するのが一意な情報（その情報を特定できるカギのような情報。例えばIDなど）が左にあるのが望ましい）。
一般的な思考から切り離して、表を作り上げる必要があるところが厄介ですよね。でも、不自由ってその不自由な状態が必要だったから生まれています。プログラムに、なにか機能を与えると、その都度制約も作り上げることになります。数字以外はエラーとする必要があったり、関数に想定以上の情報が渡されたらエラーとしたり。逆に言えば、制約がある分、機能としては色々なことが成し遂げられるはずです。


# さらに
関数は不自由ですので、それに伴ってデータ構造にも気をつける必要があります。一意な情報で他のデータを参照するvlookup、特定の条件に一致した数を集計するcountifなどを使用するということは、「その行は何を意味しているか？」を意識することになります。
例えば行の例としては

- 人を表す情報（項目例：メールアドレス、氏名、年齢、性別、所属企業）
- 契約を表す情報（項目例：契約日、契約相手、契約金額、備考）
- 企業を表す情報（項目例：名前、所在地、電話番号、メールアドレス）

があります。
ここでぜひとも行ってほしいのが、それぞれごとに表を分けることです。よくあるケースとして、まとめて一つの表で収めているケースが多いですが、以下のようなデメリットを感じています。

- 列の幅をそれぞれごとの項目に合わせられない
- 行や列が増大した場合に対応しきれない

「そもそも、（人の情報など、容易に増えない表であれ、）情報は増減することがある」と意識してください。増減する場合に1つの表にまとめていると、後々表は瓦解します。

また、「情報が溜まっていく、データだけの表（以下入力表）」と「人が見るために使う、分析のための表（以下出力表）」を分けてください。

- 入力表では自分以外の人が編集・追加する可能性がある。可能な限り数式は使用しない（可能であればフォームのように装い、場合によっては本当にフォーム化する）
- 出力表は分析の仕様が変わることが（多々）ある。分析表は見るだけのシートとすること
- 出力表ではほぼ関数のみで表を構築する。これにより、結果が異常である際に、データによるエラーか、関数によるエラーかを表で区別できる。

なにか問題に差し掛かった時は、データ構造を見直すチャンスです！理想的な関数はありませんし、今すでにある関数で構築するしかありません。あなたはいわばキッチンにいて、食材（データ）をうまい具合に調理しなければならない料理人です。フライパンでアイスクリームは作れないし、ヨーグルトメーカーで豚の角煮はつくるべきではありません。それぞれの関数の特性、不自由を理解して、調理をしていくしかないのです。そして調理に困っている時は、そもそもレシピや料理自体を見直すべきタイミングであり、最終的に食べた人が満足する料理ができればいいのです！

# 人間って
以前、「[プログラミングとは「これから起こること」を書くもの](https://qiita.com/nintia8/items/168a9d79a83a29b9cdae)」を書きましたが、関数や、その延長線上に連なる様々なプログラミング言語の様々な技術の大樹も、機能がある分制約を抱えている、更に言うと完璧ではないシステムです。

みんなしたいことって微妙に違うと思うんですよね。仕事ってみんないっしょじゃないし、そもそも求められることも若干違うし、文化も言葉も違うし。なので、似たような問題であっても同じ解決策で解決しないことも散見されます。中には「これ絶対解決無理やろ…」っていう問題もあったりします。

『市場を創る』という経済学の本にこんな一節があります。

```
市場が常に正しいとか、根本的に悪であるとするような半宗教的な観点に対して、私は市場に対してプラグマティックなアプローチをとることを主張してきた。
市場システムはそれ自体が目的なのではなく、生活水準を引き上げるための不完全な手段の1つである。
市場は魔法ではないし、非道徳的なものでもない。
市場は目覚ましい成果を生み出してきた一方でうまく機能しないこともありうる。
特定の市場がうまく機能するかどうかは、その設計にかかっているのである。
```

私たちが使うシステムも、やれvlookupは左に検索できないわ、やれarrayformulaは実行できる関数が少ないわ、やれwebサイトは様々なことを考慮しなければならないわ、という不完全な代物です。でも、システムはそれ自体が目的ではなくて、解決したいことを行うための、全くの不完全な手段の1つなんですよね。システムも、魔法じゃないし、非道徳的なものでもありません。目覚ましい成果を生み出している一方で、うまく機能しないことも（多々）あります。大事なのは、何かをつくる中で関数やプログラミングをするときに、「これは最善だが、不完全な方法である」と認識することだと思います。

不完全だけど、今はこれが一番いいから、やる。でも、いつか見直す。表を作る時も、つくった表を完璧と思わず、不完全な中での最善と考えて、つくる。そうして、もっとより良い方法のアンテナを張っておく。そんな気持ちが、大切だと思います。

# 明日は
明日は@ta-igaさんの「Rails＋BootstrapでTodoアプリを作ってみよう！」です！
お楽しみに！:smiley: