![]() |
Datenbank: Access • Version: 2008 • Zugriff über: ADOQuery
ADOQuery berechnetes Feld
Hallo,
folgende Procedure:
Delphi-Quellcode:
An Datamodule1.ADOQueryGejoliste hängt ein DBGrid an, mit folgenden Felder:
procedure TForm1.ButtonMaterialSuchenClick(Sender: TObject);
var BestandMaterialNummer, BestandMaterial : real; begin Datamodule1.ADOQueryGejoliste.Close; Datamodule1.ADOQueryGejoliste.SQL.Clear; Datamodule1.ADOQueryGejoliste.SQL.Add('SELECT [Material-Stamm].[Mat-Nr], [Material-Stamm].Bezeichnung, [Material-Stamm].[Lieferant Bezeichnung], '); Datamodule1.ADOQueryGejoliste.SQL.Add('[Material-Stamm].aktuell'); Datamodule1.ADOQueryGejoliste.SQL.Add('FROM [Material-Stamm]'); Datamodule1.ADOQueryGejoliste.SQL.Add('WHERE (([Material-Stamm].[Lieferanten-Nr]= ' + Lieferantennr.Text + ') AND ([Material-Stamm].aktuell= -1))'); Datamodule1.ADOQueryGejoliste.Open; Datamodule1.ADOQueryGejoliste.Last; Datamodule1.ADOQueryGejoliste.First; BestandMaterial := 0; while not Datamodule1.ADOQueryGejoliste.Eof do begin Datamodule1.ADOQueryRollenJoinLagerplatz.Active := False; Datamodule1.ADOQueryRollenJoinLagerplatz.SQL.Clear; Datamodule1.ADOQueryRollenJoinLagerplatz.SQL.Add('SELECT DISTINCTROW Materialrollen.[Arb-Breite], Materialrollen.lfm, Materialrollen.[Mat-Nr], '); Datamodule1.ADOQueryRollenJoinLagerplatz.SQL.Add('Materialrollen.Rollennummer, Materialrollen.Mutterrolle, Materialrollen.DatumAb, Materialrollen.GrundAb, '); Datamodule1.ADOQueryRollenJoinLagerplatz.SQL.Add('Materialrollen.DatumZu, Materialrollen.GrundZu, '); Datamodule1.ADOQueryRollenJoinLagerplatz.SQL.Add('Materialrollen.DatumWE, Rollenlager.Lagerplatz, RollenPlanung.Kommentar, RollenPlanung.AuftragPlanung, '); Datamodule1.ADOQueryRollenJoinLagerplatz.SQL.Add('RollenPlanung.RestLaenge, RollenPlanung.RestBreite FROM (Materialrollen LEFT JOIN Rollenlager ON '); Datamodule1.ADOQueryRollenJoinLagerplatz.SQL.Add('Materialrollen.Rollennummer = Rollenlager.Rollennummer) LEFT JOIN RollenPlanung '); Datamodule1.ADOQueryRollenJoinLagerplatz.SQL.Add('ON Materialrollen.Rollennummer = RollenPlanung.Rollennummer where ((Materialrollen.[Mat-Nr] = ' + Datamodule1.ADOQueryGejolisteMatNr.AsString + ') and (Materialrollen.DatumAb is NULL) and (Materialrollen.[Arb-Breite] > 179))'); Datamodule1.ADOQueryRollenJoinLagerplatz.Open; Datamodule1.ADOQueryRollenJoinLagerplatz.Last; Datamodule1.ADOQueryRollenJoinLagerplatz.First; BestandMaterialNummer := 0; while not Datamodule1.ADOQueryRollenJoinLagerplatz.Eof do begin BestandMaterialNummer := BestandMaterialNummer + ((Datamodule1.ADOQueryRollenJoinLagerplatzArbBreite.AsInteger/1000) * Datamodule1.ADOQueryRollenJoinLagerplatzlfm.AsInteger); Datamodule1.ADOQueryRollenJoinLagerplatz.Next; end; // ShowMessage('BestandMaterialNummer = ' + FloatToStr(BestandMaterialNummer)); Datamodule1.ADOQueryGejoliste.Edit; Datamodule1.ADOQueryGejolisteBESTAND.AsFloat := BestandMaterialNummer; Datamodule1.ADOQueryGejoliste.Post; Datamodule1.ADOQueryGejoliste.Next; end; GridGejo.Visible := true; end; Mat-Nr: Bezeichnung Bestand Das Feld "Bestand" ist ein 'Calculated-Feld' in Datamodule1.ADOQueryGejoliste. Die anderen Felder werden aus dem 1.-tem SELECT eingetragen. Es funktioniert soweit fast alles, jedoch das 'Datamodule1.ADOQueryGejoliste.Post;' nicht, bzw. in der Tabelle 'GridGejo' kann ich es nicht sehen. Gruß, Luckner |
AW: ADOQuery berechnetes Feld
Hallo,
Zitat:
Wie soll denn das gehen. |
AW: ADOQuery berechnetes Feld
Ich dachte, dass man gerade diese Felder manipulieren kann.
Luckner. |
AW: ADOQuery berechnetes Feld
Hallo,
die Anzeige schon: Event OnCalcFields oder FieldByName (aber ohne das Post) Aber du kannst das doch nicht speichern. Lass das Post einfach mal weg. Es könnte natürlich sein, das dir ein Update der Oberfläche fehlt. |
AW: ADOQuery berechnetes Feld
Wenn ich an der Stelle 'Datamodule1.ADOQueryGejoliste.Post;' das Grid updatete mit 'GridGejo.Update;', dann sehe ich nur ganz kurz, dass in die entsprechenden Zeile die Zahl eingetragen wird, aber dann sofort wieder gelöscht, wenn die nächste Zeile angesprochen wird.
Luckner |
AW: ADOQuery berechnetes Feld
Was soll die Funktion machen?
1) Eine Anzeige des aktuellen Bestands? oder 2) Eine Anzeige und Speicherung des aktuellen Bestands? 2) wird nicht funktionieren, weil weder die Query noch das "berechnete" Feld das können. 1) wäre schon eher möglich, aber auf dieser Basis auch ein komplizierter Ansatz. P.S.: Berechnete Felde können nur das Ergebnis einer Formel mit Werten aus dem jeweils aktuellen Datensatz darstellen, nichts abspeichern. |
AW: ADOQuery berechnetes Feld
Hallo jobo,
es reicht nur eine Anzeige. Mir fällt noch die Möglichkeit die Daten in ein Stringgrid zu schreiben. Wa ich nicht weiß, ob ich die Daten aus dem Stringgrid im Fastrepport verwenden kann: Luckner |
AW: ADOQuery berechnetes Feld
Ach so, eher Punkt 1. am Ende muss die Tabelle auf einem Drucker raus.
Luckner |
AW: ADOQuery berechnetes Feld
Zitat:
Die Berechnung bzw. die Idee "berechnetes Feld" ist ja nicht verkehrt. Das kannst Du vom Vorgehen her so wie im Delphiquellcode (Delphicode mit Formel auf Basis der 2.Query) mit einer Query machen, die Du als Subquerey der ersten Abfrage anhängst/eibaust. Dann wird automatisch alles durch die Abfrage beim Öffnen der Query berechnet. Also ADOQueryGejoliste und ADOQueryRollenJoinLagerplatz so zusammenfassen, dass direkt der (in SQL) berechnete Bestand herauskommt. Diese Query / das Grid kann natürlich auch gedruckt werden. |
AW: ADOQuery berechnetes Feld
Delphi-Quellcode:
Bin mir nicht sicher, da Deine SQLs irgendwie extrem schwer lesbar sind (aber das hatten wir ja schon).
BestandMaterialNummer := 0;
while not Datamodule1.ADOQueryRollenJoinLagerplatz.Eof do begin BestandMaterialNummer := BestandMaterialNummer + ((Datamodule1.ADOQueryRollenJoinLagerplatzArbBreite.AsInteger/1000) * Datamodule1.ADOQueryRollenJoinLagerplatzlfm.AsInteger); Datamodule1.ADOQueryRollenJoinLagerplatz.Next; end; Sieht aber schwer nach sowas in der Art aus:
SQL-Code:
Wenn das soweit in etwa korrekt ist, baust Du das bitte noch in das erste SQL mit ein und sparst Dir die (mehr als nur gewöhnungsbedürftige) Whileschleife innerhalb einer Whileschleife, zwecks Anzeige in einem Grid, ein.
select sum(Arb-Breite / 1000) * lfm as BestandMaterialNummer
from Materialrollen LEFT JOIN Rollenlager ON Materialrollen.Rollennummer = Rollenlager.Rollennummer LEFT JOIN RollenPlanung ON Materialrollen.Rollennummer = RollenPlanung.Rollennummer where Materialrollen.[Mat-Nr] = :MatNr and Materialrollen.DatumAb is NULL and Materialrollen.[Arb-Breite] > 179 group by Materialrollen.[Mat-Nr] Ein Grid holt sich von der DB die Daten, die es zur aktuellen Anzeige benötigt. Dein Whileschleifenkonstrukt ist in dem Zusammenhang bestenfalls unschädlich, schlimmstenfalls kontraproduktiv, aber höchstwahrscheinlich nichts weiter als ein Zeit- und Resourcenfresser. Bitte gewöhne Dir an in SQL-Statements nur die Daten zu selektieren, die Du auch zur Anzeige / Weiterverarbeitung benötigst. Das macht die SQLs übersichtlicher, spart Serverresourcen und beim Client Arbeitsspeicher und macht ggfls. mögliche Vereinfachungen der Statements deutlich leichter erkennbar. |
AW: ADOQuery berechnetes Feld
Hallo,
habe mir alle Vorschläge zu Herzen genommen, vor allem die von Delphi.Narium und folgende SELECT-Abfrage gebastelt:
Delphi-Quellcode:
Jetzt werden mir die Daten in der DBGrid angezeigt und ich bin fast glücklich. Es werden mir jetzt Materialien angezeigt, deren (Materialrollen.[Arb-Breite] > 179 (mm)ist. Alle Materialrollen, deren die [Arb-Breite] <= 179 werden nicht angezeigt, was korrekt ist. Der Fall jedoch, wo es kein Material auf Lager gibt, weil verbraucht, geht verloren.
SELECT Materialrollen.[Mat-Nr], sum((Materialrollen.[Arb-Breite] / 1000) * Materialrollen.lfm) as BESTAND, [Material-Stamm].Bezeichnung
FROM Materialrollen LEFT JOIN [Material-Stamm] ON Materialrollen.[Mat-Nr] = [Material-Stamm].[Mat-Nr] WHERE (([Material-Stamm].[Lieferanten-Nr] = ' + Lieferantennr.Text + ') AND ([Material-Stamm].aktuell= -1) AND (Materialrollen.DatumAb is NULL) AND (Materialrollen.[Arb-Breite] > 179)) group by Materialrollen.[Mat-Nr], [Material-Stamm].Bezeichnung Hat Jemand, bitte, eine Idee, wie man das noch zusätzlich einbaut. Danke, Luckner |
AW: ADOQuery berechnetes Feld
Hallo,
or (Feld x is Null) or (Feld1=Feld2) ?? Ich kenne deine Datenstruktur ja nicht. Wie erkennst Du, dass das Material aufgebraucht ist? Du kannst auch eine komplett neue Query "hintendranhängen" Select Query 1 Union Select Query 2 Es müssen nur die gleichen Datenfelder (Anzahl, Datentyp usw.) sein. |
AW: ADOQuery berechnetes Feld
Zitat:
Zu der Frage: Zitat:
so
Delphi-Quellcode:
oder
.. FROM Materialrollen RIGHT JOIN
[Material-Stamm] ON Materialrollen.[Mat-Nr] = [Material-Stamm].[Mat-Nr] so
Delphi-Quellcode:
.. FROM [Material-Stamm] LEFT JOIN
Materialrollen ON Materialrollen.[Mat-Nr] = [Material-Stamm].[Mat-Nr] |
AW: ADOQuery berechnetes Feld
Es kann auch sein, dass die Zusatzbedingungen den Left Join "kaputt machen".
Einfachste Möglichkeit das zu testen, wäre aus der Where Bedingung ein Teil des Joins zu machen. Also 'where' raus und große Klammer ab ..on.. Und nur weil wir grad dabei sind, vielleicht lässt Du Dich ja auch noch von Formatierung überzeugen. |
AW: ADOQuery berechnetes Feld
Hallo jobo,
habe ich geändert, jedoch ohne Veränderung in der Tabelle. Gruß, Luckner |
AW: ADOQuery berechnetes Feld
Was hast Du geändert? Ich habe so 3-4 Vorschläge gemacht.
Und was bedeutet, "ohne Änderung in der Tabelle"? |
AW: ADOQuery berechnetes Feld
Hallo jobo,
Zitat:
Wenn Material aufgebraucht ist, merke ich, wenn alle (Materialrollen.DatumAb <> NULL)ist. Also alle Materialrollen ein Abgangsdatum haben. Andererseits könnte es auch funktionieren, wenn man herausfindet, dass wenn das Produkt aus der Multiplikation = 0 ist. Irgendwas in dieser Richtung. Gruß, Luckner |
AW: ADOQuery berechnetes Feld
Ist jetzt nur geraten.
Sinngemäß in etwa sowas?
SQL-Code:
Die aufgebrauchten Materialien sollten nun in der Spalte "Aufgebraucht" einen entsprechenden Hinweise, bestehend aus den Wörten 'ja' bzw. 'nein', stehen haben.
SELECT
Materialrollen.[Mat-Nr], sum((Materialrollen.[Arb-Breite] / 1000) * Materialrollen.lfm) as BESTAND, [Material-Stamm].Bezeichnung, Aufgebraucht from ( SELECT Materialrollen.[Mat-Nr], Materialrollen.[Arb-Breite], Materialrollen.lfm, [Material-Stamm].Bezeichnung, 'nein' as Aufgebraucht FROM Materialrollen LEFT JOIN [Material-Stamm] ON Materialrollen.[Mat-Nr] = [Material-Stamm].[Mat-Nr] WHERE ( ([Material-Stamm].[Lieferanten-Nr] = ' + Lieferantennr.Text + ') AND ([Material-Stamm].aktuell= -1) AND (Materialrollen.DatumAb is NULL) AND (Materialrollen.[Arb-Breite] > 179) ) UNION ALL SELECT Materialrollen.[Mat-Nr], Materialrollen.[Arb-Breite], Materialrollen.lfm, [Material-Stamm].Bezeichnung, 'ja' as Aufgebraucht FROM Materialrollen LEFT JOIN [Material-Stamm] ON Materialrollen.[Mat-Nr] = [Material-Stamm].[Mat-Nr] WHERE ( ([Material-Stamm].[Lieferanten-Nr] = ' + Lieferantennr.Text + ') AND ([Material-Stamm].aktuell= -1) AND (Materialrollen.DatumAb is not NULL) AND (Materialrollen.[Arb-Breite] > 179) ) ) group by Materialrollen.[Mat-Nr], [Material-Stamm].Bezeichnung Aufgebraucht |
AW: ADOQuery berechnetes Feld
Hallo Delphi.Narium,
:shock: Hut ab von meiner Seite. Ich werde versuchen diese Anweisung zu übertragen und auszuprobieren. Wenn mein Kopf dann etwas freier ist, dann werde ich versuchen diese Anweisung auch zu verstehen. Dieses sprengt meine Grenzen. Vielen Dank für die Mühe. Gruß, Luckner |
AW: ADOQuery berechnetes Feld
Eventuell geht auch dashier, ist kürzer und dürfte resourcen- / laufzeitschonender sein:
SQL-Code:
SELECT
MaterialNr, sum((Arbeitsbreite / 1000) * lfm) as BESTAND, Bezeichnung, Aufgebraucht from ( SELECT Materialrollen.[Mat-Nr] As MaterialNr Materialrollen.[Arb-Breite] As Arbeitsbreite, Materialrollen.lfm, [Material-Stamm].Bezeichnung, case Materialrollen.DatumAb when null then 'nein' else 'ja' end as Aufgebraucht FROM Materialrollen LEFT JOIN [Material-Stamm] ON Materialrollen.[Mat-Nr] = [Material-Stamm].[Mat-Nr] WHERE ( ([Material-Stamm].[Lieferanten-Nr] = ' + Lieferantennr.Text + ') AND ([Material-Stamm].aktuell= -1) AND (Materialrollen.[Arb-Breite] > 179) ) ) group by MaterialNr, Bezeichnung, Aufgebraucht |
AW: ADOQuery berechnetes Feld
Zitat:
Ich fürchte ja wie oben geschrieben, dass outer verkehrt rum läuft. Dazu könnte Luckner einfach mal eine SQL Stichprobe ohne das ganze Drumrum machen. |
AW: ADOQuery berechnetes Feld
Nö, nicht ganz.
Laut der letzten Frage Zitat:
Da in der ursprünglichen Abfrage aber auf Materialrollen.DatumAb IS NULL abgefragt wurde, kann die vermisste Menge ja garnicht im Ergebnis sein. Meine Idee war halt zuerst: Nehmen wird die Abfrage mit dem bisherigen, gewünschten und inzwischen korrekten Teilergebnis und fügen noch mal das "Gegenstück" für den fehlenden Rest hinzu. Geht am Einfachsten erstmal mit Union All. Soweit, so naiv. Die Einschränkung, die für den "Datenverlust" verantworlich zeichnet, einfach rauszunehmen, war dann ein Gedanke, der erst "Minuten später" (der Groschen fällt halt pfennigweise) kam. Lassen wir dem TE jetzt erstmal ein bisserl Zeit zum verdauen. Danach wird er uns (hoffentlich) über den Erfolg / Misserfolg unterrichten ;-) |
AW: ADOQuery berechnetes Feld
Hallo Delphi.Narium,
habe beide Versionen ausprobiert. Die 2. Select-Anweisung liefert ersmal einen unbekannten Fehler. Werde versuchen ihn, mit meinen Kenntnissen, zu korrigieren. Die 1.-te, längere Anweisung liefert folgendes: Material-Nr: / Bezeichnung / Bestand / aufgebraucht 265627 / schreib-weiß, permanent / 1300465,5 / ja 265627 / schreib-weiß, permanent / 5148 / nein usw. für alle anderen Materialrollen. Es sollten nur die Datensätze bleiben die ein "nein" enthalten und nur die, die ein "ja" enthalten, dann aber der Bestand = 0. UNION ALL SELECT Materialrollen.[Mat-Nr], !!!! habe ich korrigiert. Materialrollen.[Mat-Nr], Gruß, Luckner |
AW: ADOQuery berechnetes Feld
Das 2. SQL hab' ich oben überarbeitet.
Zitat:
SQL-Code:
Und ja, das muss auch ohne dieses blöde Union all gehen.
select * from (
SELECT MaterialNr, sum((Arbeitsbreite / 1000) * lfm) as BESTAND, Bezeichnung, Aufgebraucht from ( SELECT Materialrollen.[Mat-Nr] As MaterialNr, Materialrollen.[Arb-Breite] As Arbeitsbreite, Materialrollen.lfm, [Material-Stamm].Bezeichnung, 'nein' as Aufgebraucht FROM Materialrollen LEFT JOIN [Material-Stamm] ON Materialrollen.[Mat-Nr] = [Material-Stamm].[Mat-Nr] WHERE ( ([Material-Stamm].[Lieferanten-Nr] = ' + Lieferantennr.Text + ') AND ([Material-Stamm].aktuell= -1) AND (Materialrollen.DatumAb is NULL) AND (Materialrollen.[Arb-Breite] > 179) ) UNION ALL SELECT Materialrollen.[Mat-Nr], Materialrollen.[Arb-Breite], Materialrollen.lfm, [Material-Stamm].Bezeichnung, 'ja' as Aufgebraucht FROM Materialrollen LEFT JOIN [Material-Stamm] ON Materialrollen.[Mat-Nr] = [Material-Stamm].[Mat-Nr] WHERE ( ([Material-Stamm].[Lieferanten-Nr] = ' + Lieferantennr.Text + ') AND ([Material-Stamm].aktuell= -1) AND (Materialrollen.DatumAb is not NULL) AND (Materialrollen.[Arb-Breite] > 179) ) ) group by MaterialNr, Bezeichnung, Aufgebraucht ) where (Aufgebraucht = 'nein') or (Aufgebraucht = 'ja' and Bestand = 0) Deshalb noch ein Versuch:
SQL-Code:
Wenn das jetzt funktioniert, wird's ja schon fast wieder übersichtlich ;-)
select * from (
SELECT MaterialNr, sum((Arbeitsbreite / 1000) * lfm) as BESTAND, Bezeichnung, Aufgebraucht from ( SELECT Materialrollen.[Mat-Nr] As MaterialNr Materialrollen.[Arb-Breite] As Arbeitsbreite, Materialrollen.lfm, [Material-Stamm].Bezeichnung, case Materialrollen.DatumAb when null then 'nein' else 'ja' end as Aufgebraucht FROM Materialrollen LEFT JOIN [Material-Stamm] ON Materialrollen.[Mat-Nr] = [Material-Stamm].[Mat-Nr] WHERE ( ([Material-Stamm].[Lieferanten-Nr] = ' + Lieferantennr.Text + ') AND ([Material-Stamm].aktuell= -1) AND (Materialrollen.[Arb-Breite] > 179) ) ) group by MaterialNr, Bezeichnung, Aufgebraucht ) where (Aufgebraucht = 'nein') or (Aufgebraucht = 'ja' and Bestand = 0) |
AW: ADOQuery berechnetes Feld
Hallo Delphi.Narium,
habe beide Versionen ausprobiert. Bei Version 2 (ohne UNION) gibt es gleich einen "unbekannten Fehler". Bei der Version 1 sieht erstmal gut aus. Das Produkt aus der Muliplikation stimmt auch. Aber dann! Habe den entsprechenden Materialrollen, die > 179 sind, ein Materialrollen.DatumAb eingetragen und dann wird dieses Material gar nicht mehr in der Tabelle angezeigt. Eigentlich sollte das Material aufgeführt sein mit Bestand = 0 und Aufgebraucht = ja Gruß, Luckner |
AW: ADOQuery berechnetes Feld
Ich hasse diesen "unbekannten Fehler" aus den Mircosoftprodukten, der ist einfach nie hilfreich bei der Fehlersuche :-( ;-)
Die Klammern stimmten irgendwie nicht, mindestens eine schließende war zuviel und mindestens ein Komma fehlte, also noch ein Versuch:
SQL-Code:
select * from (
SELECT MaterialNr, sum(Bestand) as BESTAND, Bezeichnung, Aufgebraucht from ( SELECT Materialrollen.[Mat-Nr] As MaterialNr, Materialrollen.[Arb-Breite] / 1000 * Materialrollen.lfm as Bestand, [Material-Stamm].Bezeichnung As Bezeichnung, case Materialrollen.DatumAb when null then 'nein' else 'ja' end as Aufgebraucht FROM Materialrollen LEFT JOIN [Material-Stamm] ON Materialrollen.[Mat-Nr] = [Material-Stamm].[Mat-Nr] WHERE [Material-Stamm].[Lieferanten-Nr] = ' + Lieferantennr.Text + ' AND [Material-Stamm].aktuell = -1 AND Materialrollen.[Arb-Breite] > 179 ) group by MaterialNr, Bezeichnung, Aufgebraucht ) where (Aufgebraucht = 'nein') or (Aufgebraucht = 'ja' and Bestand = 0) Zitat:
SQL-Code:
. Daraus resultiert:
AND (Materialrollen.DatumAb is NULL)
Zitat:
SQL-Code:
aus dem SQL. Dann sind sie im Ergebnis enthalten, was übrigens dann auch das Union All überflüssig macht.
AND (Materialrollen.DatumAb is NULL)
|
AW: ADOQuery berechnetes Feld
Hier ist ein Klammerfehler bei
sum((Bestand eine reicht. |
AW: ADOQuery berechnetes Feld
Hallo Delphi.Narium, hallo jobo,
die Aufgabenstellung ist folgende: Ein Lieferant liefert "[Material-Stamm].[Lieferanten-Nr]" verschiedene Papiersorten. Das Material (Papiersorten) liegt bei uns als Rollen von verschiedenen Grössen und Breiten auf Lager. Aufgabe: Zeige die markierten Materialien "[Material-Stamm].aktuell = -1" des Lieferanten die eine Breite > 179mm haben, die kein Abgangsdatum "Materialrollen.DatumAb" und berechne die Fläche des Materials. Aufgebraucht = nein. Falls Rollen der geforderten Breite vorhanden dann berechne die Fläche. Falls Materialrollen <= 179, dann braucht es keine Summe (kann aber trotzdem berechnet und angezeigt werden) aber der Hinweis "aufgebraucht = ja" angezeigt werden. Falls keine Rollen vorhanden, dann Fläche = 0 und aufgebraucht = ja. Ich hoffe, ich konnte das Problem jetzt besser beschreiben als meine Select-Anweisungen. Gruß, Luckner |
AW: ADOQuery berechnetes Feld
Zitat:
SQL-Code:
select * from [Material-Stamm] where [Lieferanten-Nr] = :LieferantenNr
Zitat:
SQL-Code:
select * from [Material-Stamm]
where aktuell = -1 and [Lieferanten-Nr] = :LieferantenNr Zitat:
SQL-Code:
select * from [Material-Stamm]
where aktuell = -1 and Lieferanten-Nr] = :LieferantenNr and Breite > 179 Zitat:
SQL-Code:
select *
from [Material-Stamm] s inner join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr] where s.[Lieferanten-Nr] = :LieferantenNr and s.aktuell = -1 and s.Breite > 179 and r.DatumAb is null Zitat:
SQL-Code:
select
r.[Mat-Nr] As MaterialNr, r.[Arb-Breite] / 1000 * r.lfm as Bestand, s.Bezeichnung As Bezeichnung from [Material-Stamm] s inner join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr] where s.[Lieferanten-Nr] = :LieferantenNr and s.aktuell = -1 and s.Breite > 179 and r.DatumAb is null Zitat:
SQL-Code:
select
r.[Mat-Nr] As MaterialNr, r.[Arb-Breite] / 1000 * r.lfm as Bestand, s.Bezeichnung As Bezeichnung, 'nein' as Aufgebraucht from [Material-Stamm] s inner join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr] where s.[Lieferanten-Nr] = :LieferantenNr and s.aktuell = -1 and s.Breite > 179 and r.DatumAb is null Zitat:
SQL-Code:
select
r.[Mat-Nr] As MaterialNr, 0 as Bestand, s.Bezeichnung As Bezeichnung, 'ja' as Aufgebraucht from [Material-Stamm] s inner join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr] where s.[Lieferanten-Nr] = :LieferantenNr and s.aktuell = -1 and s.Breite <= 179 and r.DatumAb is null Zitat:
SQL-Code:
select
r.[Mat-Nr] As MaterialNr, case when r.[Arb-Breite] is null then 0 else r.[Arb-Breite] / 1000 * r.lfm end as Bestand, s.Bezeichnung As Bezeichnung, case when r.[Arb-Breite] is null then 'ja' else 'nein' as Aufgebraucht from [Material-Stamm] s left join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr] where s.[Lieferanten-Nr] = :LieferantenNr and s.aktuell = -1 and s.Breite <= 179 and r.DatumAb is null Zitat:
Eventuell in die Richtung?
SQL-Code:
Nun noch mit dem Versuch der Summierung:
select
r.[Mat-Nr] As MaterialNr, r.[Arb-Breite] / 1000 * r.lfm as Bestand, s.Bezeichnung As Bezeichnung, 'nein' as Aufgebraucht from [Material-Stamm] s inner join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr] where s.[Lieferanten-Nr] = :LieferantenNr and s.aktuell = -1 and s.Breite > 179 and r.DatumAb is null union all select r.[Mat-Nr] As MaterialNr, case when r.[Arb-Breite] is null then 0 else r.[Arb-Breite] / 1000 * r.lfm end as Bestand, s.Bezeichnung As Bezeichnung, case when r.[Arb-Breite] is null then 'ja' else 'nein' as Aufgebraucht from [Material-Stamm] s left join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr] where s.[Lieferanten-Nr] = :LieferantenNr and s.aktuell = -1 and s.Breite <= 179 and r.DatumAb is null
SQL-Code:
Inzwischen hab' ich den Durchblick verloren, keine Ahnung wieviele Denk- und Syntaxfehler ich da eingebaut habe, aber vielleicht ist es ja nicht ganz hoffnungslos ;-)
select
MaterialNr, Sum(Bestand) as Bestand, Bezeichnung, Aufgebraucht from ( select r.[Mat-Nr] As MaterialNr, r.[Arb-Breite] / 1000 * r.lfm as Bestand, s.Bezeichnung As Bezeichnung, 'nein' as Aufgebraucht from [Material-Stamm] s inner join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr] where s.[Lieferanten-Nr] = :LieferantenNr and s.aktuell = -1 and s.Breite > 179 and r.DatumAb is null union all select r.[Mat-Nr] As MaterialNr, case when r.[Arb-Breite] is null then 0 else r.[Arb-Breite] / 1000 * r.lfm end as Bestand, s.Bezeichnung As Bezeichnung, case when r.[Arb-Breite] is null then 'ja' else 'nein' as Aufgebraucht from [Material-Stamm] s left join Materialrollen r on s.[Lieferanten-Nr] = r.[Lieferanten-Nr] where s.[Lieferanten-Nr] = :LieferantenNr and s.aktuell = -1 and s.Breite <= 179 and r.DatumAb is null ) group by MaterialNr, Bezeichnung, Aufgebraucht |
AW: ADOQuery berechnetes Feld
Den Aufwand von DN in Ehren, aber es ist doch ein mühsames Geschäft. Denn es fehlt hier Tabellenstruktur (Create Statement mit Constraints) und weil diese oft nicht genau genug sind, echte Testdaten.
Also mein Vorschlag: Luckner postet Table Create Scripte und Daten (handvoll insert Statements) der betroffenen Daten. Das ergibt für alle Beteiligten (Helfer und TE) ein 100% nachvollziehbares Beispiel und erspart diese Stille Post Nummer. Jeder der es später nachvollziehen will, kann es dann auch wirklich, so wie es im Forum gedacht ist. |
AW: ADOQuery berechnetes Feld
Zitat:
Gruß K-H |
AW: ADOQuery berechnetes Feld
Hallo,
ok, ich werde mal die Strukturen der entsprechenden Tabellen liefern. Meine weitere Überlegung ist, ob man diese Daten nicht in einem Stringrid unterbringen kann. Dann könnte man die Felder dann mit "while-Schleifen" befüllen. Es würde den lokalen Rechner etwas mehr belasten, aber diese Tabelle wird meisten nur einmal die Woche benötigt. Ich muß jedoch erst testen, ob ich ein Stringrid an Fastreport übergeben kann. Schöne Feiertage noch. Gruß, Luckner |
AW: ADOQuery berechnetes Feld
Theoretisch kann man alles als Daten-Quelle für FastReport verwenden.
Man legt ein
Delphi-Quellcode:
an und verdrahtet dort den Zugriff auf die Daten. Das war es schon.
TfrxUserDataSet
Zu der Abfrage selber: Man muss nicht immer die komplette Aufgabe mit einer Abfrage lösen. Man kann sich die Daten auch in Objekte laden und den Rest der Verarbeitung mit diesen Objekte erledigen. Je komplexer die Aufgabe umso einfacher/übersichtlicher wird so eine getrennte Abarbeitung. Und diese Anforderung schreit gerade danach. |
AW: ADOQuery berechnetes Feld
Zitat:
Gruß K-H |
AW: ADOQuery berechnetes Feld
Zitat:
Zitat:
Nimm einfach mal schrittweise meine SQLs von oben, bereinige sie ggfls. von Syntaxfehlern und sag uns dann, bis zu welchem Statement noch alle benötigten Daten im Ergebnis enthalten sind, bzw. was im "bestmöglichen" Ergebnis noch zuviel ist. Dann können wir da, ggfls. mit Hilfe von Testdaten, gezielt aufsetzen und, ggfls. mit 'ner Präzisierung der Aufgabenstellung, weiter nach einer Lösung suchen. Ein (momentan) noch nicht lösbares Problem, lässt sich nicht dadurch lösen, dass man einen anderen Weg geht. Es wird dann nur einen weiteren Weg des Scheiterns geben, das ist nicht zielführend. Zitat:
Zitat:
Zitat:
@Luckner Fordere bitte eine präzise Vorgabe dessen, was der Report enthalten soll und was nicht, ein und lasse dich bitte nicht mit etwas abspeisen, was nicht klar mit ja oder nein zu beantworten ist. Oder anders formuliert: Die Vorgabe muss in einem Entscheidungsbaum abzubilden sein, es darf dort keine Stelle geben, an der ein weitere Verlauf über unterschiedliche Wege möglich ist. |
AW: ADOQuery berechnetes Feld
Zitat:
in halbwegs logische Anforderungen zu überführen. Und ich habe nie herausbekommen ob Dummheit, Ignoranz oder was auch immer der Grund für diese WischiWaschi-Anforderungen war. Gruß K-H |
AW: ADOQuery berechnetes Feld
Zitat:
Oft hat es geholfen so penetrant nachzufragen, dass der Aufwand, eine präzise Vorgabe zu machen geringer war, als sich immer und immer wieder um die Beantwortung der Fragen der "blöden" Programmierer kümmern zu müssen. Es ist ja nix dagegen einzuwenden, wenn man aus dem Chaos etwas macht, was dann logisch klingt und umsetzbar zu sein scheint. Aber damit bin ich dann immer zur anfordernden Person gegangen und habe gefragt: "Willst Du das?" Und habe sie dann darauf festgenagelt mit ja oder nein zu antworten oder eben die Anforderung zu präzisieren. Meist klappte das, wenn auch selten beim ersten Versuch. |
AW: ADOQuery berechnetes Feld
Zitat:
Gruß K-H |
AW: ADOQuery berechnetes Feld
Hallo,
also ich versuche es jetzt mein Problem verständlich zu machen. Die Tabellen der Datenbank sind in MS-Access. Die Hauptanwendung ebenfalls. Die zusätzliche Tools in Delphi. Als Zugriff auf die Datenbank benutze ich ADOQuery. In diesem Fall werden 3 Tabellen angesprochen. 1. [Lieferanten-Stamm], mit [Lieferanten-Stamm].LieferantNr und [Lieferanten-Stamm].LieferantName 2. [Material-Stamm], mit den Feldern: [Material-Stamm].[Mat-Nr], [Material-Stamm].Bezeichnung, [Material-Stamm].[Lieferant-Nr], [Material-Stamm].aktuell.(Wenn [Material-Stamm].aktuell = -1 dann Materialmenge muss beobachtet werden). 3. Materialrollen, mit den Feldern: Materialrollen.[Mat-Nr], Materialrollen.Nr (Rollennummer), Materialrollen.[Arb-Breite] (nur wichtig, wenn > 179mm) , Materialrollen.lfm(wichtig wenn lfm = 0) , Materialrollen.DatumAb, usw. Aufgabe: Suche alle Materialrollen eines Lieferanten (das selectiere ich mir schon vorab und bekommen entsprechend: TEditLieferantNr.Text := [Lieferanten-Stamm].LieferantNr. Bis dahin kein Problem. dann nur noch Select über 2 Tabellen. Aufgabe: Suche alle Materialrollen von [Material-Stamm].[Lieferant-Nr] = TEditLieferantNr.Text, dessen [Material-Stamm].aktuell = -1, weil nur dieses Material interessant ist. Hier werden die [Material-Stamm].[Mat-Nr] selectiert. Suche alle Materialrollen.Nr zu dieser Materialrollen.[Mat-Nr] = [Material-Stamm].[Mat-Nr], die eine Materialrollen.[Arb-Breite] > 179 mm haben und Materialrollen.DatumAb = NULL ist. (nur dann sind ensprechende Materialrollen auf Lager. Aus allen Rollen des Materials, die selectiert wurden, berechne die qm (BESTAND). Wenn Materialrollen.[Arb-Breite] <= 179 mm haben und Materialrollen.DatumAb = NULL ist, solche Rollen sollen nicht berücksichtigt. Dieses Material muss ebenfalls in der Tabelle angezeigt werden mit BESTAND = 0. Ebenfalls wenn es keine Rollen mit Materialrollen.DatumAb = NULL gibt, dann muß das Material ebenfalls in der Tabelle aufgelistet sein mit BESTAND = 0; Natürlich haben diese Tabellen noch andere Felder, die spielen hier jedoch keine Rolle. Der Sinn des Ganzen ist, dass man bestimmte Materialsorten eines Lieferanten im Auge behält und rechzeitig bestellt, weil der Lieferant möglicherweise nicht innerhalb einer bestimmten Frist liefern kann und entsprechend auch anderes Material des Lieferanten gleich mitbestellt, falls deren Mengen zu gering erscheinen. Ich hoffe, jetzt ist es verständlich, ansonsten liefere ich weitere Antworten. Gruß, Luckner |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:21 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