世界中で刊行されている書籍には独特の方法で十桁の ISBN 番号が付されています。 十桁の数字のなかには ISBN 番号では有り得ないことがあります。 2007年から番号枯渇の理由で 13桁になったようですがここの記述はあくまでクラシカルな練習です。ISBN-13の判定は末尾に記載
一の位の数字は1倍(そのまま)にします。一の位には X が使われることもありますがこの場合 10 と数えます( Xはローマ数字の 10 の意味で大文字ですがここでは小文字 x でもよい )。十の位の数字は2倍、百の位は3倍、千の位は4倍、一万の位は5倍…のようにしてそれぞれの数字を足し算します。 このようにして得られた和が 11 で割り切れない(余りが生じる)場合は ISBN 番号ではありません。
☆ISBN が 123456789X の場合 (末尾が X のときは 10 になる) 1 2 3 4 5 6 7 8 9 X 1×10+2×9+3×8+4×7+5×6+6×5+7×4+8×3+9×2+10 = 220 220 は 11 で割り切れるので ISBN ok ☆ISBN が4579113213 の場合 4 5 7 9 1 1 3 2 1 3 4×10+5×9+7×8+9×7+1×6+1×5+3×4+2×3+1×2+3×1= 238 238 は 11 で割り切れないので ISBN ではない。
ISBN 番号が ok であっても実在するかは別問題です。ここでは、Excel を使ってこの判定をする方法にトライしてみることにします。簡単な作業に見えますが工夫が要ります。
A 列に10 桁の数字を入力すると M 列に判定結果が出ます。
図では見えませんが、 a2, a3 セルは 10 桁の入力規則が施されています。…データの入力規則を設定…は後述します。
b2 セルには 『 =mid($a2,b$1,1)*(11-b$1) 』 と入力*(注) しています。これを c2 〜 j2 セルまでコピーします。 b2 セル内容は、 『 =mid("123456789X",1,1)*(11-1) 』 になります。 mid("123456789X",1,1) は文字列("123456789X")の最初の文字列から数えて1番目の1文字(つまり1)、これに (11-1) つまり10を掛けて10になります。 同様にc2セルでは、("123456789X") の最初の文字列から数えて2番目の1文字(つまり2)に、 (11-2) つまり9を掛けて18になります。
*(注) 当初 『 =value (mid($a2,b$1,1)) *(11-b$1) 』 のように入力 (赤部分追加) し、文字列を数値に替える必要性を強調しました。しかし、たとえ全角の数字 (典型的な文字列) であっても Excel は構わずに四則演算の計算をすることが分かりました。筆者にとっては新しい発見です。
但し、次項のように sum 関数等が絡むデータでは文字列は数値と扱わないので value 関数が必要です。
『 =if(right($a2,1)="X",10,value(right($a2,1))) 』 と入力しています。 right($a2,1) は文字列( "123456789X" ) の右端の1文字 ("X") になります。 ちなみに、右端の3文字の場合には 『 rigth("123456789X", 3) 』 で "89X" を返します。
if 関数により真ならば 10、偽なら右端の 1 文字を数字に変えます。
L2 セルでは 『 =sum(b2:k2) 』 と入力して b2 〜 k2 の和を得ています。
m2 では『=if(mod($l2,11)=0,"○","×")』と入力し、11で割り切れるか判定しています。 mod 関数は割り算の余りを返します。 『 =mod(24,11) 』 は2になります。 b2 〜 m2 セルまでを b3 〜 m3 セルまでコピーすれば別の判定欄が出来ます。
次の表をコピーして貼り付ければ確かめられます。ISBN? が a1 セルに入るようにします。(貼り付けのオプション)で 「貼り付け先の書式に合わせる」 にすれば字が小さくなりません。
ISBN? | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 合計 | 判定 | |
123456789X | =MID($A2,B$1,1)*(11-B$1) | =MID($A2,C$1,1)*(11-C$1) | =MID($A2,D$1,1)*(11-D$1) | =MID($A2,E$1,1)*(11-E$1) | =MID($A2,F$1,1)*(11-F$1) | =MID($A2,G$1,1)*(11-G$1) | =MID($A2,H$1,1)*(11-H$1) | =MID($A2,I$1,1)*(11-I$1) | =MID($A2,J$1,1)*(11-J$1) | =IF(RIGHT($A2,1)="X",10,VALUE(RIGHT($A2,1))) | =SUM(B2:K2) | =IF(MOD($L2,11)=0,"○","×") |
4579113213 | =MID($A3,B$1,1)*(11-B$1) | =MID($A3,C$1,1)*(11-C$1) | =MID($A3,D$1,1)*(11-D$1) | =MID($A3,E$1,1)*(11-E$1) | =MID($A3,F$1,1)*(11-F$1) | =MID($A3,G$1,1)*(11-G$1) | =MID($A3,H$1,1)*(11-H$1) | =MID($A3,I$1,1)*(11-I$1) | =MID($A3,J$1,1)*(11-J$1) | =IF(RIGHT($A3,1)="X",10,VALUE(RIGHT($A3,1))) | =SUM(B3:K3) | =IF(MOD($L3,11)=0,"○","×") |
設定するセル範囲 ( a2 〜 a3 セル ) を選択しておいて、ここでは 10 桁の数字または文字列に合致しない場合は入力を受け付けないように設定します。
Excel2003 では 「 データ 」 → 「 入力規則 」 で、Excel2007 では 「 データ 」 → 「 データの入力規則 」 で次の図が表示されます。
「 条件の設定 」 では上部から順に指定していきます。状況に応じて必要な 「 リストボックス 」 等が自動的に加入されます。 ここでは 「 入力値の種類 」 は 「 文字列(長さ指定) 」 を、 「 データ 」 は 「 次に等しい 」 で 「 長さ 」 を 10 に指定しています。
(注) 「 空白を無視する 」 の指定が自動的にチェックされていますが、通常正の数の場合、+記号のための空白が加算され、文字列としての長さは1つ多くなります。これを回避するためです。 セル入力時に 「 入力時メッセージ 」 を設定することも出来ます。
暗算が得意な人ならすぐに判定でき何のための表なのか疑問になりますが、Excel の多彩な機能の応用例を紹介しました。
『 Excel, Word の機能の1 割くらいしか使っていない 』 という言い方を耳にしますが、1 割も使えたら相当な達人だと思います。 筆者自身は到底 1% も使えていないと自負? しています。ここで扱った Excel の関数は、 sum 関数以外はふだんはあまり目にしないものばかりです。
「 Microsoft Office Excel ヘルプ 」から抜粋します。
IF 関数… IF(論理式, [真の場合], [偽の場合]) | 指定された条件を評価した結果が TRUE の場合はある値を返し、評価した結果が FALSE の場合は別の値を返します。
VALUE 関数… VALUE(文字列) | 文字列を半角の二重引用符 (") で囲んで指定するか、または変換する文字列を含むセル参照を指定します。
MID 関数…MID(文字列,開始位置,文字数) | 文字列:取り出す文字を含む文字列を指定します。開始位置:文字列から取り出す先頭文字の位置 (文字番号) を数値で指定します。 文字列の先頭文字の位置が 1 になります。文字数:取り出す文字数を指定します。
RIGHT 関数…RIGHT(文字列,文字数) | 文字列:取り出す文字を含む文字列を指定します。文字数:取り出す文字数 (文字列の末尾からの文字数) を指定します。
MOD 関数…MOD(数値,除数) | 数値:割り算の分子となる数値を指定します。除数:割り算の分母となる数値を指定します。
ISBN-13 での判定
奇数桁はそのままで、偶数桁の数字は 3 をかけて総和が 10 で割り切れないとISBN ではありません。
例えば 978-4-1234-5678-9 の場合は
9 7 8 4 1 2 3 4 5 6 7 8 9 9 + 7×3 + 8 + 4×3 + 1 + 2×3 + 3 + 4×3 + 5 + 6×3 + 7 + 8×3 + 9 = 135 135 は10 で割り切れないので ISBN-13 ではありません。
判定表を作るなら b1〜n1 セルに 1 〜13 を埋め b2セルに 『 =mid($a2,b$1,1)*(1+iseven(b$1)*2) 』と入力して始めればよいでしょう。Excel2007 以降ならIFERROR 関数を使い 『 =iferror(mid($a2,b$1,1)*(1+iseven(b$1)*2),"") 』 にすると a2セル未入力でも Error 表示されません。ISEVEN 関数は 偶数の場合 TRUE (1)を返します。