Outlookobjekte mit Kategorien einlesen

Outlook bietet die Möglichkeit, Objekte wie Termine, E-Mails oder Kontakte mit Kategorien zu versehen. Wenn Sie solche Objekte in eine Access-Datenbank einlesen möchten, möchten Sie möglicherweise auch auf diese Kategorien zugreifen, um die Objekte in der Datenbank entsprechend verarbeiten zu können. Dieser Beitrag zeigt, wie Sie die in Ihrer Access-Datenbank gepflegten Kategorien unter Outlook bereitstellen, wie Sie in Outlook mit Kategorien arbeiten und wie Sie diese beim Import von Outlook-Objekten gleich mit einlesen.

Ein Teil dieses Beitrags bezieht sich auf Objekte, die erst mit Outlook 2007 eingeführt wurden. Dabei handelt es sich um die Auflistung Categories und das Objekt Category. Damit werden in Outlook die Kategorien verwaltet, die Sie sowohl über die Benutzeroberfläche als auch per VBA anlegen können. Damit wird die Verwendung von Kategorien um einiges einfacher gegenüber älteren Outlook-Versionen, wo diese Informationen in der Registry gespeichert wurden (sollte dies für Sie interessant sein: HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Outlook\Categories). Für diesen Beitrag bedeutet dies, dass Besitzer älterer Outlook-Versionen die Kategorien in Outlook manuell anlegen müssen, während Sie unter Outlook 2007 und 2010 die gegebenenfalls in einer Access-Datenbank vorliegenden Kategorien direkt nach Outlook übertragen können. Die übrigen Techniken, insbesondere das Einlesen von Outlook-Objekten und ihrer Kategorien, sind für die neueren Outlook-Versionen identisch (getestet ab Outlook 2003). Daher starten wir auch mit der Beschreibung dieser Techniken.

Kategorien-Vielfalt

Die erste wichtige Information ist, dass Sie für jedes Outlook-Objekt eine oder mehrere Kategorien speichern können, und zwar in Form einer Semikola-separierten Liste (s. Bild 2 aus.

pic001.png

Bild 1: Kategorien eines Outlook-Termins unter Outlook 2003

pic002.png

Bild 2: Datenmodell zum Speichern von Terminen und Outlook-Kategorien

Für das Feld Outlookkategorien der Tabelle tblOutlookkategorien legen Sie einen eindeutigen Index fest, damit jede Kategorie nur einmal angelegt wird. Die Tabelle tblTermineOutlookkategorien erhält einen zusammengesetzten, eindeutigen Index für die beiden Fremdschlüsselfelder TerminID und OutlookkategorieID, damit jeder Termin nur einmal einer Outlook-Kategorie zugeordnet werden kann.

Kategorien von Outlook einlesen

Zu Beginn möchten Sie vielleicht zunächst einmal alle bestehenden Outlook-Kategorien in die Tabelle tblKategorien einlesen. Dies erledigt die Prozedur aus Listing 1, allerdings nur für Access 2007 und jünger – ältere Outlook-Versionen bieten schlicht und einfach keine Categories-Auflistung, aus der sich diese Daten einfach auslesen lassen. Stattdessen liegen die Informationen dort in der Registry.

Listing 1: Einlesen der Outlook-Kategorien in eine Access-Tabelle

Public Function KategorienEinlesen() As String
    Dim db As DAO.Database
    Dim objOutlook As Outlook.Application
    Dim objCategory As Outlook.Category
    Dim objCategories As Outlook.Categories
    Dim strKategorien As String
    Set db = CurrentDb
    Set objOutlook = CreateObject("Outlook.Application")
    Set objCategories = objOutlook.GetNamespace("MAPI").Categories
    For Each objCategory In objCategories
        On Error Resume Next
        db.Execute "INSERT INTO tblOutlookkategorien(Outlookkategorie) VALUES(''" _
            & Replace(objCategory.Name, "''", "''''") & "'')", dbFailOnError
        On Error GoTo 0
        strKategorien = strKategorien & objCategory.Name & ";"
    Next objCategory
    KategorienEinlesen = strKategorien
End Function

Die Prozedur erstellt ein Outlook-Objekt beziehungsweise referenziert eine bereits geöffnete Instanz und speichert den Verweis in der Variablen objOutlook. Den Zugriff auf die einzelnen Kategorien liefert eine Auflistung namens Categories, die Sie als Element des MAPI-Namespaces referenzieren. Die darin enthaltenen Elemente heißen Category und werden in der folgenden For Each-Schleife durchlaufen. Innerhalb der Schleife trägt die Prozedur alle Kategorien in das Feld Outlookkategorie Tabelle tblOutlookkategorien ein. Da für dieses Feld ein eindeutiger Index festgelegt ist, löst das Anlegen eines bereits vorhandenen Eintrags einen Fehler aus. Kein Problem: Der Fehler wird einfach abgefangen und der fehlgeschlagene schreibende Zugriff auf die Tabelle schlicht ignoriert.

Damit durch eventuell enthaltene Hochkommata () kein Fehler durch eine ungültige INSERT INTO-Anweisung ausgelöst wird, werden einzelne Hochkommata per Replace-Anweisung verdoppelt. Die Funktion kann außerdem noch einen Rückgabewert liefern, der eine semikola-separierte Liste aller Kategorien liefert.

Termine einlesen

Das Einlesen der eigentlichen Termine übernimmt die Prozedur aus Listing 2.

Listing 2: Einlesen der Termine in einem bestimmten Datumsbereich

Public Sub TermineEinlesen(datStart As Date, datende As Date)
    Dim objOutlook As Outlook.Application
    Dim objNamespace As Outlook.NameSpace
    Dim objFolder As Outlook.Folder
    Dim objItems As Outlook.Items
    Dim objAppointment As Outlook.AppointmentItem
    Dim strFilter As String
    Set objOutlook = New Outlook.Application
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    Set objFolder = objNamespace.GetDefaultFolder(olFolderCalendar)
    Set objItems = objFolder.Items
    objItems.Sort "[Start]", False
    objItems.IncludeRecurrences = True
    strFilter = Datumsfilter(datStart, datende)
    Set objAppointment = objItems.Find(strFilter)
    While objAppointment Is Nothing
        With objAppointment
            TerminLoeschen .EntryID
        End With
        Set objAppointment = objItems.FindNext
    Wend
    Set objAppointment = objItems.Find(strFilter)
    While TypeName(objAppointment) <> "Nothing"
        With objAppointment
            TerminSpeichern .Subject, .Body, .Start, .End, .EntryID, .Categories
        End With
        Set objAppointment = objItems.FindNext
    Wend
End Sub

Die Prozedur erstellt ebenfalls ein Outlook-Objekt und einen MAPI-Namespace. Diesmal erfolgt der Zugriff auf den Ordner mit den Appointment-Elementen, der über die Funktion GetDefaultFolder(olFolderCalendar) referenziert wird. Dieser Ordner liefert eine Auflistung namens Items. Um alle Serientermine mit abzudecken, stellen Sie zunächst die Sortierung der enthaltenen Elemente auf das Feld Start ein und setzen dann die Eigenschaft IncludeRecurrences auf True. Die Funktion Datumsfilter liefert einen auf dem Start- und dem Enddatum basierenden Filterausdruck:

Public Function Datumsfilter(datStart As Date, datende As Date) As String
    Dim strStart As String
    Dim strEnde As String
    strStart = Format(datStart, "ddddd hh:nn")
    strEnde = Format(datende, "ddddd hh:nn")
    Datumsfilter = "[Start] <= " & Chr(34) & strEnde & Chr(34) & " AND [End] > " & Chr(34) & strStart & Chr(34)
End Function

Dieser wird anschließend der Find-Methode der Items-Auflistung zugewiesen. Wird kein Eintrag gefunden, enthält die Variable objAppointment den Wert Nothing und die Prozedur wird beendet. Anderenfalls wird der gefundene Termin in der Datenbank gelöscht, was auf Basis der EntryID des Outlook-Termins geschieht. In einer While…Wend-Schleife durchläuft die Prozedur nun zunächst alle Outlook-Termine, um diese über die Prozedur TerminLoeschen aus der Datenbank zu entfernen:

Public Sub TerminLoeschen(strEntryID As String)
    Dim db As DAO.Database
    Set db = CurrentDb
    db.Execute "DELETE FROM tblTermine WHERE EntryID =''" & strEntryID & "''", dbFailOnError
    Set db = Nothing
End Sub

Die gleiche Schleife wird noch ein weiteres Mal durchlaufen. Diesmal ruft die Prozedur innerhalb der Schleife jedoch die Prozedur TerminSpeichern auf, die für jeden Termin einen neuen Datensatz in der Tabelle tblTermine anlegt und sich auch um die Kategorien kümmert (s. Listing 3).

Listing 3: Speichern eines Termins in der Tabelle tblTermine und Anlegen der Kategorien

Public Sub TerminSpeichern(strTitel As String, strInhalt As String, datStartzeit As Date, _
        datEndzeit As Date, strEntryID As String, strKategorien As String)
    Dim db As DAO.Database
    Dim lngTerminID As Long
    Dim lngKategorieID As Long
    Dim strKategorienTemp() As String
    Dim strKategorie As String
    Dim i As Integer
    Set db = CurrentDb
    db.Execute "INSERT INTO tblTermine(Titel, Inhalt, Startzeit, Endzeit, EntryID) VALUES(''" _
        & Replace(strTitel, "''", "''''") & "'', ''" & Replace(strInhalt, "''", "''''") & "'', " _
        & ISODatum(datStartzeit) & ", " & ISODatum(datEndzeit) & ", ''" & strEntryID & "'')", _
    dbFailOnError
    If Len(strKategorien) > 0 Then
         lngTerminID = db.OpenRecordset("SELECT @@IDENTITY").Fields(0)
        strKategorienTemp = Split(strKategorien, ";")
        For i = LBound(strKategorienTemp) To UBound(strKategorienTemp)
            strKategorie = Trim(strKategorienTemp(i))
            On Error Resume Next
            db.Execute "INSERT INTO tblOutlookkategorien(Outlookkategorie) VALUES(''" _
                & strKategorie & "'')", dbFailOnError
            On Error GoTo 0
            If db.RecordsAffected = 0 Then
                lngKategorieID = db.OpenRecordset("SELECT OutlookkategorieID FROM " _
                    & "tblOutlookkategorien WHERE Outlookkategorie = ''" & strKategorie & "''").Fields(0)
            Else
                lngKategorieID = db.OpenRecordset("SELECT @@IDENTITY").Fields(0)
            End If
            db.Execute "INSERT INTO tblTermineOutlookkategorien(TerminID, OutlookkategorieID) " _
                & "VALUES(''" & lngTerminID & "'',''" & lngKategorieID & "'')", dbFailOnError
        Next i
    End If
    Set db = Nothing
End Sub

Die Prozedur nimmt als Parameter die zu speichernden Informationen zum jeweiligen Termin entgegen, unter anderem auch die Liste der Kategorien. Gleich zu Beginn schreibt sie die Termindaten in die Tabelle tblTermine, wobei in Betreff und Inhalt vorkommende Hochkommata wiederum verdoppelt werden. Wenn für den Termin in Outlook eine oder mehrere Kategorien festgelegt wurden, ermittelt die Prozedur zunächst die TerminID des soeben angelegten Termindatensatzes. Anschließend teilt sie die in der Variablen strKategorien gespeicherten Kategoriebezeichnungen mit der Split-Anweisung in einzelne Elemente auf und speichert diese in einem Array namens strKategorienTemp().

Diese Elemente durchläuft die Prozedur dann in einer For…Next-Schleife. Die jeweilige Kategorie wird von führenden und folgenden Leerzeichen befreit und in der Variablen strKategorie gespeichert. Die folgenden Anweisungen tragen die Kategorie in die Tabelle tblOutlookkategorien ein und ermitteln den Wert des Primärschlüsselfeldes OutlookkategorieID des neuen Datensatzes. Gegebenenfalls ist dieser bereits vorhanden, dann wird die Variable lngKategorieID mit dem Primärschlüsselwert des bereits angelegten Datensatzes gefüllt. Mit der TerminID und der OutlookkategorieID ausgestattet kann dann die Beziehung zwischen Termin und Kategorie in der Tabelle tblTermineOutlookkategorien hergestellt werden.

Termine mit Kategorien in Outlook anlegen

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

Schreibe einen Kommentar