anhand einer Meetingroom Vorlage aus dem I-Net habe ich mir anegschaut, wie der Autor einen zu buchenden Raum auf Terminüberschneidungen abgleicht. (Quelle: http://www-10.lotus.com/ldd/sandbox.nsf/ecc552f1ab6e46e4852568a90055c4cd/3ceb15a46ae9a99185256c9500712b1c?OpenDocument )
Hierzu nimmt der Autor vom zu buchenden Raum
- das Datum, zB 15.03.2003
- die Startzeit, zB 16:00
- die Endzeit, zB 16:05
dann generiert er sog. Timeslots in 1-Minuten-Schritten-->
16:00, 16:01, 16:02, 16:03, 16:04, 16:05
Und vergleicht diese Werte mit allen bestehenden Terminen, die am gleichen Datum stattfinden (wenn der Raum der gleiche ist), indem er auch bei den bestehenden Terminen alle Zeitwerte in 1-Minuten Slots aufbröselt.
Anbei das Script (achtet auf den letzten Teil):
'Get and create the time slots for the current uidoc so we can check the back doc for time period clashes
startdate$ = Cstr(Mdate)
slotlist$ = "" ' For formating the time value
Dim dtimefrom As New NotesDateTime(startdate$ & " " & uidoc.FieldGetText("TimeFrom"))
Dim dtimeto As New NotesDateTime(startdate$ & " " & uidoc.FieldGetText("TimeTo"))
Dim Tslot As NotesDateTime
Dim TimeSlots2() As Variant 'Set up the dynamic array to hold the 1 minute time slots
Dim x As Integer 'counter for array elements
Set Tslot = dtimefrom
Tslot.AdjustMinute - Minute(dtimefrom.LSLocalTime) Mod 1
x=0
Redim TimeSlots2(x)
While Tslot.LSLocalTime < dtimeto.LSLocalTime
If Not slotlist$ = "" Then TimeSlots2(x) = slotlist$
slotlist$ = Format$(Tslot.LSLocalTime, "hh:mm:ss")
Tslot.AdjustMinute 1
x=x +1
Redim Preserve TimeSlots2(x) 'keep the array elements so far
Wend
Forall c In view.Columns
If ( c.IsSorted And c.IsCategory ) Then
Set column = c
Exit Forall
End If
End Forall
Do While Not ( doc Is Nothing ) ' now let's check all the other documents in the collection until we run out of docs
'The first column is 0
If ( doc.ColumnValues( column.Position - 1 ) = Datevalue(Mdate) ) Then
Val1 = doc.room
' Get the intervening 1 minute slots, these were created when the document being checked was approved
TimeSlots=doc.SlotList
docroom=Cstr(Val1(0))
%REM
Check rooms for availability, also if the room in the uidoc matches a room in the document collection
then check if the time slots in the back document being checked matches any of the time values in the uidoc.
%END REM
...
If Mroom = R5 And docroom = R5 Then
Forall period In TimeSlots
V1= period
Forall s In TimeSlots2
V2 = s
If V1 = V2 Then
Goto NotAvailable
End If
End Forall
End Forall
End If
anbei auch ein Bild aus dem Debugger..
V1 ist der bestehende "Alt-"Termin, bzw. gebildete Minuten Slot (sichtbar in Variable TIMESLOT) und
V2 ist der Wert des zu buchenden "Neu"-Termins, ebenso in Minuten stepweise hochgejagt und verglichen mit V1..
(http://www.basicthinking.de/grafics/slots.jpg)
FRAGE:
wozu macht man das kompliziert? Irgendwie sehe ich nicht den Sinn dahinter. Zumal das ziemlich lahm ist, weil die Anzahl der Iteration (zweck Vergleich) der Anzahl der Minutensteps aus Alttermin und Neutermin entspricht. >:( Das was ich machen würde...
1. nimm Docs (bestehende Termine) deren Datum gleich mit dem zu buchenden neuen Termindoc ist
2. WENN StartZeit Neuer Termin (SZn) > EndZeit Alter Termin (EZa) ist
dann ok
3. WENN StartZeit Neuer Termin < EndZeit Alter Termin
dann check, ob
Ende Zeit Neuer Termin (EZn) < Start Zeit Alter Termin (SZa)
Also Beispiel:
1. alter Termin wäre heute 17:00-18:00 Uhr
neuer Termin sei heute 18:01-19:00 Uhr
dann ist erste Bedingung ok (SZn > EZa) , also keine Überschneidung
2. alter Termin wäre heute 17:00-18:00 Uhr
neuer Termin sei heute 16:00-19:00 Uhr
dann ist erste Bedingung nicht ok (SZn > EZa) , also mögliche Überschneidung (kann ja sein, daß neuer Termin aufhört, bevor "alter" Termin anfängt heute)
also: zweite Bedingung EZn<SZa auch nicht ok, damit Terminüberschneidung
3. alter Termin wäre heute 17:00-18:00 Uhr
neuer Termin sei heute 16:00-16:59 Uhr
dann ist erste Bedingung nicht ok (SZn > EZa) , also mögliche Überschneidung (kann ja sein, daß neuer Termin aufhört, bevor "alter" Termin anfängt heute)
also: zweite Bedingung EZn<SZa ok, damit keine Terminüberschneidung
Hab ich was übersehen oder warum macht der obige AUtor so ein Gedönse?
nur ein Hinweis, falls das unklar oder undeutlich ist:
der Vergleich muß unbedingt ein Datums/Zeitwert sein..eine Zeitangabe alleine bringt nix...denn es kann ja auch Termine geben wie:
01.02.2003 09:00 - 05.02.2003 10:00
Wenn man jetzt nur die Uhrzeit nehmen würde (09:00 - 10:00) dann käme man mit der "Formel", wie Du sie oben gepostet hast nicht darauf, daß dieser Termin mit einem anderen vom 03.02.2003 15:00 - 03.02.2003 16:00 kollidiert.
Ist zwar klar, aber es sei nur zur Sicherheit nochmals erwähnt.
Im Sript hab ichs momentan so, daß ich zuerst den RAUM suche, ob der schon überhaupt irgendwann belegt worden ist, anhand der Bezeichnung des Raums (also nicht ausgehend von der Zeit!!!). Dann nehme ich mir in eine Collection alle entsprechenden Raumtermine und mache erst dann den Datums/Zeitvergleich.
Ich habe mich deswegen für diese Variante entschieden, da es wie gesagt mehrtägige Termine geben kann vom obigen Typ.
Auch ein Explode von Datumswerten einer LookUp Ansicht würde nichts bringen, da man ausgehend vom neuen Termin - die beiden Eckwerte Startdatum und Enddatum nehmend - nicht unbedingt die richtigen Termine findet (zB dann wenn neuer Termin vom 01.02. - 05.02. läuft, und für den Raum schon ein Termin am 03.02.-04.02. gebucht worden ist). Sucht man also "wo ist denn ein Termin am 01.02....nix...wo ist ein Termin am 05.02...nix..." und das ist natürlich falsch.
Auszug aus Code:
'Variablen für Zeitvariablen des jetzigen Docs und der zu vergleichenden Docs
Dim dateNEUStart As Variant
Dim dateALTStart As Variant
Dim dateNEUnde As Variant
Dim dateALTEnde As Variant
'Ziehe Startdatumzeit zB. "12.03.2003 16:00" und EndDatumZeit zB. "12.03.2003 18:00" des jetzigen Docs
dateNEUStart = uidoc.FieldGetText( "StartdatumZeit" )
dateNEUEnde = uidoc.FieldGetText( "EndDatumZeit" )
startdateNEU$ = Cstr(dateNEUStart)
enddateNEU$ = Cstr(dateNEUEnde)
'Erzeuge von den beiden Anfangs und Endwerten NotesDateTime Objekte
Dim dtimefromNEU As New NotesDateTime(startdateNEU$)
Dim dtimetoNEU As New NotesDateTime(enddateNEU$)
.....
'Dann der Vergleich später...
'hole erstes Alt-Doc aus Collection heraus zwecks Vergleich
Set AltDoc = DocColl.getFirstDocument
While Not AltDoc Is Nothing
'Checklauf wenn jetziges Doc nicht neu ist
If flag=False Then
unidAlt$ = AltDoc.UniversalID
If unidAlt$ <> unid$ Then 'wenn UNID nicht übereinstimmt ist es ein anderes Alt-Doc
dateALTStart = AltDoc.StartdatumZeit(0)
dateALTEnde = AltDoc.EndDatumZeit(0)
startdateALT$ = Cstr(dateALTStart)
enddateALT$ = Cstr(dateALTEnde)
Dim dtimefrom2ALT As New NotesDateTime(startdateALT$)
Dim dtimeto2ALT As New NotesDateTime(enddateALT$)
'ist Startdatumzeit NEU > EndeDatumZeit ALT ? ..keine Überschneidung..da neue Termin nachher beginnt...wenn nicht, muß man noch weiter checken
If dtimefromNEU.TimeDifference( dtimeto2ALT ) > 0 Then
meldung$={- Raum } & Cstr(doc.Raum(0)) & {: -} & Chr(10)
Else
'ist EndeDatumZeit NEU < StartDatumZeit ALT ? ..keine Überschneidung, da neue Termin vorher fertig
If dtimetoNEU.TimeDifference( dtimefrom2ALT ) < 0 Then
meldung$={- Raum } & Cstr(doc.Raum(0)) & {: -} & Chr(10)
Else
meldung$={- Raum } & Cstr(doc.Raum(0)) & {: - Terminüberschneidung } & Chr(10) & startdateALT$ & { - } & enddateALT$ & Chr(10)
Sperrflag$="1"
End If
End If
Und abstrakt ist die Formel gemäß Deiner Schreibkonvention:
if SZn > EZa then
ueberschneidung = 0 ' keine Überschneidung
else
if EZn < SZa then 'habe die erste Bedingung wech, da bereits in ersten IF
ueberschneidung = 0
end if
end if