Eine parallele Haltung von Terminen in Outlook und einer weiteren Anwendung wie etwa einer Access-Applikation sollte man eigentlich vermeiden. Wenn Sie sich jedoch entscheiden, Ihren Tagesablauf mit Access zu planen, kann eine Integration von Outlook dennoch lohnend sein: Immerhin können Sie mit Outlook Termine von Kunden oder Mitarbeitern empfangen, um diese dann in Ihr Access-System zur Tagesplanung einzulesen. Wie dies gelingt, erfahren Sie in diesem Beitrag.
Wenn Sie Outlook-Termine in eine Access-Datenbank importieren, erfolgt dies normalerweise eins zu eins: Ein Termin entspricht dann einem Eintrag in einer entsprechenden Tabelle.
Dabei spielen Anfangs- und Endzeit keine Rolle, sie werden einfach in die Tabelle eingetragen. Dies erschwert leider die Darstellung etwa in einer Tagesübersicht: Dies ist nicht so einfach tabellarisch möglich, da ein Termin ja auch einmal von 11:05 bis 11:37 Uhr angesetzt sein kann.
Um dies in einem Formular darzustellen, müssen Sie schon erheblich tricksen, da dieses ja nur eine zeilenweise Darstellung erlaubt. Eine Einteilung in ein bestimmtes Zeitraster etwa in 15-Minuten-Schritten wäre hier also eine willkommene Erleichterung.
Erfahrungsgemäß reicht dies für die meisten in Outlook angelegten Termine auch aus – eine höhere Genauigkeit als eine Viertelstunde für einen Termin und seine Dauer ist wohl eher selten.
Ausgehend davon – und unter Berücksichtigung der Tatsache, dass die Termine auch einmal nebeneinander in einer Wochenübersicht dargestellt werden sollen – speichern wir jeden Termin in 15-Minuten-Häppchen. Dazu verwenden wir die Tabelle tblTermine, die wie in Bild 1 aufgebaut ist.
Bild 1: Tabelle zum Speichern von Terminen
Der Import der Outlook-Termine soll also wie folgt verlaufen:
- Jeder Termin wird in 15-Minuten-Häppchen aufgeteilt.
- Jeder Teiltermin landet in einem neuen Datensatz der Tabelle tblTermine. Dabei werden die Bezeichnung und die Beschreibung übernommen.
Damit wären die Felder Termindatum, Terminzeit, Bezeichnung und Beschreibung erläutert. AngelegtAm wird mit der aktuellen Zeit versehen. AufgabeID ist ein Feld, das wir für die Weiterverwendung der hier vorgestellten Teillösung im Beitrag Tagesabläufe verwalten benötigen. Bleibt noch das Feld KategorieID: Dieses soll die Zuordnung eines Termins zu einer Kategorie ermöglichen (beispielsweise Kundengespräch, Programmierung oder Auswärtstermin). Was hat das mit Outlook zu tun Nun: Auch mit Outlook können Sie Termine kategorisieren und diese beispielsweise mit einer Farbe versehen.
Diese Kategorie soll beim Einlesen der Termine erkannt und durch einen entsprechenden Wert im Feld KategorieID gekennzeichnet werden. Dieses Feld ist wiederum ein Fremdschlüsselfeld, mit dem Sie Einträge der Tabelle tblKategorien auswählen können (diese enthält die drei Felder KategorieID, Kategorie und Outlookkategorie).
Vor und nach dem Import
Ein typischer Outlook-Termin für den Import sieht wie in Bild 3 aus.
Bild 3: Der Outlook-Termin nach dem Import
Bild 2: Ausgangspunkt: Ein Outlook-Termin
Termine und Terminserien
In Outlook definieren Sie einzelne Termine oder auch Terminserien, die beispielsweise täglich oder wöchentlich zum angegebenen Zeitpunkt wiederholt werden. Die hier beschriebene Lösung importiert alle Termine so, als ob es einzelne Termine wären, und nimmt dabei keine Rücksicht darauf, ob ein Termin ein Einzeltermin oder Teil einer Terminserie ist.
Terminänderungen in Outlook
Nun kommt es beizeiten vor, dass ein mit einem Kunden oder Mitarbeiter vereinbarter Termin verschoben oder anderweitig geändert wird.
In diesem Falle soll natürlich beim nächsten Import der Outlook-Termine ein entsprechendes Update der Termine vorgenommen werden, die durch diesen Outlook-Termin in der Access-Anwendung angelegt wurden.
Hier wird es nun ein wenig kniffelig: Wir müssen entweder in Access ein eindeutiges Merkmal des Outlook-Termins ablegen, um die aktuellen Daten des Termins mit den in Access gespeicherten Daten abzugleichen oder aber den Outlook-Termin mit einem entsprechenden Merkmal versehen.
Outlook-Termine verfügen mit der EntryID über eine eindeutige Eigenschaft, die normalerweise ihren Wert nicht ändern sollte.
Also legen wir in der Tabelle tblTermine noch ein weiteres Feld namens OutlookID an, das die EntryID des Outlook-Termins speichert. Wenn ein Termin in Outlook geändert wurde, der bereits in der Datenbank gespeichert ist, soll Folgendes geschehen: Access liest die Daten des Termins ein, prüft, ob bereits Termine mit der EntryID vorliegen und ob sich die festgelegten Zeiten unterscheiden.
Falls ja, soll der vorhandene Outlook-Termin gelöscht und die neue Version in die Datenbank geschrieben werden.
Umgang mit vorhandenen Terminen
Die hier vorgestellte Variante, Termine in einer Tabelle zu pflegen, unterscheidet sich in einem wichtigen Punkt von Outlook: Die Tabelle soll nur einen Termin für einen Zeitraum gleichzeitig aufnehmen können (sollten später mehrere Mitarbeiter die Anwendung nutzen, kann natürlich jeder Termin einmal pro Mitarbeiter vergeben werden).
Das bedeutet für den Import jedoch, dass wir eine Vorgehensweise für den Fall definieren müssen, dass ein Outlook-Termin zeitlich mit einem bereits vorhandenen Termin zusammenfällt.
Also legen wir fest, dass Outlook-Termine hier Priorität haben. Bereits vorhandene Termine sollen in eine temporäre Tabelle verschoben werden, von der aus der Benutzer diese Termine entweder an eine andere Stelle verschiebt oder diese löscht. Die Tabelle, in die solche Termine verschoben werden, heißt tblTermine_Temp und ist genau so aufgebaut wie die Tabelle tblTermine.
Termine importieren
Das Importieren der Termine wird durch einen einzigen Prozeduraufruf gestartet. Die Prozedur heißt OutlooktermineEinlesen und erwartet zwei Parameter:
- datStart: Erster Tag, dessen Termine eingelesen werden sollen
- datEnde: Letzter Tag, dessen Termine eingelesen werden sollen
Wenn Sie die Prozedur beispielsweise nur für den aktuellen Tag aufrufen möchten, gelingt dies mit folgender Anweisung:
OutlooktermineEinlesen Date, Date
Die Prozedur selbst finden Sie in Listing 1. Im Folgenden beschreiben wir diese Prozedur, gehen jedoch immer wieder auch auf weitere Routinen ein, die von dieser Prozedur aus aufgerufen werden.
Listing 1: Prozedur zum Einlesen von Outlook-Terminen mit Abgleich bestehender Einträge
Public Sub OutlooktermineEinlesen(datStart As Date, datEnde As Date) Dim db As dao.Database Dim objOutlook As Outlook.Application Dim objItems As Outlook.Items Dim strFilter As String Dim datDatum As Date Dim objAppointment As Outlook.AppointmentItem Dim objItem As Object Dim datStartzeit As Date Dim datEndzeit As Date Dim strOutlookID As String Set db = CurrentDb strFilter = FilterZusammenstellen(datStart, datEnde) Set objOutlook = New Outlook.Application Set objItems = TermineHolen(objoutlook, strFilter) db.Execute "DELETE FROM tblTermine_Temp", dbFailOnError For Each objItem In objItems If TypeName(objItem) = "AppointmentItem" Then Set objAppointment = objItem With objAppointment Select Case .MeetingStatus Case olMeeting, olMeetingReceived, olNonMeeting datDatum = CDate(Int(.Start)) datStartzeit = ZeitpunktErmitteln(.Start, True) datEndzeit = ZeitpunktErmitteln(.End, False) strOutlookID = .EntryID If Not TerminVorhanden(db, strOutlookID, datDatum, datStartzeit, datEndzeit) Then TerminAnlegen db, objAppointment, datDatum, datStartzeit, datEndzeit, _ strOutlookID End If End Select End With End If Next objItem If Not IsNull(DLookup("TerminID", "tblTermine_Temp")) Then MsgBox "Es wurden Termine verschoben." End If Set objoutlook = Nothing End Sub
Die Prozedur füllt zunächst eine Variable namens db mit dem Typ Database mit einem Verweis auf die aktuelle Datenbank. Diese Variable wird später an weitere Prozeduren übergeben.
Danach erzeugt sie eine neue Outlook-Instanz beziehungsweise referenziert eine gegebenenfalls bereits geöffnete Instanz und speichert einen Verweis darauf in der Variablen objOutlook.
Damit Sie die Objekte der Outlook-Bibliothek überhaupt verwenden können, fügen Sie dem VBA-Projekt über den Verweise-Dialog (VBA-Editor, Menüpunkt Extras|Verweise) einen Verweis auf die Bibliothek Microsoft Outlook x.0 Object Library hinzu.
Filter zusammenstellen
Die beiden Parameter datStart und datEnde der Prozedur legen den Zeitraum der zu importierenden Outlook-Termine fest. Wenn Sie auf Outlook-Termine zugreifen, können Sie entweder direkt alle Termine durchlaufen oder aber die Termine vorher nach bestimmten Kriterien filtern.
Dies erledigen wir in der Funktion FilterZusammenstellen, die einen Filterausdruck auf Basis der übermittelten Daten zusammenstellt (s. Listing 2).
Listing 2: Zusammenstellen des Outlook-Filters
Public Function FilterZusammenstellen(datStart As Date, datEnde As Date) As String Dim strStart As String Dim strEnde As String Dim strFilterTemp As String strStart = Format(datStart, "ddddd") strEnde = Format(datEnde, "ddddd") strFilterTemp = "[Start] <= " & Chr(34) & strEnde & " 23:59" & Chr(34) strFilterTemp = strFilterTemp & " AND [End] > " & Chr(34) & strStart & " 00:00" & Chr(34) FilterZusammenstellen = strFilterTemp End Function
Der Filter liefert in der aktuellen Version alle Termine, deren Start oder Ende in den angegebenen Zeitraum fällt. Für den aktuellen Tag können Sie den Filter wie folgt im Direktfenster ausgeben:
Filterzusammenstellen(Date,Date) [Start] <= "02.03.2012 23:59" AND [End] > "02.03.2012 00:00"
Wenn Sie die Termine anders filtern möchten, also etwa so, dass nur Termine verwendet werden, deren Beginn nicht vor dem ersten Tag und deren Ende nicht hinter dem letzten Tag liegt, müssen Sie die Funktion FilterZusammenstellen entsprechend umformulieren.
Termine holen
Wenn die Filterbedingung zusammengestellt ist, können Sie damit gleich die entsprechenden Termine ermitteln. Dies erledigt die Funktion TermineHolen (s. Listing 3). Die Funktion erwartet zwei Parameter:
- objOutlook: Verweis auf die Outlook-Instanz
- strFilter: Filterausdruck
Listing 3: Terminaufzählung holen
Public Function TermineHolen(objOutlook As Outlook.Application, strFilter As String) As Outlook.Items Dim objMAPI As Outlook.NameSpace Dim objCalendar As Outlook.Folder Dim objItems As Outlook.Items Set objMAPI = objOutlook.GetNamespace("MAPI") Set objCalendar = objMAPI.GetDefaultFolder(olFolderCalendar) Set objItems = objCalendar.Items objItems.Sort "[Start]", False objItems.IncludeRecurrences = True Set TermineHolen = objItems.Restrict(strFilter) End Function
Die Funktion erstellt ein MAPI-Namespace-Objekt und ermittelt über dessen Funktion GetDefaultFolder den Ordner, der alle Termine enthält (olFolderCalendar).
Mit GetDefaultFolder wird der Standardkalender zurückgegeben! Sollten Sie Termine von anderen Kalendern einlesen wollen, schalten Sie eine Funktion dazwischen, mit der Sie den gewünschten Ordner auswählen können. Diese sieht beispielsweise wie in Listing 4 aus.
Listing 4: Kalender-Ordner auswählen
Public Function GetAppointmentFolder(objMAPI As Outlook.NameSpace) As Outlook.Folder Dim objFolder As Outlook.Folder Set objFolder = objMAPI.PickFolder If Not objFolder.DefaultItemType = olAppointmentItem Then MsgBox "Dies ist kein Kalender-Ordner." Else Set GetAppointmentFolder = objFolder End If End Function
Der Aufruf dieser Funktion mit dem MAPI-Namespace-Objekt öffnet den Dialog aus Bild 4. Wenn der Benutzer einen Ordner auswählt, der nicht standardmäßig AppointmentItem-Objekte enthält, erscheint eine entsprechende Meldung.
Bild 4: Dialog zum Auswählen von Outlook-Ordnern
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
den kompletten Artikel im PDF-Format mit Beispieldatenbank
diesen und alle anderen Artikel mit dem Jahresabo