Projektzeiterfassung mit Outlook und Access

Die Erfassung von Projektzeiten ist eine Aufgabe, die man gern etwas stiefmütterlich handhabt. Am Ende des Tages, der Woche oder auch des Monats muss man dann die für verschiedene Aufgaben verbrauchte Zeit aus dem Gedächtnis nachtragen. Dem wollen wir mit einer Lösung, die Outlook und Access nutzt, entgegenwirken. Damit legen Sie eine Tätigkeit einer bestimmten Dauer – in diesem Fall 25 Minuten – ganz einfach per Drag and Drop in den Outlook-Kalender an. Der Rest geschieht im Hintergrund: Die Tätigkeit wird samt Projekt und Aufgabe in einer Access-Datenbank gespeichert und kann anschließend bequem ausgewertet werden.

Der Clou bei dieser Lösung ist, dass es wirklich nur weniger Vorbereitungen sowie einer Drag-and-Drop-Aktion bedarf, um schnell eine Tätigkeit zu dokumentieren. Die grundlegende Konfiguration erfordert Outlook und Access ab der Version 2007.

Wenn Sie Outlook öffnen, stellen Sie zunächst die Ansicht der linken Leiste auf Ordner um (s. Bild 1).

Wechsel auf die Ordner-Ansicht

Bild 1: Wechsel auf die Ordner-Ansicht

Danach erscheint links eine übersicht der einzelnen Outlook-Elemente als Ordner – Posteingang, Entwürfe, Gesendete Elemente und so weiter. Für uns ist der Ordner Aufgaben interessant.

Dort legt die Lösung aus diesem Beitrag beim Starten von Outlook automatisch einen Unterordner namens Projekte an. Mit dem Eintrag Neuer Ordner… des Kontextmenüs dieses Eintrags legen Sie einen Unterordner an, der ein neues Projekt repräsentiert (s. Bild 2).

Anlegen eines neuen Projekt-Ordners

Bild 2: Anlegen eines neuen Projekt-Ordners

Zu Beispielzwecken wollen wir diesen Ordner Projekt 1 nennen.

Ein Projekt soll eine oder mehrere Aufgaben aufnehmen. Damit Sie diese anlegen können, klicken Sie den frisch angelegten Ordner Projekt 1 an. Dies blendet die aktuell für diesen Aufgabenordner vorhandenen Aufgaben im Hauptbereich von Outlook ein. Hier fügen Sie nun wie in Bild 3 die gewünschten Aufgaben hinzu – im Beispiel Aufgabe 1 und Aufgabe 2.

Hinzufügen von Aufgaben zu einem Projekt

Bild 3: Hinzufügen von Aufgaben zu einem Projekt

Nun können wir schon zur Kalenderansicht wechseln. Dabei müssen Sie allerdings etwas beachten: Wenn Sie per Mausklick auf das Kalender-Icon unten links zum Kalender wechseln, verschwindet auch die Ordneransicht wieder – und die sollte angezeigt bleiben, damit wir auch während der Arbeit mit dem Kalender Zugriff auf die Projektordner haben. Also nutzen Sie für den Wechsel zur Kalenderansicht den Eintrag Kalender aus der Ordnerliste.

Hier prüfen wir noch, ob der rechte Bereich die Aufgabenliste anzeigt. Ist dies nicht der Fall, können Sie dies etwa unter Outlook 2016 mit dem Ribbon-Eintrag An-sicht|Lay-out|Aufgabenliste|Aufgaben einblenden (s. Bild 4). Hier sehen Sie auch, wie Sie dann eine der Aufgaben aus der Aufgabenliste in den Kalenderbereich ziehen. Die Aufgabe wird dann als neue Tätigkeit genau an der Stelle angelegt, die dem aktuellen Datum und der Uhrzeit entspricht. Fertig – für die nächsten 25 Minuten steht die anstehende Aufgabe nun fest und Sie können diese bearbeiten. Danach geht es auf die gleiche Weise weiter – legen Sie eine neue Aufgabe an und bearbeiten Sie diese oder bearbeiten Sie einfach eine der vorhandenen Aufgaben weiter.

Einblenden der Aufgabenleiste und Hinzufügen von Aufgaben als Tätigkeiten zum Kalender

Bild 4: Einblenden der Aufgabenleiste und Hinzufügen von Aufgaben als Tätigkeiten zum Kalender

Datenbank zum Speichern der Projektzeitdaten

Dies war der Teil der Lösung, der sich auf die Benutzeroberfläche bezieht. Im Hintergrund geschieht noch einiges mehr: Zum Beispiel gibt es eine Access-Datenbank namens Projektzeiterfassung.accdb, welche die erfassten Daten in drei Tabelle speichert und die um Funktionen zum Auswerten der Projektzeiten erweitert werden kann.

Datenmodell der Datenbank

Das Datenmodell dieser Datenbank sieht wie in Bild 5 aus. Die Tabelle tblProjekte nimmt für jeden Ordner, den Sie unterhalb des Ordners Projekte anlegen, einen Datensatz auf und speichert dort die eingegebene Projektbezeichnung. Die übrigen Felder können nach Belieben genutzt werden, interessant ist lediglich noch das Feld GeloeschtAm. Dieses wird gefüllt, wenn der Benutzer den Projektordner in Outlook löscht.

Datenmodell der Datenbank zur Projektzeiterfassung

Bild 5: Datenmodell der Datenbank zur Projektzeiterfassung

Die Tabelle tblAufgaben speichert die einzelnen Aufgaben, die Sie im mittleren Bereich von Outlook hinzufügen, wenn Sie einen der Projektordner markiert haben. Hier finden Sie das Fremdschlüsselfeld ProjektID, das die Aufgabe einem Datensatz der Tabelle tblProjekte zuordnet. Das Feld Aufgabe ist für die Bezeichnung der Aufgabe wie in Outlook angegeben gedacht. Auch hier finden Sie wieder ein Feld namens Geloescht-Am, das beim Löschen des entsprechenden Elements aus Outlook mit dem aktuellen Datum und der Zeit gefüllt wird. Das Feld ErledigtAm schließlich wird gefüllt, wenn der Benutzer die Aufgabe in Outlook als erledigt markiert. Dies können Sie beispielsweise in der übersichtsliste der Aufgaben erledigen (s. Bild 6). Eine andere Möglichkeit bietet der Eintrag Als erledigt markieren im Kontextmenü der Aufgabenliste in der Kalenderansicht.

Markieren einer Aufgabe als

Bild 6: Markieren einer Aufgabe als “Erledigt”

Die Tabelle tblTaetigkeiten speichert schließlich die Aufgaben, die der Benutzer als Termine in den Kalender gezogen hat. Die Tabelle enthält einige Felder mehr als die zuvor vorgestellten Tabellen. Beim Anlegen einer Tätigkeit trägt die Lösung die Bezeichnung der Tätigkeit, die Startzeit, die Endzeit sowie den Wert des Primärschlüsselfeldes der Aufgabe, zu deren Erledigung die Tätigkeit dient, in die Tabelle ein. Außerdem gibt es auch hier wieder ein Feld namens GeloeschtAm, welches das Löschdatum von entfernten Tätigkeiten aufnimmt. Das Feld KategorieID, das Sie in der Abbildung des Datenmodells sehen, benötigen wir für eine Erweiterung der hier vorgestellten Lösung aus dem Beitrag Kanban mit Outlook und Access (www.access-im-unternehmen.de/1017, siehe folgende Ausgabe).

Bild 7 zeigt die drei Tabellen mit den Beispieldatensätzen, die wir weiter oben angelegt haben, in der Datenblattansicht und deutet die Verknüpfungen der vorhandenen Datensätze durch rote Pfeile an.

Tabellen der Lösung mit einigen Beispieldaten

Bild 7: Tabellen der Lösung mit einigen Beispieldaten

Programmierung der Lösung

Der Teil der Lösung, der in diesem Beitrag beschrieben wird, spielt sich VBA-technisch komplett in Outlook ab – die Access-Datenbank stellt nur die Tabellen zum Speichern der Projektzeiten bereit. In einem weiteren Beitrag namens Projektzeiten auswerten (www.access-im-unternehmen.de/1018) zeigen wir in der folgenden Ausgabe, wie Sie die gespeicherten Daten auswerten können.

Hier schauen wir uns nun an, wie die in Outlook erstellten Projekte, Aufgaben und Tätigkeiten ihren Weg in die Tabellen der Access-Datenbank finden.

VBA-Editor unter Outlook öffnen

Ich weiß nicht, wie es Ihnen geht, aber ich öffne den VBA-Editor unter Access immer mit der Tastenkombination Strg + G und lande damit sofort im Direktbereich. Unter Outlook funktioniert diese nicht. Dort gelangen Sie am schnellsten über die Tastenkombination Alt + F11 in den VBA-Editor (dies funktioniert unter Access und den übrigen Office-Anwendungen übrigens auch).

Sicherheit

Je nachdem, wie Ihre Sicherheitseinstellungen unter Outlook aussehen, können Sie keine VBA-Prozeduren im VBA-Projekt von Outlook ausführen. Aber keine Sorge – dies ändern Sie ganz schnell. öffnen Sie den Optionen-Dialog von Outlook, wechseln Sie dort zum Bereich Trust Center und klicken Sie auf Einstellungen für das Trust Center. Hier übernehmen Sie die Option für den Bereich Makroeinstellungen wie in Bild 8.

Einstellungen zum Ausführen von VBA-Code in Outlook

Bild 8: Einstellungen zum Ausführen von VBA-Code in Outlook

Achtung: Die änderungen wirken sich erst beim nächsten Start von Outlook aus.

Wichtigstes Element: Ereignisse

Eine sehr wichtige Rolle spielen dabei die Ereignisse, die beim Anlegen von Projektordnern, Aufgaben und Terminen/Tätigkeiten ausgelöst werden. Weitere Ereignisse, die wir tracken müssen, sind das Löschen dieser drei Objektarten sowie das Verschieben, also das ändern der Eigenschaften von Objekte – in diesem Fall betrifft das nur die Termine/Tätigkeiten. Die Tätigkeiten sollen ja, wenn der Benutzer diese auf den Kalender zieht, immer genau für das aktuelle Datum und die entsprechende Zeit angelegt werden. Manchmal vergisst man jedoch, eine Tätigkeit vor Beginn in Outlook anzulegen und fügt diese nachträglich hinzu. Diese muss dann natürlich nach dem Anlegen noch an die der gewünschten Zeit entsprechende Stelle verschoben werden, üblicherweise per Drag and Drop oder durch manuelles Einstellen der Zeit nach dem öffnen des Termins per Doppelklick.

Eine solche änderung muss ebenfalls ein Ereignis auslösen, damit die neuen Zeiten die beim Anlegen in der Tabelle gespeicherten Zeiten überschreiben können. Aber auch die Projekt-ordner und die Aufgaben sind änderungen unterworfen. Diese beziehen sich jedoch nur auf die jeweilige Bezeichnung.

Damit wir die Ereignisse der drei Objektarten durch entsprechende Ereignisprozeduren implementieren können, benötigen wir jeweils entsprechende Objektvariablen, die wir mit dem Schlüsselwort WithEvents deklarieren. Da nach dem öffnen von Outlook nicht immer nur neue Projekte, Aufgaben und Tätigkeiten angelegt, bearbeitet und gelöscht werden, sondern auch die bestehenden Elemente potenziell änderungen unterworfen sind, müssen wir für alle infrage kommenden Elemente Objektvariablen anlegen und diese mit den entsprechenden Ereignisprozeduren ausstatten.

Wir benötigen also beim Start von Outlook zunächst eine Prozedur, die alle vorhandenen Elemente in Form von Objektvariablen referenziert. Diese Prozedur heißt Application_Startup und landet im standardmäßig im VBA-Projekt von Outlook vorhandenen Klassenmodul ThisOutlookSession (s. Listing 1).

Public Sub Application_Startup()
     On Error GoTo Application_Startup_Err
     Dim objProject As Outlook.Folder
     Dim objTasks As clsTasks
     Dim lngError As Long
     Set objAppointments = GetMAPINamespace.GetDefaultFolder(olFolderCalendar).Items
     On Error Resume Next
     Set objProject = GetTaskfolder.Folders("Projekte")
     If Not Err.Number = 0 Then
         GetTaskfolder.Folders.Add "Projekte", olFolderTasks
     End If
     Set objProjects = GetTaskfolder.Folders("Projekte").Folders
     On Error GoTo Application_Startup_Err
     Set objAppointmentFolder = GetMAPINamespace.GetDefaultFolder(olFolderCalendar)
     Set colProjects = New Collection
     For Each objProject In objProjects
         Set objTasks = New clsTasks
         Set objTasks.Tasks = objProject.Items
         Set objTasks.Project = objProject
         colProjects.Add objTasks
     Next
Application_Startup_Exit:
     On Error Resume Next
     Exit Sub
Application_Startup_Err:
     Call Fehlerbehandlung("Projekt1/ThisOutlookSession", "Application_Startup", _
         Erl, "Bemerkungen: ./.")
     GoTo Application_Startup_Exit
End Sub

Listing 1: Diese Prozedur wird bei Start von Outlook automatisch ausgelöst.

VBA-Projekt von Outlook

Bezüglich des VBA-Projekts von Outlook müssen Sie ein wenig von der Access-Denkweise abweichen: Unter Access hat ja jede Datenbankdatei ein eigenes VBA-Projekt – genau wie die Dokumente in Word oder Excel. Unter Outlook gibt es nur ein VBA-Projekt, das der Anwendung Outlook selbst zugeteilt ist.

Fehlerbehandlung

Die Prozedur enthält eine Fehlerbehandlung, die alle Fehler in Form einer entsprechenden Meldung behandelt. Dies dient primär dazu, die Lösung stabil zu gestalten. üblicherweise werden beispielsweise Objektvariablen bei nicht behandelten Fehlern geleert, was im Falle dieser Lösung natürlich katastrophal wäre: Wenn der Benutzer nach einem nicht behandelten Fehler fleißig weiter Projekte, Aufgaben und Tätigkeiten bearbeitet, wird nämlich keines der mit den Objektvariablen verbundenen Ereignisse mehr ausgelöst und die Daten werden nicht in der Datenbank gespeichert.

Die Prozedur Application_Startup stellt nun zunächst die Variable objAppointments des Typs Items auf die im Kalender-Ordner enthaltenen Elemente ein. Die entsprechende Variable deklarieren wir wie folgt im Kopf des Klassenmoduls:

Dim WithEvents objAppointments As Outlook.Items

Um einen leichteren Zugriff auf die Elemente von Outlook zu schaffen, haben wir im Modul mdlOutlook ein paar Hilfsfunktionen beigefügt. Hier kommen gleich mehrere zum Einsatz. Die erste heißt GetMAPINamespace und liefert einen Verweis auf das MAPI-Namespace-Objekt von Outlook, über das wir auf alle Elemente von Outlook zugreifen können (siehe unten). Das von GetMAPINamespace gelieferte Objekt bietet die Methode GetDefaultFolder, die mit dem Parameter olFolderCalendar einen Verweis auf den Standard-Kalenderordner von Outlook holt und speichert ihn in objAppointments.

Nun folgt ein Schritt, der dem Benutzer ein wenig Arbeit abnehmen soll: Wenn unterhalb des Aufgaben-Ordners in der Ordnerliste von Outlook noch kein Eintrag namens Projekte vorhanden ist, soll die Prozedur diesen automatisch anlegen. Dazu referenziert die Prozedur bei deaktivierter Fehlerbehandlung diesen Ordner über das Element Projekte der Folders-Auflistung für den Aufgaben-Ordner.

Den Aufgaben-Ordner liefert ebenfalls eine unserer Hilfsfunktionen aus dem Modul mdlOutlook, nämlich GetTaskfolder (siehe unten). Führt dieser Zugriff auf den Ordner zu einem Fehler, ist offensichtlich, dass der Ordner noch nicht vorhanden ist. Die Prozedur verwendet dann die Add-Methode der Folders-Auflistung des mit GetTaskfolder ermittelten Aufgaben-Ordners, um den Ordner namens Projekte hinzuzufügen. Danach speichert sie einen Verweis auf die Folders-Auflistung dieses Ordners in der Variablen objProjects, die ebenfalls mit dem Schlüsselwort WithEvents im Kopf des Klassenmoduls deklariert wird:

Dim WithEvents objProjects As Outlook.Folders

Die nächste auf diese Variable namens objAppointmentFolder füllt die Prozedur mit einem Verweis auf den Kalender-Ordner:

Dim WithEvents objAppointmentFolder As Outlook.Folder

Auch diesen erhalten wir mit der GetDefaultFolder-Methode des mit Get-MAPI-Namespace ermittelten MAPI-Namespace-Objekts.

Für die Implementierung weiterer Ereignisse benötigen wir auch noch Objekte auf Basis der Ordner, die der Benutzer unterhalb des Projekte-Ordners anlegt und die jeweils ein Projekt repräsentieren. Dies ist etwas aufwendiger, da wir jeden einzelnen Ordner referenzieren müssen. Dies erledigen wir mit einer Hilfsklasse, die jeweils einen Ordner aufnimmt und die dann in einer Collection namens colProjects landet. Diese deklarieren wir wie folgt im Kopf des Klassenmoduls:

Dim colProjects As Collection

Die Prozedur erzeugt diese Collection neu. Dann durchläuft sie alle Ordner im Folder Projekte in einer For Each-Schleife über die Elemente der Auflistung objProjects und legt für jeden Ordner ein neues Objekt der Klasse clsTasks an. Diese weist eine Eigenschaft namens Tasks auf, die mit der Items-Auflistung des aktuellen Projekte-Ordners gefüllt wird. Der Verweis auf den aktuellen Projekt-Ordner selbst landet in der Eigenschaft Project. Schließlich wird das so präparierte Objekt der Collection colProjects hinzugefügt.

Das waren bereits die Vorbereitungen. Nun müssen wir noch die zahlreichen Ereignisprozeduren implementieren, damit die in Outlook eingegebenen Projekte, Aufgaben und Tätigkeiten auch in den Tabellen der Datenbank landen.

Die Hilfsfunktionen GetOutlook, GetMAPINamespace und GetTaskFolder

Die drei Hilfsfunktionen aus Listing 2 finden Sie im Standardmodul mdlOutlook im VBA-Projekt von Outlook – dort natürlich mit Fehlerbehandlung, die wir hier aus Platzgründen gekürzt haben. Die erste Funktion liefert einen Verweis auf das Outlook.Application-Objekt. Dabei prüft sie, ob die lokale Variable mOutlook bereits mit einem Verweis auf das Application-Objekt gefüllt ist. Falls nicht, was eigentlich nur beim ersten Aufruf geschieht, füllt es diese Variable damit. Die Funktion gibt dann einen Verweis auf den Inhalt von mOutlook zurück.

Dim mOutlook As Outlook.Application
Dim mNamespace As Outlook.NameSpace
Dim mTaskFolder As Outlook.Folder
Public Property Get GetOutlook() As Outlook.Application
     If mOutlook Is Nothing Then
         Set mOutlook = Application
     End If
     Set GetOutlook = mOutlook
End Property
Public Property Get GetMAPINamespace() As Outlook.NameSpace
     If mNamespace Is Nothing Then
         Set mNamespace = GetOutlook.GetNamespace("MAPI")
     End If
     Set GetMAPINamespace = mNamespace
End Property
Public Property Get GetTaskfolder() As Outlook.Folder
     If mTaskFolder Is Nothing Then
         Set mTaskFolder = GetMAPINamespace.GetDefaultFolder(olFolderTasks)
     End If
     Set GetTaskfolder = mTaskFolder
End Property

Listing 2: Hilfsfunktionen für den einfachen Zugriff auf Outlook-Objekte

Die Funktion GetMAPINamespace erledigt dies mit der Variablen mNamespace und nutzt dazu die GetNamespace-Methode des Application-Objekts, das es mit der Funktion GetOutlook holt.

Fehlt noch die Funktion GetTaskfolder, die einen Verweis auf den Aufgaben-Ordner von Outlook ermittelt und zurückgibt. Dabei nutzt diese die beiden zuvor beschriebenen Funktionen sowie die lokale Variable mTaskfolder.

Die Klasse clsTasks

Diese Klasse haben Sie soeben bereits kennen gelernt, als wir für jedes Folder-Objekt eine Instanz dieser Klasse erstellt und über die Eigenschaften Tasks und Project jeweils einen Verweis auf die Aufgaben-Auflistung und den Projekt-Ordner übergeben haben.

Diese beiden Eigenschaften stellt die Klasse über die beiden Property Set-Prozeduren Tasks und Project bereit, die wie in Listing 3 aussehen.

Private WithEvents mTasks As Outlook.Items
Private WithEvents mProject As Outlook.Folder
Public Property Set Tasks(objTasks As Outlook.Items)
     Set mTasks = objTasks
End Property
Public Property Set Project(objProject As Outlook.Folder)
     Set mProject = objProject
End Property

Listing 3: Elemente der Klasse clsTasks

Damit die übergebenen Verweise in der Klasse gespeichert werden, tragen die Property Set-Prozeduren diese in die beiden Variablen mTasks und mProject ein. Beide deklarieren wir wieder mit dem Schlüsselwort With-Events, denn auch für diese wollen wir wieder Ereignisprozeduren anlegen. Diese stellen wir in den folgenden Abschnitten vor.

Auf Outlook-Aktionen reagieren und Daten in Access speichern

Damit hätten wir das Grundgerüst erstellt. Nun folgt eine Reihe von Ereignisprozeduren, mit denen wir die Benutzer-eingaben in Outlook abfangen und die dabei anfallenden Daten in der Access-Datenbank speichern. Diese schauen wir uns in der Reihenfolge an, wie sie beim Arbeiten mit der Lösung auftreten.

Verweis auf die DAO-Bibliothek

Spätestens jetzt, wo es an das Speichern von Daten in die Tabellen der Access-Datenbank geht, benötigen wir für das VBA-Projekt von Outlook einen Verweis auf die DAO-Bibliothek beziehungsweise auf die modernere Variante, die Microsoft Office x.0 Access database engine Object Library. Diesen fügen Sie wie in Bild 9 hinzu (VBA-Editor, Menüeintrag Extras|Verweise).

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