■データモジュールの拡張
  ●学習内容  
     今回のアプリケーションでは、マスター/詳細関係を使ってスタッフ情報を追加します。データモジュールの作成について以下の手順で説明していきます。  
  コンポーネントの設定  
  コードの記述
 
   
■コンポーネントの設定  
   前に作成したデータモジュールにコンポーネントを追加します。追加したコンポーネントについてイメージにリンクしてあるので設定をしてください。  
   
 
 
●StaffDS
コンポーネンの種類 TDataSource
プロパティ 設定値
DataSet StaffQuery
Name StaffDS
       
●StaffQuery
コンポーネントの種類 TQuery
プロパティ 設定値
CachedUpdates True
DataBaseName 作成したエリアス名
DataSource CinemaDS
Name StaffQuery
Params 0-cinema_code
DataType ftInteger

SQL
 
 
 

SELECT a.* , b.staff_genre_name
FROM staff.db a , staff_genre.db b
WHERE a.staff_genre_code = b.staff_genre_code
AND cinema_code = :cinema_code
UpdateObject  
UpdateSQL2
    SQLプロパティ中にcinema_code = :cinema_code と記述されています。これは、パラメータを使ってマスター/詳細関係を作成しています。詳細に付いてはマスター/詳細関係を参照してください。また、DataSourceプロパティにCinemaSDが設定されていることに注意してくださ。また、Paramsプロパティも必ず設定してください。  
  
●UpdateSQL2
@
 
UpdateSQL2をダブルクリックするか、右クリックによるポップアップメニューから[UpdateSQLの設定(U)]を選択します。
A
 
キー項目に「Staff_code」選択し、更新する項目「Staff_code」「Staff_genre_name」以外の項目を選択し、「SQL文を生成(G)」ボタンを押します
   
 
●SGenreDS
コンポーネント:TDataSource
プロパティ 設定値
Name SGenreDS
DataSet SGenreQuery
 
●SGenreQuery
コンポーネント:TQuery
プロパティ 設定値
DatabaseName 作成したエリアス名
Name SGenreQuery
   
SQL    SELECT * FROM staff_genre.db
         
■コードの記述
■イベントハンドラ
 
コンポーネント:CienamaQuery
イベント 発生タイミング
AfterCancel キャンセルしたあと GO
AfterScroll レコードがスクロールした後 GO
BeforeDelete 削除前 GO
BeforeInsert 挿入前 GO
 
コンポーネント:StaffQuery
イベント 発生タイミング
AfterDelete 削除後 GO
AfterPost データセットに書き込んだ後 GO
BeforePost データセットに書き込む前 GO
OnUpDateRecord キャッシュアップデートがレコードに適用された時 GO
 
項目コンポーネント:StaffQueryStaff_name
イベント 発生タイミング
OnValidate 項目の編集終了時 GO
 
項目コンポーネント:StaffQueryStaff_Genre_code
イベント 発生タイミング
OnValidate 項目の編集終了時 GO
 
■メソッド
可視属性 宣言  
Public procedure StaffQueryPost; GO
         
■CinemaQuery.AfterCancelイベント  
    procedure TCinemaDM.CinemaQueryAfterCancel(DataSet: TDataSet);
begin
 Form1.DBNavigator2.Enabled := True;
 Form1.SpeedButton1.Enabled := True;
end;
 
 
■CinemaQuery.AfterScrollイベント
procedure TCinemaDM.CinemaQueryAfterScroll(DataSet: TDataSet);
var
 JPG: TJPEGImage;
 BlobStream: TBlobStream;
begin
 // BLOB項目から読み込む
 if not CinemaQuery.FieldByName('image').IsNull then
 begin
  JPG := TJPEGImage.Create;
  // BLOBストリームを作成して画像を読み込む
  BlobStream := TBlobStream.Create(TBlobField(CinemaQuery.                                  FieldByName('image')),bmRead);
  try
   // BLOBストリームからJPEGデータを読み込む
   JPG.LoadFromStream(BlobStream);
   // Image1に画像を表示する
   Form1.Image1.Picture.Assign(JPG);  
  finally
   BlobStream.Free;
   JPG.Free;
  end;
 end
 else
  Form1.Image1.Picture.Assign(Nil);

 if CinemaDM.StaffQuerystaff_name.Text = '' then
 //詳細テーブルのDBEditが更新されないのでコードで更新を行う
  Form1.DBEdit1.Clear
 else
  Form1.DBEdit1.Text := CinemaDM.StaffQuerystaff_name.AsString;
end;
  詳細情報のDBEditが更新されないのでコードで更新を行うものとする。  
   
■CinemaQuery.BeforeDeleteイベント
procedure TCinemaDM.CinemaQueryBeforeDelete(DataSet: TDataSet);
//StaffQueryは詳細テーブルなのでマスターテーブルを削除する場合は
//詳細テーブルのデータをすべて削除した後に削除する

begin
 StaffQuery.First;
 While not StaffQuery.Eof do
  begin
  StaffQuery.Delete;
  end;
 CinemaDM.StaffQueryPost;
end;
   
■CinemaQuery.BeforeInsertイベント
procedure TCinemaDM.CinemaQueryBeforeInsert(DataSet: TDataSet);
//必須項目を登録する前に挿入する事を禁止するため
begin
 Form1.SpeedButton1.Enabled := False;
 Form1.DBNavigator2.Enabled := False;
end;
   
  ■StaffQuery.AfterDeleteイベント  
    procedure TCinemaDM.StaffQueryAfterDelete(DataSet: TDataSet);
begin
 CinemaDM.StaffQueryPost;
end;
 
       
  ■StaffQuery.AfterPostイベント  
    procedure TCinemaDM.StaffQueryAfterPost(DataSet: TDataSet);
begin
 CinemaDM.StaffQueryPost;
end;
 
■StaffQuery.BeforePostイベント
procedure TCinemaDM.StaffQueryBeforePost(DataSet: TDataSet);
var ii:Integer;
begin
//Cinema_codeを自動的に登録させるため
 if StaffQuery.FieldByName('cinema_code').IsNull then
 StaffQuery.FieldByName('cinema_code').Asstring :=
                   CinemaQuerycinema_code.AsString;
//必須項目の内容をチェックするためにOnValidateを呼び出す
 for ii := 0 to DataSet.FieldCount -1 do
  begin
   if Assigned(DataSet.Fields[ii].OnValidate) then
   DataSet.Fields[ii].OnValidate(DataSet.Fields[ii]);
  end;
end;
■StaffQueryStaff_name.Validateイベント
  procedure TCinemaDM.StaffQuerystaff_nameValidate(Sender: TField);
//必須項目の内容をチェック
begin
 if Sender.AsString = '' then
 begin
 Application.MessageBox('スタッフ名は必須入力です','警告',MB_OK +
                        MB_ICONEXCLAMATION);
 Sender.FocusControl;
 Abort;
 end;
end;
       
■StaffQueryStaff_Genre_code.Validateイベント  
procedure TCinemaDM.StaffQuerystaff_genre_codeValidate(Sender: TField);
//必須項目の内容をチェック
begin
 if Sender.AsInteger = 0 then
 begin
 Application.MessageBox('ジャンルは必須入力です','警告',MB_OK +
                         MB_ICONEXCLAMATION);
 Sender.FocusControl;
 Abort;
 end;
end;
 
  ■CinemaDM.StaffQueryPostメソッド  
   

procedure TCinemaDM.StaffQueryPost;
begin
 with StaffQuery do
  begin
   ApplyUpdates; //UpdateRecordイベントのよびだし
   CommitUpdates;
   Close; //読み出し専用結果セットの更新はこの方法
   Open;
  end;
end;

 
    詳細については、キャッシュアップデートを参考にしてくださ。  
 
■StaffQuery.UpdateRecordイベント
procedure TCinemaDM.StaffQueryUpdateRecord(DataSet: TDataSet; UpdateKind:
TUpdateKind; var UpdateAction: TUpdateAction);
begin
 UpdateSQL2.Apply(UpdateKind) ; //SQL文を実行
 UpdateAction := uaApplied;
end;
    詳細については、キャッシュアップデートを参考にしてくださ。