ナッキーの「Turbo Delphiはじめて奮戦記」 - 第17回 アンケートプログラムでデータベース操作

By: Hitoshi Fujii

Abstract: 前回データベース対応したアンケートプログラムですが、データベースを使わなかった第15回のアンケートプログラムの機能を持ちません。追加や削除のボタンを作りながら、データベースのデータを扱う方法を学びます。

Hide image
nacky75

ナッキー

前回のデータベースはやっぱり難しかったな。画面を作るのはすごく簡単だったけど、データベースを扱うのは難しそう。

 

Hide image
takahashi75

高橋先生

まだ、コンポーネントを配置しただけだから、データベースを扱った実感がないのかもしれないね。今回は実際にデータベースをコードで操作してみよう。


    データベースについてもう一度

データベースについて何となくはわかったけど、もう一度聞いておきたいな。教えて、高橋先生!

高橋先生:じゃあもう一度おさらいしながら、データベース操作に必要な説明をしよう。ここに出てくるデータベースは、「リレーショナルデータベース」という種類のデータベースのこと。データベースは、データベース管理システム(DBMS)に管理されたデータの集まりだ。データを表のような形で参照することができる。テーブル(表)やクエリのデータセットは関連するデータの集まりのレコード(行)と、同じ種類の集まりのフィールド(項目)でできている。データを扱うときも、どのレコードのどのフィールドかを知る必要があるよ。

Hide image
01レコードとフィールド

図01 レコードとフィールド

ナッキー:そういえば、レコードとかフィールドってでてきたの覚えてます。

高橋先生:レコードはデータベースを扱うときの単位の1つ。テーブルの中では1度に扱えるレコードは1つだけなんだ。そのレコードのことをカレントレコードと呼ぶよ。内容を参照するにしても、削除するにしても、操作したいレコードの箇所にカレントレコードを移してから作業しなくちゃならない。

ナッキー:カレントレコードしか操作できないんですね。でもカレントレコードを移すってどういう感じだろう?

高橋先生:穴の開いたカードがあるとしよう。1レコード分が見える穴の開いたカードだ。見えているレコードがカレントレコードということだとする。穴の開いた部分を下や上にずらすと、1レコードずつ見ることができる。

Hide image
02カレントレコード

図02 カレントレコード

ただ見るだけではなくて、穴の位置を移動する作業が必要なんだ。前回作ったアンケートプログラムでは表のように見えるTDBGridコンポーネントを使っていたから、マウスでクリックするとカレントレコードの移動ができる。コード上で移動するにはTSimpleDataSetコンポーネントのメソッドを使って移動できるよ。

ナッキー:カレントレコードの移動は、コンポーネントやメソッドを使ってできるのね。コードでレコードの操作するときはTSimpleDataSetコンポーネントのメソッドを使ってするんだ。

高橋先生:レコード操作をするときに気にしてほしいのは、データセットの状態だ。コンポーネントを使うと自動的にデータセットの状態を変化させてくれることがあるけれど、任意で遷移させることもできるよ。まずは閉じている状態。値の参照など何もできない。データセットの設定は閉じている状態で行う。次に開いている状態。これで、データの読み取りができる。それから編集状態。カレントレコードを変更できる。編集状態に似ているのが追加状態。新しいデータを追加することができる。編集状態、追加状態共にデータベースには反映していない。編集状態の時にはデータバッファという作業用の場所に変更がたまっているだけになるよ。データバッファの変更情報をデータベースサーバーに書き込むと、開いている状態に戻る。

任意で状態を変化させるならTSimpleDataSetのメソッドを使うといいね。

状態

できること

メソッド

閉じている状態

テーブルやデータベースの設定ができる

Close

開いている状態

データの読み取りができる

Open

編集状態

データベースの編集ができる

Edit


開いている状態にするのは「Open」メソッドのほかにActiveプロパティをTrueにしても変更できる。データベースサーバーに書き込むには「ApplyUpdates」メソッドを使おう。

ナッキー:編集するのは開くだけじゃダメなのね。作業に適した状態があるんだ。今Activeプロパティは「True」にしてあるから読み取りができる状態ね。


    画面を整える

前回やったことも少しは思い出しました。これからデータベースの操作をするのかな?

高橋先生:まずは現在のプログラムをもう少し整えよう。ラベルが英語のままなので日本語にしよう。項目コンポーネントのラベルにはフィールド名が採用される。データベースのフィールド名には半角の英数字しか使えないことが多いから、全角の名前がつけられない。そこでフィールド名のほかに項目コンポーネントのプロパティを設定しよう。

ナッキー:項目コンポーネントってどんなコンポーネントでしたっけ?

高橋先生:TSimpleDataSetコンポーネントをダブルクリックして表示する項目エディタで登録したコンポーネントだよ。フォームにドラッグしてコンポーネントを配置したよね。

ナッキー:コンポーネントがずらーっと並んで楽しかったです。

高橋先生:その項目コンポーネントだよ。それぞれに「DisplayLabel」プロパティで名前を入力すると、ラベル名に採用される。たとえばTDBGridコンポーネントのタイトルにも使われるよ。TDBEditコンポーネントについているラベルは変更されない。配置する前にDisplayLabelプロパティが設定されていないと反映しないんだ。だから、TLabelコンポーネントとTDBEditコンポーネントは、削除してもう1度配置してみよう。コンポーネントの幅を調整して見やすくしてね。

ナッキー:えー。せっかく配置したのにもったいないな。でもドラッグするだけだからラベルを全部書き直すよりは楽なのね。


まずはInterBase サービスマネージャーを起動します。Windows OSのスタートメニューで「Borland InterBase 7.5 Develper [instance = gds_db]」の「InterBase サービスマネージャー [instance = gds_db]」をクリックします。「ステータス(T)」欄に、「InterBaseをWindowsサービスとして起動する」にチェックが付いていないことを確認します。「InterBaseサーバーは停止中」となっていれば、[起動(S)]ボタンをクリックして起動します。「InterBaseサーバーは稼動中」と変化したのを確認して[閉じる](×)ボタンで終了します。

Hide image
03サービスマネージャー

図03 InterBase サービスマネージャー

次にプロジェクトを開きます。Turbo Delphiを起動して、画面中央の「ホームページ」で「ProfileDB.bdsproj」を選択。もし一覧に表示されていなければ、ツールバーの[プロジェクトを開く(Ctrl+F11)]ボタンをクリックします。「プロジェクトを開く」ダイアログボックスから「ProfileDB.bdsproj」を探します。もしも、プロジェクトを開くとき「dbExpressエラー:[0x0015]:接続失敗」といったエラーメッセージが表示されたら、もう1度InterBase サービスマネージャーを起動してInterBaseサーバーが起動しているか確認してみて欲しいんですって。

Hide image
04エラーメッセージ

図04 エラーメッセージ

画面上部の「FormProfileDB」タブを選択して、画面をフォームデザイナに切り替えます。フォーム上に前回作ったデータが表示されていなければ、「SQLConnection1」コンポーネントを探して「データベース」カテゴリで「Connected」プロパティを「True」にします。さらに「SimpleDataSet1」を選択して、「その他」カテゴリの「Active」プロパティを「True」にしておきます。

データベースに接続できたら、項目エディタを表示します。SimpleDataSet1コンポーネントを探してダブルクリック、もしくは右ボタンクリックして「項目の設定(T)...」を選択します。項目エディタに登録した項目コンポーネントを選択して、DisplayLabelプロパティを変更します。「ID」はそのままにして、以下の表を参考に変更します。

FULLNAME

カテゴリ名

プロパティ名

設定値

ローカライズ対象

DisplayLabel

名前


ADDRESS

カテゴリ名

プロパティ名

設定値

ローカライズ対象

DisplayLabel

住所


BIRTHDAY

カテゴリ名

プロパティ名

設定値

ローカライズ対象

DisplayLabel

誕生日


MALE

カテゴリ名

プロパティ名

設定値

ローカライズ対象

DisplayLabel

性別


PET

カテゴリ名

プロパティ名

設定値

ローカライズ対象

DisplayLabel

ペットの有無


DBGrid1コンポーネントの上部にあるタイトルが変更できたことを確認します。うまく変更できたら、画面上部のTLabelとTDBEditのコンポーネントをすべて削除します。TLabelコンポーネントとTDBEditコンポーネントをすべて選択して、キーボードの[Delete]キーを押します。

Hide image
05コンポーネントの削除

図05 コンポーネントの削除

次に、配置を整えるためにTPanelコンポーネントを配置します。データベース接続のSQLConnection1、SimpleDataSet1、DataSource1と、DBGrid1はそのままでいいので、画面右下のツールパレットから「Standard」カテゴリの「TPanel」をDBGrid1上部に1つ配置します。

Hide image
06TPanelコンポーネントの配

図06 TPanelコンポーネントの配置

ほかのコンポーネントを配置するためにプロパティも設定します。Panel1を選択して、画面左下のオブジェクトインスペクタ、プロパティページで「ローカライズ対象」カテゴリの「Caption」を削除します。「レイアウト」カテゴリの「Align」プロパティを「alTop」にします。

Panel1

カテゴリ名

プロパティ名

設定値

ローカライズ対象

Caption

内容を削除

レイアウト

Align

alTop


さらに高さを広げてDBGrid1の近くまで伸ばします。次にDBGrid1のAlignプロパティも設定します。DBGrid1を選択して、「レイアウト」カテゴリの「Align」プロパティを「alClient」にしておきます。

DBGrid1

カテゴリ名

プロパティ名

設定値

レイアウト

Align

alClient



Hide image
07ベースのレイアウト

図07 ベースのレイアウト

設定ができたら、項目エディタからすべての項目をドラッグしてパネルの左上に配置します。今度はラベルが日本語で表示されます。

Hide image
08項目コンポーネントの配置

図08 項目コンポーネントの配置

次に配置したコンポーネントの幅を調整します。住所などはドラッグで調整しにくいのでDBEdit3コンポーネントを選択して、「Width」プロパティに「150」程度を入力してから幅を整えると操作しやすいです。

DBGrid1コンポーネントの項目の幅も調整します。こちらも住所が調整しにくいのでプロパティを使います。プロパティを使うためには「カラムエディタ」を使用します。DBGrid1コンポーネントをダブルクリックするか、右ボタンクリックして「カラムエディタ(L)...」を選択します。

Hide image
09カラムエディタ

図09 カラムエディタ

ツールバーの左から3番目[すべての項目の追加]ボタンをクリックして項目を追加します。「ADDRESS」を選択してWidthプロパティを「100」程度にします。

Hide image
10幅の調整

図10 幅の調整

ドラッグですべての項目がDBGrid1コンポーネントに表示できるように幅を調整します。設定できたらカラムエディタは閉じておきます。

Hide image
11配置完了

図11 配置完了

高橋先生:性別やペットの有無は、「True」や「False」では、どちらが何を示しているかがわかりにくいね。わかりやすくするために、項目コンポーネントの「DisplayValues」プロパティに、「Trueのときの値;Falseのときの値」をセットしよう。「MALE」の場合は「男性;女性」、「PET」の場合は「有;無」とする。

ナッキー:そうすると、表の中に「男性」とか「無」と表示されるんですね。

高橋先生:ただし、この設定はTDBGridコンポーネントしか反映しないんだ。TDBCheckBoxコンポーネントは変化がないよ。


Boolean型のデータを、値に置き換えて表示できるようにします。項目エディタで「MALE」を選択します。プロパティページの「ローカライズ対象」カテゴリで「DisplayValues」プロパティに、「男性;女性」と入力します。「;」(セミコロン)は半角で入力します。同様にして項目エディタで「PET」を選択します。「DisplayValues」プロパティで「有;無」と入力します。DBGrid1を確認します。正しく設定できたら、性別欄は「男性」か「女性」ペット欄は「有」か「無」となります。

Hide image
12DisplayValuesの設定

図12 DisplayValuesの設定

高橋先生:もうちょっと、設定をしよう。日付の入力は西暦、年、月の順で間に「/」を入れるんだ。記述の方法がそろっていないとうまくいかないから項目コンポーネントの「EditMask」プロパティを設定する。ここで「!9999/99/00;1;_」と入力すると入力しやすくなる。ダイアログボックスを使って設定してもいいよ。

ナッキー:どんなふうに入力しやすいか、よくわからないんですけど。

高橋先生:設定用のダイアログボックスの中に「テスト」欄があるので試してみるといいよ。


じゃあ、設定してみます。項目エディタで「BIRTHDAY」を選択します。プロパティページの「ローカライズ対象」カテゴリで「EditMask」を探します。クリックすると「…」ダイアログボタンが表示されますので、それをクリックします。「入力マスクの設定」ダイアログボックスが表示されます。

Hide image
13入力マスクの設定

図13 入力マスクの設定

右側の「例(S):」から「日付」を選択します。「入力マスク(I):」に「!99/99/00;1;_」と表示されますので、「99」を付け足して「!9999/99/00;1;_」とします。これで西暦を2桁ではなく、4桁で表示することができるんですって。「テスト(T):」欄で試してみることができるんですって。半角数字で入力してみます。「/」は入力しなくてもいいのね。確認できたら[OK]ボタンをクリックします。

このあとコードを記述するので、コンポーネントのNameプロパティを設定します。ついでにフォームのCaptionプロパティも設定します。

※ 手順によってはフォーム名が異なる場合があります。

Form1(フォーム)

カテゴリ名

プロパティ名

設定値

その他

Name

frmProfileDB

ローカライズ対象

Caption

アンケート


DBEdit1(ID)

カテゴリ名

プロパティ名

設定値

その他

Name

dbedtID


DBEdit2(FULLNAME)

カテゴリ名

プロパティ名

設定値

その他

Name

dbedtFullName


DBEdit3(ADDRESS)

カテゴリ名

プロパティ名

設定値

その他

Name

dbedtAddress


DBEdit4(BIRTHDAY)

カテゴリ名

プロパティ名

設定値

その他

Name

dbedtBirthday


DBCheckBox1(MALE)

カテゴリ名

プロパティ名

設定値

その他

Name

dbcbxMale


DBCheckBox2(PET)

カテゴリ名

プロパティ名

設定値

その他

Name

dbcbxPet


DBGrid1

カテゴリ名

プロパティ名

設定値

その他

Name

dbgrdProfile


SimpleDataSet1

カテゴリ名

プロパティ名

設定値

その他

Name

sdsProfile


できたら保存しておきます。ツールバーの[すべて保存]ボタンをクリックします。sdsProfileコンポーネントの項目エディタも使わないので閉じてしまいます。

    追加・削除ボタンを作る

フォームの調整はできましたね。次はデータベースを使って何かするって言ってたけど、何をどうするのかな?教えて、高橋先生!

高橋先生:いよいよ、データベースを操作するボタンを作ろう。まず、作ってもらうのは[追加(A)]ボタンと[削除(D)]ボタンだ。新しいデータの追加と、既存のデータの削除ができるようにする。

ナッキー:以前のプログラムには[編集(E)]ボタンがあって、編集用のダイアログボックスを作ったような気がしますが、今回はないんですか?

高橋先生:編集ならこのままできるんだ。変更したいレコードを選択して、TDBEditコンポーネントでも、TDBGridコンポーネントでも編集できる。TDBGridコンポーネントの場合はフィールドをクリックして青く反転したら、もう一度クリックする。ダブルクリックではないから注意してね。

ナッキー:へぇ、そのまま編集できちゃうんだ。じゃあ、追加や削除はどうやるんですか?

高橋先生:メソッドを使おう。今回はsdsProfileコンポーネントのメソッドを使う。追加は「Append」メソッド、削除は「Delete」メソッドで処理できる。削除の場合は「MessageDlg」関数を使って削除の確認もしよう。

ナッキー:MessageDlg関数ってメッセージボックスに「はい」「いいえ」のボタンが付いていて、選ぶことができるんでしたよね。以前使ったの覚えてますよ。

高橋先生:if文の条件文に関数を使っていたね。今回も同じようにして作れるよ。


では、ボタンを2つ追加します。フォームデザイナの画面で、TDBEditコンポーネントとTDBGridコンポーネントの間に、ボタンを置くための隙間を作ります。次に、ツールパレット「Standard」ページからTButtonコンポーネントを探して、TDBEditコンポーネントとTDBGridコンポーネントの間の中央に2つ配置します。

Hide image
14追加ボタン削除ボタンの配

図14 [追加]ボタンと[削除]ボタンの配置

それぞれ「プロパティ」ページでプロパティを設定します。

Button1([追加]ボタン)

カテゴリ名

プロパティ名

設定値

その他

Name

btnAddData

ローカライズ対象

Caption

追加(&A)


Button2([削除]ボタン)

カテゴリ名

プロパティ名

設定値

その他

Name

btnDelete

ローカライズ対象

Caption

削除(&D)


配置できたらコードを記述します。まずは[追加(A)]ボタンから選択して、イベントページで「入力」カテゴリの「OnClick」をダブルクリックします。sdsProfileコンポーネントの「Append」メソッドでレコードの追加をします。太字部分を記述します。

procedure TfrmProfileDB.btnAddDataClick(Sender: TObject);
begin
  sdsProfile.Append;
end;

[追加(A)]ボタンができたら、[削除(D)]ボタンを実装します。画面をフォームデザイナに切り替えて、[削除(D)]ボタンを選択します。イベントページの「入力」カテゴリで、「OnClick」をダブルクリックします。MessageDlg関数を使って、戻り値が「mrYes」だったらsdsProfileコンポーネントの「Delete」メソッドでレコードを削除します。太字部分を記述します。

procedure TfrmProfileDB.btnDeleteClick(Sender: TObject);
begin
  if MessageDlg('削除してもいいですか?',mtConfirmation,
    [mbYes,mbNo],0) = mrYes  then
    sdsProfile.Delete;
end;

できたら、保存して実行します。ツールバーの[すべて保存]ボタンをクリックします。次にツールバーの[実行]ボタンをクリックして、実行してみます。まずは[追加(A)]ボタンをクリックして、レコードを記述します。数件入力できたら、どれか1つのレコードを選択して[削除(D)]ボタンをクリックします。メッセージが表示されたら、[はい(Y)]ボタンをクリックして削除できることを確認します。できたらプログラムを終了します。もう1度[実行]ボタンをクリックして実行してみます。追加したレコードがなくなっていることを確認できたら、プログラムを終了します。

Hide image
15追加ボタン削除ボタンの実

図15 [追加]ボタンと[削除]ボタンの実行テスト

Hide image
16プログラムの再起動

図16 アンケートプログラムの再起動

    保存ボタンを作る

えー、どういうことなんだろう?せっかく登録したのに、削除したもの以外もなくなっちゃっています。[削除(D)]ボタンって全部消しちゃうのかな?でも、最初からあった自分のレコードは残っていたわよね。教えて、高橋先生!

高橋先生:どのボタンも正常に働いていたよ。でもプログラムをそのまま終了すると追加したデータはなくなってしまうんだ。

ナッキー:それじゃあ、[追加(A)]ボタンってどんな役割があるんですか?

高橋先生:レコードを追加する機能があるよ。でも追加している場所はInterBaseサーバーじゃないんだ。

ナッキー:ん?それなら、どこに追加してるのかな?

高橋先生:「データベースキャッシュ」という作業用の場所に追加している。変更はデータベースキャッシュに複数レコードを溜め込むことができるよ。データベースキャッシュにあるレコードをInterBaseサーバーに反映させる、TSimpleDataSetコンポーネントの「ApplyUpdates」メソッドを使うよ。そうだな、水槽(データベース)に水(レコード)を入れるために、コップで1レコードずつ入れるのではなくて、1度バケツ(データベースキャッシュ)にためてから、バケツから水槽にまとまった水を入れる(ApplyUpdates)んだ。

Hide image
17データベースキャッシュ

図17 データベースキャッシュ

ナッキー:なーんだ。[追加(A)]ボタンはInterBaseサーバーに追加してたんじゃなくて、別の場所に追加してたんだ。アンケートプログラムの画面は変化するから、InterBaseサーバーに追加しているんだと思いました。

高橋先生:実は[削除(D)]ボタンでの削除も、直接InterBaseサーバーからレコードを削除するわけじゃないんだ。ボタンを使わない編集の操作も同様だ。削除も編集も「ApplyUpdates」メソッドを使わないと、InterBaseサーバーに反映しないことになっている。

ナッキー:どうして、そんな面倒なことになっているんですか?

高橋先生:データベースは複数の人が接続することを考えて作っている。データベースへの書き込みをしているとき、ほかの人がアクセスしないように監視したり、不正なデータが書き込まれないかチェックしたりしている。一度に全部やると大変だから編集や削除などをデータベースキャッシュにためておいて、あとでまとめてデータベースへの書き込みができるよう、別のメソッドを使うようになっている。そのほうがプログラムで制御もしやすいよ。今回は[保存(S)]ボタンを作って、ApplyUpdatesメソッドを使ってみよう。

ナッキー:もっと複雑なことになっているんですね。追加のときも、削除のときもデータベースキャッシュに変更がたまっている状態なんだ。データベースキャッシュをInterBaseサーバーに書き込むのがApplyUpdatesメソッドなのね。


では、[保存(S)]ボタンを作ります。画面をフォームデザイナに変更して、ツールパレット「Standard」ページからTButtonコンポーネントを1つ[削除(D)]ボタンの右側に配置します。配置したらプロパティを設定します。

Button1([保存]ボタン)

カテゴリ名

プロパティ名

設定値

その他

Name

btnSave

ローカライズ対象

Caption

保存(&S)



Hide image
18保存ボタンの配置

図18 [保存]ボタンの配置

設定できたら、コードを記述します。ApplyUpdatesメソッドには、許可するエラーの数をパラメータに設定できます。まず、[保存(S)]ボタンを選択して、イベントページ「入力」カテゴリの「OnClick」をダブルクリックします。今回は無制限でエラー許可する「-1」をセットします。太字部分を記述します。

procedure TfrmProfileDB.btnSaveClick(Sender: TObject);
begin
  sdsProfile.ApplyUpdates(-1);
end;

できたら、保存して実行します。ツールバーの[すべて保存]ボタンをクリックします。次にツールバーの[実行]ボタンをクリックして、実行します。実行できたら[追加(A)]ボタンをクリックして、レコードを記述します。数件入力できたら、どれか1つのレコードを選択して[削除(D)]ボタンをクリックします。メッセージが表示されたら、[はい(Y)]ボタンをクリックして削除できることを確認します。できたら[保存(S)]ボタンをクリックしてからプログラムを終了します。もう1度[実行]ボタンをクリックして実行してみます。追加したレコードが残っていることが確認できたら、プログラムを終了します。

Hide image
19データの保存を確認

図19 データの保存を確認

    前へ・次へボタンを作る

レコードが増えて、なんだか嬉しい。でも、フォームデザイナの画面は反映しないのね。教えて、高橋先生!

高橋先生:フォームデザイナの画面は変更を、すぐさま反映させるようにしていないからしかたないよ。どうしても反映した画面にしたいときは、sdsProfileコンポーネントの「Active」プロパティを1度「False」にしてから「Active」変更すれば、更新される。このように、開発中でも最新のデータを表示できるんだ。この機能を「ライブデータ」というよ。

ナッキー:レコードがちゃんと増えました。さっき、データが消えちゃったので心配になっちゃって。今度はちゃんとレコードの追加や削除が反映していましたね。

高橋先生:レコードが増えたので、今度はカレントレコードを移動させてみよう。1つ前のレコードに移動するボタンと、次のレコードへ移動するボタンをつくるよ。レコードの移動にもメソッドが用意されている。1つ前へ移動するのはsdsPrifileコンポーネントの「Prior」メソッド、次へ移動するのは「Next」メソッドだよ。

ナッキー:コードでもカレントレコードの移動ができるんですね。


ボタンを2つ作ります。フォームデザイナの画面で、ツールパレット「Standard」ページからTButtonコンポーネントを2つ、[追加(A)]ボタンの左側に並べて配置します。配置したらプロパティを設定します。

Button1([前へ]ボタン)

カテゴリ名

プロパティ名

設定値

その他

Name

btnPrior

ローカライズ対象

Caption

前へ(&P)


Button2([次へ]ボタン)

カテゴリ名

プロパティ名

設定値

その他

Name

btnNext

ローカライズ対象

Caption

次へ(&N)



Hide image
20前へボタン次へボタンの配

図20 [前へ]ボタンと[次へ]ボタンの配置

[前へ(P)]ボタンから実装します。[前へ(P)]ボタンを選択して、イベントページ「入力」カテゴリの「OnClick」をダブルクリックします。sdsPrifileコンポーネントの「Prior」メソッドを使って前へ移動します。太字部分を記述します。

procedure TfrmProfileDB.btnPriorClick(Sender: TObject);
begin
  sdsProfile.Prior;
end;

できたら、フォームデザイナの画面に戻って[次へ(N)]ボタンを選択します。OnClickイベントハンドラを作成します。イベントページ「入力」カテゴリの「OnClick」をダブルクリックします。sdsPrifileコンポーネントの「Next」メソッドを使って前へ移動します。太字部分を記述します。

procedure TfrmProfileDB.btnNextClick(Sender: TObject);
begin
  sdsProfile.Next;
end;

記述したら、保存して実行します。ツールバーの[すべて保存]ボタンをクリックします。次にツールバーの[実行]ボタンをクリックして、実行します。[次へ(N)]ボタンや[前へ(P)]ボタンでカレントレコードの位置を変更してみます。

    キャンセルボタンも作ろう

ボタンもたくさんできたわね。TSimpleDataSetのメソッドもいろいろ使ってみました。そろそろ完成?

高橋先生:もう1つ、[キャンセル]ボタンを作ろう。さっきデータベースキャッシュに変更をためておくという説明をしたね。そのデータベースキャッシュに入っている変更をやめてしまうんだ。バケツの例えだと、水を出して空にするんだ。

ナッキー:そうすると、[保存(S)]ボタンをクリックしても変更はInterBaseサーバーに反映しないんですね。

高橋先生:そうだね。sdsProfileコンポーネントの「Cancel」メソッドで、追加や削除などの変更を取り消すことができる。


もう1つボタンを追加します。フォームデザイナの画面に切り替えて、ツールパレットの「Standard」カテゴリから「TButton」を選択します。[削除(D)]ボタンと[保存(S)]ボタンの間に配置します。表のようにプロパティを変更します。

Button1([キャンセル]ボタン)

カテゴリ名

プロパティ名

設定値

その他

Name

btnCancel

ローカライズ対象

Caption

キャンセル(&C)



Hide image
21キャンセルボタンの配置

図21[キャンセル]ボタンの配置

[キャンセル(C)]ボタンを選択して、イベントページ「入力」カテゴリの「OnClick」をダブルクリックします。sdsPrifileコンポーネントの「Cancel」メソッドを使って変更の取り消しをします。太字部分を記述します。

unit FormProfileDB;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DBXpress, WideStrings, Grids, DBGrids, StdCtrls, DBCtrls, DB, Mask,
  DBClient, SimpleDS, SqlExpr, ExtCtrls;

type
  TfrmProfileDB = class(TForm)
    SQLConnection1: TSQLConnection;
    sdsProfile: TSimpleDataSet;
    sdsProfileID: TIntegerField;
    sdsProfileFULLNAME: TStringField;
    sdsProfileADDRESS: TStringField;
    sdsProfileBIRTHDAY: TDateField;
    sdsProfileMALE: TBooleanField;
    sdsProfilePET: TBooleanField;
    DataSource1: TDataSource;
    dbgrdProfile: TDBGrid;
    Panel1: TPanel;
    Label1: TLabel;
    dbedtID: TDBEdit;
    Label2: TLabel;
    dbedtFullName: TDBEdit;
    Label3: TLabel;
    dbedtAddress: TDBEdit;
    Label4: TLabel;
    dbedtBirthday: TDBEdit;
    dbcbxMale: TDBCheckBox;
    dbcbxPet: TDBCheckBox;
    btnAddData: TButton;
    btnDelete: TButton;
    btnSave: TButton;
    btnNext: TButton;
    btnPrior: TButton;
    btnCancel: TButton;
    procedure btnAddDataClick(Sender: TObject);
    procedure btnDeleteClick(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure btnCancelClick(Sender: TObject);
    procedure btnPriorClick(Sender: TObject);
    procedure btnNextClick(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  frmProfileDB: TfrmProfileDB;

implementation

{$R *.dfm}

procedure TfrmProfileDB.btnAddDataClick(Sender: TObject);
begin
  sdsProfile.Append;
end;

procedure TfrmProfileDB.btnCancelClick(Sender: TObject);
begin
  sdsProfile.Cancel;
end;

procedure TfrmProfileDB.btnDeleteClick(Sender: TObject);
begin
  if MessageDlg('削除してもいいですか?',mtConfirmation,
    [mbYes,mbNo],0) = mrYes  then
    sdsProfile.Delete;
end;

procedure TfrmProfileDB.btnSaveClick(Sender: TObject);
begin
  sdsProfile.ApplyUpdates(-1);
end;

procedure TfrmProfileDB.btnPriorClick(Sender: TObject);
begin
  sdsProfile.Prior;
end;

procedure TfrmProfileDB.btnNextClick(Sender: TObject);
begin
  sdsProfile.Next;
end;

end.

記述したら、保存して実行します。ツールバーの[すべて保存]ボタンをクリックします。次にツールバーの[実行]ボタンをクリックして、実行します。適当に変更したあと、[キャンセル(C)]ボタンをクリックして、[保存(S)]ボタンをクリックしてアンケートプログラムを1度終了します。もう1度[実行]ボタンでデータに変化がないことを確認します。

ナッキー:データベースを扱うメソッドをたくさん使ってボタンを作ったので、データベースが使えた気持ちになりました。

高橋先生:少しは、データベースが嫌いじゃなくなったかな?TSimpleDataSetなどのコンポーネントを使うとメソッドやプロパティが使えるから楽々コーディングできるね。

ナッキー:じゃあ、これで完成なんですね。

高橋先生:いやー、そうは言ってないよ。今回は楽しくデータベースに向き合ってもらうのが目的だから難しい説明はしていない。もう少しアンケートプログラムを使ってデータベースを勉強してもらいたいな。

ナッキー:えー、もっと難しくなるんですかぁ。今回は少しデータベースがわかってきたかなと思ったのに。

高橋先生:時間をかけてやっていこうね。

ナッキー:そんなに時間がないんですよ。明日幼稚園の遠足だから弁当の材料を買いに行かなくっちゃ。

高橋先生:また、行っちゃうわけ。

ナッキー:はーい。行ってきまーす。


ナッキーの「Turbo Delphiはじめて奮戦記」

Prev | Next | Index


Server Response from: ETNASC01