![]() |
Datenbank: MySQL • Version: 5.1 • Zugriff über: Zeos
Einer query zusätzliche Felder hinzufügen und als CheckBox editieren
Hallo zusammen,
ich krame gerade meine alten Delphikenntnisse aus, um eine Absenzenverwaltung für unsere Schule zu basteln. Was ich brauche: ich hole aus einer Query die Namen der Schüler eines Kurses (sch_id, sch_name). Die Namen sollen in einem DBGrid angezeigt werden, allerdings möchte ich daneben noch eine (bzw. merhere) Spalte mit einer Checkbox haben - die wird angeklickt, wenn ein Schüler zu einem bestimmten Termin gefehlt hat - dh. diese Information kommen nicht aus einer Query, sondern werden beliebig editiert und dann am einfachsten am Ende mit einem "alles speichern" Zeile für Zeile ausgelesen und dann weiterverarbeitet (für alle angeklickten wird eine Absenz gespeichert). Je nach Fall sollen es mehrere unabhängige Spalten werden, die man anklicken kann (gefehlt_Tag1, gefehlt_Tag2 etc). Was ich bislang probiert habe: (Mysql 5, Zeos, Delphi 6 prof) - zusätzliche Felder direkt per mysql generieren: select sch_id, sch_name, false as gefehlt from schueler... - oder zusätzliche Felder über die Query hinzufügen (als int oder boolean,beides probiert) - zum Anzeigen habe ich das SMDBGrid mit dem "vorgefertigten" Checkbox-Editor versucht - der zeigt zwar Checkboxen richtig an, wenn die Daten aus einer query kommen, man kann aber keine Werte ändern (obwohl natürlich query, query.felder, grid und grid.spalten auf readonly = false gesetzt sind) - und das JvDBUltimateGrid aus den Jedi-Komponenten, das hat ja auch die Eigenschaft "boolean editor".. damit kann ich zwar ne checkbox setzen, die aber beim Verlassen des Felds wieder unchecked wird. Ich bin gerade wirklich am Verzweifeln. Lasse ich mir die Felder als stinknormale integer anzeigen, kann ich Werte ändern. Die gleichen Daten an einem SMDBGrid angehängt, ändert das SMDBGrid dann auch schön artig die Checkboxen - aber eben ein direktes Anklicken der Boxen im SMDBGrid funzt nicht. Hat jemand vielleicht einen Tipp, wie ich das lösen kann? Vielen Dank für eure Hilfe! LG.. Heiko |
AW: Einer query zusätzliche Felder hinzufügen und als CheckBox editieren
Berechnete Felder sind ja readonly, bei manchen Datasets kann man das überschreiben oder direkt berechnete Felder einfügen, deren Schreibschutz man entfernt, auf Feld.SetText kann entsprechend reagiert werden.
Der einfachere Ansatz wäre die Daten in ein Clientdataset zu kopieren, dem die benötigten Spalten bereits hinzugefügt wurden und dieses für die Darstellung zu verwenden. Ich hatte etwas derartiges mal gekapselt ....
Delphi-Quellcode:
type
TMyFieldDef=Record Name:String; Size:Integer; DataType:TFieldType; end; TFieldDefArray = array of TMyFieldDef;
Delphi-Quellcode:
function GetClientDSForDS (ADataSet: TDataSet; AFieldDefArray: TFieldDefArray; AClientDataSet: TClientDataSet=nil): TClientDataSet;
var i: integer; Function NoAutoInc(ft:TFieldType):TFieldType; begin if ft=ftAutoInc then Result := ftInteger else Result := ft; end; begin if Assigned(AClientDataSet) then Result := AClientDataSet else result := TClientDataSet.Create(nil); Result.Close; Result.FieldDefs.Clear; for I := 0 to ADataSet.FieldCount-1 do begin Result.FieldDefs.Add(ADataSet.Fields[I].FieldName, NoAutoInc(ADataSet.Fields[I].DataType), ADataSet.Fields[I].Size); end; for I := 0 to High(AFieldDefArray)do result.FieldDefs.Add(AFieldDefArray[I].Name, AFieldDefArray[I].DataType, AFieldDefArray[I].Size); Result.CreateDataSet; ADataSet.First; while not ADataSet.Eof do begin Result.Append; for I := 0 to ADataSet.FieldCount-1 do begin result.FieldByName(ADataSet.Fields[I].FieldName).Assign(Adataset.Fields[i]); end; Result.Post; ADataSet.Next; end; end; |
AW: Einer query zusätzliche Felder hinzufügen und als CheckBox editieren
Verwende eine Memory-Table mit allen Feldern die du benötigst.
Dann kopiere die Datensätze aus deiner Query (sch_id, sch_name) in die Memory-Table. Die zusätzlichen Felder bleiben leer (NULL) oder können mit einem Defaultwert belegt werden. Damit sind dann alle Daten im Speicher und können beliebig editiert werden. In der JVCL gibt es z.B. in Unit JvMemoryDataset die Klasse TJvMemoryData. |
AW: Einer query zusätzliche Felder hinzufügen und als CheckBox editieren
Hallo,
vielen Dank für eure schnellen Antworten, die beide - so wie ich das sehe - in die gleiche Richtung gehen. Der Fehler liegt also darin, dass die Datenmenge aus der Query nicht editierbar ist und deswegen die geänderten Checkboxen ihre Werte nicht zurückschreiben können. Richtig? Beide Ideen finde ich genial, werd ich jetzt gleich mal ausprobieren! LG.. Heiko |
AW: Einer query zusätzliche Felder hinzufügen und als CheckBox editieren
..Ernüchterung :(
1) @SX2008: JvMemoryTable... Sollte doch eigenltich nicht so schwer sein. Ich gebe als Dataset meine Datenquery an und nutze "Borrow Structure", um die Struktur zu importieren - damit hab ich alle Felder in der memTable. Interessanterweise sind manche auf readonly = true gesetzt, manche nicht, ebenso manche mit required= true bzw. false. Wenn ich aber die Daten holen will (egal ob in der IDE oder per LoadFromDataSet(meineSQLQuery, meineSQLQuery.RecordCount, lmCopy, true)), passiert... immer wieder ein Fehler "Feld_xxx darf nicht leer sein!". In meineSQLQuery steht was drin, daran liegts nicht. Seltsam. Wie bekommst du die Daten in die memTable? 2) @ Bummi: Ich muss gestehen: meine aktive Delphi-Zeit ist lange her. Bin mir deswegen nicht ganz sicher ob ich deine Zeilen richtig eingebaut hab. In meinem main-form steht jetzt also ganz oben gleich nach der uses-Klauses die Type-Def. für TMyFieldDef. In die Public-Deklaration von Tf_main hab ich dann die Signatur der GetClientDSForDS Methode rein, den Quelltext dann natürlich in die Implementation. Das wird compiliert, nur... wie wende ich es an? Ich muss mir ja erst dieses Definitionen-Array basteln. Hast du da evtl. noch nen Code-Schnipsel? Ich brauch ja einfach nur drei Felder: schuelerid (ftInteger), kursid (ftInteger), schuelername (ftString). Die Daten hierfür liegen in meineSQLQuery. Die Methode liefert mir theoretisch die Daten aus meineSQLQuery in einem clientDataSet zurück. Aber leider krachts auch hier - genau der gleiche Fehler wie oben!?!?! Sobald ich die MemoryTable auf active=true setze bzw. GetClientDSForDS aufrufe, stolpert er und sagt "Feldxxx darf nicht leer sein" - das ist das erste Feld von meineSQLQuery. Irgendwelche Ideen...? Mannmannmann warum muss das alles so schwer sein... ;) |
AW: Einer query zusätzliche Felder hinzufügen und als CheckBox editieren
Ich hätte es nicht in die Klasse eingebaut, sondern gegf. in eine Tools-Unit.
Das mit dem Recordarray ist nicht kompliziert
Delphi-Quellcode:
Wenn Du die Felder per SQL schon drin hast kannst Du ein leeres FieldDefArray mitgeben.
var
RA:TFieldDefArray; begin SetLength(RA,2); RA[0].Name := 'Feldx'; RA[0].Datatype := ftString; RA[0].Size := 20; RA[1].Name := 'Feldy'; RA[1].Datatype := ftboolean; RA[1].Size := 0; //Wenn Du nichts einfügen willst SetLength(RA,0); Der Fehler "Feldxxx darf nicht leer sein" scheint schon beim alleinigen lesenden Zugriff auf den Dataset aufzutreten das Clientdataset hat ja keine derartigen Einschränkungen zugewiesen bekommen, mit Zeos und MySQL bin ich allerdings nicht bewandert ... |
AW: Einer query zusätzliche Felder hinzufügen und als CheckBox editieren
Tataaaa!
Dank Bummis Hilfe hab ich's mit seiner Möglichkeit über ein ClientDataSet hinbekommen. Hatte ja eh eine Tools-Unit, da war das gut aufgehoben (uses-Klausel anpassen wg. DataSet). Da ich MySQL verwende muss ich die boolean-Felder manuell hinzufügen (mysql ersetzt boolean durch tinyint, dann klappt das mit dem SMDB-Grid nicht automatisch mit den Checkboxen). Kleines Kosmetikproblem: ich bekomme aus meiner Query noch einige andere Felder, für die "Absenzeingabe" will ich aber nur den Namen + die Checkboxfelder anzeigen, deswegen muss ich zur Laufzeit alle anderen unsichtbar setzen (schöner wärs die Eigenschaften alle schon zur Entwurfszeit festlegen zu können). Aber egal, alles kein großes Problem jetzt! Nochmals vielen Dank für eure Hilfe, Problem gelöst :)) |
AW: Einer query zusätzliche Felder hinzufügen und als CheckBox editieren
Kleine Nachfrage: weiß jemand, wie ich alle Felder einer Spalte bearbeiten kann?
Hintergrund: ein Kurs findet normalerweise z.B. 4mal pro Woche statt, dh. ich erzeuge 4 Checkbox-Spalten. Es kann aber z.B. sind dass es in der aktuellen Woche nur 2 Termine gibt - da ich auch "Fehlanzeige" speichern möchte, darf ich also nicht blind durch alle Spalten gehen, sondern muss es ermöglichen, dass man z.B. Spalte 3 und 4 disabled. Bearbeiten kann ich mit column.readonly := true blocken, das geht locker. Aber nun möcht ich noch, dass alle evtl gesetzen Haken dieser Spalte wieder gelöscht (dh. auf feld.asboolean := false und zudem idealerweise die ganze Spalte angegraut wird. Das könnte schön über OnTitleClick erfolgen, dachte ich. Also in der Art:
Delphi-Quellcode:
Leider klappt auch das Setzen der Farben nicht.
procedure TmeinForm.smdb_KursabsenzenTitleClick(Column: TColumn);
if Column.ReadOnly = false then begin //UncheckAll(smdb_Kursabsenzen, Column); <- Versuch, klappt aber nicht Column.ReadOnly := true; Column.Color := clblue; end else begin Column.ReadOnly := false; Column.Color := clwhite; end; Hat jemand dazu vielleicht nen Hinweis...? Danke! Ich w |
AW: Einer query zusätzliche Felder hinzufügen und als CheckBox editieren
Kommando leider doch nochmal zurück. An sich klappt alles, nur werden offenbar alle integer-Felder nicht kopiert - lass ich mir den Inhalt des originalen DataSets anzeigen, stehen die schuerlerids schön als int drin. Nach dem Kopieren in das ClientDataSet sind alle Spalten identisch, nur die int-Werte der schuelerids sind jetzt leer!
Ist leider doof, ich brauch die Schülerids natürlich, um die Fehlzeiten zuordnen zu können :( Bummi, hast du eine Idee woran das liegen könnte? Etwas verzweifelnde Grüße Heiko |
AW: Einer query zusätzliche Felder hinzufügen und als CheckBox editieren
Mhhh, nicht auf Anhieb, hast Du mal debugt nach TFieldType des Feldes ....
|
AW: Einer query zusätzliche Felder hinzufügen und als CheckBox editieren
Zitat:
Dachte vielleicht, dass das an einem Spezialfeldtyp von den Zeos-Komponenten liegt, dass die da irgendwas tricksen was nicht Standard ist - dem ist aber leider nicht so, die persistenten Felder in der mysql-Query sind alle die Felder aus der DB-Unit (schuelerid ist TLargeIntField). Debuggen: Hm. In der NoAutoInc wird schuelerid as ftLargeInt richtigerweise erkannt. Warum klappts nicht? Wenn ich in NoAutoInc ftLargeInt als ftInteger erzeuge, funktionierts!?!? Verstehe ich nicht :( Naja, mal sehen obs noch weitere Schwierigkeiten damit gibt... Auf jeden Fall nochmal Danke! |
AW: Einer query zusätzliche Felder hinzufügen und als CheckBox editieren
|
AW: Einer query zusätzliche Felder hinzufügen und als CheckBox editieren
Ahhhhh, das sieht doch stark nach einer Ursache aus. Ja, ich hab noch D6 prof.
Offenbar ist die "neue" midas.dll abwärtskompatibel bis D5 ( ![]() Jetzt hab ich sie mal spaßeshalber in c:\windows\syswow64 für die alte ersetzt, aber das ändert offenbar nichts, gleicher Fehler. Die midas.dll wird im laufenden Projekt eingebunden (Ansicht - Debug - Module). Aber ohne den Zusatz if (ft = ftLargeint) then Result := ftInteger in NoAutoInc bleiben die schuelerids leer. Naja immerhin läufts so, ist zwar seltsam aber damit werd ich wohl leben (müssen). Trotzdem Danke! Lg Heiko |
AW: Einer query zusätzliche Felder hinzufügen und als CheckBox editieren
Ich denke dafür würde ich mir eine temporäre Tabelle auf dem MySQL erzeugen und diese dann im DBGrid anzeigen lassen.
Dabei kann man auch berücksichtigen, dass man eben nur x Spalten benötigt (das CREATE TEMPORARY TABLE-Statement muss man halt anpassen). Wenn die Eingabe abgeschlossen ist, dann trägt man einfach (geht z.B. auch mit einer StoredProcedure) die Werte aus der temporären Tabelle in die echte Tabelle ein. Das sollte auch unabhängig von der verwendeten Delphi-Version möglich sein, da wir aus der Client-Sicht eine echte komplett beschreibbare Tabelle vor uns haben ;) Ach ja, man darf natürlich die Feldliste nicht schon zur Design-Time komplett zuweisen, da wir ja eine dynamische Feldliste haben ;) |
AW: Einer query zusätzliche Felder hinzufügen und als CheckBox editieren
Zitat:
Nur sind UDF dann halt das nächste Thema, mit dem ich noch nie zu tun hatte. Ideal wäre sowas wie select getAbsenzenliste(kursid, termin1, termin2, ...., terminx) wobei termin1 bis terminx einfache zeitstempel sind. Die UDF holt dann erst mal alle kursmitglieder des kurses und prüft dann für jeden jeden Termin durch. Tja, im Kopf hätt ich's schon... Na mal sehen, aktuell klappts mit dein Einzelqueries schon mal ganz gut, das Netz darf halt nicht klemmen... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:56 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz