BufDataSet Master Detail

Deel dit artikel

,

geen foto beschikbaar

Opzet applicatie

Dit keer ga ik een master detail relatie opzetten tussen twee BufDataSets. We beginnen weer met een nieuwe applicatie via Nieuw -> Applicatie. Vervolgens zetten we de benodigde componenten op het form en saven het project als platen.lpi en het form als main.pas. Het form ziet er dan als volgt uit.

bufdataset master detail design

Afbeelding 1: Design applicatie main form.

Vervolgens de eigenschappen van de componenten aanpassen:

Het form:

  • Name: mainForm
  • Caption: Platen overzicht

BufDataset1:

  • Name: bdsPlaten
  • FieldDefs: 3 Items toevoegen via de fieldseditor
  • IndexFieldNames: ID

BufDataset1.FieldDefs.0:

  • Name: ID
  • DataType: ftAutoInc

BufDataset1.FieldDefs.1:

  • Name: Album
  • DataType: ftString
  • Size: 30

BufDataset1.FieldDefs.2:

  • Name: Artiest
  • DataType: ftString
  • Size: 30

DataSource1:

  • Name: dsPlaten
  • Dataset: bdsPlaten

BufDataset2:

  • Name: bdsTracks
  • FieldDefs: 3 items toevoegen via de fieldseditor
  • IndexFieldNames: ID

BufDataset2.FieldDefs.0:

  • Name: ID
  • DataType: ftAutoInc

BufDataset2.FieldDefs.1:

  • Name: AlbumID
  • DataType: ftInteger

BufDataset1.FieldDefs.2:

  • Name: Tracknaam
  • DataType: ftString
  • Size: 50

DataSource2:

  • Name: dsTracks
  • Dataset: bdsTracks

DBNavigator1:

  • DataSource: dsPlaten

DBGrid1:

  • Anchors: akBottom, akLeft, akRight, akTop
  • DataSource: dsPlaten

DBNavigator2:

  • Anchors: akBottom, akLeft
  • DataSource: dsTracks

DBGrid2:

  • Anchors: akBottom, akLeft, akRight
  • DataSource: dsTracks

Code

Nog wat code voor de goede werking. Voeg onder het kopje Private van het Type TmainForm

private
  fn1: string;
  fn2: string;

toe.

Eerst de OnCreate van het form om te bepalen of de bestanden al bestaan, anders bestanden aanmaken:

procedure TmainForm.FormCreate(Sender: TObject);
begin
  fn1 := 'platen.bds';
  if FileExists(fn1) then
  begin
    bdsPlaten.LoadFromFile(fn1);
    bdsPlaten.Active := True;
    bdsPlaten.First;
  end
  else
  begin
    bdsPlaten.CreateDataset;
    bdsPlaten.Active := True;
    bdsPlaten.SaveToFile(fn1);
  end;
  fn2 := 'tracks.bds';
  if FileExists(fn2) then
  begin
    bdsTracks.LoadFromFile(fn2);
    bdsTracks.Active := True;
    bdsTracks.First;
  end
  else
  begin
    bdsTracks.CreateDataset;
    bdsTracks.Active := True;
    bdsTracks.SaveToFile(fn2);
  end;
end;

Vervolgens de OnClose event, bestanden wegschrijven en app sluiten:

procedure TmainForm.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  bdsPlaten.SaveToFile(fn1);
  bdsTracks.SaveToFile(fn2);
  CloseAction := caFree;
end;

De OnFilteredRecord event van bdsTracks, zorgen dat alleen de records behorende bij de gekozen plaat in de andere dataset getoond worden:

procedure TmainForm.bdsTracksFilterRecord(DataSet: TDataSet; var Accept: Boolean);
begin
  Accept := (bdsTracks.FieldByName('AlbumID').AsInteger = bdsPlaten.FieldByName('ID').AsInteger);
end;

De BeforeInsert event van bdsPlaten, om de tweede grid leeg te maken bij een nieuwe plaat:

procedure TmainForm.bdsPlatenBeforeInsert(DataSet: TDataSet);
begin
  DBGrid2.Clear;
end;

De OnAfterPost events van beide BufDatasets, om te zorgen dat de tracks op de goede volgorde staan:

procedure TmainForm.bdsTracksAfterPost(DataSet: TDataSet);
begin
  bdsTracks.First;
end;

procedure TmainForm.bdsPlatenAfterPost(DataSet: TDataSet);
begin
  bdsTracks.Filtered := False;
  bdsTracks.Filtered := True;
  bdsTracks.First;
end;

De OnBeforePost event van dbsTracks om het veld AlbumID automatisch te vullen:

procedure TmainForm.bdsTracksBeforePost(DataSet: TDataSet);
begin
  bdsTracks.FieldByName('AlbumID').Value := bdsPlaten.FieldByName('ID').Value;
end;

En tot slot de OnClick event van DBNavigator1:

procedure TmainForm.DBNavigator1Click(Sender: TObject; Button: TDBNavButtonType);
begin
  if ((Button = nbNext) or (Button = nbPrior) or (Button = nbFirst) or (Button = nbLast)) then
  begin
    bdsTracks.Filtered := False;
    bdsTracks.Filtered := True;
    bdsTracks.First;
  end;
end;

Resultaat

Het resultaat is als volgt:

Draaiend programma bufdatasetmasterdetail

Afbeelding 2: Applicatie draaiend met voorbeeld data.

Sourcecode beschikbaar op mijn github pagina.

 

©2022 Don Wilbrink.

E-mail:

Actueel

'Meld je aan voor de nieuwsbrief' van HCC!programmeren

'Abonneer je nu op de nieuwsbrief en blijf op de hoogte van onze activiteiten!'

Aanmelden