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