Entwickeln des Quellcodes zur Behandlung von Hauptereignissen (dbExpress-Tutorial)

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Tutorial: Mit dbExpress Datenbanken in einer Anwendung anzeigen und aktualisieren

Dieser Abschnitt enthält den Quellcode zur Behandlung der Hauptereignisse der Formularkomponenten.

Auswahl eines Eintrags aus dem Kombinationsfeld

Durch Auswahl der Datenbankverbindung aus dem TComboBox-Steuerelement wird dieses Ereignis ausgelöst und außerdem das TComboBox-Steuerelement geschlossen. Wählen Sie die TComboBox-Komponente aus. Doppelklicken Sie auf der Registerkarte Ereignisse im Objektinspektor auf das Ereignis OnCloseUp, um den Stub für diese Ereignisbehandlungsroutine zu erzeugen. Geben Sie den folgenden Code ein:

Delphi

procedure TForm2.ComboBoxConnectionsCloseUp(Sender: TObject);
begin
  // Wurde eine Auswahl getroffen?
  if ComboBoxConnections.ItemIndex = -1 then
    Exit;

  // Hilfsobjekte initialisieren.
  if not Assigned(AllTables) then
    AllTables := TStringList.Create;
  if Assigned(FMetaDataProvider) then
    FreeAndNil(FMetaDataProvider);

  // Falls eine geöffnete Verbindung vorhanden ist, soll sie geschlossen werden. Anzeigen, dass die Verbindung nicht aktiv ist.
  if SQLConnection1.Connected then
    SQLConnection1.Close;
  CheckBoxActive.Checked := False;

  // Die ausgewählte Datenbankverbindung öffnen.
  SQLConnection1.ConnectionName := ComboBoxConnections.Items[ComboBoxConnections.ItemIndex];
  SQLConnection1.LoadParamsOnConnect := True;
  SQLConnection1.LoginPrompt := False;
  SQLConnection1.Open;
  SQLConnection1.GetTableNames(AllTables, False);  //Liste der Tabellen aus der Datenbank abrufen

  // Metadaten für die ausgewählte Verbindung ermitteln.
  FMetaDataProvider := TDBXDataExpressMetaDataProvider.Create;
  FMetaDataProvider.Connection := sqlconnection1.DBXConnection;  //auf die geöffnete Verbindung setzen
  FMetaDataProvider.Open;

  // Das Listenfeld mit den Tabellen dieser Datenbankverbindung füllen.
  PopulateListBox;

  // Status einiger Dialogfeldelemente initialisieren.
  SQLDataSet1.CommandText := '';
  EditSQL.Text := '';
  CheckBoxActive.Enabled := False;
  ButtonApply.Enabled := False;
end;

C++

void __fastcall TForm1::ComboBoxConnectionsCloseUp(TObject *Sender)
{
  // Wurde eine Auswahl getroffen?
  if (ComboBoxConnections->ItemIndex == -1)
return;

  // Hilfsobjekte initialisieren.
  if (!AllTables)
AllTables = new TStringList();
  if (FMetaDataProvider) {
delete FMetaDataProvider;
FMetaDataProvider = NULL;
  }

  // Falls eine geöffnete Verbindung vorhanden ist, soll sie geschlossen werden. Anzeigen, dass die Verbindung nicht aktiv ist.
  if (SQLConnection1->Connected)
SQLConnection1->Close();
  CheckBoxActive->Checked = false;

  // Die ausgewählte Datenbankverbindung öffnen.
  SQLConnection1->ConnectionName = ComboBoxConnections->Items->Strings[ComboBoxConnections->ItemIndex];
  SQLConnection1->LoadParamsOnConnect = true;
  SQLConnection1->LoginPrompt = false;
  SQLConnection1->Open();
  SQLConnection1->GetTableNames(AllTables, false);  //Liste der Tabellen aus der Datenbank abrufen

  // Metadaten für die ausgewählte Verbindung ermitteln.
  FMetaDataProvider = new TDBXDataExpressMetaDataProvider();
  FMetaDataProvider->Connection = SQLConnection1->DBXConnection;  //auf die geöffnete Verbindung setzen
  FMetaDataProvider->Open();

  // Das Listenfeld mit den Tabellen dieser Datenbankverbindung füllen.
  PopulateListBox();

  // Status einiger Dialogfeldelemente initialisieren.
  SQLDataSet1->CommandText = "";
  EditSQL->Text = "";
  CheckBoxActive->Enabled = false;
  ButtonApply->Enabled = false;
}

Bemerkungen zur Behandlung der Eintragsauswahl

Der Code überprüft, ob eine aktive Verbindung vorhanden ist und schließt diese, weil eine andere Verbindung ausgewählt wurde. Obwohl eine Datenbank ausgewählt wurde, ist sie noch nicht aktiv.

Die Verbindung wird mithilfe des in der TComboBox-Komponente ausgewählten Eintrags – der gewählten Datenbankverbindung – geöffnet.

  • Im Delphi lautet der Code dafür:
ComboBoxConnections.Items[ComboBoxConnections.ItemIndex]
  • Im C++ lautet der Code:
ComboBoxConnections->Items->Strings[ComboBoxConnections->ItemIndex]

Nachdem die Verbindung geöffnet ist, können Metadaten – Namen der Datenbanktabellen – mit der Prozedur GetTableNames abgerufen werden. Diese Namen werden in der TStringList-Variable AllTables gespeichert.

Metadaten werden auch mit dem Objekt TDBXDataExpressMetaDataProvider ermittelt, das von TDBXMetaDataProvider abgeleitet ist.

PopulateListBox ist eine Hilfsfunktion, die später erläutert wird. Diese Funktion fügt nur die gerade ermittelten Tabellennamen in das Listenfeld ein.

Obwohl die Datenbankverbindung geöffnet ist, wurden noch keine Daten gelesen. Deshalb werden im Code verschiedene Steuerelemente deaktiviert, die nur verwendet werden, wenn Daten vorhanden sind.

Auswahl der Tabelle

Die Tabelle wird durch Doppelklicken auf einen Tabellennamen in dem Listenfeld ausgewählt, das bei der Auswahl der Datenbankverbindung gefüllt wurde. Wählen Sie die Listenfeldkomponente aus, um für dieses Ereignis eine Behandlungsroutine zu schreiben. Doppelklicken Sie auf der Registerkarte Ereignisse im Objektinspektor auf das Ereignis OnDblClick, um den Stub für die Ereignisbehandlungsroutine zu erzeugen. Fügen Sie den folgenden Quellcode für die Behandlungsroutine ein:

Delphi

procedure TForm2.ListBox1DblClick(Sender: TObject);
var
  FieldNamesList: TStringList;
  SQLStmt: String;
  I: Integer;
begin
  // Eine Tabelle ist jetzt ausgewählt, daher nun die entsprechenden Steuerelemente aktivieren.
  CheckBoxActive.Enabled := True;
  ButtonApply.Enabled := True;
  TableName := ListBox1.Items[ListBox1.ItemIndex];  //Tabellennamen abrufen

  // Feldnamen (Spaltennamen) für diese Tabelle abrufen.
  FieldNamesList := TStringList.Create;
  FieldNamesList.Clear;
  SQLConnection1.GetFieldNames(TableName, FieldNamesList);

  // Select-SQL-Anweisung für alle Felder erstellen.
  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
    // Feldnamen nicht gefunden, daher '*' verwenden
    SQLStmt := 'select * from '+TableName;
  FreeAndNil(FieldNamesList);

  // SQL-Anweisung zum Abrufen aller Tabellendaten erstellen.
  EditSQL.Text := SQLStmt;
  // CommandText auf SQL-Anweisung setzen.
  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;

  // Eine Tabelle ist jetzt ausgewählt, daher nun die entsprechenden Steuerelemente aktivieren.
  CheckBoxActive->Enabled = true;
  ButtonApply->Enabled = true;
  TableName = ListBox1->Items->Strings[ListBox1->ItemIndex];  //Tabellennamen abrufen

  // Feldnamen (Spaltennamen) für diese Tabelle abrufen.
  FieldNamesList = new TStringList();
  FieldNamesList->Clear();
  SQLConnection1->GetFieldNames(TableName, FieldNamesList);

  // Select-SQL-Anweisung für alle Felder erstellen.
  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
    // Feldnamen nicht gefunden, daher '*' verwenden
SQLStmt = "select * from " + TableName;
  delete FieldNamesList;
  FieldNamesList = NULL;

  // SQL-Anweisung zum Abrufen aller Tabellendaten erstellen.
  EditSQL->Text = SQLStmt;

  // CommandText auf SQL-Anweisung setzen.
  SQLDataSet1->CommandText = EditSQL->Text;
  if (ClientDataSet1->Active)
ClientDataSet1->Close();
  ClientDataSet1->Open();
  CheckBoxActive->Checked = true;
}

Bemerkungen zur Behandlung der Tabellenauswahl

Da die Datenbanktabelle ausgewählt wurde, können die Steuerelemente zur Datenbehandlung aktiviert werden.

Es wird eine Liste aller Feldnamen (Spaltennamen) der Tabelle erstellt. Damit wird die SQL-Anweisung SELECT zum Abrufen der Daten aller Felder in der Tabelle erstellt.

Nach dem Erstellen der SQL-Anweisung wird sie in die Eigenschaft CommandText der TSQLConnection-Komponente übernommen. Während des Entwurfs wurde DbxCommandType bereits auf "Dbx.SQL" gesetzt, um anzugeben, dass die TSQLConnection SQL-Anweisungen verwendet.

Die erstellte SELECT-Anweisung wird beim Öffnen der Datenmenge (TClientDataSet) ausgeführt; falls sie geöffnet ist, wird sie geschlossen. Dadurch werden die Daten der Tabelle in der TDBGrid-Komponente angezeigt. Das TDBNavigator-Steuerelement ist nun ebenfalls aktiv.

Klicken auf eine Tabellenzelle

Die Anwendung ermöglicht die Anzeige von Felddaten durch Klicken in eine TDBGrid-Zelle. Der Wert der Zelle wird in einem TDBMemo-Steuerelement in einem eigenen Formular angezeigt. Dieses Formular wird im Abschnitt Hinzufügen eines Formulars zum Anzeigen des Zellinhalts erstellt.

Doppelklicken Sie auf der Ereignis OnCellClick der TDBGrid-Komponente, um den Stub für diese Ereignisbehandlungsroutine zu erzeugen. Fügen Sie dann den folgenden Quelltext hinzu:

Delphi

procedure TForm2.DBGrid1CellClick(Column: TColumn);  //Column = angeklickte Tabellenspalte
begin
  if ClientDataSet1.Active then
  begin
    // Wenn das Formular nicht angezeigt wird, wird es erstellt.
    if not Assigned(MemoForm) then
    begin
      MemoForm := TFormCurrentField.Create(Self);
      MemoForm.DBMemoCurrentField.DataSource := DataSource1;  //Datenquelle festlegen
    end;

    // Formular genau unterhalb des Hauptdialogfeldes positionieren.
    MemoForm.Top := Self.Top+Self.Height;
    MemoForm.Left := Self.Left;

    MemoForm.Visible := False;
    MemoForm.Visible := True;
    MemoForm.DBMemoCurrentField.DataField := Column.FieldName;
    // Im Titel Informationen über das Feld anzeigen
    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)
  {
    // Wenn das Formular nicht angezeigt wird, wird es erstellt.
if (!MemoForm)
{
MemoForm = new TFormCurrentField(this);
      MemoForm->DBMemoCurrentField->DataSource = DataSource1;  //Datenquelle festlegen
}

    // Formular genau unterhalb des Hauptdialogfeldes positionieren.
MemoForm->Top = this->Top + this->Height;
MemoForm->Left = this->Left;

MemoForm->Visible = false;
MemoForm->Visible = true;
    MemoForm->DBMemoCurrentField->DataField = Column->FieldName;
    // Im Titel Informationen über das Feld anzeigen
//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;
  }
}

Bemerkungen zum Klicken auf eine Tabellenzelle

Dieses Ereignis wird im Wesentlichen durch Setzen der Eigenschaften des Formulars MemoForm behandelt. MemoForm ist ein TFormCurrentField-Objekt. TFormCurrentField wird im Abschnitt Hinzufügen eines Formulars zum Anzeigen des Zellinhalts definiert. Die Behandlungsroutine setzt auch Eigenschaften der TDBMemo-Komponente auf dem Formular. Die Eigenschaft DataField enthält den Spaltennamen. Durch Setzen von DataSource auf die Datenquelle wird ermöglicht, dass in dem TDBMemo-Steuerelement die Felddaten angezeigt werden.

Zurück

Schreiben des Quellcodes zur Initialisierung der Anwendung

Weiter

Schreiben des Quellcodes zur Behandlung von Unterereignissen