Lies in den Artikel rein und unten bekommst Du ein unschlagbares Angebot!
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:
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.
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)
- 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
Bild 3: Status eines 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: