DBGrid: Lookup-Wert für Fremdschlüsselspalte anzeigen

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
sierdolg
Beiträge: 66
Registriert: Mi 24. Okt 2012, 15:50

DBGrid: Lookup-Wert für Fremdschlüsselspalte anzeigen

Beitrag von sierdolg »

Liebe Expertengemeinde,

auf einem DBGrid, die auf eine Artikeltabelle gesetzt ist (ein Datensatz entspricht einer Rechnungsposition) werden diverse Informationen wie Bestellnummer, Menge, Einzelpreis,Hersteller,Kategorie usw. gelistet. Den Gesamtpreis, der nur informationshalber angezeigt und daher nur berechnet, aber nicht in der Datenbank gespeichert werden soll, konnte ich erhalten, indem ich im Dialog "Felder bearbeiten" (Doppelklick aufs Dataset) ein berechnetes Feld hinzugefügt und die Zuweisungsformel ins Ereignis CalcFields des Datasets eingetragen habe:

Code: Alles auswählen

procedure TDataModule1.ztPositionCalcFields(DataSet: TDataSet);
begin
  ztPositionGesamtpreis.Value:=ztPositionMenge.Value*ztPositionEinzelpreis.Value;
  ztPositionNettopreis.Value:=ztPositionEinzelpreis.Value/MWST_SATZ;
  //...
end;


Nun wollte ich für die Fremdschlüsselwerte (z.B. HerstellerID) auch wieder sprechende Namen (z.B. Hersteller) anzeigen lassen, denn in einer etwa vor 4 Jahren erstellten Vorgängerversion hatte das auch schon ohne weiteres funktioniert. Folglich habe ich wie damals im DataModule das vom DBGrid genutzte DataSet in gleicher Weise wie oben mit dem Dialog "Felder bearbeiten" um ein Lookup-Feld (FieldKind: fkLookup) ergänzt, z.B.

Code: Alles auswählen

 
KeyFields: HerstellerID
LookupDataSet: ztHersteller
LookupKeyFields: HerstellerID
LookupResultField: Hersteller
LookupCache: TRUE

Damals war allein durch diese Einstellungen nicht nur die LookupResult-Werte statt des Fremdschlüssels angezeigt worden, beim Editieren hatte das DBGrid auch selbsttätig die Eingabe mit einer Dropdown-Box unterstützt.

Im Entwurfsmodus (also im Designer) werden daraufhin auch die gewünschten Daten gezeigt. Starten läßt sich das Programm allerdings nicht, es kommt stets ein wenig aussagekräftiges "Operation cannot be performed in an inactive dataset." Entferne ich das Nachschlagefeld wieder, läuft das Programm wieder (nur eben ohne Nachschlagewerte). Es kann von daher also eigentlich nur um das Dataset des Nachschlagefelds gehen.

Die große Frage lautet also: wo und wie muß da noch zur Laufzeit nachgeholfen werden?
Ein "DataModule1.ztPositionHersteller.LookupDataSet.Active:=True;", versuchsweise in TForm1.FormShow gesetzt, hat auch nichts genützt, und leider finde ich zu diesem Thema auch nirgendwo ein erhellendes Beispiel.


Abschließend noch das wichtigste zum Drumherum: benutzt wird ein aktuelles Lazarus (trunk) mit aktuellem FPC (trunk) mit Zeos Access (zcomponent 7.2), alles mit fpclazupdeluxe installiert (also nichts linuxdistributionsspezifisches) auf Debian Stable 8 alias Jessie 64 Bit.

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: DBGrid: Lookup-Wert für Fremdschlüsselspalte anzeigen

Beitrag von Soner »

Den Fehler kenne ich, man muß zuerst die Lookuptabellen aktivieren dann die "Haupttabelle". Man muß nach dem Designen alles Active:=false machen und beim Programmstart zuerst die Nebentabellen(Lookuptabellen) dann die Haupttabelle öffnen/activ setzen.
Beim Vorgängerversion hast du wahrscheinlich zufällig erst die Komponenten für die Lookuptabellen erstellt, deshalb lief es damals.
Es ließe sich vermeiden wenn man im Formdesigner Erstellungsreihenfolge ("Create Order") von Komponenten ändern könnte aber Lazarus bietet diese Möglichkeit noch nicht.

sierdolg
Beiträge: 66
Registriert: Mi 24. Okt 2012, 15:50

Re: DBGrid: Lookup-Wert für Fremdschlüsselspalte zei

Beitrag von sierdolg »

Vielen Dank, Soner, Volltreffer - "Creation order" war das relevante Stichwort!
Hab's augenscheinlich trotzdem nur teilweise gelöst - der Fehler tritt aber inzwischen erneut auf, obwohl ich nach einigen Änderungen auf Anhieb in dieser Hinsicht nichts "grob falsches" mehr sehe.
Wie kann man am besten herausfinden, welche Komponente bzw. welche "Operation" das Problem verursacht? Denn über beides schweigt sich die Meldung ja aus...

Auf dem Konsolenfenster erscheint:

Code: Alles auswählen

[FORMS.PP] ExceptionOccurred 
  Sender=EDatabaseError
  Exception=Operation cannot be performed on an inactive dataset
  Stack trace:
  $000000000078CB60
  $000000000078EFD1
  $000000000078F683
  $000000000062A3D0  INITRESOURCECOMPONENT,  line 804 of lresources.pp
  $00000000004A552E
  $000000000045A834  CREATEFORM,  line 2190 of include/application.inc
  $000000000041E44D  main,  line 18 of project1.lpr
TApplication.HandleException Operation cannot be performed on an inactive dataset
  Stack trace:
  $000000000078CB60
  $000000000078EFD1
  $000000000078F683
  $000000000062A3D0  INITRESOURCECOMPONENT,  line 804 of lresources.pp
  $00000000004A552E
  $000000000045A834  CREATEFORM,  line 2190 of include/application.inc
  $000000000041E44D  main,  line 18 of project1.lpr

sierdolg
Beiträge: 66
Registriert: Mi 24. Okt 2012, 15:50

Re: DBGrid: Lookup-Wert für Fremdschlüsselspalte anzeigen

Beitrag von sierdolg »

Anscheinend reicht es nicht, im Code (DataModuleX.DataModuleCreate) die Connection zu trennen (.disconnect), wie weil offenbar selbst das immer schon zu spät kommt. Wenigstens scheinen dann alle daran hängenden Datasets automatisch implizit auf inaktiv zu wechseln.

Kann man das manuelle Disconnect im Designer vor dem Kompilieren (und idealerweise das Wiedereinschalten danach, denn der Sinn eines RAD-Tools ist ja eigentlich, (gleich) visuell (weiter)arbeiten zu können) irgendwie automatisieren?

Antworten