Outlook: Kalender und Termine programmieren

Möchtest Du den gesamten Artikel lesen? Und vielleicht sogar den Artikel im PDF-Format und die Beispieldateien herunterladen? Dann hole Dir den Artikel gleich hier - völlig kostenlos!

Outlook-Kalender und -Termine sind neben den E-Mails und Kontakten weitere wichtige Elemente. In diesem Artikel schauen wir uns an, wie wir per VBA auf die einzelnen Kalender und die darin enthaltenen Termine zugreifen können. Dabei durchlaufen wir Kalender und Termine, um diese auszulesen, legen neue Termine an, löschen Termine und bearbeiten vorhandene Termine. Wozu das alles? Damit wir wissen, welche Elemente und welche Eigenschaften wir per VBA referenzieren müssen, um verschiedene Aufgaben erfüllen zu können: Zugriff von anderen Anwendungen, um Termine anzulegen, Termine zu lesen oder auch um Termine aus Outlook heraus in andere Kalenderanwendungen wie beispielsweise Google Calendar zu exportieren.

Den Outlook-Kalender dürfte mittlerweile jeder kennen: Er bietet auf der linken Seite die Monatsübersicht, auf der rechten Seite sehen wir die jeweils aktive Ansicht der Termine. In Bild 1 wird beispielsweise die Monatsübersicht dargestellt. Daneben gibt es auch noch Tages- und verschiedene Wochenansichten. Die Ansichten interessieren uns in diesem Artikel jedoch nicht, denn wir wollen ausschließlich per VBA auf die enthaltenen Termine zugreifen. Dabei haben wir folgende Aktionen im Blick:

Der Outlook-Kalender in der Monatsansicht

Bild 1: Der Outlook-Kalender in der Monatsansicht

  • Referenzieren von Kalendern
  • Funktion zum Holen des Standardkalenders
  • Durchlaufen und Referenzieren von Terminen
  • Aktuell markierten Termin referenzieren
  • Wichtige Eigenschaften von Terminen
  • Eigenschaften für den aktuellen Termin ausgeben
  • Details zu Erinnerungen
  • Methoden von Terminen
  • Ereignisse von Terminen
  • Anlegen eines neuen Termins
  • Auslesen bestimmter Termine
  • Löschen vorhandener Termine
  • Bearbeiten vorhandener Termine
  • Details zu Zeitzonen

Wo programmieren wir Outlook?

Wir führen die nachfolgend vorgestellten Beispiele im VBA-Projekt von Outlook aus. Das heißt, dass wir Outlook öffnen und mit der Tastenkombination Alt + F11 zum VBA-Editor wechseln. Hier legen wir für unsere Beispiele ein neues Modul an, beispielsweise namens mdlKalenderUndTermine. Mehr zum Ausführen von VBA-Prozeduren in Outlook haben wir im Artikel Outlook: Codebeispiele ausprobieren (www.vbentwickler.de/313) beschrieben.

Referenzieren von Kalendern

Unter Outlook finden wir den Standardkalender und gegebenenfalls noch weitere, freigegebene Kalender. Wir wollen uns in diesem Artikel auf den Standardkalender beziehen.

Dazu nutzen wir die Prozedur aus Listing 1. Hier deklarieren wir zunächst Objektvariablen für die Outlook-Anwendung selbst, für den MAPI-Namespace, der alle Informationen wie E-Mails, Kontakte, Termine et cetera enthält und eine Folder-Variable namens objCalendar. Warum der Datentyp Folder? Weil alle Elemente von Outlook in Foldern gespeichert sind. Es gibt kein spezielles Objekt etwa mit dem Typ Calendar.

Public Sub ReferenceCalendar()
     Dim objOutlook As Outlook.Application
     Dim objMAPI As Outlook.NameSpace
     Dim objCalendar As Outlook.Folder
     Set objOutlook = New Outlook.Application
     Set objMAPI = objOutlook.GetNamespace("MAPI")
     Set objCalendar = objMAPI.GetDefaultFolder(olFolderCalendar)
     Debug.Print "Calender name: " & objCalendar.Name
     Debug.Print "Appointments: " & objCalendar.Items.count
End Sub

Listing 1: Referenzieren des Standardkalenders

Danach referenzieren wir zuerst die Outlook-Anwendung. Mit New Outlook.Application greifen wir entweder auf die laufende Outlook-Anwendung zu oder erzeugen eine neue Instanz.

In der aktuellen Umgebung, also im VBA-Editor mit dem VBA-Projekt von Outlook, sollten wir allerdings mit Application auf die aktuelle Outlook-Instanz zugreifen – hier könnte die Verwendung von New Outlook.Application zu Problemen führen. Aber damit wir den Code ohne Umschweife in andere VBA-Projekte beispielsweise von Excel oder Access übertragen oder diesen in twinBASIC oder ähnlichen Entwicklungsumgebungen nutzen können, greifen wir hier im Text explizit auf die jeweiligen Objekte zu.

Die nächste Anweisung referenziert den MAPI-Namespace mit der Variablen objMAPI. Dann greifen wir mit der GetDefaultFolder und dem Parameter olFolderCalendar auf den Kalender-Ordner von Outlook zu und speichern den Verweis in objCalendar. Dann geben wir den Namen des Folders aus, der in der deutschen Version Kalender heißt, und ermitteln noch die Anzahl der im Kalenderordner enthaltenen Elemente.

Funktion zum Holen des Standardkalenders

Diese Schritte sind immer nötig, wenn wir auf Elemente des Kalender-Ordners zugreifen wollen. Damit wir nicht immer die gleichen Anweisungen in die folgenden Beispielprozeduren und -funktionen schreiben müssen, programmieren wir die Prozedur ReferenceCalendar in eine Funktion um, die wir GetDefaultCalendar nennen. Diese Funktion soll einen Rückgabewert des Datentyps Folder liefern. Sie enthält weitestgehend die gleichen Anweisungen wie die Prozedur, von der sie abgeleitet wurde – am Ende gibt sie jedoch noch den Verweis auf den Kalender als Funktionswert zurück:

Public Function GetDefaultCalendar() As Folder
     Dim objOutlook As Outlook.Application
     Dim objMAPI As Outlook.NameSpace
     Dim objCalendar As Outlook.Folder
     Set objOutlook = New Outlook.Application
     Set objMAPI = objOutlook.GetNamespace("MAPI")
     Set objCalendar = _
         objMAPI.GetDefaultFolder(olFolderCalendar)
     Set GetDefaultCalendar = objCalendar
End Function

Durchlaufen und Referenzieren von Terminen

In der folgenden Prozedur durchlaufen wir alle Termine des aktuellen Kalenders. Das können, wenn Du den Kalender intensiv nutzt, viele Einträge sein. Du kannst vorsichtshalber innerhalb der Schleife die Anweisung DoEvents einbauen, damit Du zwischenzeitlich abbrechen kannst, wenn es zu lange dauert.

Die Prozedur ListAppointments deklariert zwei Objekte zum Referenzieren der Kalender-Einträge. Eigentlich wollen wir auf die AppointmentItem-Elemente zugreifen, aber der Kalender-Ordner kann auch Elemente anderer Typen enthalten. Deshalb referenzieren wir jedes Element erst einmal mit der Variablen objItem mit dem allgemeinen Datentyp Object.

Zuvor lesen wir allerdings den Kalender-Ordner mit der zuvor beschriebenen Funktion GetDefaultCalendar ein. Danach durchlaufen wir in einer For…Each-Schleife alle Elemente der Auflistung objCalendar.Items. In der Schleife untersuchen wir in einer Select Case-Bedingung den Wert von TypeName(objItem), was beispielsweise die Zeichenkette AppointmentItem liefert. Genau diesen Fall wollen wir untersuchen und weisen den Inhalt von objItem der Variablen objAppointmentItem zu. Dann geben wir beispielhaft den Betreff des Termins aus:

Public Sub ListAppointments()
     Dim objCalendar As Outlook.Folder
     Dim objAppointmentItem As Outlook.AppointmentItem
     Dim objItem As Object
     Set objCalendar = GetDefaultCalendar
     For Each objItem In objCalendar.Items
         Select Case TypeName(objItem)
             Case "AppointmentItem"
                 Set objAppointmentItem = objItem
                 With objAppointmentItem
                     Debug.Print .Subject
                 End With
         End Select
     Next objItem
End Sub

Aktuell markierten Termin referenzieren

Gerade beim Experimentieren mit den Eigenschaften von Kalenderelementen kann es hilfreich sein, den aktuell markierten Eintrag im Kalender zu referenzieren.

Das erledigen wir mit der folgenden Funktion, die ein Objekt des Typs Outlook.AppointmentItem zurückliefern soll. Sie referenziert erst die Outlook-Anwendung und dann den aktiven Explorer (sprich: das Hauptfenster).

Schließlich prüft sie, ob der Wert der Eigenschaft Count der Auflistung Selection ungleich 0 ist. In diesem Fall referenziert sie das erste markierte Element mit der Variablen objAppointmentItem, das sie dann auch als Funktionswert zurückliefert:

Public Function GetSelectedAppointmentItem() _
         As Outlook.AppointmentItem
     Dim objOutlook As Outlook.Application
     Dim objExplorer As Outlook.Explorer
     Dim objAppointmentItem As AppointmentItem
     Set objOutlook = New Outlook.Application
     Set objExplorer = objOutlook.ActiveExplorer
     If Not objExplorer.Selection.count = 0 Then
         Set objAppointmentItem = _
             objExplorer.Selection.Item(1)
     End If
     Set GetSelectedAppointmentItem = objAppointmentItem
End Function

Wichtige Eigenschaften von Terminen

Bevor wir nun genauer auf die verschiedenen Aktionen eingehen, die wir mit Terminen erledigen können, sehen wir uns einige wichtige Eigenschaften von Terminen an. In Bild 2 haben wir markiert, wo wir einige der Eigenschaften in einem Outlook-Termin in der Benutzeroberfläche finden.

Ein Termin im Inspektor.

Bild 2: Ein Termin im Inspektor.

Und hier sind die Eigenschaften:

  • AllDayEvent: Gibt an, ob es sich um einen ganztätigen Termin handelt.
  • BillingInformation: Normalerweise nicht genutzte Eigenschaft, die man mit benutzerdefinierten Werten füllen kann.
  • Body: Inhalt des Termins.
  • BodyFormat: Format des Inhalts, kann die Werte olFormatHTML, olFormatPlain oder olFormatRichText annehmen.
  • BusyStatus: Zeigt an, welchen Status der Bericht anzeigen soll – zum Beispiel Frei (0 olFree), An anderem Ort tätig (4 olWorkingElsewhere), Mit Vorbehalt (1 olTentative), Gebucht (2 olBusy) oder Außer Haus (3 olOutOfOffice) (siehe Bild 3)
  • Status eines Termins

    Bild 3: Status eines Termins

  • Categories: Kategorien des Termins. Liefert eine Liste der Kategorien, denen der Termin zugeordnet ist.
  • Duration: Dauer des Termins in Minuten
  • End: Ende des Termins mit dem Datentyp Date
  • EndTimeZone: Gibt die Zeitzone für das Ende des Termins an.
  • EndInEndTimeZone: Gibt die Zeit für das Ende des Termins in der als Parameter übergebenen Zeitzone an.
  • EntryID: Eindeutige ID des Termins
  • Importance: Gibt die Priorität des Termins an. Mögliche Werte sind 0 olImportanceLow, 1 olImportanceNormal und 2 olImportanceHigh.
  • IsRecurring: Gibt an, ob es sich um einen Serientermin handelt.
  • GetOrganizer: Liefert den Organisator des Termins.
  • Location: Gibt den Ort des Termins an.
  • ReminderMinutesBeforeStart: Gibt an, wie viele Minuten vor einem Termin eine Erinnerung erfolgen soll.
  • ReminderOverrideDefault: Gibt an, ob die Standardeinstellungen des Benutzers für eine Erinnerung überschrieben werden sollen.
  • ReminderPlaySound: Gibt an, ob mit der Erinnerung ein Ton abgespielt werden soll.
  • ReminderSet: Gibt an, ob eine Erinnerung ausgegeben werden soll.
  • ReminderSoundFile: Gibt den Pfad zu einer Sounddatei an, die bei Eintreten der Erinnerung abgespielt werden soll.
  • RTFBody: Inhalt des Termins im RTF-Format
  • Sensitivity: Gibt an, wie vertraulich der Termin ist. Mögliche Werte sind 0 olNormal, 1 olPersonal, 2 olPrivate oder 3 olConfidental. Nur die Werte 0 und 2 können über die Benutzeroberfläche eingestellt werden. Bei 0, 1 und 3 ist die Umschaltfläche Privat im Ribbon nicht aktiviert, bei 2 ist sie aktiviert.
  • Start: Start des Termins mit dem Datentyp Date
  • StartTimeZone: Gibt die Zeitzone für den Start des Termins an.
  • StartInStartTimeZone: Gibt die Zeit für den Start des Termins in der als Parameter übergebenen Zeitzone an.
  • Subject: Betreff des Termins

Eigenschaften für den aktuellen Termin ausgeben

Wenn wir schon mit der Funktion GetSelectedAppointmentItem den aktuellen Termin ermitteln können, wollen wir auch direkt einmal alle soeben vorgestellten Eigenschaften ausgeben. Dies erledigen wir mit der Prozedur ShowAppointmentItemProperties aus Listing 2.

Public Sub ShowAppointmentItemProperties()
     Dim objAppointmentItem As AppointmentItem
     Set objAppointmentItem = GetSelectedAppointmentItem
     With objAppointmentItem
         Debug.Print "AllDayEvent: " & .AllDayEvent
         Debug.Print "BillingInformation: " & .BillingInformation
         Debug.Print "Body: " & .Body
         Debug.Print "BodyFormat: " & .BodyFormat
         Debug.Print "BusyStatus: " & .BusyStatus
         Debug.Print "Categories: " & .Categories
         Debug.Print "Duration: " & .Duration
         Debug.Print "End: " & .End
         Debug.Print "EndTimeZone: " & .EndTimeZone
         Debug.Print "EndInEndTimeZone: " & .EndInEndTimeZone
         Debug.Print "EntryID: " & .EntryID
         Debug.Print "IsRecurring: " & .IsRecurring
         Debug.Print "Location: " & .Location
         Debug.Print "Importance: " & .Importance
         Debug.Print "ReminderMinutesBeforeStart: " & .ReminderMinutesBeforeStart
         Debug.Print "ReminderOverrideDefault: " & .ReminderOverrideDefault
         Debug.Print "ReminderPlaySound: " & .ReminderPlaySound
         Debug.Print "ReminderSet: " & .ReminderSet
         Debug.Print "ReminderSoundFile: " & .ReminderSoundFile
         ''Debug.Print "RTFBody: " & .RTFBody
         Debug.Print "Sensitivity: " & .Sensitivity
         Debug.Print "Start: " & .Start
         Debug.Print "StartTimeZone: " & .StartTimeZone
         Debug.Print "StartInStartTimeZone: " & .StartInStartTimeZone
         Debug.Print "Subject: " & .Subject
         Debug.Print "GetOrganizer: " & .GetOrganizer
     End With
End Sub

Listing 2: Ausgeben der Eigenschaften eines Termins

Hier referenzieren wir den aktuellen Termin und geben dann per Debug.Print alle besprochenen Eigenschaften mit Namen und Wert im Direktbereich aus. Die Eigenschaft RTFBody haben wir auskommentiert, da diese nur Binärcode liefert, der ohnehin nicht lesbar ist.

Details zu Erinnerungen

Wenn wir Erinnerungen per VBA einstellen wollen, reicht es nicht wie in der Benutzeroberfläche aus, die Anzahl der Minuten einzustellen, die zwischen der Erinnerung und dem Termin liegen sollen.

Genau genommen reicht es aus, die Eigenschaft ReminderSet auf True einzustellen. Allerdings wird dann der Standardwert für die Eigenschaft ReminderMinutesBeforeStart übernommen, die bei uns auf 15 Minuten eingestellt ist. Entweder man legt den Standardwert über die Benutzeroberfläche auf einen anderen Wert fest (in den Outlook-Optionen im Bereich Kalender|Kalenderoptionen) oder man setzt explizit die Eigenschaft ReminderMinutesBeforeStart auf den gewünschten Wert ein.

Methoden von Terminen

Für Termine finden wir die folgenden wichtigen Methoden:

  • Display: Zeigt einen Termin im Inspector an.
  • Save: Speichert den Termin.
  • SaveAs: Erlaubt das Speichern eines Termins im Dateisystem. Als Parameter muss der Dateipfad angegeben werden. Als Dateiendung verwenden wir .ics, für den zweiten Parameter Type geben wir den Wert olICal an.

Ereignisse von Terminen

Das AppointmentItem-Element bietet auch einige Ereignisse an, die wir implementieren können. Allerdings sind diese im Kontext dieses Artikels nicht relevant, sondern eher, wenn man auf Aktionen des Benutzers über die Benutzeroberfläche reagieren möchte – beispielsweise, wenn er den Termin schließt, eine Anlage hinzufügt et cetera.

Anlegen neuer Termine

Einen neuen Termin legen wir unter VBA mit der Methode CreateItem des Outlook.Application-Objekts an. Dabei übergeben wir mit olAppointmentItem den Typ des zu erstellenden Objekts – wir können mit dieser Methode nämlich auch E-Mails, Kontakte et cetera erstellen. Das Ergebnis referenzieren wir mit der Variablen objAppointmentItem, damit wir noch seine Eigenschaften einstellen und den Termin speichern können.

Mit der ersten Beispielprozedur erstellen wie einen Termin mit den Standardeinstellungen – das heißt, wir nehmen keine Anpassungen von Eigenschaften vor uns speichern den Termin direkt mit der Save-Methode des AppointmentItem-Elements:

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