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.
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:
Afbeelding 2: Applicatie draaiend met voorbeeld data.
Sourcecode beschikbaar op mijn github pagina.
©2022 Don Wilbrink.
E-mail: d.wilbrink@freedom.nl
30 oktober 2022