Hallo.
Ich habe eine Tabelle mit Aufträgen. In jeder Zeile steht ein Abgabedatum für den jeweiligen Prozess. Dieses Datum lasse ich mit den Format ww als KW ausgeben.
Jetzt möchte ich eine Abfrage, wieviele Aufträge ich pro KW habe.
Anschließend möchte ich in meinen Formular "Auftragseingabe" eine Tabelle sehen können, die mir anzeigt, wieviele Aufträge ich pro KW habe.
Hat jemand eine Idee?
Gruß
Marco
Hallo Marco,
ZitatDieses Datum lasse ich mit den Format ww als KW ausgeben.
Format dient nur der Anzeige, damit kannst Du nicht "rechnen".
Füge in die Abfrage ein berechnetes Feld ein, dass dir die KW berechnet *).
Dieses Feld kannst Du anschliessend zum Filtern verwenden.
gruss ekkehard
*) z.B. (gibt imNetz auch noch andere Lösungen)
Public Function KWausDatum( _
ByVal XDatum As Date) As Integer
'---------------------------------------------------------------------------------
' Purpose : Gibt die Kalenderwoche des Datum als Zahl zurück.
' Wenn eine Wochennummer in ein unterschiedliches Jahr fällt,
' so wird dies berücksichtigt; d.h. 31.12.2002 = 01\2003
' bzw. 1.1.1999 = 53\1998
'---------------------------------------------------------------------------------
Dim X As Integer
Dim y As Integer
Dim z As Integer
KWausDatum = 0
If Not IsDate(XDatum) Then XDatum = Date
XDatum = CDate(XDatum)
X = Year(XDatum)
y = Month(XDatum)
z = Format(XDatum, "ww", vbMonday, vbFirstFourDays)
If y = 12 And z < 40 Then X = X + 1
If y = 1 And z > 10 Then X = X - 1
KWausDatum = Val(Right("00" & z, 2))
Ende_CleanUp:
On Error Resume Next
Exit Function
Fehler:
'nach Belieben
End Function
Mit Verlaub Ekkehard, die gezeigte Funktion ist Humbug. XDatum kann nie Null sein. x und y fließen nirgends in's Ergebnis ein. Die Format-Funktion weist Fehler beim bestimmen der Wochennummer auf. Außerdem würde ich für Funktionen, die in SQL verwendet werden können, i.d.R. Variant-Argumente wählen, um mögliche Null-Werte nicht casten zu müssen.
Hier wären zwei Alternativen (jeweils mit Hilfsfunktionen, die Jahr und Wochennummer isolieren), die gleiches Laufzeitverhalten aufweisen: Version 1 ist vom englisch-sprachigen Wikipedia-Artikel abgeleitet und gibt Jahr und Wochennummer in einem Array aus (Anpassung gemäß Version 2 ließe sich auch realisieren); Version 2 gibt Jahr multipliziert mit 100 plus Wochennummer zurück.
Version 1:'Gibt Jahr und Wochennummer in einem Variant Array zurück
Public Function GetISO8601YearAndWeek(ByVal aDate)
Dim yr As Integer 'Jahr
Dim dow As Integer 'Wochentag
Dim doy As Integer 'Tag des Jahres
Dim week As Integer 'Wochennummer
Dim is_leap As Boolean 'Schaltjahr
Dim jan1st As Date '1. Januar des Jahres
Dim thursday As Date 'Donnerstag der Woche
If Not IsDate(aDate) Then
GetISO8601YearAndWeek = Array(Null, Null)
Exit Function
End If
yr = Year(aDate)
dow = Weekday(aDate)
doy = aDate - DateSerial(Year(aDate), 1, 0)
'Nach MSDN ist dow für Sonntag 0, nach ISO8601 sollte Sonntag 7 sein
If (dow = 0) Then dow = 7
'Diese Berechnung ergibt nach
'http://en.wikipedia.org/wiki/ISO_week_date#Calculation die Wochennummer
week = Int((doy - dow + 10) / 7)
'Wenn die Woche 0 oder 53 ist, müssen wir einige Schecks machen
If (week = 0) Then
'Wenn wir week=0 erhalten, liegt die Woche noch im letzten Jahr
yr = yr - 1
'Ein Jahr hat nur dann 53 Wochen, wenn es mit einem Donnerstag beginnt
'oder ein Schaltjahr ist und mit Mittwoch startet
jan1st = DateSerial(yr, 1, 1)
is_leap = ((yr Mod 4 = 0) And (yr Mod 100 <> 0)) Or (yr Mod 400 = 0)
If ((Weekday(jan1st) = vbThursday) Or _
((Weekday(jan1st) = vbWednesday) And (is_leap))) Then
week = 53
Else
week = 52
End If
ElseIf (week = 53) Then
'Ermittle, ob der Donnerstag der Woche in dem selben Jahr liegt.
'Falls nicht, dann liegt die Woche auch im nächsten Jahr
thursday = aDate + 4 - dow
If (Year(thursday) > yr) Then
GetISO8601YearAndWeek = Array(yr + 1, 1)
Exit Function
End If
End If
GetISO8601YearAndWeek = Array(yr, week)
End Function
'Gibt des Jahr der ISO8601-Woche von aDate zurück
Public Function GetISO8601Year(ByVal aDate)
GetISO8601Year = GetISO8601YearAndWeek(aDate)(0)
End Function
'Gibt die Wochennummer nach ISO8601von aDate zurück
Public Function GetISO8601Week(ByVal aDate)
GetISO8601Week = GetISO8601YearAndWeek(aDate)(1)
End Function
Version 2:'Gibt Jahr * 100 + Wochennummer nach ISO8601 zurück
Public Function ISO8601YearWeek(ByVal aDate)
Dim week As Integer
Dim FirstThursday As Date
If Not IsDate(aDate) Then
ISO8601YearWeek = Null
Exit Function
End If
FirstThursday = DateSerial(Year(aDate - Weekday(aDate - 1) + 4), 1, 3)
week = Int((aDate - FirstThursday + Weekday(FirstThursday) + 5) / 7)
If Month(aDate) = 12 And week = 1 Then
ISO8601YearWeek = (Year(aDate) + 1) * 100 + week
ElseIf Weekday(aDate) > vbSunday And Weekday(aDate) < vbThursday Then
ISO8601YearWeek = Year(aDate) * 100 + week
Else
ISO8601YearWeek = Year(FirstThursday) * 100 + week
End If
End Function
Public Function ISO8601Year(ByVal aDate)
If Not IsDate(aDate) Then
ISO8601Year = Null
Exit Function
End If
ISO8601Year = ISO8601YearWeek(aDate) \ 100
End Function
Public Function ISO8601Week(ByVal aDate)
If Not IsDate(aDate) Then
ISO8601Week = Null
Exit Function
End If
ISO8601Week = ISO8601YearWeek(aDate) Mod 100
End Function
@ekkehard: Leider noch zweite Korrektur.
ZitatDieses Datum lasse ich mit den Format ww als KW ausgeben.
=> Die Format-Eigenschaft erzeugt nur eine Anzeige, intern bleibt das Datum ein Datum.
=> Die Format-Funktion erzeugt einen neuen Wert als String.
Mit beiden kann man rechnen, nur ergeben sich wegen des unterschiedlichen Datentyps und des unterschiedlichen Inhaltes sehr unterschiedliche Wirkungen.
ZitatJetzt möchte ich eine Abfrage, wieviele Aufträge ich pro KW habe.
SELECT
KW_And_Year(Datum) AS AnyWeek,
COUNT(*) AS AnzahlAuftraege
FROM
EineTabelle
GROUP BY
KW_And_Year(Datum)Die Funktion zur Berechnung der Kalenderwoche (Jahr nicht vergessen wegen Jahreswechseln) kann man beliebig einsetzen, auch eine falsche Kalenderwoche würde hier richtig gruppiert.
Zum Laufzeitverhalten: Hier wird über die Kalenderwoche gruppiert. Da ist es günstiger, wenn über eine (Ganz)Zahl gruppiert würde statt über einem Text. Noch etwas günstiger wird es, wenn man eine gut geplante Kalendertabelle einbezieht, die neben dem Datum (Primärschlüssel) die gespeicherte Berechnung der KW (indiziert) enthält. Dazu gibt es hier eine Betrachtung: Grundlagen - SQL ist leicht (3) - Kalendertabelle (http://www.ms-office-forum.net/forum/showthread.php?t=298670)
Hallo,
@Lachtaube
ZitatMit Verlaub Ekkehard, die gezeigte Funktion ist Humbug.
Tja, das ist eine uralte Prozedur, die ich, damals noch, unreflektiert abgeschrieben
habe. Und da ich immer richtige Ergebnisse erhalten habe auch keine weiteren
Gedanken daran verschwendet.
@Eberhard
ZitatMit beiden kann man rechnen, nur ergeben sich wegen des
unterschiedlichen Datentyps und des unterschiedlichen Inhaltes sehr
unterschiedliche Wirkungen.
Da war ich wohl etwas kurzsichtig. Liegt wohl daran, das ich Format (Eigenschaft
und Funktion) nur in Formularen und/bzw. bei Datumswerten in SQL, wenn
nötig, verwende, und bei Berechnungen auch versuche den passenden Datentyp
zu verwenden.
@Marco
Mit den ganzen Infos und Codebeispielen solltest du das jetzt hinbekommen.
gruss ekkehard
Hey erstmal vielen Dank für die ganzen Infos.
Ich habe leider nur noch nie mit VBA Codes gearbeitet.
Wo muss ich die den einfügen? Und wie kann ich die Funktion dann einbinden?