Entwickler-Ecke

Datenbanken - DBGrid berechnendes Feld


mergall - Di 06.08.02 18:51
Titel: DBGrid berechnendes Feld
Hallo Ihr unermüdlichen,

Habe mal eine Frage!

Habe zwei verknüpfte Tabellen: Mitarbeiter.db und Zeiten.db Habe jetzt über eine SQL Anweisung (Query) die Auswertung in ein DBGrid vorgenommen. Es werden Name, Anfangszeit, Endzeit, Krank und Urlaub ausgegeben.

Ich möchte aber in diesem Grid auch Berechnungen durchführen. So zum Beispiel einen Stundensaldo, je datensatz. Irgendwie klappt das aber nicht bei einem Query.

Bei einem normalen TTable konnte man ja virtuelle calc oder lookup Felder einfügen. Funktioniert das auch ähnlich bei den Querys oder muss man das über die SQL Abfrage realisieren. Wobei SUM ect ja immer nur die Gesamtsummen der ganzen Tabelle wiedergibt.

Kann mir vielleicht jemand einen Tip geben.

Vielen Dank habe hier schon viel durch bloses Lesen gelernt.
Gruß Mergall


Christian S. - Di 06.08.02 20:35

Hi!

Ich habe eine kleine Vereinsverwaltung als "Testdatenbank" für Ideen. Da funktioniert folgende Anweisung:


Quelltext
1:
SELECT vorname, nachname, (3*mitgliedsnummer) FROM mitglieder                    


Die Abfrage macht natürlich keinen Sinn, aber es funktioniert.

Hilft Dir das?

MfG,
Peter


Cashels - Di 06.08.02 21:13

Calculated Fields kannst du auch ohne weiteres bei TQuery einsetzen, da spricht nix dagegen. Alternativ kannst du auch direkt über eine passend SQL Anweisung deine Berechnungen durchführen...

Dass SUM in Sql sich nur auf ganze Tabellen bezieht stimmt so nicht ganz. Kuck dir mal in dem Zusammenhang die Struktur "group by" an...

Gruss,
Tom


mergall - Do 08.08.02 17:47

Vielen Dank für Eure schnellen Antworten

ich möchte ja eine Zeitdifferenz eines jeden Datensatzes in meinem DBGrid angezeigt bekommen ohne diese in die Datenbank schreiben zu müssen.

Wenn ich allerdings ein CalcField im Feldeditor der Query anlege, dann zeigt er mir beim active - Zustand nur die eine leere angelegte Spalte an.

Bei einer Abfrage wie von Peter Lustig, zB. (Endzeit-Anfangszeit) kommt natürlich nur Müll raus.

Kann mir vielleicht jemand noch einen Tip geben, in welche Richtung ich gehen muss. Habe mir auch schon alle SQL Befehle wie Months between ect. angeschaut aber mein Hauptproblem ist eigentlich immer noch dieses calc Field, was ich einfach nicht in den Grid bekomme.

Gruß Mergall


Christian S. - Do 08.08.02 18:53

Hi!

Ich habe eine Table "abeiter" erstellt, wobei jeder Datensatz die Eigenschaften "endzeit" und "startzeit" besitzt, jeweils im Format TIME.

Folgendes gibt mir im DBGrid die Stunden zwischen startzeit und endzeit aus.


Quelltext
1:
 SELECT (endzeit-startzeit)*24 FROM arbeiter                    


MfG,
Peter

P.S.: Sag' mir bitte, wenn ich Dein Problem missverstanden habe!


mergall - Do 08.08.02 19:10

Hallo,

nein Du hast mein Problem schon verstanden, ich hab nur den Wald vor lauter Bäumen nicht mehr gesehen. Deine Abfrage funktioniert jetzt bei mir genauso. Wenn man das TDatetime nicht *24 nimmt stimmts natürlich nicht.

Habe folgende Abfrage:

Quelltext
1:
2:
3:
4:
select Name, Datum, Anfangszeit, Endzeit, Krank, Urlaub,
(Endzeit-Anfangszeit)*24 Saldo from
Mitarbeiter, Zeiten where (Zeiten.PersonalID = Mitarbeiter.PersonalID)
and (Name = :Name) and (Datum<= :BDatum) and (Datum >= :ADatum);

Möchte also die Anfangs- und Endzeit einer Bestimmten Person in einem bestimmten Zeitraum abfragen. Die Berechnung des jeweiligen Saldos funktioniert ja jetzt auch.

Kann man das Format der Ausgabe leicht ändern? (2 Nachkommastellen) Und gibt es nun eine Möglichkeit diese virtuellen Felder anzusprechen um weitere Berechnungen durchzuführen. Denke da an einen aktuellen Stundensaldo.

Jedenfalls vielen Dank schon einmal.

Gruß René


Spike - Do 08.08.02 19:21

mergall hat folgendes geschrieben:
Wenn ich allerdings ein CalcField im Feldeditor der Query anlege, dann zeigt er mir beim active - Zustand nur die eine leere angelegte Spalte an.


Du mußt den Wert des Feldes in OnCalcFields berechnen. Dann wird auch was angezeigt. Dann kannst Du auch z.B. einen formatierten String ausgeben.

Spike


Christian S. - Do 08.08.02 20:23

Hi!

Theoretisch gibt es den Befehl "Round" (laut dieser Seite http://www.hrz.uni-dortmund.de/S1/download/skripte/sql/sqlora_2.html)

Aber irgendwie funktioniert er nicht so, wie er dort beschrieben steht. Leider bin ich auch nicht so bewandert in SQL. Solltest Du herausfinden, wie das geht, dann poste es bitte hier. Würde mich auch interessieren.

MfG,
Peter


Spike - Do 08.08.02 20:42

Also der Befehl ROUND(n[,m]) funktioniert nach meiner Erfahrung nur wenn n vom Typ Double ist. Mit Single geht es nicht - aber frag mich nicht warum. :wink:

Spike


Christian S. - Do 08.08.02 21:03

Hi!

@Spike:
Das ist natrülich ärgerlich.

Wie funktioniert das mit dem OnCalcFields? (ich meine nicht, wie ich an das
Ereignis komme, sondern wie ich die Werte dort berechnen kann).

MfG,
Peter


Spike - Do 08.08.02 21:18

zum Beispiel so:

Quelltext
1:
2:
3:
4:
procedure TForm1.Query1CalcFields(DataSet: TDataSet);
begin
  With Dataset do FieldValues['Calc_Feld'] := FieldValues['Wert1'] * 2;
end;

macht natürlich wenig Sinn, aber ich hoffe es erklärt Deine Frage.

Spike


Christian S. - Do 08.08.02 21:34

Hi!

Ich habe zwei Probleme:
1. Wenn ich folgenden Code benutze, müssten die Spalten "Anfangszeit" und "Endzeit" doch die gleichen Werte enthalten, oder?

Quelltext
1:
  with Dataset do FieldValues['endzeit']:=FieldValues['anfangszeit'];                    

Tun sie aber nicht. Die Werte sind unverändert.

2. Bei Deinem Code: muss die Spalte Calc_Feld nicht dann schon existieren?

MfG,
Peter


Spike - Do 08.08.02 21:43

1.) Wenn Du dem Feld Endzeit einen neuen Wert zuweist (wie in Deinem Beispiel) mußt Du Anschließend die Methode Dataset.Post aufrufen damit die Werte auch in die DB geschrieben werden.

2.) berechnete Felder (in meinem Beispiel: Calc_Feld) mußt Du vorher zu TQuery hinzufügen. Doppelklick auf das Symbol -> Popupmenu -> neues Feld -> berechnet. In der Datenbank muß es diese Spalte natürlich nicht geben.

Spike


Christian S. - Do 08.08.02 22:19

Hi!

JA! So funktioniert es prima! Ist ja wirklich komfortabel zu machen. Viel einfacher, als sich mit den SQL-Statements herumzuschlagen.


@mergall:
Ich glaube inzwischen, dass Spikes Variante die Bessere ist. Hier kannst Du dann auch die berechneten Felder (wir hatten sie noch "virtuelle Felder" genannt) weiterverabeiten. Außerdem wird z.B. endzeit-anfangszeit direkt im hh:mm:ss - Format ausgegeben, was die Sache mit der Rundung erledigt.

MfG,
Peter


mergall - So 11.08.02 15:26

ja denke auch das Spikes Variante die Bessere ist.
Funktioniert einwandfrei.
Danke jedenfalls an alle....

Denke das damit dieses Problem gelöst ist.

Tschau
Mergall