蔵書データベース
表計算ソフトをデータベースとして使うことがあります。
しかし,条件を与えて抽出するという単純な作業でもそれほど簡単ではありません。
ネット上を「Excel 抽出」で探すと簡単にできるように書いてありますが,結構手続きが必要です。
Cindyscriptのリスト処理を使えば1行のコマンドで抽出ができます。
それを表示するのも,コンソールに表示するのであればKeTCindyの Dispmat()関数でできます。
あいまい検索や条件の絞り込みも簡単。
表にして描画面に表示するのであれば,Tabledata() で表を作って,すこしスクリプトを書けばよいのです。
その準備にはすこし時間がかかりますが,準備さえできれば簡単に条件抽出ができます。
条件を変えるたびに一連の操作をやり直さなければならない表計算ソフトとは比べものになりません。
では,蔵書データベースを例に作っていきましょう。
ただし,データベースといっても,データの管理を行うものではありません。データを検索・抽出するものです。
(1) データの作成
(2) データの抽出
(3) 絞り込み検索
(4) 抽出したデータの表示
===============================================================
(1) データの作成
データの作成方法の一例を示します。
図書館の蔵書管理ソフトで,蔵書データを csv 形式で出力します。
これを表計算ソフトに読み込み,必要な項目(列)だけを残します。
ここでは,次の項目を残しました。
ISBN,受入日,書名,叢書名等,著者名,出版社,版年
データの整理ができたら,そのままコピーアンドペーストでCindyscriptエディタに貼り付けてもよいでしょう。
あるいは,csv に書き出して,さらにテキストエディタで処理することも考えられます。
ここでは,いったん csv に書き出して,テキストエディタで件数の削減などの処理をし,それをCindyscriptエディタに貼り付けました。
およそ1000件のデータをいれたものが,このページの下にありますので,ダウンロードして以下の作業を行ってみてください。
(2) データの抽出
まず文字列 Orgdata の内容をリスト化しますが,今回はKeTCindyの Tab2list() は使わず,Cindyscript の tokenize() を使います。
というのは,Tab2list() では,数でできているものは数値化するのですが,ここではその機能が具合が悪いのです。この中には ISBN と 受入日が入っており,これらは数と - , / でできているため,数値化して引き算,割り算をしてしまうからです。tokenize()は文字列のままでリスト化しますので,今回は具合がよいのです。
Database=tokenize(Orgdata,[unicode("000a"),","]);
Index=Database_1;
これは,最初に一度だけ実行すればよいので,Initialization スロットに置くのがよいでしょう。件数が多い場合,Drawスロットに置くと毎回実行するために動作が遅くなります。
Initializaiton スロットには,KETlibのページとDataのページがあるでしょう。
もう一度 フォルダアイコンをクリックすればその次にページができます。
Cinderellaは,このページの順に読み込むので,Dataのページの次にないとエラーになりますので注意してください。
データの抽出は,Draw スロットに書きます。
たとえば,4番目の項目が 叢書名等 ですので,
data=select(Database,indexof(#_4,"ブルーバックス")>0);
Dispmat(data);
とすれば,ブルーバックスのものが抽出されてコンソールに表示されます。
ここで使用した indexof(文字列,検索文字列) は,第2引数の文字列が第1引数の文字列の中にあればその位置を返すので,
data=select(Database,indexof(#_4,"ブル")>0);
でも同じような結果になります。
(3) 絞り込み検索
著者名の漢字があいまいだった場合,たとえば「佐藤勝彦」の「かつひこ」の漢字を忘れた場合は
data=select(Database,indexof(#_5,"佐藤")>0);
で「佐藤**」が抽出されます。さらに,抽出された data から,
data=select(data,indexof(#_5,"彦")>0);
で抽出すれば,「佐藤*彦」が検索・抽出されます。
(4) 抽出したデータの表示
抽出したデータをCinderellaの描画面に一覧表として表示します。
まず,Tabledata() で表を作りましょう。
この例の場合は,項目数が7つなので,1画面に10件表示するとして,ひとまず
Tabledata("",7,11,350,110,[]);
としましょう。
それから,試しに,始めから10件ほどを表示してみます。
Putrow(1,"c",Index);
repeat(10,s,
Putrow(s+1,"l",data_s);
);
表が画面からはみ出しています。
Cinderellaのウィンドウを広げればよいですが,ノートパソコンだと狭いかもしれません。
それぞれのセル幅を調整しますが,表の全体が入るようにしても,書名や著者名がセルからはみ出します。
そこで,長くなりそうな項目 書名・叢書名・著者名・出版社 は文字の長さを調整します。
substring(文字列,a,b) を使います。a文字目の次からb文字目までの部分文字列を作る関数です。
repeat(length(data),s,
data_s_3=substring(data_s_3,0,18);
data_s_4=substring(data_s_4,0,8);
data_s_5=substring(data_s_5,0,12);
data_s_6=substring(data_s_6,0,8);
);
これで入るようになりました。
セルの幅や,何文字目までで切るかは適宜決めてください。
さて,著者名「佐藤」で検索した結果は5件でしたので欄が5件余っています。
その分余分に表示しようとしたので,コンソールに 「WARNING: Index out of range!」が5つ表示されているでしょう。
また,10件より多い場合はスクロールさせて表示したいですね。
10件より少ない場合は,if 分で判定すればよいでしょう。
スクロールはスライダを作って,表示する先頭の番号を決めればよいのでした。(「(5) データの一覧表」を参照)
スライダの上下の点をA,B,スライダ上の点をCとして,
rown=length(data);
start=floor(|A,C|/|A,B|*rown);
でスタート位置を決めます。
また,表示する番号が件数を越えないときに表示するように
repeat(10,s,
if(start+s<=rown,Putrow(s+1,"l",data_(start+s)));
);
とします。
仕上げに,抽出された件数を表の下に表示するようにしましょう。
if(rown>0,
drawtext([20,-1],rown+"件見つかりました");
,
drawtext([20,-1],"該当するものはありません");
);
以上を整理すると,次のようになります。
---蔵書データ検索 ---------------------------------------------------------
// 1 2 3 4 5 6 7
// ISBN,受入日,書名,叢書名等,著者名,出版社,版年
data=select(Database,indexof(#_4,"ブルー")>0);
//data=select(data,indexof(#_5,"堀場")>0); //2つめからは dataで絞り込み
rown=length(data);
if(rown>0,
drawtext([20,-1],rown+"件見つかりました");
,
drawtext([20,-1],"該当するものはありません");
);
// 文字の長さ調整
repeat(length(data),s,
data_s_3=substring(data_s_3,0,18);
data_s_4=substring(data_s_4,0,8);
data_s_5=substring(data_s_5,0,12);
data_s_6=substring(data_s_6,0,8);
);
Tabledata("",7,11,350,110,[]);
start=floor(|A,C|/|A,B|*rown);
Putrow(1,"c",Index);
repeat(10,s,
if(start+s<=rown,Putrow(s+1,"l",data_(start+s)));
);
----------------------------------------------------------------------
ここまでできてしまえば,あとは検索条件を入れるだけで一発で検索できます。
抽出結果をTeXに出力することも,もちろんできます。
さて,このページの下にあるサンプルは約1000件のデータですが,実際のところ何件くらいまで処理できるでしょうか。
筆者のノートパソコンで試した結果,約3万件のデータでも検索にほとんど時間はかかりませんでした。
この3万件は,ある高等学校の図書館の蔵書データです。
ただし,立ち上げるときに10秒ほど時間がかかりました。
<「KeTCindyCalc に戻る」>