Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi In einem DBGrid andere Dinge anzeigen als drinstehen (https://www.delphipraxis.net/183004-einem-dbgrid-andere-dinge-anzeigen-als-drinstehen.html)

Der schöne Günther 3. Dez 2014 16:42

Delphi-Version: XE7

In einem DBGrid andere Dinge anzeigen als drinstehen
 
Ihr Profis habt das ja schon alle x mal gemacht 8-): Ich lasse den Benutzer mit einem
Delphi-Quellcode:
TDBGrid
in einer Ergebnismenge wühlen. Ich möchte ihm allerdings in einer Spalte (Zahl) nicht das anzeigen was drinsteht, sondern den zehnfachen Wert.

Wo muss ich ansetzen? Ich kenne mich mit Datenbanken nicht aus, irgendwo habe ich den Terminus "Berechnete Felder" im Hinterkopf.

Ich finde auf dem
Delphi-Quellcode:
TDBGrid
nichts und nicht auf dem
Delphi-Quellcode:
TDataSource
nichts. Was übersehe ich?

mm1256 3. Dez 2014 16:50

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Bin zwar kein Profi...aber vielleicht reicht's trotzdem:

Delphi-Quellcode:
procedure TForm1.DBGridDrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
begin
  with (Sender as TDBGrid).Canvas do begin
    Column.Field.AsFloat...

  end;

p80286 3. Dez 2014 16:53

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Delphi-Quellcode:
select wert*10 from irgendwo
oder

Pseudocode:
Delphi-Quellcode:
xx.Cells[x,y].Text=inttostr(myquery.field[z].asinteger*10;
(das geht natürlich mit TDBGrid nicht)

aber ich befürchte Du meinst etwas anderes.

Gruß
K-H

Dejan Vu 3. Dez 2014 16:57

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Du kannst:
1. Berechnete Felder erstellen. Dazu fügst Du in deinem TDatset-Derivar ein neues Feld ein, setzt den Modus auf 'calculated' und setzt das Feld im OnCalculate(Fields?)-Ereignis des TDataset à la 'myCalcField.AsInteger := random(20)';

2. Du erstellst Eventhandler für OnGetText/OnSetText für das Feld (blöde Idee)

3. Du überschreibst, wie mein Vorredner geschrieben hat, das onDraw-Event des Grids (auch nicht soooo toll, finde ich)

Fang mal mit calculated fields an. Ist praktisch. OnGetText/OnSetText verwendet man zum 'übersetzen' von Feldern (eher Transliteration).

Der schöne Günther 3. Dez 2014 17:11

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Zitat:

Zitat von p80286 (Beitrag 1282127)
aber ich befürchte Du meinst etwas anderes.

Richtig, ich will ja nur die Anzeige anpassen. Arbeiten möchte ich natürlich mit den "echten" Daten.

Zitat:

Zitat von mm1256 (Beitrag 1282126)
Bin zwar kein Profi...aber vielleicht reicht's trotzdem:

Danke für die Idee. Das wird sicher funktionieren, wäre aber mein letzter Ausweg. Es ist im Endeffekt genau was ich will, aber zwingt einem zum "Malen".

Zitat:

Zitat von Dejan Vu (Beitrag 1282128)
Berechnete Felder erstellen. [...]

Das wird es wohl werden. Was mich, so als Amateur, daran jetzt stört ist: Warum blähe ich die Ergebnismenge hier künstlich auf? Klar, das wird wahrscheinlich auf Client-Seite erst nachträglich drangedichtet werden (hoffe ich), aber mir ist das unsympathisch, dass da jetzt jeder drankommt.

Ich wollte eigentlich nur die Werte im DBGrid anpassen. Blöd dass der da nichts anbietet. :x

himitsu 3. Dez 2014 17:16

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Zitat:

Zitat von p80286 (Beitrag 1282127)
(das geht natürlich mit TDBGrid nicht)

Dafür gibt es dort die Unterscheidung zwischen Value, EditValue und DisplayValue, wobei man den DisplayValue beliebig ändern kann.

Der schöne Günther 3. Dez 2014 17:28

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Was? Erkläre dich!
DisplayValue hört sich gut an, aber was hat es mit einem TDBGrid zu tun?

Dejan Vu 3. Dez 2014 17:30

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1282131)
Warum blähe ich die Ergebnismenge hier künstlich auf?

Tust Du ja nicht.

Der schöne Günther 3. Dez 2014 17:32

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Ich formuliere es anders herum: Ich fummele am TDataSet herum. Ich hätte erwartet, direkt den TDBGrid oder wenigstens das TDataSource anfassen zu können.

Wenn ich jetzt irgendeine Logik habe, die das TDataSet auswertet kann sie auch an die berechneten Felder dran die nur für die Anzeige verwendet werden. Finde ich, spontan, doof.

Dejan Vu 3. Dez 2014 17:42

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Ich würde das wirklich im TDataset machen. Die TDataSource ist ja nur ein Verteiler für Dinge, die mit den Daten passieren (events und so). Das Grid wäre wäre noch eine Möglichkeit, aber das TDBGrid bietet hier keine komfortable Möglichkeit.

Auf der Ebene, auf der Du dich bewegst (RAD mit datensensitiven Elementen), würde ich auch die 'rapid' Lösung nehmen, also die, die am schnellsten und direktesten mit dem geringsten Aufwand zu Ziel führt. Willst Du dagegen eine nachhaltige, erweiterbare, skalierbare und schießmichtot Lösung, dann könntest Du dir natürlich ein Viewmodel bauen, aber, WTF.

Der schöne Günther 3. Dez 2014 17:43

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Na gut, dann dreh ich eben am RAD :spin2: soweit nicht noch jemand etwas tolles einfällt

Uwe Raabe 3. Dez 2014 17:44

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Zitat:

Zitat von Dejan Vu (Beitrag 1282128)
2. Du erstellst Eventhandler für OnGetText/OnSetText für das Feld (blöde Idee)

Ist eigentlich gar nicht so blöd. Solange die Felder im DBGrid nicht geändert werden, braucht man sich um den OnSetText-Event auch gar nicht kümmern, aber auch das wäre für diesen Anwendungsfall nicht schwer.

Man kann ja auch problemlos mit den tatsächlichen Werten der Felder weiterarbeiten, da diese ja nicht verändert werden. Der Event wird ja nur bei der Abfrage der Properties
Delphi-Quellcode:
Text
und
Delphi-Quellcode:
DisplayText
ausgewertet. Die Properties
Delphi-Quellcode:
Value
oder
Delphi-Quellcode:
AsString
oder alle anderen
Delphi-Quellcode:
As<XXX>
liefern immer noch die Originalwerte.

Dejan Vu 3. Dez 2014 17:52

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1282142)
Ist eigentlich gar nicht so blöd. Solange die Felder im DBGrid nicht geändert werden, braucht man sich um den OnSetText-Event auch gar nicht kümmern, aber auch das wäre für diesen Anwendungsfall nicht schwer.

Richtig ... 'solange'.. Aber dann hat man eine schwer zu findende Macke in seiner SW. Ich mag das 'verbiegen' von Originalwerten nicht, außer zur Transliteration, aber dann ist das gewollt. Allerdings ist das alles Geschmackssache bzw. eine Frage des Patterns. Wenn ich in meiner Anwendung häufig Änderungen der Darstellung über das OnGetText mache, dann werde ich da bei Problemen auch nachschauen...

Hmm.. Vielleicht wirklich nicht so blöd, meine kurzzeitige Gehirnabsenkung.

Ich persönlich (der es gerne klar und einfach hat), bevorzuge 'MyField' und 'MyFakedField' als explizite Feldnamen für die Daten. Dann weiß ich selbst nach 10 Tagen noch, was Sache war.

himitsu 3. Dez 2014 18:03

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1282136)
DisplayValue hört sich gut an, aber was hat es mit einem TDBGrid zu tun?

Delphi-Grids sind strohdoof, aber es hat zumindestens etwas mit dem DB im Namen zu tun. :roll:

TField.FieldName
TField.DisplayName
TField.DisplayLabel

TField.Value
TField.Text
TField.DisplayText
TField.OnGetText
TField.OnSetText
TFloatField.DisplayFormat
...

Außerdem gibt es z.B. die LookupComboboxen, ebenso wie gewisse Fields/Editoren, welche eine Lookup-Funktion anbieten.
Und dann gibt's in so mancher Anzeigekomponenten auch nochmal ähnliche Funktionen, wie z.B. in den Columns der DevArt-Grids.

Der schöne Günther 3. Dez 2014 18:06

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Das
Delphi-Quellcode:
OnGetText
-Event eines TFields ist wirklich auch interessant. Denn es sagt mir ja explizit, ob er den Wert grade zur Anzeige oder zum Benutzen haben will:

Delphi-Quellcode:
TFieldGetTextEvent = procedure(
   Sender: TField;
   var Text: string;
   DisplayText: Boolean
) of object;

Gute Argumente auf beiden Seiten. Ich muss da mal drüber grübeln...

Dejan Vu 3. Dez 2014 19:13

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Was mir jetzt daran nicht mehr gefällt, ist, dass das Feld nun *immer* als 'DisplayText' deinen gefakten Wert anzeigt. Egal wo. Du kommst also kaum noch an die echten Daten ran (mit datensensitiven Controls). Wenn das so gewünscht ist. Gut. Wenn nicht, weiß nich...

Der schöne Günther 3. Dez 2014 19:19

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Doch, genau das war eigentlich gewünscht.

Konkretes Beispiel: Rational denkende Menschen (und Software) schreiben und lesen SI-Einheiten. Ein Angelsachse hingegen möchte das in Zoll angezeigt bekommen.

Die Verarbeitung und alles passiert weiterhin mit SI-Einheiten. Ich denke hierfür ist das genau richtig :thumb:

Uwe Raabe 3. Dez 2014 21:07

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1282147)
Denn es sagt mir ja explizit, ob er den Wert grade zur Anzeige oder zum Benutzen haben will

Genauer: zur Anzeige oder zu Bearbeitung (sprich: Feld wird in datensensitivem Control editiert).

Wie schon erwähnt, den originalen Feldwert bekommt man über Value bzw. die As<XXX>-Properties.

Der schöne Günther 4. Dez 2014 12:22

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Das einzige was mich immer noch wuschig macht ist die Tatsache, dass direkt am TDataSet auf reine Anzeige-Sachen eingehen muss.

Das TDataSet, seine Verbindung und anderes Zubehör hatte ich immer auf einem Datenmodul (sprachneutral), Anzeige wie ein TDBGrid und das TDataSource auf einem Formular. Jetzt muss ich anfangen, das zu vermischen.

Oder habe ich es schon immer falsch gemacht?

himitsu 4. Dez 2014 12:32

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Man kann im DataSet einheitliche Verhalten implementieren, wo die Anzeige dann überall gleich ist.
CalcFields sind ja auch Dinge, welche da erstmals nichts mit den Daten zu tun haben und dennoch sind sie im DataSet implementiert.

Und, wie bereits erwähnt, gibt es von anderen Anbietern auch "ordentliche" Grids, welche welcher die Anzeige ebenfalls in sich anpassen können.

p80286 4. Dez 2014 12:36

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Dann laß doch die Finger von dem TDBwasweißich.
Bei mir kommen die Daten aus der Query in irgendeinem "nichtdisplayformat an, und ich kann damit machen was ich will, z.b. für amerianische Benutzer deren Datumsformat für die Anzeige und für deutsche deren Format (ja ich weiß, ISO ist eigentlich das Datumsformat, aber meine Benutzer wissen das nicht)
Auf jeden Fall habe ich immer eine strikte Trennung zwischen Daten und Anzeige.

Gruß
K-H

Uwe Raabe 4. Dez 2014 12:52

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1282227)
Das einzige was mich immer noch wuschig macht ist die Tatsache, dass direkt am TDataSet auf reine Anzeige-Sachen eingehen muss.

Das TDataSet, seine Verbindung und anderes Zubehör hatte ich immer auf einem Datenmodul (sprachneutral), Anzeige wie ein TDBGrid und das TDataSource auf einem Formular. Jetzt muss ich anfangen, das zu vermischen.

Das kommt darauf an, was du wirklich erreichen willst. Soll lediglich in diesem einen Grid die Anzeige des Feldwertes ander sein, als es die Standardformatierung des TField-Objects vorgibt, oder soll dieses Feld in allen Anzeige- und Editier-Controls in dieser veränderten Form dargestellt werden. Im ersten Fall sollte man die Manipulation in dem Grid oder dem dazugehörigen Formular durchführen. Für den zweiten Fall sind die Events des Feldes der richtige Ort.

Es ist ja auch nicht so, daß auch im normalen Betrieb die Datenfelder in ihrem nativen Format angezeigt werden. Alle TField-Objekte haben ein Standardverhalten für die Umwandlung der realen Feldinhalts in eine lesbare und editierbare Form. Bei numerischen Feldern kann man das auch noch durch das Property DisplayFormat steuern. Nur wenn man von diesem Standard abweichen will, muss man das in OnGetText und OnSetText selber implementieren (z.B. ein Integerfeld binär als Folge von 0 und 1 darstellen und editieren). Die visuelle Darstellung und Eingabe metrischer Datenwerte in imperialen Einheiten ist ein durchaus öfter anzutreffender Anwendungsfall. Ob die Umwandlung dann tatsächlich stattfindet entscheidet wird meistens über einen entsprechenden Konfigurationseintrag entschieden.

Dejan Vu 4. Dez 2014 13:29

AW: In einem DBGrid andere Dinge anzeigen als drinstehen
 
Wenn Du mit einem TDB-Grid arbeiten willst, dann mach die Formatierung in einem Dataset. Wenn dir die Quelle nicht passt (weil das quasi die Rohdaten sind), dann mach eine Kopie (als CDS oder Memdata). Das ist nichts anderes als ein Viewmodel. Und in der Kopie kannst Du dann machen, was Du willst.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:01 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz