Hallo liebe Experten dieses Forums.
Ich habe mal wieder keinen Plan und weiß nicht weiter.
Ich möchte gern einen Umsatzvergleich haben, der wie folgt definiert ist.
Zeige mir alle DS mit Datum von 1.1.2015 bis heute und alle DS mit Datum 1.1.2014 bis Heute vor einem Jahr.
Also einen Zeitabschnitt des laufenden Jahres mit exakt dem Zeitraum vor einem Jahr.
Ich habe mir das Datumsfeld "Erstellt" als serielle Zahl umgewandelt.
Jetzt habe ich 2 Spalten mit der seriellen Zahl.
"Erstellt" und "Heute"...
Wenn ich in den Kriterien z.B. das eingebe, was im Bild zu sehen ist,
bekomme ich auch das gefiltert.
Aber ich weiß nicht wie ich das eingeben muss, damit ich einen Vergleich zwischen den beiden Jahresabschnitten sehen kann.
Kann mir da jemand ein wenig weiterhelfen?
Danke
Gruß Achim
(http://www.bilder-upload.eu/thumb/92bf1d-1436900941.jpg) (http://www.bilder-upload.eu/show.php?file=92bf1d-1436900941.jpg)
Hi,
was genau willst du denn miteinander vergleichen?
Könnte folgende Abfrage evtl. dein Ziel sein:
Select KNR, Kunde, Artikel,
IIF(Year(Erstellt) = Year(Date()) -1, Umsatz, NULL) As Umsatz_Vorjahr,
IIF(Year(Erstellt) = Year(Date()), Umsatz, NULL) As Umsatz_aktJahr
From Werkzeug_Artikel
Where Erstellt Between DateSerial(Year(Date())-1,1,1) AND DateSerial(Year(Date())-1,30,6) OR Erstellt Between DateSerial(Year(Date()),1,1) AND DateSerial(Year(Date()),30,6)
BTW:
Bei Abfragen bitte stets den SQL-Code zeigen.
Das ist alles so kompliziert. Und von SQL habe ich überhaupt keine Ahnung.
Was will ich haben......Hmmm...tja...
Ich habe einen Kundenumsatz 2015 als Summe bis zum heutigen Tage.
Wenn ich einen prozentualen Vergleich haben will zum Vorjahr,
dann darf ich auch nur den Umsatz 1.1.2014 bis heutiges Datum des letzten Jahres nehmen.
Ich habe eine Kreuztabelle erstellt, die mir die Jahresumsätze des Kunden von 2004 bis 2015 zeigt. Das sieht so aus.
TRANSFORM Sum(Qry_Werkzeug_Artikel.Umsatz) AS SummevonUmsatz
SELECT Qry_Werkzeug_Artikel.KNR, Kunden.PLZ, Kunden.Ort, Kunden.Kunde
FROM Kunden INNER JOIN Qry_Werkzeug_Artikel ON Kunden.KNR = Qry_Werkzeug_Artikel.KNR
GROUP BY Qry_Werkzeug_Artikel.KNR, Kunden.PLZ, Kunden.Ort, Kunden.Kunde
PIVOT Qry_Werkzeug_Artikel.Jahr;
In dieser Kreuztabelle kann ich das Feld ERSTELLT nicht mit einbringen,
weil ja schon das Feld JAHR als Spaltenüberschrift existiert.
Jetzt dachte ich, mit Hilfe einer Abfrage diesen Vergleichszeitraum als Bedingung zum Filtern zu nehmen.
ZitatUnd von SQL habe ich überhaupt keine Ahnung.
Ist das für Dich Programm oder nur eine momentane Zustandsbeschreibung?
Für den zweiten Fall kannst Du weiterlesen.
ZitatIch habe mir das Datumsfeld "Erstellt" als serielle Zahl umgewandelt.
Warum? Auch so ist ein DateTime-Wert vorrangig (intern) eine Zahl, also ein Wert, mit dem man mathematisch rechnen könnte.
Idee: In Deiner Kreuztabelle verwendest Du alle Jahre. Die könnte man auch beim gewünschten Zeitraumvergleich einsetzen, ansonsten filtert man die überflüssigen Jahre weg.
Man verwendet eine (zusätzliche) Jahrestabelle mit den relevanten Jahren. Man könnte diese auch per Abfrage erzeugen:
SELECT DISTINCT Year(Erstellt) FROM Werkzeug_ArtikelDiese ermöglicht dann folgenden Ansatz:
SELECT
T.KNr,
T.Umsatz,
Year(T.Erstellt) AS Jahr
FROM
Werkzeug_Artikel AS T,
Jahrestabelle AS J
WHERE
T.Erstellt BETWEEN DateSerial(J.Jahr, 1, 1)
AND
DateSerial(J.Jahr, Month(Date()), Day(Date()))
Ich habe es auf anderem Wege versucht zu lösen.
So wie es jetzt ist, funktioniert es.
Und dabei ergibt sich eine andere kleine Problematik.
Das hier steht in der Abfrage in den Kriterien:
>=ZLong(#01.01.2014#) Und <=(ZLong(#01.01.2014#)+DatDiff("d";#01.01.2015#;Jetzt()))
Jetzt brauche ich nur noch das JETZT() gegen den Wert der in der Tabelle steht zu tauschen. Ich habe das JETZT() mit Hilfe des Ausdrucksgenerators gegen den Feldnamen getauscht. Und in der Tabelle Berechnungs_Werte steht im Feld fld_Datum der Wert 30.06.2015.
>=ZLong(#01.01.2014#) Und <=(ZLong(#01.01.2014#)+DatDiff("d";#01.01.2015#;[Berechnungs_Werte]![fld_Datum]))
Das sähe dann so aus, funktioniert aber nicht. Denn beim Start der Abfrage will wird jetzt eine Eingabe für das Feld gefordert.
Das verstehe ich nicht. In dem Feld steht doch das Datum drin.
Ich möchte doch nur das JETZT() gegen den Datumswert des Feldes fld_Datum ersetzen.
Was muss ich da ändern?
Gruß Achim
Hi,
zeige bitte den SQL-Code der Abfrage.
SELECT CLng([Erstellt]) AS ErstelltZahl, Werkzeug_Artikel.Erstellt, Werkzeug_Artikel.Umsatz, Werkzeug_Artikel.KNR, Werkzeug_Artikel.Kunde, Werkzeug_Artikel.Artikel, Werkzeug_Artikel.Jahr
FROM Werkzeug_Artikel
WHERE (((CLng([Erstellt]))>=CLng(#1/1/2014#) And (CLng([Erstellt]))<=(CLng(#1/1/2014#)+DateDiff("d",#1/1/2015#,Now())))) OR (((Werkzeug_Artikel.Erstellt) Like "*2015"))
ORDER BY Werkzeug_Artikel.Erstellt;
Gruß Achim
Hi,
die Tabelle "Berechnungs_Werte" kommt in der Abfrage aber doch gar nicht vor.
In welcher Beziehung steht sie zur Tabelle "Werkzeug_Artikel"?
Wenn ich zur Tabelle Werkzeug_Artikel noch die Tabelle Berechnungs_Werte hinzufüge,
gibt es eine Beziehung der ID, mehr nicht.
Starte ich nun die Abfrage, kommt es nicht mehr zur Eingabeaufforderung, aber es kommt auch kein Ergebnis mehr.
Das bedeutet wohl, dass die Abfrage das Feld mit dem Inhalt 30.06.2015 nicht wahrnimmt.
Hier der Code:
SELECT CLng([Erstellt]) AS ErstelltZahl, Werkzeug_Artikel.Erstellt, Werkzeug_Artikel.Umsatz, Werkzeug_Artikel.KNR, Werkzeug_Artikel.Kunde, Werkzeug_Artikel.Artikel, Werkzeug_Artikel.Jahr
FROM Werkzeug_Artikel INNER JOIN Berechnungs_Werte ON Werkzeug_Artikel.ID = Berechnungs_Werte.ID
WHERE (((CLng([Erstellt]))>=CLng(#1/1/2014#) And (CLng([Erstellt]))<=(CLng(#1/1/2014#)+DateDiff("d",#1/1/2015#,[Berechnungs_Werte]![fld_Datum])))) OR (((Werkzeug_Artikel.Erstellt) Like "*2015"))
ORDER BY Werkzeug_Artikel.Erstellt;
Hi,
Zitatgibt es eine Beziehung der ID
macht das denn auch Sinn?? Was haben die IDs der Tabellen miteinander zu tun?
Gibt es keine Referenz von Werkzeug_Artikel zu Berechnungs_Werte oder umgekehrt?
Ich habe in der Entwurfsansicht "Tabelle hinzufügen" die Tabelle Berechnungs_Werte hinzugefügt.
Automatisch erscheint nun die Beziehungslinie zwischen den beiden Tabellen.
Fett hervorgehoben ist in beiden Tabellen das ID und als Option ist Punkt 1 ausgewählt.
Warum die beiden IDs miteinander verknüpft sich, kann ich nicht sagen.
Ich habe die nicht gesetzt.
Naja, wenn das nicht geht, kann ich ja auch statt des JETZT() eine Variable nehmen und als Input immer das von mir gewünschte Datum eingeben.
Wäre auch ne Möglichkeit. Vielleicht sogar noch besser.
ZitatAutomatisch erscheint nun die Beziehungslinie zwischen den beiden Tabellen.
das passiert automatisch sobald Access indizierte Datenfelder gleichen Namens findet. Es ist also unbedingt zu vermeiden, in allen Tabellen einen Key namens ID zu haben.
Davon abgesehen sollten die Tabellenbeziehungen über das Beziehungsfenster eingepflegt werden.
Meine sonstigen Fragen hast du damit aber leider nicht beantwortet.
Wenn es sich um diese Frage handelt,
Zitat
Gibt es keine Referenz von Werkzeug_Artikel zu Berechnungs_Werte oder umgekehrt?
dann kann ich die nicht beantworten, weil ich die nicht verstehe.
Alles Mist. Muss nochmal ganz von vorne anfangen. Habe gerade gemerkt, dass das, was ich hier gebastelt habe, doch nicht funktioniert.
Das ist meine Kreuztabelle
TRANSFORM Sum(qry_Werkzeug_Artikel.Umsatz) AS SummevonUmsatz
SELECT qry_Werkzeug_Artikel.KNR, Kunden.PLZ, Kunden.Ort, qry_Werkzeug_Artikel.Kunde
FROM qry_Werkzeug_Artikel INNER JOIN Kunden ON qry_Werkzeug_Artikel.KNR = Kunden.KNR
GROUP BY qry_Werkzeug_Artikel.KNR, Kunden.PLZ, Kunden.Ort, qry_Werkzeug_Artikel.Kunde
ORDER BY qry_Werkzeug_Artikel.Kunde
PIVOT qry_Werkzeug_Artikel.Jahr;
Und das hier ist die Abfrage mit dem Filterkriterium:
SELECT CLng([Erstellt]) AS ErstelltZahl, Werkzeug_Artikel.Erstellt, Werkzeug_Artikel.Umsatz, Werkzeug_Artikel.KNR, Werkzeug_Artikel.Kunde, Werkzeug_Artikel.Artikel, Werkzeug_Artikel.Jahr
FROM Werkzeug_Artikel
WHERE (((CLng([Erstellt]))>=CLng(#1/1/2014#) And (CLng([Erstellt]))<=(CLng(#1/1/2014#)+DateDiff("d",#1/1/2015#,#4/30/2015#)))) OR (((Werkzeug_Artikel.Erstellt) Like "*2015"))
ORDER BY Werkzeug_Artikel.Erstellt;
Jetzt habe ich mal statt dem JETZT() ein festes Datum eingegeben; und zwar den 30.04.2015.
Die Ergebnisse sind jetzt alle DS von Januar 2014 bis April 2014. das wäre richtig. Aber eigentlich sollten jetzt in der Spalte daneben die DS Januar 2015 bis April 2015 stehen, um dann meinen Prozentualen Vergleich zu berechnen.
Aber es sind immer alle DS des Jahres 2015 drin.
Und das wäre falsch für meine Berechnung in Prozent.
Das wäre dann nämlich der Umsatz des Kunden von Januar 2014 bis April 2014 in prozentualer Differenz zu Januar 2015 bis Juli 2015.
Ich habe mal ins Modul eine Function eingegeben und den Input Wert der Variablen DatVar dann zu übergeben, aber das geht auch nicht.
Public Function DatVar() 'Variable für Datumsvorgabe zur Berechnung der Umsatzvergleiche
Dim Datum_Bis As Date
DatVar = InputBox("Bitte das Datum (tt.m.jj) eingeben")
End Function
Das Ziel wäre sowieso, dass ich mein Formular starte, das als Datenherkunft die Kreuztabelle hat und die Inputbox mich nach dem Datum fragt.
Hi,
kannst du eine Beispiel-DB mit Testdaten hochladen? Dann wäre es sicher leichter eine Lösung zu finden.
Ich habe es gelöst, also meine Vorstellung des Umsatzvergleich geht damit.
Wie kann ich über eine Inputabfrage das
SELECT Werkzeug_Artikel.Erstellt, CLng([Erstellt]) AS ErstelltZahl, Werkzeug_Artikel.Umsatz, Werkzeug_Artikel.KNR, Werkzeug_Artikel.Kunde, Werkzeug_Artikel.Artikel, Werkzeug_Artikel.Jahr
FROM Werkzeug_Artikel
WHERE (((CLng([Erstellt]))>=CLng(#1/1/2014#) And (CLng([Erstellt]))<=CLng(#1/31/2014#))) OR (((CLng([Erstellt]))>=CLng(#1/1/2015#) And (CLng([Erstellt]))<=CLng(#1/31/2015#)))
ORDER BY Werkzeug_Artikel.Erstellt;
hintere Datum (31.01.2014 und 31.01.2015) der Abfrage übergeben? Es ist fast eine Art VON ....BIS.
Wenn ich da eine Funktionsvariable einbaue, bekomme ich immer den Hinweis, dass das kein Datum ist.
Hallo,
ZitatEs ist fast eine Art VON ....BIS.
wieso "fast" und warum willst du nur das Endedatum variabel halten?
ZitatWenn ich da eine Funktionsvariable einbaue, bekomme ich immer den Hinweis, dass das kein Datum ist.
Dann zeige, wie du das machst, inkl. des dazu eingesetzten Funktions-Code.
Ich habe die VBA Function wieder gelöscht. Finde die auch nicht mehr.
War ja auch nur ne Inputbox, die das gewünschte Datum abfragt.
SELECT Werkzeug_Artikel.Erstellt, CLng([Erstellt]) AS ErstelltZahl, Werkzeug_Artikel.Umsatz, Werkzeug_Artikel.KNR, Werkzeug_Artikel.Kunde, Werkzeug_Artikel.Artikel, Werkzeug_Artikel.Jahr
FROM Werkzeug_Artikel
WHERE (((CLng([Erstellt]))>=CLng(#1/1/2014#) And (CLng([Erstellt]))<=CLng(#2/15/2014#))) OR (((CLng([Erstellt]))>=CLng(#1/1/2015#) And (CLng([Erstellt]))<=CLng(#2/15/2015#)))
ORDER BY Werkzeug_Artikel.Erstellt;
TRANSFORM Sum(qry_Werkzeug_Artikel.Umsatz) AS SummevonUmsatz
SELECT qry_Werkzeug_Artikel.KNR, Kunden.PLZ, Kunden.Ort, qry_Werkzeug_Artikel.Kunde
FROM qry_Werkzeug_Artikel INNER JOIN Kunden ON qry_Werkzeug_Artikel.KNR = Kunden.KNR
GROUP BY qry_Werkzeug_Artikel.KNR, Kunden.PLZ, Kunden.Ort, qry_Werkzeug_Artikel.Kunde
ORDER BY qry_Werkzeug_Artikel.Kunde
PIVOT qry_Werkzeug_Artikel.Jahr;
Ich hatte mal versucht über das DatDiff die Anzahl der Tage vom 1.1. bis zum gewünschten Datum zu nehmen. Dann das Jahr minus 1 als Vergleich zum anderen Jahr mit der selben Anzahl Tage...Aber das ging auch nicht.
Ich versuche es nochmal etwas verständlicher zu bringen.
Die obere Abfrage dient als Filter, bzw. als Bedingung für die Ausgabe der Kreuztabellenabfrage.
So wie es jetzt im SQL Code zu sehen ist, funktioniert es.
Ich gehe in die obere Abfrage, Entwurfsansicht, ändere das Datum (oben aktuell drin 15.02. 2014 zu 2015) und bekomme einen neuen Vergleich in der Kreuztabelle.
Das ist natürlich ganz schön umständlich.
Daher wollte ich beim Start meines Formulars, dass dann als Datenherkunft diese Abfragen hat, eine Inputbox starten, die mir das gewünschte Datum vorgibt.
Annahme die Inputbox geht auf, ich gebe dann z.B. 31.05.2015 ein.
Jetzt steht in der unteren Bedingung der Kriterien das 31.05.2015 drin,
und automatisch in den Kriterien der Abfrage wird der obere Wert auf 31.05.2014 gesetzt.
Also eigentlich der eingegebene Inputwert minus 1 Jahr.
Hi,
du kannst hierzu doch eine ganz normale Parameterabfrage einsetzen, in der du Datum-von und Datum-bis eingibst und für die zweite Auswahl davon jeweils ein Jahr abziehst.
Besipiel:
SELECT Werkzeug_Artikel.Erstellt, CLng([Erstellt]) AS ErstelltZahl, Werkzeug_Artikel.Umsatz, Werkzeug_Artikel.KNR, Werkzeug_Artikel.Kunde, Werkzeug_Artikel.Artikel, Werkzeug_Artikel.Jahr
FROM Werkzeug_Artikel
WHERE (
(CLng([Erstellt])>=CLng(DateValue([Datum von:])) And
CLng([Erstellt])<=CLng(DateValue([Datum bis:]))
) OR (
(CLng([Erstellt])>=CLng(DateAdd("y",-1, DateValue([Datum von:]))) And
CLng([Erstellt])<=CLng(DateAdd("y",-1, DateValue([Datum bis:])))
)
ORDER BY Werkzeug_Artikel.Erstellt;
Bzgl. Parameter in Verbindung mit Kreuztabellenabfragen beachte bitte donkarls FAQ 3.18 (http://www.donkarl.com/faq/FAQ3Tabfragen.htm#3.18).
Ich bekomme ständig die Fehlermeldung Syntaxfehler....Fehlender Operator im Ausdruck.
Ich weiß gar nicht, welcher da fehlen soll.
DateAdd hat als Syntax (Intervall, Zeit, Datum). Und das scheint mir doch gegeben.
Oder ist das "-1" das Problem?
Hat das bei dir funktioniert?
Nebenbei gefragt:
WHERE CLng(Erstellt)>=CLng(#1/1/2014#)
Das Vollstopfen von Vergleichen mit Funktionen findet hier im Thread inflationär statt. Wofür ist das gut und wo lernt man das?
Ich persönlich empfinde bei diesem Anblick da schon so etwas wie körperlichen Schmerz:
- Eine Indexnutzung wird ausgeschlossen. In einer Datenbank (potentiell große Datenmengen) ist das ungeschickt bis "strafbar" und sollte daher auf die Fälle beschränkt werden, wo solches auf Grund der Gestaltung nicht vermeidbar ist.
- Funktionen ausführen bedeutet auch Aufwand, bei datensatzweiser Wiederholung um so mehr. Unnützer Aufwand beeinflusst auch Performance.
Daher: Welchen besonderen Grund gibt es?
Hi,
was den Syntaxfehler betrifft, so gibt es zu viele Klammern.
Nimm die öffnenden Klammern vor CLng jeweils weg.
Was die Funktionen betrifft, so ist der Einsatz von CLng und DateValue in diesem Zusammenhang komplett überflüssig.
SELECT Werkzeug_Artikel.Erstellt, ([Erstellt]) AS ErstelltZahl, Werkzeug_Artikel.KNR, Werkzeug_Artikel.Kunde, Werkzeug_Artikel.Artikel, Werkzeug_Artikel.Jahr
FROM Werkzeug_Artikel
WHERE (((([Erstellt]))>=DateValue(#1/1/2015#) And (([Erstellt]))<=(DateValue([Datumsbereich für das aktuelle Jahr:])))) OR (((([Erstellt]))>=DateValue(#1/1/2014#) And (([Erstellt]))<=(DateValue([Datumsbereich für das letzte Jahr:]))))
ORDER BY Werkzeug_Artikel.Erstellt;
Das ist nun die aktuelle Variante, die auch funktioniert.
Ich gebe z.B. 15.5.15...ENTER....und dann 15.5.14 ein.
Ist nicht komfortabel, aber ich bekomme meine gewünschte Lösung eines prozentualen Vergleichs.
Geil wäre es, wenn sich die Abfrage öffnet, die Datumsfrage stellt und das HEUTIGE Datum bereits als Vorschlag da stehen würde.
Dann drücke ich nur Enter und gebe bei der 2. Eingabe das Datum minus 1 Jahr ein.
Aber wie man einbauen kann, weiß ich wirklich nicht.
Wenn du das heutige Datum haben willst, warum setzt du es nicht direkt in der Abfrage ein?
Und die zweite Eingabe ist komplett überflüssig, da sich das Datum aus dem ersten berechnen lässt.
Die dazu benötigten "Bausteine" wurden doch alle bereits gezeigt, warum denkst du dir immer wieder etwas Neues aus?
Das heutige Datum als Vorschlag lässt sich nur mit einer Input-Box lösen, bzw. mit einem Funktionsaufruf:
WHERE ([Erstellt]>=DateValue(#1/1/2015#) And [Erstellt]<=get_DatumBis())
Public Function getDatumBis()
get_DatumBis = Format(InputBox("Datum bis eingeben:", Date()), "\#yyyy\/mm\/dd\#")
End Function
Aber auch das von-Datum solltest du variabel halten, oder willst du die Abfrage ständig ändern?
Ich habe alles wieder auf ein festes Datum gesetzt.
Wenn ich es anders haben will, gehe ich die Abfrage und ändere einfach das Datum.
SELECT Werkzeug_Artikel.Erstellt, CLng([Erstellt]) AS ErstelltZahl, Werkzeug_Artikel.Umsatz, Werkzeug_Artikel.KNR, Werkzeug_Artikel.Kunde, Werkzeug_Artikel.Artikel, Werkzeug_Artikel.Jahr
FROM Werkzeug_Artikel
WHERE (((CLng([Erstellt]))>=CLng(#1/1/2014#) And (CLng([Erstellt]))<=CLng(#3/31/2014#))) OR (((CLng([Erstellt]))>=CLng(#1/1/2015#) And (CLng([Erstellt]))<=CLng(#3/31/2015#)))
ORDER BY Werkzeug_Artikel.Erstellt;
Wenn ich nämlich das Formular starte bekomme ich die Meldung,
dass die Feldnamen nicht erkannt werden von diesem Join.
Und die Kreuztabellenabfrage kann ich im Entwurf nicht öffnen.
Da komme ich wegen der Fehlermeldung nicht mehr rein.
Ist nicht weiter tragisch. Diesen prozentualen Vergleich schaue ich mir doch nur ganz selten an. Geht doch so auch.
Danke trotzdem für die Hilfe.....
Es ist alles lösbar... man muss nur sämtliche Details kennen, die dabei eine Rolle spielen.
Zitatdass die Feldnamen nicht erkannt werden von diesem Join.
Wie lautet die konkrete Fehlermeldung und wie sieht der Code (deine Version!) dazu aus?
Eine vermutlich einfacher umzusetzende Lösung wäre, die Datumsangaben per Formular einzutragen und in den Kriterien der Abfrage auf diese zuzugreifen.