TQueryのデータをDBGridで編集可能にする

 TQuery内で複数テーブルをJOINしている場合、その内容を DBGrid上で直接編集することはできません。

TQuery の RequestLive プロパティを True に設定することはできますが、更新しようとすると(Openすると)上記のようなエラーが表示されます。

これを解決するには、まず、Query の、CacheUpdate プロパティを True に、RequestLive プロパティを True に設定します。
次に、ツールパレット上の UpdateSQL コンポーネントを使います。
BDEパレットあたりにあります。それをフォームに配置し、Query の UpdateObject プロパティに今配置した UpdateSQL を指定します。

次に UpdateSQL を選択し、右クリックのポップアップメニューから 「UpdateSQL の設定」を選びます。

すると以下のようなダイアログが表示されます。
テーブル名のコンボボックスにはSELECTされているテーブルの一覧が表示されます。この中から変更対象となるテーブルを選択します。
次にキー項目リストの中からそのテーブルのプライマリキーを選択します。複数ある場合は [ SHIFT ] か、[ CONTROL ] を押しながら選択します。
次に更新する項目の中から同じように、変更対象となるフィールドを選択します。グリッド上で修正させる項目です。
ここまで終わったら [ SQL文を生成 ] ボタンをクリックし、 [ OK ] をクリックします。

あとはキャッシュアップデートを制御するコードをちょこちょこ記述します。
今回の例ではフォームロード時にトランザクションを開始し、ボタン1でコミット、ボタン2でロールバックします。

■ キャッシュアップデートの例
implementation                                  

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Database1.StartTransaction;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if  (Query1.UpdatesPending) then  begin
    Query1.ApplyUpdates;
  end;
  Database1.Commit;
  Query1.CommitUpdates;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if  (Query1.UpdatesPending) then  begin
    Query1.CancelUpdates;
  end;
  Database1.Rollback;
end;

このキャッシュアップデートと言う仕組みは、フォーム上での編集内容を即座にデータベースに通知するのではなく、ローカルに保存しておき、最後に変更内容をデータベースへ送信します。ですので、最後にデータベースへ送信するコードが必要になります。それが ApplyUpdates メソッドです。逆に、変更内容を送信せず破棄する場合は CancelUpdates メソッドを使います。データベースに反映させていない更新内容があるかどうかは、UpdatesPending プロパティで確認できます。