メイン イベントを処理するコードを作成する(dbExpress チュートリアル)

提供: RAD Studio
移動先: 案内検索

チュートリアル:アプリケーションで 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 に格納されます。

さらに、TDBXDataExpressMetaDataProviderTDBXMetaDataProvider の派生クラス)を使ってメタデータを取得します。

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;
  }
}

テーブル セルのクリックに関する注釈

このイベントは、主にフォーム MemoFormTFormCurrentField オブジェクト)のプロパティを設定することで処理されます。 TFormCurrentField については、「セル表示フォームを追加する」のセクションで定義します。 特に、ハンドラはフォーム上の TDBMemo コンポーネントのプロパティを設定します。 DataField プロパティには列名が格納されています。 DataSource をデータ ソースに設定することで、TDBMemo に実際のフィールド データを表示できるようになります。

前のチュートリアル

アプリケーションを初期化するコードを作成する

次のチュートリアル

マイナー イベントを処理するコードを作成する