Toon posts:

[Delphi] Lookup field in een databasegrid

Pagina: 1
Acties:
  • 143 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Ik wil in een dbgrid een veld weergeven waarin de gebruiker een naam uit een lijst kan selecteren. Alleen deze waarde wordt dus uit een andere tabel gehaald en in de 1e tabel wordt deze keuze opgeslagen door het id nummer op te slaan.

Maar hoe moet ik dat doen? Het probleem is dus dat er een tekst waarde weergegeven moet worden en een integer waarde moet worden bewaard.

(Ik heb de volgende componenten gebruikt:

DBGrid, DataSource, IBQuery, IBUpdateSQL, IBTransaction)

Verwijderd

Gewoon aan de TTable [in jouw geval TIBQuery, denk ik] die gekoppeld is aan TDBGrid, een nieuw veld [Field type: Lookup] toevoegen met de fields editor.

Verwijderd

Topicstarter
Het is me nog niet gelukt.

De datagrid moet dus in een kolom een naam weergeven die uit tabel B gehaald moet worden door een query. Dit moet de gebruiker kunnen selecteren door op de cel te klikken waardoor er een lijst met die namen wordt weergegeven.

Vervolgens moet de naam niet worden opgeslagen maar het id nummer van die naam in tabel B moet dus in tabel A komen te staan.

Verwijderd

Oke, hier staat een voorbeeld wat je makkelijk na kunt maken.

Bij jouw is de naam dus het "result field" en id nummer de "lookup key".

Verwijderd

Topicstarter
Het werkt nog steeds niet. Ik zal het nu wat uitvoeriger beschrijven:

Ik heb een DBGrid die een overzicht geeft van artikelen. Aan die DBGrid hangt een Datasource en aan die datasource hangt een Query die informatie ophaalt uit de tabel: ARTIKELEN.

Deze tabel heeft o.a. het volgende veld:

- ARTIKELVERPAKKINGID Integer not null

Dit veld is d.m.v. een foreign key gekoppeld aan de tabel: ARTIKELVERPAKKING(stamtabel) en aan het veld VERPAKKINGID.

De tabel ARTIKELVERPAKKING heeft o.a. de volgende velden:

-VERPAKKINGID Integer not null PK
-VERPAKKINGOMSCHRIJVING VARCHAR(10)


Nu wil ik dus dat de gebruiker in een kolom in de DBGrid een verpakkingstype kan selecteren (VERPAKKINGOMSCHRIJVING dus) maar dat de VERPAKKINGID opgeslagen wordt in de ARTIKELVERPAKKINGID van de tabel ARTIKELEN.



Ik heb nu het volgende o.a. geprobeerd:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  VerpakkingsType := TField.Create(Self);
  dtModule.IBQueryOverzichtArtikelen.Fields.Add(VerpakkingsType);
  with VerpakkingsType do
  begin
    Name := 'Artikelverpakkingstype';
    FieldName := 'ARTIKELVERPAKKINGID';
    FieldKind := fkLookup;
    SetFieldType(ftString);
    Size := 10;
    LookupDataSet := dtModule.IBQueryArtikelVerpakking;
    LookupKeyFields := 'VERPAKKINGID';
    LookupResultField := 'VERPAKKINGOMSCHRIJVING';
    Lookup := True;
  end;

Maar het werkt niet. Wat doe ik verkeerd?


(Zo krijg ik bijvoorbeeld: Invalid size field
of kan het veld niet voor lookup gebruiken)

Verwijderd

Property FieldName moet een nieuwe naam zijn [Bob in Borland vb]

Property KeyFields moet ARTIKELVERPAKKINGID zijn.

Verwijderd

Topicstarter
Ik krijg nog steeds de foutmelding: Invalid field size
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  VerpakkingsType := TField.Create(Self);
  dtModule.IBQueryOverzichtArtikelen.Fields.Add(VerpakkingsType);
  with VerpakkingsType do
  begin
    Name := 'Artikelverpakkingstype';
    FieldName := 'Bob';
    FieldKind := fkLookup;
    SetFieldType(ftString);
    Size := 10;
    KeyFields := 'ARTIKELVERPAKKINGID';
    LookupDataSet := dtModule.IBQueryArtikelVerpakking;
    LookupKeyFields := 'VERPAKKINGID';
    LookupResultField := 'VERPAKKINGOMSCHRIJVING';
    Lookup := True;
  end;

  DBGridArtikelOverzicht.Columns[1].Title.Caption := 'Verpakking';
  DBGridArtikelOverzicht.Columns[1].Field := VerpakkingsType;

Verwijderd

Niet:
code:
1
VerpakkingsType := TField.Create(Self);

maar:
code:
1
VerpakkingsType := TStringField.Create(Self);

Verwijderd

Topicstarter
Oke dat probleem is opgelost, nu het volgende :Z :)

Field bob has no dataset
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  with dtModule do
  begin
    IBQueryArtikelVerpakking.SQL.Clear;
    IBQueryArtikelVerpakking.SQL.ADD('SELECT VERPAKKINGID, VERPAKKINGOMSCHRIJVING FROM ARTIKELVERPAKKING ');
    IBQueryArtikelVerpakking.Open;
  end;

  dtModule.IBQueryOverzichtArtikelen.Active := False;
  dtModule.IBQueryOverzichtArtikelen.SQL.Clear;
  with dtModule.IBQueryOverzichtArtikelen.SQL do
  begin
    Add(' SELECT ARTIKELID, ARTIKELVERPAKKINGID, ARTIKELNAAM, PRIJS, AFZET, ARTIKELNUMMER ' +
      ' FROM ARTIKELEN ');
  end;
  dtModule.IBQueryOverzichtArtikelen.Open;

  VerpakkingsType := TStringField.Create(Self);
  dtModule.IBQueryOverzichtArtikelen.Fields.Add(VerpakkingsType);
  with VerpakkingsType do
  begin
    Name := 'Artikelverpakkingstype';
    FieldName := 'Bob';
    FieldKind := fkLookup;
    SetFieldType(ftString);
    Size := 10;
    KeyFields := 'ARTIKELVERPAKKINGID';
    LookupDataSet := dtModule.IBQueryArtikelVerpakking;
    LookupKeyFields := 'VERPAKKINGID';
    LookupResultField := 'VERPAKKINGOMSCHRIJVING';
    Lookup := True;
  end;

  DBGridArtikelOverzicht.Columns[1].Title.Caption := 'Verpakking';
  DBGridArtikelOverzicht.Columns[1].FieldName := 'Bob';

Verwijderd

Eh, property DataSet setten :? Had je ook wel kunnen bedenken :)

[edit]
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
  VerpakkingsType := TStringField.Create(Self);
  with VerpakkingsType do
  begin
    Name := 'Artikelverpakkingstype';
    FieldName := 'Bob';
    FieldKind := fkLookup;
    DataSet := dtModule.IBQueryOverzichtArtikelen;
    Size := 10;
    KeyFields := 'ARTIKELVERPAKKINGID';
    LookupDataSet := dtModule.IBQueryArtikelVerpakking;
    LookupKeyFields := 'VERPAKKINGID';
    LookupResultField := 'VERPAKKINGOMSCHRIJVING';
  end;

Verwijderd

Topicstarter
Ja ik had dat al geprobeerd alleen dat werkte ook niet!

Foutmelding: IBQueryOverzichtArtikelen: Cannot perform this operation on an open dataset


Dus dtModule.IBQueryOverzichtArtikelen.Open pas na het creeren van het verpakkingstype Field.

Maar dan krijg ik weer de melding:

IBQueryOverzichtArtikelen: Duplicate field name 'bob'

Nou er komt nergens 2 keer bob voor.

Verwijderd

Zie mijn edit; je moet
code:
1
 dtModule.IBQueryOverzichtArtikelen.Fields.Add(VerpakkingsType);

verwijderen; omdat als je property DataSet set, het field automatisch wordt toegevoegd.

En de DataSet moet niet open zijn, zie de foutmelding :)

Verwijderd

Topicstarter
Ik heb nu dus de volgende code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  with dtModule.IBQueryArtikelVerpakking do
  begin
    SQL.Clear;
    SQL.ADD('SELECT VERPAKKINGID, VERPAKKINGOMSCHRIJVING ' +
        ' FROM ARTIKELVERPAKKING ');
    Open;
  end;

  with dtModule.IBQueryOverzichtArtikelen.SQL do
  begin
    Clear;
    Add(' SELECT ARTIKELID, ARTIKELVERPAKKINGID, ARTIKELNAAM, PRIJS, AFZET, ARTIKELNUMMER ' +
      ' FROM ARTIKELEN ');
  end;

  VerpakkingsType := TStringField.Create(Self);
  with VerpakkingsType do
  begin
    Name := 'Artikelverpakkingstype';
    FieldName := 'Bob';
    FieldKind := fkLookup;
    DataSet := dtModule.IBQueryOverzichtArtikelen;
    Size := 10;
    KeyFields := 'ARTIKELVERPAKKINGID';
    LookupDataSet := dtModule.IBQueryArtikelVerpakking;
    LookupKeyFields := 'VERPAKKINGID';
    LookupResultField := 'VERPAKKINGOMSCHRIJVING';
  end;

  dtModule.IBQueryOverzichtArtikelen.Open;

  DBGridArtikelOverzicht.Columns.Clear;
  with DBGridArtikelOverzicht.Columns do
    for i := 1 to 5 do
    Add;

  DBGridArtikelOverzicht.Columns[0].FieldName := 'ARTIKELNAAM';
  DBGridArtikelOverzicht.Columns[0].Title.Caption := 'Artikelnaam';

  DBGridArtikelOverzicht.Columns[1].FieldName := 'Bob';
  DBGridArtikelOverzicht.Columns[1].Title.Caption := 'Verpakking';

  DBGridArtikelOverzicht.Columns[2].FieldName := 'PRIJS';
  DBGridArtikelOverzicht.Columns[2].Title.Caption := 'Prijs';

  DBGridArtikelOverzicht.Columns[3].FieldName := 'AFZET';
  DBGridArtikelOverzicht.Columns[3].Title.Caption := 'Afzet';

  DBGridArtikelOverzicht.Columns[4].FieldName := 'ARTIKELNUMMER';
  DBGridArtikelOverzicht.Columns[4].Title.Caption := 'Artikelnummer';
  DBGridArtikelOverzicht.Columns[4].Alignment := taRightJustify;

Ik krijg nu weer een foutmelding bij het openen van de query IBQueryOverzichtArtikelen. De melding is: IBQueryOverzichtArtikelen: Field 'ARTIKELVERPAKKINGID' not found

Dit veld bestaat gewoon in de tabel artikelen en ik heb aangegeven in de query dat dat veld moet worden opgehaald.

Verwijderd

Is het perse nodig dat je het allemaal run-time doet?

Zo ja, dan moet je ook ARTIKELVERPAKKINGID als veld toevoegen. Net zoals je VerpakkingsType hebt toegevoegd...

Verwijderd

Topicstarter
Waarom zou ik ARTIKELVERPAKKINGID zelf moeten toevoegen. Ik voer toch een query uit, die dat veld ophaalt????

Verwijderd

Als je alleen de SQL property invult, is het aantal velden in property Fields 0. Daar kan ik ook niets aan doen :)

Om een lookup field te maken moet Delphi alle velden kennen [Hiermee bedoel ik dat ze in de property Fields moeten staan], die je daarvoor wilt gebruiken; meestal voeg je die dan design-time toe.

Maar dit kan natuurlijk ook run-time.

Verwijderd

Topicstarter
Dus ik moet dit bijvoorbeeld doen:
code:
1
2
3
4
5
6
  VerpakkingsIDType := TIntegerField.Create(Self);
  with VerpakkingsIDType do
  begin
    FieldName := 'ARTIKELVERPAKKINGID';
    FieldKind := fkData;
  end;

Deze code staat dan net voor de code die het VerpakkingsType Field aanmaakt.

Maar ik krijg dan nog steeds de melding dat het veld Artikelverpakkingid niet gevonden kan worden.

Verwijderd

Property DataSet?

Verwijderd

Topicstarter
YES, het werkt :P :9


Bedankt voor je hulp!!!

Verwijderd

Het zou tijd worden :)

Verwijderd

Topicstarter
Ja, had je ook gelijk de oplossing moeten geven :+
Pagina: 1