メイン イベントを処理するコードを作成する(dbExpress チュートリアル)
チュートリアル:アプリケーションで dbExpress を使用してデータベースを表示および更新する への移動
このセッションでは、フォームのコンポーネントに関連するメイン イベントを処理するコードについて説明します。
目次
コンボ ボックス項目の選択
TComboBox からデータベース接続を選択すると、このイベントがトリガされ、また、その結果、TComboBox が閉じます。 TComboBox コンポーネントを選択します。 [オブジェクト インスペクタ]の[イベント]タブで、[OnCloseUp]
イベントをダブルクリックして、このイベント ハンドラのスタブを生成します。 次に、以下のコードを入力します。
Delphi の場合
procedure TForm2.ComboBoxConnectionsCloseUp(Sender: TObject);
begin
// Was a selection made?
if ComboBoxConnections.ItemIndex = -1 then
Exit;
// Initialize some utility objects.
if not Assigned(AllTables) then
AllTables := TStringList.Create;
if Assigned(FMetaDataProvider) then
FreeAndNil(FMetaDataProvider);
// If there was an open connection, close it. Indicate the connection is not active.
if SQLConnection1.Connected then
SQLConnection1.Close;
CheckBoxActive.Checked := False;
// Open the selected database connection.
SQLConnection1.ConnectionName := ComboBoxConnections.Items[ComboBoxConnections.ItemIndex];
SQLConnection1.LoadParamsOnConnect := True;
SQLConnection1.LoginPrompt := False;
SQLConnection1.Open;
SQLConnection1.GetTableNames(AllTables, False); //get the database's list of tables
// Get metadata for selected connection.
FMetaDataProvider := TDBXDataExpressMetaDataProvider.Create;
FMetaDataProvider.Connection := sqlconnection1.DBXConnection; //set to our open connection
FMetaDataProvider.Open;
// Populate the list box with the tables in this database connection.
PopulateListBox;
// Initialize some dialog items' state.
SQLDataSet1.CommandText := '';
EditSQL.Text := '';
CheckBoxActive.Enabled := False;
ButtonApply.Enabled := False;
end;
C++ の場合
void __fastcall TForm1::ComboBoxConnectionsCloseUp(TObject *Sender)
{
// Was a selection made?
if (ComboBoxConnections->ItemIndex == -1)
return;
// Initialize some utility objects.
if (!AllTables)
AllTables = new TStringList();
if (FMetaDataProvider) {
delete FMetaDataProvider;
FMetaDataProvider = NULL;
}
// If there was an open connection, close it. Indicate the connection is not active.
if (SQLConnection1->Connected)
SQLConnection1->Close();
CheckBoxActive->Checked = false;
// Open the selected database connection.
SQLConnection1->ConnectionName = ComboBoxConnections->Items->Strings[ComboBoxConnections->ItemIndex];
SQLConnection1->LoadParamsOnConnect = true;
SQLConnection1->LoginPrompt = false;
SQLConnection1->Open();
SQLConnection1->GetTableNames(AllTables, false); //get the database's list of tables
// Get metadata for selected connection.
FMetaDataProvider = new TDBXDataExpressMetaDataProvider();
FMetaDataProvider->Connection = SQLConnection1->DBXConnection; //set to our open connection
FMetaDataProvider->Open();
// Populate the list box with the tables in this database connection.
PopulateListBox();
// Initialize some dialog items' state.
SQLDataSet1->CommandText = "";
EditSQL->Text = "";
CheckBoxActive->Enabled = false;
ButtonApply->Enabled = false;
}
項目選択の処理に関する注釈
別の接続を既に選択しているので、上記コードでは、アクティブな接続があるかどうかを確認し、存在する場合はそれを閉じます。 データベースは既に選択されていますが、まだアクティブにはなっていません。
TComboBox で選択した項目を使って接続(選択したデータベース接続)を開きます。
- Delphi コードでは、この TComboBox からの選択は次のようになります。
ComboBoxConnections.Items[ComboBoxConnections.ItemIndex]
- C++ コードでは、TComboBox からの選択は次のようになります。
ComboBoxConnections->Items->Strings[ComboBoxConnections->ItemIndex]
接続がいったん開けば、GetTableNames 手続きを使ってメタデータ(データベースのテーブル名)を取得できます。 これは TStringList 型の変数 AllTables
に格納されます。
さらに、TDBXDataExpressMetaDataProvider
(TDBXMetaDataProvider
の派生クラス)を使ってメタデータを取得します。
PopulateListBox
はユーティリティ関数で、後で出てきます。 この関数は、取得したテーブル名を、後でアクセスできるようにリスト ボックスに追加するだけです。
データベース接続は既に開きましたが、まだ何もデータを読み取っていません。 データが存在する時にのみ使用するさまざまなコントロールがコードで無効になっているのは、そのためです。
テーブルの選択
リスト ボックス内のテーブル名をダブルクリックすることで、テーブルを選択します。このリスト ボックス内の項目は、データベース接続の選択時に設定されています。 このイベントのハンドラを作成するには、リスト ボックス コンポーネントを選択します。 [オブジェクト インスペクタ]の[イベント]タブで、[OnDblClick]
イベントをダブルクリックして、このイベント ハンドラのスタブを生成します。 ハンドラのコードを以下に示します。
Delphi の場合
procedure TForm2.ListBox1DblClick(Sender: TObject);
var
FieldNamesList: TStringList;
SQLStmt: String;
I: Integer;
begin
// Activate appropriate controls now that table is selected.
CheckBoxActive.Enabled := True;
ButtonApply.Enabled := True;
TableName := ListBox1.Items[ListBox1.ItemIndex]; //get table name
// Get field (column) names for this table.
FieldNamesList := TStringList.Create;
FieldNamesList.Clear;
SQLConnection1.GetFieldNames(TableName, FieldNamesList);
// Construct SQL Select statement for all fields.
if FieldNamesList.Count > 0 then
begin
SQLStmt := 'select ';
for I := 0 to FieldNamesList.Count - 1 do
begin
SQLStmt := SQLStmt + FieldNamesList[I] + ',';
end;
SQLStmt[Length(SQLStmt)] := ' ';
SQLStmt := SQLStmt + 'from '+TableName;
end
else
// Can't find field names, so use '*'
SQLStmt := 'select * from '+TableName;
FreeAndNil(FieldNamesList);
// Set up SQL statement to get all table's data.
EditSQL.Text := SQLStmt;
// Set CommandText to SQL statement.
SQLDataSet1.CommandText := EditSQL.Text;
if ClientDataSet1.Active then
ClientDataSet1.Close;
ClientDataSet1.Open;
CheckBoxActive.Checked := True;
end;
C++ の場合
void __fastcall TForm1::ListBox1DblClick(TObject *Sender)
{
TStringList *FieldNamesList;
String SQLStmt;
int I;
// Activate appropriate controls now that table is selected.
CheckBoxActive->Enabled = true;
ButtonApply->Enabled = true;
TableName = ListBox1->Items->Strings[ListBox1->ItemIndex]; //get table name
// Get field (column) names for this table.
FieldNamesList = new TStringList();
FieldNamesList->Clear();
SQLConnection1->GetFieldNames(TableName, FieldNamesList);
// Construct SQL Select statement for all fields.
if (FieldNamesList->Count > 0)
{
SQLStmt = "select ";
for (I = 0; I < FieldNamesList->Count; I++)
{
if (I == 0)
SQLStmt = SQLStmt + FieldNamesList->Strings[I];
else
SQLStmt = SQLStmt + "," + FieldNamesList->Strings[I];
}
SQLStmt = SQLStmt + " from " + TableName;
}
else
// Can't find field names, so use '*'
SQLStmt = "select * from " + TableName;
delete FieldNamesList;
FieldNamesList = NULL;
// Set up SQL statement to get all table's data.
EditSQL->Text = SQLStmt;
// Set CommandText to SQL statement.
SQLDataSet1->CommandText = EditSQL->Text;
if (ClientDataSet1->Active)
ClientDataSet1->Close();
ClientDataSet1->Open();
CheckBoxActive->Checked = true;
}
テーブル選択の処理に関する注釈
これで、データベース テーブルを選択したので、データ処理コントロールをアクティブにすることができます。
テーブルの全フィールド名(フィールドは列とも言います)のリストを作成します。 これらを使用して、テーブル内の全フィールドのデータを取得するための SQL SELECT
文を作成します。
SQL 文ができたら、それを TSQLConnection コンポーネントの CommandText プロパティに格納します。 TSQLConnection で SQL コマンドを使用することを示すために、設計時に既に DbxCommandType プロパティを "Dbx.SQL" に設定してあります。
TClientDataSet を開く(既に開いている場合はいったん閉じる)ことで、作成した SELECT
文を実行します。 その結果、テーブルのデータが TDBGrid に表示されます。 TDBNavigator も今はアクティブになっています。
テーブル セルのクリック
このアプリケーションでは、TDBGrid セルをクリックすることでフィールド データを表示できます。 セルの値は TDBMemo に別個の形式で表示されます。これについては、「セル表示フォームを追加する」のセクションで作成します。
[オブジェクト インスペクタ]の[イベント]タブで TDBGrid コンポーネントの [OnCellClick]
イベントをダブルクリックして、このイベント ハンドラのスタブを生成します。 次に、以下のコードを追加します。
Delphi の場合
procedure TForm2.DBGrid1CellClick(Column: TColumn); // Column = クリックされたテーブル列
begin
if ClientDataSet1.Active then
begin
// If the form isn't displayed, create it.
if not Assigned(MemoForm) then
begin
MemoForm := TFormCurrentField.Create(Self);
MemoForm.DBMemoCurrentField.DataSource := DataSource1; //set data source
end;
// Position form just below main dialog.
MemoForm.Top := Self.Top+Self.Height;
MemoForm.Left := Self.Left;
MemoForm.Visible := False;
MemoForm.Visible := True;
MemoForm.DBMemoCurrentField.DataField := Column.FieldName;
// Format caption with information on the field.
MemoForm.Caption := Format('Field Name: %s / Record Num: %d',[Column.FieldName, DBGrid1.DataSource.DataSet.RecNo]);
MemoForm.Width := Self.Width;
end;
end;
C++ の場合
void __fastcall TForm1::DBGrid1CellClick(TColumn *Column)
{
if (ClientDataSet1->Active)
{
// If the form isn't displayed, create it.
if (!MemoForm)
{
MemoForm = new TFormCurrentField(this);
MemoForm->DBMemoCurrentField->DataSource = DataSource1; //set data source
}
// Position form just below main dialog.
MemoForm->Top = this->Top + this->Height;
MemoForm->Left = this->Left;
MemoForm->Visible = false;
MemoForm->Visible = true;
MemoForm->DBMemoCurrentField->DataField = Column->FieldName;
// Format caption with information on the field.
//MemoForm->Caption = Format("Field Name: %s / Record Num: %d",[Column->FieldName, DBGrid1->DataSource->DataSet->RecNo]);
MemoForm->Caption.sprintf(L"Field Name: %s / Record Num: %d",Column->FieldName, DBGrid1->DataSource->DataSet->RecNo);
MemoForm->Width = this->Width;
}
}
テーブル セルのクリックに関する注釈
このイベントは、主にフォーム MemoForm
(TFormCurrentField
オブジェクト)のプロパティを設定することで処理されます。 TFormCurrentField
については、「セル表示フォームを追加する」のセクションで定義します。 特に、ハンドラはフォーム上の TDBMemo コンポーネントのプロパティを設定します。 DataField プロパティには列名が格納されています。 DataSource をデータ ソースに設定することで、TDBMemo に実際のフィールド データを表示できるようになります。