| Autor |
Beitrag |
hansa
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Do 05.12.02 19:42
Hi,
wie mach ich das eigentlich, wenn zu einer Table genau die Werte aus einer anderen benötigt werden ? Ich brauche bei einer Rechnung zu jeder Rechnungsposition den richtigen Artikel. Habe ich jetzt die Rechnungs-DataSet bringt er mir mit folgendem immer denselben Artikel:
Quelltext 1: 2: 3:
| WITH RecDataMod.ArtDS DO SelectSQL.Text := 'SELECT * FROM ART WHERE ID = ' + RecDataMod.RecDS.FieldByName ('ID_ART').AsString; |
Das soll keine Lookup-Box werden sondern eine 1:1 Beziehung.
Gruß
Hansa
|
|
Alfons-G
      
Beiträge: 307
Win XP Prof, Linux, Win 7
D5 Prof, D7 Architect, D2005 Architect, D2007 Architect
|
Verfasst: Do 05.12.02 20:09
_________________ Alfons Grünewald
|
|
hansa 
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Do 05.12.02 20:15
Hi Alfons,
ja genau das wars. Der Witz ist, daß ich es vorher bei anderen Tables so gemacht habe und jetzt nicht mehr wußte wie. Das ist schon länger her und ich finde den Quelltext nicht.
Gruß
Hansa
|
|
hansa 
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Do 05.12.02 20:37
Nee,
zu früh gefreut.  Bei meinem Beispiel hat er mir nur den ersten Artikel geliefert. Mache ich es so :
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| RecDataMod.RecDS.First; while not RecDataMod.RecDS.Eof do begin WITH RecDataMod.ArtDS DO begin { RecDataMod.ArtDS.active := false; } SelectSQL.Text := 'SELECT * FROM ART8 WHERE ID = ' + RecDataMod.RecDS.FieldByName ('ID_ART').AsString; { RecDataMod.ArtDS.active := true; } END; RecDataMod.RecDS.Next; end; |
Dann kriege ich nur den letzten Artikel. Seltsamerweise habe ich aber mit diesem hier : Quelltext 1: 2: 3: 4:
| WITH RecDataMod.RecDS DO SelectSQL.Text := 'SELECT * FROM REC8 WHERE ID_RECKOPF = ' + RecDataMod.RecKopfDS.FieldByName ('ID').AsString; RecDataMod.RecDS.active := true; |
die richtigen 4 Rechnungspositionen aus der DB gefischt. Die erkenne ich am Preis, der bei den Positionen hinterlegt ist.
Gruß
Hansa
|
|
Alfons-G
      
Beiträge: 307
Win XP Prof, Linux, Win 7
D5 Prof, D7 Architect, D2005 Architect, D2007 Architect
|
Verfasst: Do 05.12.02 21:23
Du hast bei Deinem nicht funktionierenden Beispiel das vergessen: RecDataMod.RecDS.Next;Dann klappt's.

_________________ Alfons Grünewald
|
|
hansa 
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Fr 06.12.02 00:22
Hi Alfons,
hmm, tja da häng ich genau fest (Siehe weiter oben).
Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| RecDataMod.RecDS.First; while not RecDataMod.RecDS.Eof do begin WITH RecDataMod.ArtDS DO begin SelectSQL.Text := 'SELECT * FROM ART8 WHERE ID = ' + RecDataMod.RecDS.FieldByName ('ID_ART').AsString; END; RecDataMod.RecDS.Next; ****************************** end |
Sehe logisch keinen Fehler, wo könnte denn da was fehlen
Gruß
Hansa
|
|
LCS
      
Beiträge: 1305
Erhaltene Danke: 1
WIN 7, WIN 8
Delphi XE5, Delphi XE, Delphi 2007
|
Verfasst: Fr 06.12.02 08:55
Hi
ich würde sagen es muss so aussehen:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| RecDataMod.RecDS.First; while not RecDataMod.RecDS.Eof do begin WITH RecDataMod.ArtDS DO begin SelectSQL.Text := 'SELECT * FROM ART8 WHERE ID = ' + RecDataMod.RecDS.FieldByName ('ID_ART').AsString; Active := True; END; RecDataMod.RecDS.Next; ****************************** RecDataMod.ArtDs.Active := False; end |
Allerdings finde ich, dass es auch einfacher geht. Möglichkeit 1: Du erweiterst die SQL von RecDs so, dass du bereits hier mit JOIN die beiden Tabellen verbindest. Dann müsstest du nur mit einer Datenmenge arbeiten.
Möglichkeit 2: Du änderst die SQL von ArtDs ab in:
Quelltext 1:
| SELECT * FROM ART8 where ID = :ID_ART |
Anschliessend weisst du der Eigenschaft DataSource von ArtDs die Datasource zu, die an RecDs hängt. Damit wird bei jeder Bewegung in RecDs die ArtDs entsprechend positioniert und du sparst dir das alles.
Gruss Lothar
_________________ Der BH ist für die Brust, der Plan ist für'n Ar...
|
|
hansa 
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Fr 06.12.02 13:26
Hi,
| Zitat: | Dann müsstest du nur mit einer Datenmenge arbeiten.
|
Glaube, daß das sowieso besser wäre. Der Rechnungsempfänger, obwohl er keine Ahnung hat, sieht im Prinzip jede Zeile auf der Rechnung als Element einer Datenmenge an. Deshalb sollte man sich auch in einem Computerprogramm nicht allzu weit von der menschlichen und somit auch der eigenen Denkweise entfernen.
Also werde ich das mit JOIN machen und sehen, wo der nächste Haken ist.
Gruß
Hansa
|
|
hansa 
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Fr 06.12.02 13:45
Hi,
| Zitat: | SelectSQL.Text := 'SELECT * FROM REC8 JOIN ART8 ON ART8.ID=ID_ART';
|
Da kriege ich zwar keine Fehlermeldung, aber die Artikel sind nicht da und es sind zu viele Rechnungspositionen zu sehen. Woher soll das Programm eigentlich wissen, daß es sich nur um eine Rechnung handeln soll ? Es sieht so aus, daß er alle Rechnungspositionen auflistet, die für diesen Kunden jemals erfaßt wurden. Die Einschränkung über die RecKopf-ID müßte ich ja auch noch unterbringen.
Moment, jetzt schreib ich mal die ganze Prozedur hier rein. Mit der SQL-Syntax bin ich noch nicht so fit :
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
| procedure TReDruck.LabeledEdit1Exit(Sender: TObject); begin RecDataMod.RecKopfDS.active := false; RecDataMod.KuDS.active := false; RecDataMod.RecDS.active := false; RecDataMod.ArtDS.active := false; WITH RecDataMod.RecKopfDS DO SelectSQL.Text := 'SELECT * FROM RECKOPF8 WHERE RECHNNR ='+LabeledEdit1.TEXT; RecDataMod.ReckopfDS.Active := true;
IF NOT RecDataMod.ReckopfDS.IsEmpty THEN BEGIN
WITH RecDataMod.KuDS DO SelectSQL.Text := 'SELECT * FROM KUNDE8 WHERE ID = ' + RecDataMod.RecKopfDS.FieldByName ('ID_KUNDE').AsString; RecDataMod.KuDS.active := true;
WITH RecDataMod.RecDS DO SelectSQL.Text := 'SELECT * FROM ART8 JOIN REC8 ON ART8.ID=ID_ART'; RecDataMod.RecDS.active := true;
QuickRep1.Preview; END ELSE ShowMessage ('Eine Rechnung mit dieser Nr. existiert nicht !'); Close; end; |
Glaube, daß das nicht mehr viel sein kann. Aber ich habe noch keine Vermutung, warum das nicht geht.
Gruß
Hansa
|
|
LCS
      
Beiträge: 1305
Erhaltene Danke: 1
WIN 7, WIN 8
Delphi XE5, Delphi XE, Delphi 2007
|
Verfasst: Fr 06.12.02 13:59
Hi
Knapp daneben ist auch vorbei  . Als erstes brauchst du natürlich die Felder aus beiden Tabellen. Und dann muss das ganze natürlich noch auf die Rechnungsnummer eingeschränkt werden, die du brauchst.
Quelltext 1: 2: 3:
| Select R.*, A.* FROM REC8 R JOIN ART8 A ON (A.ID_ART = R.ID_ART) WHERE R.Rechnungsnummernfeld = Irgendeinerechnungsnummer |
Gruss Lothar
_________________ Der BH ist für die Brust, der Plan ist für'n Ar...
|
|
hansa 
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Fr 06.12.02 14:18
Hi,
Quelltext 1: 2: 3: 4:
| WITH RecDataMod.RecDS DO SelectSQL.Text := 'Select R.*, A.* FROM REC8 R JOIN ART8 A ON (A.ID_ART = R.ID_ART)' + 'WHERE R.ID_RECKOPF = RECKOPF8.ID'; RecDataMod.RecDS.active := true; |
Ich glaube, das hier ist noch knapper daneben.  Die .* sind wahrscheinlich überflüssig. Egal. Da kommt jetzt trotzdem die Feflermeldung : A.ID_ART Column unknown.
Gruß
Hansa
|
|
hansa 
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Fr 06.12.02 14:28
Hi,
das hier ist noch knapper daneben :
Quelltext 1: 2: 3: 4:
| WITH RecDataMod.RecDS DO SelectSQL.Text := 'Select R.*, A.* FROM REC8 R JOIN ART8 A ON (A.ID = R.ID_ART)' + 'WHERE R.ID_RECKOPF = ' + RecDataMod.RecKopfDS.FieldByName ('ID').AsString; RecDataMod.RecDS.active := true; |
Der Fehler war leicht zu finden, A.ID_ART gibt es wirklich nicht, das muß ganz einfach A.ID heißen. Nur, die Artikel sind nicht da.  Die 4 Rechnungspos. sind aber jetzt richtig.
Gruß
Hansa
[/quote]
|
|
LCS
      
Beiträge: 1305
Erhaltene Danke: 1
WIN 7, WIN 8
Delphi XE5, Delphi XE, Delphi 2007
|
Verfasst: Fr 06.12.02 14:28
Hi
Na, ja. Deine Spaltennamen kenn ich natürlich nicht.  Ich bin einfach mal davon ausgegangen, dass die Artikel-ID in beiden Tabellen denselben Namen hat. Hier musst du natürlich dann selbst die entsprechenden Spaltennamen einsetzen.
Und so ganz nebenbei: Mit deiner Where-Klausel bin ich auch nicht ganz einverstanden:
Quelltext 1: 2: 3: 4: 5:
| WITH RecDataMod.RecDS DO SelectSQL.Text := 'Select R.*, A.* FROM REC8 R JOIN ART8 A ON (A.ID_ART = R.ID_ART)' + 'WHERE R.ID_RECKOPF = ' + QuotedStr(RecDataMod.ReckopfDS.FieldByName('RECHNR').AsString); RecDataMod.RecDS.active := true; |
Versuchs mal so
Lothar
_________________ Der BH ist für die Brust, der Plan ist für'n Ar...
|
|
hansa 
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Fr 06.12.02 14:36
Hi,
so siehts im Moment aus :
Quelltext 1: 2: 3: 4: 5:
| WITH RecDataMod.RecDS DO SelectSQL.Text := 'Select R.*, A.* FROM REC8 R JOIN ART8 A ON (A.ID = R.ID_ART)' + 'WHERE R.ID_RECKOPF = ' + RecDataMod.RecKopfDS.FieldByName ('ID').AsString; RecDataMod.RecDS.active := true; RecDataMod.ArtDS.active := true; |
Das ArtDS war NICHT active = true, dafür kamen keine Artikel. Bei obigem kommt allerdings bei jeder Rechn.Pos. der erste Artikel in der Art-Table. Jetzt fliegt die Kugel ganz dicht an der Zielscheibe vorbei. Aufs Schützenfest kann ich aber noch nicht.
Gruß
Hansa
|
|
LCS
      
Beiträge: 1305
Erhaltene Danke: 1
WIN 7, WIN 8
Delphi XE5, Delphi XE, Delphi 2007
|
Verfasst: Fr 06.12.02 14:48
Das versteh ich jetzt aber gar nicht. Der Status der ArtDs spielt an dieser Stelle überhaupt keine Rolle, weil die Artikel ja zusammen mit den Rechnungspositionen von RecDs geliefert werden. Hast du mal versucht die SQL direkt auszuführen (IBConsole)? Wenn es kein Problem mit den Datentypen von A.ID und R.ID_ART gibt muss das so eigentlich funktionieren.
Gruss Lothar
_________________ Der BH ist für die Brust, der Plan ist für'n Ar...
|
|
SvenL
Hält's aus hier
Beiträge: 9
|
Verfasst: Fr 06.12.02 15:24
Titel: Hi ,
sag mal hast DU in dem Datamod "RecDataMod" eventuel schon eine SQL Abfrage Drin
und solltest Du wärend der Laufzeit nicht diese Anweisung erstmal mit Clear löschen
und dann mit SQL.ADD Deine Abfrage übergeben???
Oder ist die Idee blöd?? 
|
|
LCS
      
Beiträge: 1305
Erhaltene Danke: 1
WIN 7, WIN 8
Delphi XE5, Delphi XE, Delphi 2007
|
Verfasst: Fr 06.12.02 15:37
Titel: Re: Hi ,
Hi
| SvenL hat folgendes geschrieben: | Oder ist die Idee blöd??  |
Nein, ist es nicht. Und wenn wär's auch nicht schlimm. (Wir würden nur fürchterlich lästern und uns das Maul über dich zerreissen.)
Es ist nur nicht notwendig weil er ja SelectSQL.Text verwendet und damit alles was schon drinsteht überschreibt.
Gruss Lothar
_________________ Der BH ist für die Brust, der Plan ist für'n Ar...
|
|
hansa 
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Sa 07.12.02 15:37
Hi,
Quelltext 1:
| Select R.*,A.* FROM REC8 R JOIN ART8 A ON (A.ID = R.ID_ART) WHERE R.ID_RECKOPF = 50 |
hab ich jetzt mal als SQL-Script laufen lassen, kein Error. Nur wo sehe ich das Ergebnis ?  Jetzt aber noch eine Frage : Müssen die Felder, womit der JOIN abläuft eventuell unbedingt indiziert sein? Im Moment haben meine Tables nur einen primary Key auf den jeweiligen IDs liegen, sonst nichts! Bei meinem jetztigen Kenntnisstand ist noch durchaus damit zu rechnen, daß ich etwas elementares übersehe.
Verwende ich obiges 1:1 in Delphi kriege ich jedenfalls folgendes : richtige Anzahl Rechn.Pos. mit richtigen Preisen, als Artikel kommt immer der erste Artikel, der in der Art-Table drin ist.
Gruß
Hansa
|
|
hansa 
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: So 08.12.02 15:36
Hi,
das Problem hat sich etwas verlagert.  Da ich langsam überhaupt keine Idee mehr hatte, was da falsch sein könnte, bin ich einfach mal umgekehrt davon ausgegangen, daß es sehr wohl stimmt und der Fehler woanders steckt.
Ich muß dazu sagen, daß dieses Verhalten bei einem QuickReport auftritt. Für den habe ich noch kein Gespür entwickelt, da ich ihn erst diese Woche zum ersten mal benutze.  Ich legte also ein Grid auf die Form und sieh an, alles war so wie es sein sollte. Vielleicht hat einer eine Idee, wo das Problem in Zusammenhang mit dem QR liegt.
Das mit dem Join geht also jetzt. Nun habe ich aber noch eine prinzipielle Frage. Also im Moment habe ich vier DataSets auf der Form. Für Rechnungskopf, Kunde, Rechnungspos., Artikel.
Die Datasource des Grids ist das Rechnungspos.-Dataset. Da stehen aber nun auch die Artikel mit drin. Wenn ich jedes Select-Statement als Datenmenge betrachte, wären es nur 3, trotz der 4 DataSets.
1. Select * From RecKopf
2. Select * from Kunde
3. Das mit dem Join, welches die Rechnungspos. und Artikel liefert.
Nun könnte ich ja zumindest noch 1 und 2 auch mit Join behandeln, dann hätte ich nur noch 2mal Select. Mir stellt sich aber jetzt die Frage, was ist eigentlich besser ? Also ehrlich gesagt bin ich fast der Meinung, die SQL-Abfragen nicht zu sehr zu verschachteln, damit man den Überblick behält. Aber ich weiß nicht, ob das aus anderen Gründen vielleicht nicht so ratsam ist.
Gruß
Hansa
|
|
hansa 
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: So 08.12.02 16:05
Hi,
die Artikel sind jetzt auch im Quickreport. Allerdings muß man den Artikel-Feldern jetzt als DataSet RechnPos zuordnen.  Bei meinem letzten Posting habe ich so was in der Richtung schon geahnt. In einem größeren Team könnte das tödlich sein. Muß man sich an solche Sachen gewöhnen oder bin ich auf dem Holzweg und mache irgendwas verkehrt ?
Gruß
Hansa
|
|