記述師は如何にして探求書リストを作りしか?③著者名並べ替え異聞

ここでエクセル探求書リストのキモ、<並び替え>がうまくできるか実行してみます。 書店の店頭で本を探しやすいリストにするためには、やはり<著者名>での50音順で並べるのが一番。

ということで、ソートしてみます。そうすると明らかに変な並びが見つかるはず。同じ著者名なのに、別々なところにまとまっていたり。

すべてのセルを選択し、<ふりがな>を表示にすると、ふりがなのついているものとついていないものがあるはずです。これはエクセルで入力したものと、テキストデータの違い。
テキストデータにはふりがなのデータが入っていないので、通常のふりがなを基準にした並べ替えでは、別物として捉えられてしまうのですね。
並べ替えにふりがなを使わない場合は、文字コード順というこれまたよくわからない並べ替えになってしまうので、なんとかふりがなを付けたいところ。

エクセルでは複数のセルに一度にふりがなを付ける方法はないため、ここはマクロを使わなくてはなりません。
<エクセル ふりがな 一括>とでも検索すればマクロを作ってくれている人が見つかるはずです。それをダウンロードすれば<ふりがな問題>は解決。
これで基本的にはきちんと並べ替えが実行されます。

ただし<国内>のシートだけは、です。

そう、<海外>のシートはそうはいきません。
例えばエラリー・クイーンの場合、当然<エ>のところへ並べ替えになりますが、もちろん<ク>のとこが正解。創元推理文庫やハヤカワ文庫がそういう順になっているわけですから、本を探す場合それが正解なのです!

姓名を最初からわけて入力すれは良いのですが、前述の如くすでに3000冊超の入力済みが。無理です。もしかしたら無理じゃないのかもしれないけれど、私のエクセル能力では無理です。

そこで目を付けたのが<・(なかぐろ)>。

ま、当然ですな。<・>のあとの文字列(姓)を抽出して、並べ替えに使いたいわけです。
<特定の文字のセル内の位置>を検索するFINDかSEARCH関数で抽出したいとこですが(県名みたいに)。

例えば<エラリー・クイーン>の場合、

=SEARCH("・",<著者名>,1)

これを<出版形態>のひとつ隣のセルに入れます。これで<・>の位置が出ます。<エラリー・クイーン>の場合は5が返ります。さらにその隣のセルに次の数式を入力。

=MID(<著者名>,<・の位置>+1,30)

すると、<・>のひとつ隣から30文字分の文字列が返されます。30文字に意味はないんですが(別に100文字でも良い)、まあ30文字を超える姓の長さの人はいないかなと。V・S・ラマチャンドランでも、え~と8文字か。

しかし!もちろんこれではうまくいきませんでした……。

そう、<・>が複数ある場合もあります。ちょうど今でた<V・S・ラマチャンドラン>のように。さらには<ジョージ・R・R・マーティン>のように三つまであります!

FINDやSEARCHは左側から検索を開始するので、今回の数式だと、<V・S・ラマチャンドラン>なら<S>が、<ジョージ・R・R・マーティン>ならひとつめの<R>が返ってしまいます。

いろいろ考えましたが……その結果、これしか思いつきませんでした。
今までの数式をチャラにして、仕切りなおし。

まず、最初のセルに次の数式を入力します。

=LEN(<著者名>)-LEN(SUBSTITUTE(<著者名>,"・",""))

LEN関数はセル内の文字数をカウントする関数、SUBSTITUTE関数はセル内の特定の文字列を置換する関数です。
つまり、<著者名>すべての文字数から、<・>を削除した文字数を引くことで、逆に<・>の個数をカウントしています。

次に二つ目のセルに数式を入れます。

=IF(<・のカウントセル>=1,SEARCH("・",<著者名>,1),IF(<・のカウントセル>=2,SEARCH("・",<著者名>,SEARCH("・",<著者名>,1)+1),IF(<・のカウントセル>=3,SEARCH("・",<著者名>,SEARCH("・",<著者名>,1)+1)+2,<著者名>)))

もし、<・>が1個の場合、普通に文字列の左端から数えて幾つ目に<・>があるか、その位置を返します。
もし<・>が2個の場合、ひとつ目の<・>の位置+1の位置から<・>を探します。これで二つ目の<・>の位置が返ります。
さらに<・>が3個の場合、ひとつ目の<・>の位置+1から探した二つ目の<・>の位置+1からもう一度探します。これで三つ目の<・>の位置が返ります。

そこでさらに隣のセルに先ほどの数式を入力します。

=MID(<著者名>,<・の位置>+1,30)

これで三つ目のセルには<著者名>の中からファミリーネームが抽出されて表示されるはずです。
さらにこの三つの数式を一つのまとめると、

=IF(LEN(<著者名>)-LEN(SUBSTITUTE(<著者名>,"・",""))=0,<著者名>,MID(<著者名>,IF(LEN(<著者名>)-LEN(SUBSTITUTE(<著者名>,"・",""))=1,SEARCH("・",<著者名>,1),IF(LEN(<著者名>)-LEN(SUBSTITUTE(<著者名>,"・",""))=2,SEARCH("・",<著者名>,SEARCH("・",<著者名>,1)+1),IF(LEN(<著者名>)-LEN(SUBSTITUTE(<著者名>,"・",""))=3,SEARCH("・",<著者名>,SEARCH("・",<著者名>,1)+1)+2,<著者名>)))+1,30))

になります。これで一つのセルだけでファミリーネームが抽出できました。
しかしこれだと<=>に対応できないのと……あと共著の場合にダメなんですよねぇ……。

<V・S・ラマチャンドラン/サンドラ・ブレイクスリー>

これだと……ブレイクスリーが抽出されてしまいます。確認してないけど。まあそこまではいいか。

また

=IF(LEN(<著者名>)-LEN(SUBSTITUTE(<著者名>,"・",""))=0,<著者名>

この数式を、最初に入れることで、<・>がゼロの場合(つまり日本人作家の場合)のエラーを回避します。

ということで、超ややこしく、エレガントさのかけらもない数式になってしまいました。他にやりようがあるのかなぁ。

FINDやSEARCHが、<左からしか探せない>というのが大きな問題なのですから、文字列を反転させる手がある気もします。
つまり<エラリー・クイーン>ではなく<ンーイク・ーリラエ>にして、左から<・>を検索すれば良いわけです。ただ残念ながらそんな文字列操作関数がありません。
マクロでなんとか出来るみたいですが、マクロとかを使うと将来スマートフォンに移植したとき動くのか心配(その前に関数は動くのか?)ですし、それ以前に、私にそんな技術がないのですよ……。

いまんとこ、この関数で満足しています。