1とチェックしたセルの行の名前だけを並べる

上で書いたラクチンに面倒な作業が済む、そういうものというのは、デイサービスで来所する利用者さんの名簿に、何もかも情報を詰め込み一元管理して、それをアウトプットするときに色々な形式で出力できるようにしようとしている、まぁそういうものなわけです。住所録にしたり、バイタルチェック表にしたりできるように、とにかく情報を詰め込むと。その名簿っていうのは、端的に言うと、利用者名が一番はじの方にあって、その右に住所やら身長やら何やらが並んでいくわけですね。
で、月火水木金ってタイトルがついている欄があって、そこに1を入れると、その利用者さんが来所する曜日って事にしたい、という欲求もあるわけです。それで、例えば、月曜日にはこの利用者さん達が来ますよ〜っていうのをリスト化したいと。
つまり、タイトルにあるように、1とチェックしたセルの行の名前だけを並べる必要が出てくるわけです。
エクセルをあんまり分かっていないお馬鹿な自分は、こんな事で悩みました。で、やった方法。利用者さんの数は80人超えることはないから・・・っていう職員さんの発言を元にやってます。

  1. とにかくリスト作りのために新しいシートを用意し、1〜80の数字を1列に並べる。
  2. 利用者さんの名前も元のデータベースのシートから参照してきて*11列に並べる。
  3. 更に上は0.80から下は0.01まで、0.01刻みで、80人分数字を並べた列を作る。
  4. 月曜なら月曜の利用者が入っているか入っていないかを表す1があったりなかったりする列を参照して*21列に並べる。
  5. そこから少し離れたある列に、1があるかないかの列と、0.80〜0.01まで並んでいる列を足し合わせた列を作る。上の方にある行は同じ1が入っている行でも少し数字が大きくなるわけですね*3
  6. そこから2列左のところに、RANK(5.の列のセル,5.の列全体,0)と書いて、5.の列の数字の大きさが大きい順に、ランク付けされた列を作る。
  7. その右隣、つまり6.と5.に挟まれた列に、2.をそのまま参照して利用者さんの名前を並べた列を作る。
  8. =VLOOKUP(1.の数字が1〜80まできれいに並んでいる列のセル,6.のランク付けの列と7.の名前が並んでいる列全体,2*4,FALSE)で名前を並べ替えた列を作る。
  9. =IF(VLOOKUP(8.の並び替えられた名前が並んでいる列のセル,7.の名前が並んでいる列全体と5.の列全体,2,FALSE)<1,"",8.の並び替えられた名前が並んでいる列のセル))*5

こんな方法で並べ替えして1がついている行の名前だけ取ってきて、隙間なく並べることができました。もっと巧い方法ありそうだけれどなぁ・・・。ループ処理と1を判定するルーチンを持ったプログラムを作れば、こんなの何でもないですし。何でもシート上の関数で処理を済まそうとするから複雑になるんだな。

*1:参照方法はROW()で行番号を取ってそれを使ってINDEXでもINDIRECT(ADDRESS)のどちらを使っても良いですから、セルを参照する方法にした方がいいですね。普通に参照すると元のデータベース上で行の削除などをした場合、対応できなくなります

*2:これも*2と同じく普通に参照するのはやめましょう

*3:これを元にランク付けができますし、更に1未満のものと1以上のものに分かれます

*4:2列目を指定なので、1.の昇順の数字と一致する数字が6.のランクの数字ににある行の7.の名前のセルを取ってくることになります

*5:7.の名前に対応する5.の列が1未満だったら""を表示してNULLに、1以上だったら最後に出てくる8.の並び替えられた名前が並んでいる列のセルをそのまま表示。1未満の、つまり元々1でチェックされていなかった行を足切りするためだけの操作です