PDA

Vollständige Version anzeigen : Mit Datums-Angaben arbeiten: die schlankeste Methode


JoeNazz
05.07.2006, 12:54
Hallo,

ich bin gerade dabei in VBA viel mit Kalenderdaten zu arbeiten. Nun habe ich einmal eine Frage, bevor ich den echten Code programmiere, in welcher Weise ich wohl am schnellsten und einfachsten zum Ziel komme.

EdhM (= Ende des heutigen Monats)
Ziel:
Das Datum des letzten Tages des heutigen Monats herausfinden.

Der Weg:
Ich habe als Variable 'heute' das Datum von heute, zb. '05.07.2006'.
Mit einer Schleife zähle ich nun 'heute' jeweils um einen Tag hoch, bis sich die Monatszahl von '07' auf '08' um 1 erhöht hat. Hier breche ich die Schleife ab, setze das Datum wieder um einen Tag zurück und erhalte als Ergebnis bspw. '31.07.2006' in der Variable 'EdhM'.

Machbar?

EdlM (= Ende des letzten Monats)
Ziel:
Das Datum des letzten Tages des vergangenen Monats herausfinden.

Der Weg:
Ich habe als Variable 'heute' das Datum von heute, zb. '05.07.2006'.
Mit einer Schleife zähle ich nun 'heute' jeweils um einen Tag runter, bis sich die Monatszahl von '07' auf '06' um 1 verringert hat. Hier breche ich die Schleife ab und erhalte als Ergebnis bspw. '30.06.2006' in der Variable 'EdlM'.

Realistisch?

vM (= volle Monate)
Ziel:
Die Anzahl an vollen Monaten in einem bestimmten Zeitraum herausfinden.

Der Weg:
Ich habe als Variablen 'start' als das Datum des Tages, von wo aus die vollen Monate gezählt werden sollen und 'ende" als Datum des Tages, bis wann die vollen Monate gezähl werden.
Ich beginne mit 'start', wenn 'start' als Tag '01' enthält; sonst schreibe ich in 'start' = 'start' plus einen Monat und der Tag ist der erste Tag des Monats, also '01'.
Nun zähle ich mit einer Schleife die Monate hoch, bis der aktuelle Monat mit 'ende' identisch ist. Wenn 'ende' nicht der letzte Tag des Monats ist (Prozedur ähnlich von EdhM s.o.), sollen die Anzahl der Monate wieder um 1 verringert werden. Ich erhalte 'vM'.

Schlank genug?

ATg (= Anzahl an Tagen)
Ziel:
Die Anzahl an Tagen herausfinden, wenn ich mehrere einzelne Datumsangaben und auch Zeiträume habe.

Der Weg:
Ich habe mehrere Zeitpunkte (01.01.2006, 02.02.2006, 03.03.2006) und mehrere Zeiträume (04.04.2006-08.04.2006, 05.05.2006-10.05.2006, 06.06.2006-12.06.2006). Nun habe ich die Variable 'ATg'. Ich zähle in einer Schleife die Anzahl an Zeitpunkten und speichere sie in 'ATg'. Nun habe ich eine große Schleife, die die Anzahl an Zeiträumen ermittelt und eine kleine Schleife so oft ausführt, wie Zeiträume vorhanden sind. Die kleine Schleife zählt das Anfangsdatum des Zeitraumes tageweise hoch, bis das Enddatum des Zeitraumes erreicht ist und zählt dabei einen Zähler hoch. In der kleinen Schleife ist 'ATg' = Zähler + 'ATg'.

Noch richtig gedacht?

AWTg (= Anzahl an Werktagen)
Ziel:
Die Anzahl an Werktagen herausfinden, die sich in einem bestimten Zeitraum, z.B. 29.06.2006-03.07.2006, befinden. (Als Werktage definiere ich den Montag, Dienstag, Mittwoch, Donnerstag und Freitag.)

Der Weg:
Ich ermittle den Wochentag des Anfangszeitraums. (Wie genau ich das mache, weiß ich noch nicht.) Dabei wäre der 29.06.2006 ein Donnerstag, für mich er 4. Tag in der Woche. Nun zähle ich mit einer Schleife die Anzahl an Tage in dem Zeitraum bis zum 03.07.2006, das wären 6 Tage. Die 6 Tage addiere ich nun zur Nummer des Wochentages des Anfangsdatums, also 4, und erhalte 10. Die 10 dividiere ich durch die Anzahl an Wochentagen, also 7, und ich erhalte rund 1,43. Mich interessieren nur die Vorkommastelle, deswegen extrahiere ich die 1 aus der 1,43 (wie, weiß ich noch nicht). Nun multipliziere ich die 1 mit 2, dabei ist 2 die Summe von den nicht zu zählenden Tage Samstag und Sonntag. Ich erhalte 2 und subtrahiere diese 2 von der Anzahl an Tagen im Angegebenen Zeitraum. Ich erhalte 4. Dabei ist 4 schlussendlich die Anzahl an Werktagen im angegebenen Zeitraum 'AWTg'.

Nachvollziehbar?

Generell wären das erstmal alle Variablen, mit denen ich Arbeiten muss. Ich wäre Euch nun dankbar, wenn ihr mich in meiner Denkweise korrigieren würdet, falls notwendig. Wenn alles klar ist, mache ich mir Gedanken zum genauen VBA-Code der jeweiligen Aufgaben und poste meine Versuche in diesem Thread. Auch wenn ihr im vorraus schon ein paar Tipps hättet, wär ich Euch dankbar!

Viele Grüße
Jonas

J_Eilers
05.07.2006, 13:11
Hi,

letzter Tag dieses Monats:

DateSerial(Year(Date), Month(Date) + 1, 0)

letzter Tag des vorherigen Monats:

DateSerial(Year(Date), Month(Date), 0)

Monate:

DateDiff("m", Date, "01.01.01")

Tage:

DateDiff("d", Date, "01.01.01")

Zu den Arbeitstagen findest du im Codearchiv ein Beispiel von TommyK.

JoeNazz
07.07.2006, 09:26
Dankeschön, Jan,

das hat mir schonmal sehr weitergeholfen!

Viele Grüße
Jonas

JoeNazz
07.07.2006, 09:51
Wie extrahiere ich denn nun die Wochenenden aus einem bestimmten Zeitraum? Gibts da auch so eine intelligente Funktion oder muss ich mich mit folgenden Code, den ich mir gerade ausgedacht habe, weiterhelfen:

'Deklarieren
Dim Von as Date 'Startdatum
Dim Bis as Date 'Enddatum
Dim AlleTage as Integer 'Anzahl an Tagen vom Startdatum bis zum Enddatum
Dim AnzWochen as Integer 'Wochenanzahl
Dim Werktage as Integer 'Anzahl an Werktagen ohne Samstag und Sonntag

'Initialisieren
Von = "01.05.2006"
Bis = Date
AlleTage = DateDiff("d", Von, Bis)
AnzWochen = DateDiff("ww", Von, Bis)

Werktage = AlleTage - AnzWochen * 2 'An dieser Stelle wurden von jeder Woche zwei Tage abgezogen

War das jetzt gut gelöst oder hat jemand einen besseren Vorschlag? Ich lasse mich gerne korrigieren.

Viele Grüße
Jonas

J_Eilers
07.07.2006, 10:06
Was einfacheres fällt mir auf die Schnelle nicht ein.

FW
07.07.2006, 10:15
... Dein Algorithmus ist falsch: Nimm doch mal z. B. 02.07.2006 und 03.07.2006!
Da musst Du wohl jedes Datum im Bereich einzeln abfragen, oder nach einen gescheiten Algorithmus hier im Forum suchen. Wenn ich mich recht erinnere, dann gab's diese Frage schon mal...

Paul.Ostermeier
07.07.2006, 10:35
die Aufgabenstellung ist m.E.n nicht ganz so einfach zu lösen

FW hat recht, der Code liefert falsche Ergebnisse ( z.B sobald der Starttermin/EndTermin auf einem Samstag oder Sonntag liegt )

außerdem zieht man IMHO von den Werktagen eines Zeitraums zusätzlich noch die
Feiertage ab ....

deshalb wäre mein Vorschlag:

'/// Dein Code
AlleTage = DateDiff("d", Von, Bis)

aktDatum = Von
For I = 1 To AlleTage
If IstWerktag(aktDatum) Then
Werktage = Werktage + 1
End If
aktDatum = Von + I
Next I
MsgBox Werktage

'///

Public Function IstWerktag(ByVal D As Date) As Boolean
IstWerktag = Weekday(D) <> vbSunday And Weekday(D) <> vbSaturday _
And IsNull(DLookup("Feiertag", "tblFeiertage", "Feiertag = #" & Format(D, "yyyy-m-d") & "#"))
End Function

falls Du auf die Feiertage verzichten kannst lass eben die entsprechende Bedingung
in der Funktion weg ...

MfG
Paul

JoeNazz
07.07.2006, 11:00
Hey, danke, Paul!

Wirklich intelligent gelöst! Das setzt natürlich vorraus, dass ich die Tabelle mit den Feiertagen aktuell halte. Ab es stimmt, Feiertage müssen schon auch enthalten sein.

Vielen Dank
Jonas