6.思ったより簡単にデータベースが使えるんなら、作ってみましょうか その3

●データを読み取ろう

「さて、次は書き込んだ情報を読み取ってみましょう。」
「はい。今のところ、書き込んだだけでしたから、本当に書き込まれているか心配です。」
「そうでしょうね。ところで、書き込むときに、データベースを箱とカードに例えましたが、あなたなら、どうやってこの箱から情報を探しますか?」
「えっと、手と目を使って、という答えじゃないですね。」
「ええ…」
「確か、あのカードには見出しがついていましたから、最初に、見出しを頼りに必要なカードを探して、それから情報を読むでしょうね。」
「だいたい、そんなところでしょう。その動作をまとめてみると、簡単な作業単位に分解することができます。」
「作業単位?」
「はい。まず、見出しを頼りにカードを探すこと、カードを探してから情報を読むこと、ですね。」
「ああ、簡単な単位に分解したんですね。」

 

「ええ。よく見ると、データベースに書き込むことと、手順が同じなことに気付きませんか?」
「えっと…」
「まず、操作したいカードを特定します。そして、特定したカードに処理をするわけですね。」
「あ、本当だ、前回の説明と同じですね。見出しを指定して、書き込みましたね。」
「ええ、そうです。今回のアプリは、その見出しに日付と時間を使いましたね。」
「はい。秒単位まで、日付と時間を見出しにしました。」
「この見出しを頼りに、データを読み出すのは、

  res=DbRead(Db,strKey,strData)

とします。」
「ありゃ?書き込みのDbInsert()と同じですか?」
「ええ、DbInsert()とDbRead()と、コマンドは違いますが、指定する引数などの書式は同じです。」
「それは理解しやすいですね。あれ?でも、カードを特定してから読み込むんじゃ?」
「書き込む際に使った『見出し』って、重複していないですよね?だから、見出しが決まれば、カードが決まるわけですよ。」
「重複なしだから、できるんですね。」
「そう。そして、見出しが見つからなかったら、変数res に 2 が返されるんです。」
「1つの命令語で、検索と読み込みをしているわけですか。」
「そういうことになります。さて、何か読み込んでみることにしましょうか。」
「はい。」
「では、書き込んだ日付と時間を覚えていますか?」
「…え!?」
「ははは、無理ですね。だから、今回の画面のデザインでは選択式にしたんですよね。」
「あ、そうでした、そうでした。日付と時間を選んだら、行動が表示されるんでしたね(汗)」

 

「選択式にしたのは、1つは、そういう理由なんです。日記のネタ用のアプリでなくても、いちいち、細かい時間を覚えているわけないですよね。」
「ええ、まだ理由があるんですか?」
「はい。この見出しなんですけど、結構『シビア』で、例えば、"2002/06/30"と"2002/6/30"では違うものに扱われるんです。」
「同じ6月30日なんですけど…6の前に"0"があるかないか、ですね。」
「この1文字が重要で、この1文字の違いで、見出しが見つけられない場合があるんですよ。」
「ははぁ、だから選択式にしたわけですか。」
「そういうことです。記録されている見出しの一覧を作っておいて、そこから選択すれば確実ですからね。」
「じゃ、見出しの一覧を作ってしまえば、おしまいですね!」
「ええ、ただ、問題があってですね、見出しを使ったデータベースの操作では、見出しを取り出すことができないんですよ。」
「へ?」
「つまり、見出しを指定して、データを読み書きするわけですから、操作する時に見出しを指定しなければならないんですよ。」
「あ!与える側ですね。」
「そうです。見出しを与えて、カードを特定しますから、その逆は…」
「できない!と」
「んー、実は『できにくい』んですけど。ま、できないと思った方が説明しやすいので(笑)」
「じゃ、どうすれば良いんですか?」
「へへへ。実は、データベースへのアクセス方法、もう1つの方法があるんです。」
「!」


●データベース、2つのモード

「先ほど、データベースから情報を読む方法を、見出しを頼りにカードを探し、カードを探してから情報を読む、と言われましたね。」
「ええ、まず、カードを特定する必要があるということなので、見出しを利用しました。」
「でも、カードを特定するだけなら、別の方法も考えられるんですよ。」
「えっと…」
「深く考えなくても、簡単ですよ。例えば、前から何枚目、とか。」
「…あ!なるほど。前から何枚目のカード、とすれば、1枚のカードを特定できますね。」

  

「そうなんです。見出しにこだわらなくても、カードを特定する方法はあるわけです。」
「なるほど。これで、カードを特定して情報を読み出せば・・・?あれ?カードには、見出しと情報が書かれているんですよね。」
「そうです。」
「だったら、見出しの一覧を作ることは、結局できないんじゃないかと…」
「確かに、そのままでは無理ですね。見出しを使った読み書きでは、データベースのカードには『見出し』と『情報』が書かれています。でも、何枚目、という方法だと違うんです。」
「うむむ、ちょっと複雑そうですね。」
「いえいえ、むしろ、もう少し原始的になって『見出し』も『情報』も区別なく『カードに書かれているモノ』になってしまうんです。」

  

「確かに原始的ですが、かえって不便そうですね…」
「ええ、見出しを使う利点は、そのカードの情報のヒントを、見出しを使って区別できる点ですね。例えば、今回は、見出しが書き込んだ日付と時間になっているでしょ。」
「はい。日付と時間を頼りに、行動記録を書き込んだり読み込んだりするのが目的ですね。」
「でも、見出しがわからないとカードが特定できないから、見出しの一覧を作りたい場合、見出しを使わない方法に頼るしかありません。」
「うーん、なんとなく理解はできました。要するに、データの1件はカードで、そのカードを特定するには見出しを使う方法と、前から何枚目、という方法があるんですね。」
「はい。」
「ここまでは、わかったとしましょう。後の見出しを使わない方法で見出しの一覧を作る、という部分を、もう少し具体的に説明してください。」
「はいはい。まず、データを読み出す方法、DbRead()でしたが、こちらの方法では、DbGet()になります。

  res=DbGet(Db,strData)

 見出しがないので、DbRead()で使われていた変数strKeyを使っていませんね。」
「ええ、でも…」
「言いたい事はわかります。何番目のカード、というところが抜けていますね。これは、別の命令語でDbPosition()を使います。

  res=DbPosition(Db,recNo,offSet)

 recNoがカードの番号で、先頭が1番になります。一方、もう1つのoffSetは、オフセット値と言います。」
「オフセット?」
「はい。recNoでカードが特定できたら、次は、offSetで、カード内の位置を指定するんです。」
「位置?」
「見出しを使わないモードでは、カード上の情報はすべて『カード上に書かれているモノ』になっています。なので、先頭から何文字目から取り出しなさい、という形式になっているんです。」
「あ、そうか、見出しも情報も関係ないから、とにかく位置を指定するんですね。」
「そういうことになります。ちなみに、先頭は0文字目になります。」
「でも、取り出しはじめる位置は指定するんですけど、最後は何文字目まで取り出されるんですか?」
「それは、わかりません。」
「は?!」
「正しくは、状況によって変わるんです。例えば、見出しモードでこんな情報を書き込んだとしますね。

  res=DbInsert(Db,"KEY01","mizuno-ami","Ohyoi3")

 見出しは『KEY01』書き込んだ情報は『mizuno-ami』と『Ohyoi3』という文字列情報が2つです。」
「はい。」
「これを、2つのモードから見ると、それぞれ、こんなイメージになるんです。」

 

「全部、つながっているんですね。この『▲』は何ですか?」
「これは、1つの情報の終わりを示す記号で、実際は『▲』ではなく、別のものが入っています。とりあえず、何らかの区切り文字が1文字入っていると覚えておいて下さい。」
「はい。」
「この状態でですね、例えば、

  res=DbPosition(Db,1,6)
  res=DbGet(Db,strData)

 とすると、変数strDataには『mizuno-ami』が代入されます。」
「えっと、0,1,2,3,・・・あ、6番目だ。」
「賢いのは、自動的に区切り記号までを読み取ってくれるので、先頭だけ指定するんです。勝手に残りの『Ohyoi3』というデータまで取ってきたりしません。」
「なるほど。意外と便利じゃないですか。」
「でも、こうしてみましょうか。

  res=DbPosition(Db,1,8)
  res=DbGet(Db,strData)

 こうすると、変数strDataには『zuno-ami』が入ります。」
「確かに8番目はその場所になりますけど・・・それって、あまり正しい情報じゃないですね。」
「これが、意外と便利そうで不便な点です。」
「それじゃ、あまり使い道がなさそうですが。」
「でも1つだけ決まっていることがあります。それは『見出しは必ず、先頭にある』という点です。」
「…あ!ということは、

  res=DbPosition(Db,1,0)
  res=DbGet(Db,strData)

 とすれば、1番目のカードの見出しを読み込めるんですね。」
「そういうことになります。データベース内に、何枚カードがあるかを得る関数にDbGetNoRecs()というのがありますので、これと併用します。

  Dim i as Integer
  Dim intNum as Integer
  Dim res as integer
  Dim Db as Database
  Dim strKey as String

  Popup1007.Clear

  res=DbOpen(Db,"PHS04DB",0)
  intNum=DbGetNoRecs(Db)

  For i=1 to intNum
    res=DbPosition(Db,i,0)
    res=DbGet(Db,strKey)
    Popup1007.Add strKey
  Next

  res=DbClose(Db)

 カードの枚数を変数intNumに代入して、For〜NextでDbPosition()を変化させて、全部のカードから見出しを取り出しています。
 Popup1007は『日付を選んでね』とデザインした、ポップアップリストです。」

   

「ちょっと長いですけど、それほど難しくはありませんね。なんとなく、見出しの一覧が取り出せることがわかります。」
「はい。これを、FormのAfter()の部分に記述しておけば、良いわけです。」
「なるほど〜」
「ちなみに、紹介するのが遅くなりましたが、このデータベースの見出しのことをキー(KEY)と呼ぶことがあります。そこで、見出しを使う方法を『キーモード(KEY MODE)』、見出しを使わない方法を『ノンキーモード(NON-KEY MODE)』と呼んだりもします。」
「キーモードで書き込んだキーを、ノンキーモードで読み出して一覧を作る、ってことですか。ちょっと不思議な感じがしますね。」
「もしかしたら、別の命令後を使うと、キーモードだけで全部できるかもしれませんが、こちらの方が簡単なので紹介しました。キーモードとノンキーモードについては、どこかでもう少し詳しくお話した方がよいかもしれませんね。」
「ええ、機会があれば、お願いします。」
「さて、喜んでばかりはいられません。アプリの完成までもう一息ありますよ。」
「あ、一覧ができただけでしたね(笑)」


●さあ、仕上げよう

「さて、Popup1007に一覧ができていますから、実は、残りはとっても簡単です。」
「とっても?」
「ええ、ポップアップリストのイベントは、何かが選択された時に発生しますので、その時にデータベースを読みにいくだけです。」
「…あ、キーの一覧から選択しているので、それをそのままキーとして指定すればいいんですね!」
「はい。そうなります。具体的にはポップアップのイベント部分に、

  Dim Db as Database
  Dim res as Integer
  Dim strKey as String
  Dim strData as String

  strKey=Popup1007.ItemText(Popup1007.Selected)

  res=DbOpen(Db,"PHS04DB",0)
  res=DbRead(Db,strKey,strData)
  res=DbClose(Db)

  Field1004.Text=strData

 とします。多少、キーを作っている部分が複雑ですが、.Selectedはリストの何番目のデータが選ばれているかを返すもので、.ItemText(n)は、n番目の具体的な内容を返すもの、ということが理解できれば、それほど難しくはないでしょう。」
「複合技ですね。何とか大丈夫みたいです。」
「後は、通常の、キーモードでのデータの読み込みですね。」
「はい。これは、書き込みの逆ですね。」
「これで、完成になります。」


●エピローグ

「では、早速、試してみてください。」
「えっと、書き込んだら、一覧が…おお、できますね。で、一覧を選択すると、内容が…おお、表示されました。できましたね!」

※注:スクリーンショットがないのは、手抜きではありません(笑)。必ず、各自でご確認下さい。

「良かったですね。これで動作確認もOKということですね。」
「ありがとうございました!」
「いえいえ、これで当初の目的どおり、日記のネタを覚えているのが楽になりますね。」
「はい。ついでに、データベースの扱い方もなんとなく覚えましたので、プログラミングが楽しくなりそうです。早速、今日から使ってみたいと思います。」
「しっかりとお役立て下さい。」
「本当に、ありがとうございました。(と慌てて出て行く)」

「あ、あの…行っちゃった。慌しい人だなぁ…
 書き込みボタンしかないから不要なデータを消さないと、使い勝手が悪くなりますよ、って言おうとしたんですけど…ま、いいか。
 動くだけのアプリは、意外と簡単に作れるけど、使い勝手の良いアプリとなると…くふふ。さて、次回のネタはどうしましょう(笑)」



copyright(C)2002 Hacker Dude-san all rights reserved.