DBGrid mit DBLookupCombo als Editor

Rund um die LCL und andere Komponenten

DBGrid mit DBLookupCombo als Editor

Beitragvon charlytango » 4. Nov 2016, 12:24 DBGrid mit DBLookupCombo als Editor

Hi,

Der Einbau einer DBLookupCombo als Editor in einen DBgrid hat nach einigem Suchen geklappt.
Aber da scheint es noch Haken und Ösen zu haben

gegeben sei eine Tabelle 'zahlung' mit den Feldern 'Betrag' und 'zahlungsart', wobei die zahlungsart als Code eingetragen wird.

Dazu gibt es die Tabelle DCODE mit den Feldern 'Code' und 'Codetext'
'Code' ist die zahlungsart die in die Tabelle 'Zahlung' eingetragen werden soll, 'Codetext' ist der Klartext dazu.

Als Editor fungiert ein DBLookupcombo der im Edit-Fall mit Hilde des Events OnSelectEditor wie folgt eingeblendet wird.

Code: Alles auswählen
procedure TForm1.DBGrid1SelectEditor(Sender: TObject; Column: TColumn;
  var Editor: TWinControl);
begin
  if DBLookupComboBox1.DataField=Column.FieldName then begin
    DBLookupComboBox1.BoundsRect:=DBGrid1.SelectedFieldRect;
    Editor:=DBLookupComboBox1;
    DBLookupComboBox1.Visible:=true;
  end;
end;


Klappt soweit, allerdings würde ich auch gerne im Browse-Modus des DBGrids den Klartext und nicht den Code angezeigt bekommen.
Vermutlich war ich da blind, denn sowas klappt sicher - bitte einen kräftigen Schubs in die richtige Richtung ;)

Was mich allerdings nachdenklich stimmt ist, wenn ich das DBLookupcombo auf ReadOnly stelle (damit der user den Klartext nicht editieren kann) bekomme ich eine Fehlermeldung:
Operation not allowed, dataset SQLQuery_Data is not in an edit or insert mode

Ohne ReadOnly klappt alles und mit ReadOnly geht nix mehr ?

Testcode liegt bei. (einfach Checkbox klicken zum Testen)

Bitte um Hilfe in diesen beiden Punkten
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
charlytango
 
Beiträge: 105
Registriert: 12. Sep 2015, 11:10
Wohnort: Wien
OS, Lazarus, FPC: FPC 3.0; Laz 1.6 | 
CPU-Target: Win 32Bit, 64bit
Nach oben

Beitragvon Michl » 4. Nov 2016, 21:31 Re: DBGrid mit DBLookupCombo als Editor

charlytango hat geschrieben:Was mich allerdings nachdenklich stimmt ist, wenn ich das DBLookupcombo auf ReadOnly stelle (damit der user den Klartext nicht editieren kann) bekomme ich eine Fehlermeldung
So sollte es dann gehen:
Code: Alles auswählen
procedure TForm1.DBGrid1SelectEditor(Sender: TObject; Column: TColumn;
  var Editor: TWinControl);
begin
  if DBLookupComboBox1.DataField=Column.FieldName then begin
    DBLookupComboBox1.BoundsRect:=DBGrid1.SelectedFieldRect;
    Editor:=DBLookupComboBox1;
    DBLookupComboBox1.Visible:=true;
    SQLQuery_Data.Edit// <-- Eingefügt
  end;
end;   


charlytango hat geschrieben:Klappt soweit, allerdings würde ich auch gerne im Browse-Modus des DBGrids den Klartext und nicht den Code angezeigt bekommen.
Ich arbeite viel mit Joins, Subselects und anderen Relationen, führe Insert, Update und Co händisch aus und weiß daher nicht, wie es sonst gemacht wird.

Ich würde es so lösen:
Code: Alles auswählen
  SQLQuery_Data.SQL.Text :=
    'SELECT za.betrag, dc.codetext as zahlweise ' +
    'FROM zahlung AS za, dcode AS dc ' +
    'WHERE (za.zahlungsart = dc.code);';     
Da die Datenbankkomponenten keine komplexen Selects updaten können, würde ich dies nun händisch machen.

Vielleicht weiß ja af0815 oder ein anderer Datenbankguru hier mehr.
Code: Alles auswählen
type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 
Michl
 
Beiträge: 2191
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon af0815 » 4. Nov 2016, 22:09 Re: DBGrid mit DBLookupCombo als Editor

Wenn man in der Query doppelklickt, dann kann man die Felder einfügen. Dort hat man auch die Möglichkeit die fieldkind auf Lookup zustellen. Damit sollte es auch im Grid angezeigt werden, wie mit dem Lookup beim Editieren. Aber Achtung die Lookup-table muß bereits aktiv sein bzw. richtig mit SQL bestückt sein, bevor man die Query mit dem lookup aktiv setzt, ansonsten gibt es ärger.

Ich habe schon länger nichts damit gemacht :-) Bin etwas eingerostet in den spezialitäten wie lookups, löse das meiste durchs programm (oder Framework).

Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
af0815
 
Beiträge: 3266
Registriert: 7. Jan 2007, 10:20
Wohnort: Niederösterreich
OS, Lazarus, FPC: Win7/Linux (L stable FPC stable) per fpcup | 
CPU-Target: 32Bit (64Bit)
Nach oben

Beitragvon charlytango » 5. Nov 2016, 10:28 Re: DBGrid mit DBLookupCombo als Editor

Danke erstmal f die Hinweise.

Just for The Records:

Damit der user den Text der DBDropdownCombo nicht ändern kann, muss man ihren Style ändern -- ReadOnly ist da falsch.

Code: Alles auswählen
DBLookupComboBox1.Style := csDropDownList;


Für die Anzeige des Klartextes im Grid wäre mein Zugang, dass ich die Anzeige mit dem Join von von Michl mache und die DBDropdowncombo direkt im SQLQuery updaten lasse. Geht nicht -- bei Queries mit Joins scheint das Dataset in einen ReadOnly-Modus zu gehen und damit ist editieren auch nicht möglich.

grml...

was mich im Moment ärgert ist dass ich keine schnelle Lösung für ein Allerweltsproblem finde - der Wunsch einen Klartext anzuzeigen und dahinter den Code zu schreiben ist ja nix Extravagantes.
charlytango
 
Beiträge: 105
Registriert: 12. Sep 2015, 11:10
Wohnort: Wien
OS, Lazarus, FPC: FPC 3.0; Laz 1.6 | 
CPU-Target: Win 32Bit, 64bit
Nach oben

Beitragvon wp_xyz » 5. Nov 2016, 13:49 Re: DBGrid mit DBLookupCombo als Editor

Hast du den Vorschlag von af0815 mit den Lookup-Feld ausprobiert? Da brauchst du gar keine LookupCombo, die ist schon im Grid eingebaut, wenn das Feld als Lookup-Feld erkannt wird.

Im Anhang findest du eine lauffähige Variante deines Programms mit dem Lookup-Feld für die Spalte Zahlungsart. Leider ist es in Lazarus etwas hakelig, ein Lookup-Feld einzurichten. Es ist schon eine Zeit her, seitdem ich das mit Delphi gemacht habe, aber ich meine mich zu erinnern, da ging das ganz flüssig.

Wichtig: Um im Designmode die DB öffnen zu können, muss der Datenbankname mit absolutem Pfad in der Connection eingetragen sein, sonst sucht die IDE relativ zum Lazarus-Verzeichnis; du solltest das später, wenn alles eingerichtet ist, wieder auf relativ zurücksetzen oder den Pfad erst zur Laufzeit eintragen. Genauso solltest du im ObjectInspector Connection auf Connected=false und die Queries auf Active=false setzen und erst zur Laufzeit wieder reaktivieren.

Das Lookup-Feld wird zusätzlich zu den durch die SQL-Anweisung der Query definierten Felder im feldeditor erzeugt (Rechtsklick auf Query, Neues feld, FieldType = ftLookup). Die zu setzenden Properties sind relativ selbsterklärend (LookupDataset, LookupKeyFields, LookupResultField). Einige Zeit grübeln musste ich über FieldName und KeyFields: FieldName ist der Name des erzeugten Lookup-Feldes, darf nicht derselbe sein wie der des Original-feldes, sonst spielt das Grid verrückt. KeyFields ist der Name des Feldes der Query, aus dem die Original-Werte (vor dem Lookup) stammen (hier: zahlungsart).

Im Grid richtest du zum Schluss für die anzuzeigenden Felder Columns ein.

P.S. Lazarus weiß zur Designzeit eigentlich, in welchem Ordner die exe des Programms landen wird und könnte den relativen Pfad zur DB auch richtig auflösen. Scheint mir ein Bug zu sein.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Zuletzt geändert von wp_xyz am 5. Nov 2016, 18:08, insgesamt 1-mal geändert.
wp_xyz
 
Beiträge: 2279
Registriert: 8. Apr 2011, 08:01

Beitragvon charlytango » 5. Nov 2016, 17:53 Re: DBGrid mit DBLookupCombo als Editor

ich hab kurz reingesehen --- chapeau...sehr seidige Lösung

Ich werde mir das gleich morgen reinziehen und versuchen es bei mir einzubauen.
Wiewohl ich befürchte dass das nicht 1:1 für mein TMemDataset laufen wird.

In diesem Fall geht es um einen Buchungswizared, der Zahlungen unterschiedlichen Typs (Bar, Bankomat, Teilzahlungen etc) in einem TMemdataset entgegen nimmt und dann pro zeile etwas komplexer mit SQL Inserts und Updates verbucht.
Bin gespannt was da noch auf mich lauert 8)
charlytango
 
Beiträge: 105
Registriert: 12. Sep 2015, 11:10
Wohnort: Wien
OS, Lazarus, FPC: FPC 3.0; Laz 1.6 | 
CPU-Target: Win 32Bit, 64bit
Nach oben

Beitragvon charlytango » 18. Sep 2017, 07:27 Re: DBGrid mit DBLookupCombo als Editor

Hi,

Neuaufnahme des Themas damit eine Lösung im Forum auch gemeinsam gefunden wird.
Die aktuelle Aufgabe ist nach wie vor ein Lookup-Feld in einen DBGrid einzubauen -- nur diesmal zur Laufzeit.
Auch nach erheblichem Rechercheaufwand bringe ich es nicht hin.

IDE Bug ?
Die Version von wp_xyz funktioniert hervorragend, aber beim Nachbau musste ich bemerken dass ich in der IDE kein Lookupfeld
anlegen konnte. Die zum Speichern nötigen Buttons waren deaktiviert (Möglicherweise ein Bug?)
Das zuständige Dataset war dabei in der IDE nicht aktiv.
Einfache Datenfelder ließen sich nach Warnung dass die Feldauswahl nicht möglich ist, anlegen. Das Lookup-Feld hingegen nicht.
Meine Vermutung ist, dass eine Datenverbindung bestehen müsste, was ich in meiner IDE-Umgebung nicht habe.


Alleine deswegen brauche ich Einstellungen im Code, zudem sind künftig die Einstellungen in der IDE imho aufwendiger als z.B. einen Codeschnipsel zu kopieren und die Feldnamen anzupassen.


Ich habe zu Testzwecken versucht das programm von wp_xyz so abzuwandeln dass die in der IDE erzeugten Felder gelöscht und per code neu angelegt werden.

Mittlerweile bin ich mir sicher dass auch einiges bei der Definition der Felder fehlt, es klappt einfach nicht.

Die Feld-Attribute habe ich aus dem .lfm File übernommen.

Code: Alles auswählen
procedure TForm1.FormCreate(Sender: TObject);
var
  fld: TField;
begin
  SQLite3Connection1.DatabaseName := 'test.sqlite3'//alter Code von wp_xyz
  SQLite3Connection1.Connected := True;               //alter Code von wp_xyz
 
  // Alle zu Designtime definierten Felder in SQLQuery_Data löschen
 
  if SQLQuery_Data.Active then SQLQuery_Data.Close;
  SQLQuery_Data.Fields.Clear;
 
 
  //Felder per Code neu aufbauen
 
  fld := TCurrencyField.Create(nil);
  with fld do
  begin
    FieldKind := fkData;
    FieldName := 'Betrag';
    Index := 0;
    LookupCache := False;
    ProviderFlags := [pfInUpdate, pfInWhere];
    ReadOnly := False;
    Required := False;
    //Dataset := dsData; // this automatically adds the field to the Dataset's Fields collection.
                                    // irgendwo gefunden, keine Ahnung ob das stimmt
  end;
  SQLQuery_Data.Fields.Add(fld);
 
  fld := TStringField.Create(nil);
  with fld do
  begin
    DisplayWidth := 20;
    FieldKind := fkData;
    FieldName := 'zahlungsart';
    Index := 1;
    LookupCache := False;
    ProviderFlags := [pfInUpdate, pfInWhere];
    ReadOnly := False;
    Required := False;
    Size := 5;
    //Dataset := dsData; // this automatically adds the field to the Dataset's Fields collection.
  end;
  SQLQuery_Data.Fields.Add(fld);
 
  fld := TStringField.Create(nil);
  with fld do
  begin
    DisplayLabel := 'Zahlungsart';
    DisplayWidth := 20;
    FieldKind := fkLookup;
    FieldName := 'luZahlungsart';
    Index := 2;
    KeyFields := 'zahlungsart';
    LookupCache := True;
    LookupDataSet := SQLQuery_Code;
    LookupKeyFields := 'code';
    LookupResultField := 'codetext';
    ProviderFlags := [pfInUpdate, pfInWhere];
    ReadOnly := False;
    Required := False;
    //Dataset := dsData; // this automatically adds the field to the Dataset's Fields collection.
  end;
  SQLQuery_Data.Fields.Add(fld);
 
  SQLQuery_Data.FieldDefs.Update;   //Keine Ahnung ob das hier nötig ist ????
 
  //Queries öffnen
  SQLQuery_Code.Open;   //alter Code von wp_xyz
  SQLQuery_Data.Open;   //alter Code von wp_xyz
 
end;


Symptom ist eine Access Violation und ein leeres SQLQuery_Data.
charlytango
 
Beiträge: 105
Registriert: 12. Sep 2015, 11:10
Wohnort: Wien
OS, Lazarus, FPC: FPC 3.0; Laz 1.6 | 
CPU-Target: Win 32Bit, 64bit
Nach oben

• Themenende •

Zurück zu Komponenten und Packages



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste

cron
porpoises-institution
accuracy-worried