PDA

Vollständige Version anzeigen : Abfrage von Zeiträumen


TommyK
17.02.2004, 16:34
Hallo,

Problemstellung:
Heute möchte ich mich mit der Errechnung von Zeiträumen als Abfragekriterium beschäftigen.
Fast jeder hat schon vor der Aufgabe gestanden, ich brauche die Daten des letzten Quartals oder die Termine der nächste Woche.
Um jetzt zu den benötigten Datumsangaben zu kommen nehme ich meinen Tischkalender oder fange an mir selbst etwas zu schreiben usw.
Und wie es dann in der Praxis aus, entweder man bekommt zwei Inputboxen vorgesetzt „Bitte geben Sie das Startdatum ein:“.... Äh, nächste Woche erster Tag, wo ist der blöde Kalender?
Schöner wäre es man könnte Access sagen, Ich will die Daten „der nächsten Woche“. Aber leider tut sich Access damit schwer oder will mich nicht verstehen.
Um dies aber doch zutun habe ich mal ein Funktion geschrieben, die diese Begriffe „der nächsten Woche“ usw., übersetzt.
Das Ganze ist beliebig erweiterbar (s. weiter unten)
Das im Bsp. Enthaltene UFO ist nur aus Demozwecken enthalten und wird nicht zum Betrieb der Funktion benötigt.

Voraussetzungen:

Das Bsp ist unter A97, A00 und AXP lauffähig, unter A03 wurde es nicht getestet.


Funktionsweise:

Hier die eigentlichen Funktion:

<div><link href="http://www.ms-office-forum.net/forum/externals/codeconv.css" rel="stylesheet"><pre><span class="TOKEN">Public Function</span> CalcDate(dateDatum <span class="TOKEN">As</span> Date, intValue <span class="TOKEN">As</span> Integer, intFirstLast <span class="TOKEN">As</span> Integer, strArt <span class="TOKEN">As</span> <span class="TOKEN">String</span>) <span class="TOKEN">As</span> Date
<span class="REM">'*******************************************</span>
<span class="REM">'Name: CalcDate (Function)</span>
<span class="REM">'Purpose: Ermittelt verschiedene Datumsangaben aus den Bereichen Tag, Woche, Monat, Quartal, Halbjahr und Jahr</span>
<span class="REM">'Author: Thomas Ke&szlig;ler</span>
<span class="REM">'Date: Februar 12, 2004, 11:45:00</span>
<span class="REM">'Inputs: dateDatum= Datum ab dem gerechnet werden soll, intValue= Berechnungswert +/- vom dateDatum</span>
<span class="REM">' intFirstLast= Berechnung des ersten oder letzten Datums des gew&auml;hlten Zeitraumes (-1=Beginn, 0=Ende)</span>
<span class="REM">' strArt= Art des Datums ( D=Tag, W=Woche, M= Monat, Q= Quartal, H= Halbjahr und J=Jahr</span>
<span class="REM">'Output: Datum</span>
<span class="REM">'Example: X=CalcDate(Date,-1,-1,M) w&uuml;rde den ersten Tag des letzten Monats ausgehend vom heutigen ermitteln</span>
<span class="REM">'*******************************************</span>
<span class="TOKEN">On Error GoTo</span> Err_Date
&nbsp;
<span class="TOKEN">Dim</span> varQ_First <span class="TOKEN">As</span> Variant, varQ_Last <span class="TOKEN">As</span> Variant
<span class="TOKEN">Dim</span> varHbj_First <span class="TOKEN">As</span> Variant, varHbj_Last <span class="TOKEN">As</span> Variant
<span class="TOKEN">Dim</span> varFirstDayWeek <span class="TOKEN">As</span> Variant
<span class="TOKEN">Dim</span> dateLastDayMonth <span class="TOKEN">As</span> Date
<span class="TOKEN">Dim</span> intMonth <span class="TOKEN">As</span> Integer, intYear <span class="TOKEN">As</span> <span class="TOKEN">Integer</span>
&nbsp;
<span class="REM"> ' Wenn falsche Parameter dann raus hier</span>
<span class="TOKEN">If</span> <span class="TOKEN">Not</span> IsDate(dateDatum) <span class="TOKEN">Then</span> dateDatum = Date
<span class="TOKEN">If</span> intFirstLast &gt; 0 <span class="TOKEN">Or</span> intFirstLast &lt; -1 <span class="TOKEN">Then</span> GoTo Err_Date_Exit
&nbsp;
<span class="REM"> ' erster Tag der aktuellen Woche</span>
varFirstDayWeek = FirstDayWeek(dateDatum)
<span class="REM"> ' erster Tag des aktuellen Quartals</span>
varQ_First = FirstDayQuartal(dateDatum)
<span class="REM"> ' letzter Tag es aktuellen Quartals</span>
varQ_Last = LastDayQuartal(dateDatum)
<span class="REM"> ' erster Tag des aktuellen Halbjahres</span>
varHbj_First = FirstDayHalfYear(dateDatum)
<span class="REM"> ' letzter Tag des aktuellen Halbjahres</span>
varHbj_Last = LastDayHalfYear(dateDatum)
&nbsp;
<span class="REM"> ' Startdatum des gew&auml;hlten Zeitraumes</span>
<span class="TOKEN">If</span> intFirstLast = -1 <span class="TOKEN">Then</span>
<span class="REM"> ' Auswahl des Typs</span>
Select Case strArt
Case <span class="TOKEN">Is</span> = &quot;D&quot;
<span class="REM"> 'Tage</span>
CalcDate = dateDatum + intValue
Case <span class="TOKEN">Is</span> = &quot;W&quot;
<span class="REM"> ' Wochen</span>
CalcDate = varFirstDayWeek + intValue
Case <span class="TOKEN">Is</span> = &quot;M&quot;
<span class="REM"> ' Monate</span>
intMonth = Month(dateDatum)
CalcDate = DateSerial(Year(dateDatum), intMonth + intValue, 1)
Case <span class="TOKEN">Is</span> = &quot;Q&quot;
<span class="REM"> ' Quartale</span>
intYear = Format(DateAdd(&quot;m&quot;, intValue, varQ_First), &quot;yyyy&quot;)
intMonth = Format(DateAdd(&quot;m&quot;, intValue, varQ_First), &quot;mm&quot;)
CalcDate = DateSerial(intYear, intMonth, 1)
Case <span class="TOKEN">Is</span> = &quot;H&quot;
<span class="REM"> ' Halbjahre</span>
intYear = Format(DateAdd(&quot;m&quot;, intValue, varHbj_First), &quot;yyyy&quot;)
intMonth = Format(DateAdd(&quot;m&quot;, intValue, varHbj_First), &quot;mm&quot;)
CalcDate = DateSerial(intYear, intMonth, 1)
Case <span class="TOKEN">Is</span> = &quot;J&quot;
<span class="REM"> ' Jahre</span>
intYear = Year(dateDatum)
CalcDate = DateSerial(intYear + intValue, 1, 1)
<span class="TOKEN">Case Else</span>
<span class="REM"> ' ung&uuml;ltiger Wert</span>
GoTo Err_Date_Exit
<span class="TOKEN">End</span> Select
<span class="REM"> ' Enddatum des gew&auml;hlten Zeitraumes</span>
<span class="TOKEN">Else</span>
<span class="REM"> ' Auswahl des Typs</span>
Select Case strArt
Case <span class="TOKEN">Is</span> = &quot;D&quot;
<span class="REM"> 'Tage</span>
CalcDate = dateDatum + intValue
Case <span class="TOKEN">Is</span> = &quot;W&quot;
<span class="REM"> ' Wochen</span>
CalcDate = varFirstDayWeek + intValue
Case <span class="TOKEN">Is</span> = &quot;M&quot;
<span class="REM"> ' Monate</span>
intMonth = Month(dateDatum)
dateLastDayMonth = DateSerial(Year(dateDatum), intMonth + intValue, 1)
CalcDate = LastDayMonth(dateLastDayMonth)
Case <span class="TOKEN">Is</span> = &quot;Q&quot;
<span class="REM"> ' Quartale</span>
intYear = Format(DateAdd(&quot;m&quot;, intValue, varQ_Last), &quot;yyyy&quot;)
intMonth = Format(DateAdd(&quot;m&quot;, intValue, varQ_Last), &quot;mm&quot;)
dateLastDayMonth = DateSerial(intYear, intMonth, 1)
CalcDate = LastDayMonth(dateLastDayMonth)
Case <span class="TOKEN">Is</span> = &quot;H&quot;
<span class="REM"> ' Halbjahre</span>
intYear = Format(DateAdd(&quot;m&quot;, intValue, varHbj_Last), &quot;yyyy&quot;)
intMonth = Format(DateAdd(&quot;m&quot;, intValue, varHbj_Last), &quot;mm&quot;)
dateLastDayMonth = DateSerial(intYear, intMonth, 1)
CalcDate = LastDayMonth(dateLastDayMonth)
Case <span class="TOKEN">Is</span> = &quot;J&quot;
<span class="REM"> ' Jahre</span>
intYear = Year(dateDatum)
CalcDate = DateSerial(intYear + intValue, 12, 31)
<span class="TOKEN">Case Else</span>
<span class="REM"> ' ung&uuml;ltiger Wert</span>
GoTo Err_Date_Exit
<span class="TOKEN">End</span> Select
<span class="TOKEN">End</span> <span class="TOKEN">If</span>
&nbsp;
Err_Date_Exit:
<span class="TOKEN">Exit Function</span>
Err_Date:
<span class="TOKEN">Dim</span> strErrString <span class="TOKEN">As</span> <span class="TOKEN">String</span>
strErrString = &quot;Error Information...&quot; &amp; vbCrLf
strErrString = strErrString &amp; &quot;Error#: &quot; &amp; Err.Number &amp; vbCrLf
strErrString = strErrString &amp; &quot; Description: &quot; &amp; Err.Description &amp; vbCrLf
MsgBox strErrString, vbCritical + vbOKOnly, &quot;Error in Function: CalcDate&quot;
<span class="TOKEN">Resume</span> Err_Date_Exit
<span class="TOKEN">End</span> <span class="TOKEN">Function</span>
&nbsp;</pre></div>
Code eingefügt mit dem MOF Code Converter (http://www.ms-office-forum.net/forum/codeconverter.php)


Weiterhin sind einige Hilfsfunktionen im Modul enthalten die CalcDate benötigt:

<div><link href="http://www.ms-office-forum.net/forum/externals/codeconv.css" rel="stylesheet"><pre><span class="REM"> ' erster Tag der aktuellen Woche</span>
varFirstDayWeek = FirstDayWeek(dateDatum)
<span class="REM"> ' erster Tag des aktuellen Quartals</span>
varQ_First = FirstDayQuartal(dateDatum)
<span class="REM"> ' letzter Tag es aktuellen Quartals</span>
varQ_Last = LastDayQuartal(dateDatum)
<span class="REM"> ' erster Tag des aktuellen Halbjahres</span>
varHbj_First = FirstDayHalfYear(dateDatum)
<span class="REM"> ' letzter Tag des aktuellen Halbjahres</span>
varHbj_Last = LastDayHalfYear(dateDatum)
&nbsp;</pre></div>
Code eingefügt mit dem MOF Code Converter (http://www.ms-office-forum.net/forum/codeconverter.php)

Die Funktion "CalcDate" ermittelt dann das Start- bzw. Enddatum
des gewählten Zeitraumes.

Syntax und Argumente:

CalcDate(dateDatum As Date, intValue As Integer, intFirstLast As Integer, strArt As String)

dateDatum = ein beliebiges gültiges Datum das als Bezugsdatum für die Funktion gilt
intValue = Berechnungsfaktor, ist in der Tabelle "tbl_Zeitraeume" hinterlegt (Start oder Ende)
intFirstLast = bei Wert -1 wird das Startdatum des gewählten Zeitraumes berechnet und bei 0 das Enddatum
strArt = Art des Zeitraumes, ist in der Tabelle "tbl_Zeitraeume" hinterlegt

Es gibt jetzt 2 Möglichkeiten das Bsp in der Praxis zu benutzen:

1. Möglichkeit:
Will man das Ganze, visuell (per Auswahl Kombifeld), in der Praxis zu nutzen muss man nur die Tabelle "tbl_Zeitraeume" und das Modul "mod_BerechnungenDatum" in seine DB kopieren.
Eine Kombifeld erstellen und den Zeitraum auswählen.
Der Funktion "CalcDate" werden dann die Spalten des Kombifeldes übergeben.
z.B.: für das Startdatum und das Enddatum (als Bezugsdatum wird hier das heutige Datum, Funktion Date(), genommen:
Me.txt_S = CalcDate(Date, Me.cmb_Zeit.Column(2), -1, Me.cmb_Zeit.Column(4))
Me.txt_E = CalcDate(varDate, Me.cmb_Zeit.Column(3), 0, Me.cmb_Zeit.Column(4))

Der Aufruf in der jeweiligen Abfrage wäre dann als Kriterium:

<div><link href="http://www.ms-office-forum.net/forum/externals/codeconv.css" rel="stylesheet"><pre>Zwischen [Formulare]![frm_Start]![txt_S] Und [Formulare]![frm_Start]![txt_E]</pre></div>
Code eingefügt mit dem MOF Code Converter (http://www.ms-office-forum.net/forum/codeconverter.php)

Aufbau der Tabelle „tbl_Zeiträume“:

lfd_Nr als Primärfeld. = Nummernkreis der Zeiträume
Folgende Nummernkreise sind vorgegeben, können aber beliebig verändert werden.
10-99 Tage , 100-999 Wochen , 1000-1999 Monate , 2000-2999 Quartale, 3000-3999 Halbjahre , 4000-4999 Jahre

Zeitraum = eine beliebige Bezeichnung die Zeitraum beschreibt
Start = Bezugswert für das Startdatum zum Referenzdatum
Ende = Bezugswert für das Enddatum zum Referenzdatum
Kurz = Kurzbezeichnung für die Art des Zeitraumes, definiert den Bezugsfaktor
D = Tage für Tagesberechnungen
W= Tage für Wochenberechnungen
M = Monate für Monatsberechnungen
Q = Monate für Quartalsberechnungen
H = Monate für Halbjahresberechnungen
J = Jahre für Jahresberechnungen
Einheit = definiert die Einheit für die Felder Start und Ende (nur informativ)

Will man einen Zeitraum in die Tabelle neu eingegeben werden, sind folgende Werte zu setzten:

Lfd_Nr: z.B. 1021 (für den Nummernkreis Monate)
Start: -4
Ende: -1
Kurz: M (für Monatsberechnung)
Einheit: Monate

2. Möglichkeit:
Die Funktion "CalcDate" direkt der Abfrage als Kriterium übergeben.
z.B. die letzen 4 Monate, Referenz Datum Heute:

<div><link href="http://www.ms-office-forum.net/forum/externals/codeconv.css" rel="stylesheet"><pre>Zwischen CalcDate(Datum();-4;-1;&quot;M&quot;) Und CalcDate(Datum();-1;0;&quot;M&quot;)</pre></div>
Code eingefügt mit dem MOF Code Converter (http://www.ms-office-forum.net/forum/codeconverter.php)

Es besteht aber die Möglichkeit das Referenzdatum beliebig festzulegen.


Hier gehts zum Download: Auswahl von Zeiträumen (http://www.ms-office-forum.net/daten/access/02_2004/118989.zip)