Zur Hauptseite ... Zum Onlinearchiv ... Zum Abonnement ... Zum Newsletter ... Zu den Tools ... Zum Impressum ... Zum Login ...

Achtung: Dies ist nicht der vollständige Artikel, sondern nur ein paar Seiten davon. Wenn Sie hier nicht erfahren, was Sie wissen möchten, finden Sie am Ende Informationen darüber, wie Sie den ganzen Artikel lesen können.

Kompletten Artikel lesen?

Einfach für den Newsletter anmelden, dann lesen Sie schon in einer Minute den kompletten Artikel und erhalten die Beispieldatenbanken.

E-Mail:

Gedrucktes Heft

Diesen Beitrag finden Sie in Ausgabe 3/2015.

Unser Angebot für Sie!

Lesen Sie diesen Beitrag und 500 andere sofort im Onlinearchiv, und erhalten Sie alle zwei Monate brandheißes Access-Know-how auf 72 gedruckten Seiten! Plus attraktive Präsente, zum Beispiel das bald erscheinende Buch 'Access 2010 - Das Grundlagenbuch für Entwickler'!

Diesen Beitrag twittern

Outlook-Textbausteine mit Access

Wäre es nicht toll, wenn Sie eine Kundenanfrage, die keine individuelle Antwort erfordert, per Textbaustein beantworten könnten, der dennoch etwas Individualität aufweist? Dazu würde es ja beispielsweise reichen, wenn Sie den Kunden ordentlich anreden, beispielsweise mit »Sehr geehrter Herr Müller«. Das Ganze sollte dann auch noch mit möglichst wenig Handgriffen geschehen, also beispielsweise über einen Klick auf einen Ribbon-Eintrag der zu beantwortenden Mail oder einen Kontextmenü-Eintrag. Wie dies gelingt und wie Sie Ihre Kundendatenbank einbeziehen, um Anrede und Name zur E-Mail-Adresse des Absenders zu ermitteln, zeigt dieser Beitrag.

Textbausteine für Outlook-Mails

Textbausteine etwa im Antworttext auf Support-Anfragen sind ja im Allgemeinen verpönt. Allerdings muss man auch sagen, dass es ermüdend sein kann, wenn man als Support-Mitarbeiter immer wieder die gleichen Anfragen mit ähnlichen Antworten zurücksendet. Entscheidend ist also vielleicht gar nicht einmal, dass man überhaupt Textbausteine verwendet, sondern dass man diese sinnvoll einsetzt – der Kunde darf auch durchaus erkennen, dass er eine Standardantwort auf seine Anfrage erhält. Das gilt allerdings nur, wenn er dadurch auch die Antwort erhält, die sein Problem löst.

Wir wollen uns erstmal von diesen kommunikativen Problemen lösen und uns der technischen Umsetzung zuwenden. Auch wenn es ein Leichtes ist, den Posteingang und somit auch die Kundenanfragen etwa in die Kundendatenbank umzuleiten und von dort aus zu antworten, so ist der eine oder andere doch so sehr den Umgang mit Outlook gewöhnt, dass er sich ungern davon lossagen möchte. Also verlegen wir den Schwerpunkt der Lösung dieses Kapitels einmal nicht in die Access-Anwendung, sondern direkt nach Outlook.

Die Lösung soll es ermöglichen, auf eine Kunden-Anfrage zu antworten und dabei Textbausteine aus der Datenbank abzurufen. Nun könnten Sie natürlich einfach ein paar unpersönliche Textbausteine verwenden, aber dafür müssten Sie beispielsweise die Anrede in der E-Mail (je nach Umgang Sehr geehrter Herr Müller, Hallo Herr Müller oder auch Lieber Herr Müller) von Hand formulieren. Es wäre also praktisch, wenn die Lösung auch dies übernehmen könnte. Das würde erfordern, dass wir anhand der Absenderadresse der Anfrage-E-Mail erkennen, um welchen Kunden es sich handelt. Dazu müssten wir mit der E-Mail-Adresse auf die Kundendatenbank zugreifen und erstens herausfinden, ob der Kunde überhaupt ermittelt werden kann und zweitens Anrede, Vorname und/oder Nachname ermitteln. Daraus bauen wir dann die E-Mail-Anrede zusammen.

Fehlt nur noch der eigentliche Text. Wir gehen davon aus, dass diese Lösung einfache Anfragen beantworten soll, also beispielsweise danach, wo der Leser eines Access-Magazins seine Zugangsdaten für das Online-Archiv findet. Die verschiedenen Antworttexte sollen dabei einfach über das Kontextmenü in der Antwort-E-Mail auswählbar sein. Ein Klick soll den Text dann, versehen mit der personalisierten Anrede, in die Mail übertragen.

Soweit zur Aufgabenstellung – fangen wir an!

Technik: Outlook-Add-In

Zu meinem Befremden hat Microsoft die Möglichkeit, Kontextmenüs in Outlook-Fenstern über die CommandBars-Auflistung auszulesen und anzupassen, komplett gestrichen. Das wäre auch zu einfach gewesen: Wir hätten die komplette Funktion dann einfach in das VBA-Projekt von Outlook integrieren können. Stattdessen müssen (oder dürfen) wir uns nun mit der Programmierung eines COM-Add-Ins mittels Visual Studio 2013 beschäftigen. Dürfen deshalb, weil dies doch sehr interessante Möglichkeiten eröffnet. Die Grundlagen zur Erstellung eines COM-Add-Ins sowie zu seiner Weitergabe haben Sie bereits im Beitrag COM-Add-Ins mit Visual Studio Community 2013 (www.access-im-unternehmen.de/982) kennengelernt, und wie Sie ein solches Add-In mit einem geeigneten Setup-Projekt weitergeben, erfahren Sie unter dem Titel COM-Add-Ins: Setup erstellen (www.access-im-unternehmen.de/983). Also steigen wir gleich in die Materie ein.

COM-Add-In erstellen

Starten Sie zunächst Visual Studio. Dann wählen Sie den Menübefehl Datei|Neu|Projekt... aus. Im nun erscheinenden Dialog entscheiden wir uns für ein Projekt mit der Vorlage Outlook 2010-Add-In und legen den Projektnamen Textbausteine2010 fest (s. Bild 1).

Neues Add-In für Outlook 2010 anlegen

Bild 1: Neues Add-In für Outlook 2010 anlegen

Warum Outlook 2010? Nun: Auf dem Rechner mit Visual Studio ist nur Office 2010 installiert. Daher ist es praktisch, zunächst für Outlook 2010 zu entwickeln – so kann man den aktuellen Stand immer mal wieder zum Debuggen testen. Später schauen wir uns dann an, wie Sie das Projekt für Outlook 2013 bereitstellen.

Visual Studio erstellt nun das Projekt und zeigt das Klassenmodul ThisAddIn mit den beiden Standard-Ereignisprozeduren der hier vorgesehenen Schnittstelle an. Hier müssen wir nun Code unterbringen, der dafür sorgt, dass die entsprechenden Kontextmenü-Einträge zum Kontextmenü des E-Mail-Entwurfs hinzugefügt werden.

Erster Test

Schauen wir uns gleich mal an, ob die mit einem einfachen Meldungsfenster ausgestattete Er­eig­nis­prozedur beim Debuggen mit Outlook funktioniert. Die Prozedur sieht nun so aus:

Private Sub ThisAddIn_Startup() Handles Me.Startup
     MsgBox("Startup")
End Sub

Klicken Sie dann auf die Schaltfläche mit dem Pfeil nach rechts und dem Text Starten, auf den Menüeintrag Debuggen|Debugging starten oder auf die Taste F5. Dies öffnet Outlook und die frisch angelegte MsgBox erscheint.

Kontextmenü-Erweiterung hinzufügen

Nun fügen wir zunächst die reine Kontextmenü-Erweiterung hinzu – zunächst in Form eines einzigen Eintrags. Dazu sind mehrere Schritte nötig, die dem Access-Entwickler ungewohnt vorkommen dürften. Dieser fügt ja der Anwendung eine Tabelle namens USysRibbons hinzu, welche die Ribbon-Definition enthält, und gibt dann für die Eigenschaften der Anwendung und der Formulare an, welches Ribbon mit welchem Fenster angezeigt werden soll.

Grundstruktur zum Projekt hinzufügen

Hier benötigen Sie zunächst eine neue Klasse, welche die grundlegende Struktur für den Aufbau einer individuellen Ribbon-Definition liefert. Diese fügen Sie über den Menüeintrag Projekt|Neues Element hinzufügen... von Visual Studio zum Projekt hinzu (s. Bild 2).

Hinzufügen eines neuen Elements

Bild 2: Hinzufügen eines neuen Elements

Dies zeigt den Dialog Neues Element hinzufügen aus Bild 3 an. Hier finden Sie eine ganze Reihe möglicher Elemente vor, die nach Kategorien sortiert sind. Wählen Sie hier den Eintrag Menüband (XML) aus. Geben Sie als Bezeichnung für die zu erstellende Klasse den Wert Ribbon_Mail.vb ein und klicken Sie auf Hinzufügen.

Auswahl des Elements Menüband (XML) namens Ribbon_Mail

Bild 3: Auswahl des Elements Menüband (XML) namens Ribbon_Mail

Anschließend erscheint die automatisch generierte Klasse in Visual Studio (s. Bild 4). Die Klasse enthält die Implementierung der Schnittstelle IRibbonExtensibility. Deren wichtigstes Element ist die Funktion GetCustomUI. Diese wird beim Laden des Add-Ins ausgelöst und kann mit der anzuwendenden Ribbon-Definition gefüllt werden.

Die neu hinzugefügte Klasse

Bild 4: Die neu hinzugefügte Klasse

Diese Funktion sieht aktuell wie folgt aus:

Public Function GetCustomUI(ByVal ribbonID As String) _
         As String Implements _
         Office.IRibbonExtensibility.GetCustomUI
     Return GetResourceText( _
         "Textbausteine2010.Ribbon_Mail.xml")
End Function

Mit Return übergibt sie das Ergebnis der Funktion GetResourceText, welche den Inhalt einer im Projekt eingebundenen XML-Datei einliest – in diesem Fall namens Ribbon_Mail.xml. Diese Datei finden Sie auch im Projektmappen-Explorer, s. Bild 5.

Der Projektmappen-Explorer mit der Ressourcen-Datei

Bild 5: Der Projektmappen-Explorer mit der Ressourcen-Datei

Schauen wir uns diese Ressourcen-Datei einmal an:

<?xml version="1.0" encoding="UTF-8"?>
<customUI ... onLoad="Ribbon_Load">
   <ribbon>
     <tabs>
       <tab idMso="TabAddIns">
         <group id="MyGroup" label="My Group">
         </group>
       </tab>
     </tabs>
   </ribbon>
</customUI>

Dies kommt dem Access-Entwickler nun doch wieder sehr bekannt vor – zumindest wenn er bereits einmal mit Access 2007 oder neuer gearbeitet hat.

Erster Test

Wollen wir einmal schauen, ob diese Erweiterung bereits angezeigt wird, und starten das Debugging mit F5. Outlook wird geöffnet, unsere MsgBox-Anweisung zeigt ihre Meldung an, aber am Ribbon ändert sich nichts.

Nun: Vielleicht ist ein Fehler aufgetreten, den wir nicht sehen, weil die entsprechende Option nicht aktiviert ist. Diese Einstellung finden Sie im Optionen-Dialog von Outlook im Bereich Erweitert|Entwickler (s. Bild 6). Aktivieren Sie dort die Option Add-In-Benutzeroberflächenfehler anzeigen und schließen Sie die Optionen wieder.

Aktivieren der Anzeige von Ribbon-Fehlern

Bild 6: Aktivieren der Anzeige von Ribbon-Fehlern

Nun beenden wir das Debugging, indem wir Outlook schließen, und starten erneut mit F5.

Es geschieht immer noch nichts. Um zu prüfen, ob die Prozedur GetCustom­UI überhaupt aufgerufen wird, fügen wir dort eine MsgBox-Anweisung ein. Allerdings ohne Erfolg. Dann zeigt sich, dass Lesen immer weiterhilft: Oben im automatisch erstellten Klassenmodul steht nämlich der Hinweis, dass man die folgende Prozedur in die Klasse ThisAddIn kopieren soll:

Protected Overrides Function _
         CreateRibbonExtensibilityObject() As _
         Microsoft.Office.Core.IRibbonExtensibility
     Return New Ribbon_Mail()
End Function

Bingo! Nach dem erneuten Start des Debuggers öffnet sich Outlook und zeigt das Tab-Element namens Add-Ins mit dem Group-Element MyGroup an (s. Bild 7).

Die erste Ribbon-Anpassung

Bild 7: Die erste Ribbon-Anpassung

Ribbon im Mail-Fenster

Nun wollen wir allerdings nicht das Ribbon des Hauptfensters von Outlook anpassen, sondern ein Kontextmenü des Mail-Fensters. Nun bietet die Funktion GetCustomUI ja den Parameter ribbonID an. Dieser enthält den Namen des Objekts, von dem aus die Funktion aufgerufen wurde. Zu Testzwecken erweitern wir GetCustomUI zunächst um ein Meldungsfenster, das den Inhalt von ribbonID ausgibt (s. Listing 1).

Public Function GetCustomUI(ByVal ribbonID As String) As String Implements Office.IRibbonExtensibility.GetCustomUI
     MsgBox(ribbonID)
     Return GetResourceText("Textbausteine2010.Ribbon_Mail.xml")
End Function

Listing 1: Ausgabe der ribbonID des aktuell aufgerufenen Ribbons

Wenn Sie nun erneut debuggen, erscheint beim Start von Outlook zunächst ein Meldungsfenster mit dem Inhalt Microsoft.Outlook.Explorer. Dies ist also anscheinend die Bezeichnung des Hauptfensters von Outlook. Öffnen Sie nun ein neues E-Mail-Fenster, erscheint die Meldung aus Bild 8. Dieser Abbildung entnehmen wir erstens, dass das Mail-Fenster Microsoft.Outlook.Mail.Compose heißt, und zweitens, dass das Ribbon dieses Fensters sich zum Zeitpunkt des Aufrufs von GetCustomUI offensichtlich noch im Aufbau befindet. Wenn Sie eine bereits vorhandene Mail öffnen, heißt das Fenster übrigens Microsoft.Outlook.Mail.Read. Wir müssen also nun zunächst eine Prüfung auf den Wert von ribbonID in die Funktion Get­Cus­tomUI einbauen, die nur im Falle des Wertes Microsoft.Outlook.Mail.Compose eine neue Ribbon-Definition zurückgibt. Dazu verwenden wir eine Select Case-Anweisung, die so aussieht:

Die Funktion GetCustomUI wird auch beim Öffnen eines E-Mail-Fensters aufgerufen.

Bild 8: Die Funktion GetCustomUI wird auch beim Öffnen eines E-Mail-Fensters aufgerufen.

Select Case ribbonID
     Case "Microsoft.Outlook.Mail.Compose"
         Return GetResourceText( _
             "Textbausteine2010.Ribbon_Mail.xml")
End Select

Diese Änderung allein führt nun dazu, dass die bereits bekannte Ribbon-Definition nun auf das Fenster zum Erstellen einer neuen E-Mail angewendet wird (s. Bild 9). Wo wir schon einmal soweit sind: Eigentlich können wir die Bezeichnungen der Textbausteine ja auch über das Ribbon verfügbar machen. Damit müsste der Benutzer zwar erst die Stelle im Text markieren, an welcher der Textbaustein eingefügt werden soll, aber immerhin wäre dieser Befehl dann immer sichtbar. Die Erfahrung zeigt, dass Benutzer nicht unbedingt immer das Kontextmenü auf der Suche nach nützlichen Befehlen durchsuchen. Fügen wir also zunächst Steuerelemente zum Ribbon hinzu, die vorerst einige statische Texte in die Mail einfügen.

Ribbon-Definition im Mail-Fenster

Bild 9: Ribbon-Definition im Mail-Fenster

Textbaustein-Auswahlmenü zum Ribbon hinzufügen

Die Textbausteine sollen per Menu-Steuerelement auswählbar sein. Wo auf den verschiedenen Tabs des Ribbons der neuen E-Mail platzieren wir dieses? Ein eigenes Tab wäre wohl übertrieben. Wenn Sie die Funktion zum Einsetzen von Textbausteinen oft nutzen möchten, können Sie diese direkt auf dem Ribbon-Tab namens Nachricht anzeigen, das direkt beim Öffnen der neuen Mail erscheint. Besser geeignet scheint jedoch das Tab Einfügen. Also wollen wir dort ein Menu-Element mit vorerst vier Einträgen unterbringen, die jeweils die Bezeichnung Textbaustein 1, Textbaustein 2, Textbaustein 3 und Textbaustein 4 enthalten.

Grundlegender XML-Code für die Ribbon-Anpassung

Der dazu benötigte XML-Code sieht wie in Listing 2 aus.

<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" loadImage="loadImage">
     <ribbon>
         <tabs>
             <tab idMso="TabInsert">
                 <group id="grpEinfuegen" label="Textbausteine" insertAfterMso="GroupInclude">
                     <menu label="Textbaustein auswählen" id="mnuTextbausteine" size="large" image="text_32">
                         <button label="Textbaustein 1" id="btnTextbaustein1" onAction="onAction" image="text_16"/>
                         <button label="Textbaustein 2" id="btnTextbaustein2" onAction="onAction" image="text_16"/>
                         <button label="Textbaustein 3" id="btnTextbaustein3" onAction="onAction" image="text_16"/>
                         <button label="Textbaustein 4" id="btnTextbaustein4" onAction=""nAction""image="text_16"/>
                     </menu>
                 </group>
             </tab>
         </tabs>
     </ribbon>
</customUI>

Listing 2: Ribbon-Definition mit einem Menü und vier Unterpunkten

In dieser Definition stecken eine Reihe Elemente, die wir erläutern müssen – gerade für Ribbon-Neulinge, aber auch für Entwickler, die schon einmal mit Ribbons entwickelt haben. Die Ribbon-Definition beschreibt die Struktur der Ribbon-Steuerelemente.

Das customUI-Element ist das Hauptelement. Darunter finden wir das ribbon-Element, das alle Elemente enthält, welche das Aussehen der Ribbon-Leiste oben in der Anwendung beschreiben. Es gibt noch andere Elemente wie etwa Kontextmenüs, aber dazu kommen wir ja gleich.

Unterhalb des ribbon-Elements folgt ein zusammenfassendes tabs-Element, das die einzelnen tab-Elemente einfasst. Die tab-Elemente enthalten beispielsweise ein Attribut namens label, mit dem Sie die Beschriftung eines benutzerdefinierten tab-Elements festlegen. In diesem Fall wollen wir aber kein tab-Element hinzufügen, sondern ein group-Element zu einem eingebauten tab-Element hinzufügen. Dazu müssen wir den Namen dieses tab-Elements ermitteln und diesen für die Eigenschaft idMso des tab-Elements angeben.

idMso für eingebaute Ribbon-Elemente ermitteln

Aber woher erfahren wir den Namen dieses Elements? Dies ist insbesondere unter Outlook eine Herausforderung, denn hier gibt es nicht nur ein Ribbon, sondern eines für die Hauptanwendung und je ein weiteres für die vielen weiteren Fenster – etwa zum Verfassen einer Mail, zum Anzeigen einer Mail, zum Anzeigen eines Termins, zum Anzeigen eines Kontakts und viele mehr. Microsoft hat eine Reihe von Excel-Dateien bereitgestellt, die jeweils eine Liste aller Elemente eines Ribbons enthalten. Sie finden diese zum Download unter und . In Bild 10 haben wir beispielsweise die Dateien für Office 2013 dargestellt, die von uns benötigte ist markiert.

Liste aller Dateien mit Ribbon-Elementen für die verschiedenen Anwendungen und Outlook-Inspektoren

Bild 10: Liste aller Dateien mit Ribbon-Elementen für die verschiedenen Anwendungen und Outlook-Inspektoren

Wir möchten nun beispielsweise wissen, wie das tab-Element heißt, dem wir unser group-Element hinzufügen möchten. Wir wissen lediglich, dass die deutsche Fassung Einfügen heißt. Und so öffnen wir die Datei outlookmailitemcontrols.xlsx und schauen, ob wir einen Eintrag finden, der in der Spalte Control Type den Wert Tab besitzt und der übersetzt etwas mit Einfügen zu tun hat. Diesen finden wir recht schnell, wie Bild 11 zeigt.

Ermitteln des Namens eines tab-Elements

Bild 11: Ermitteln des Namens eines tab-Elements

Somit erhalten wir den Wert TabInsert für das Attribut idMso. Nun haben wir also einen Bezug zum Einfügen-Tab hergestellt. Wir möchten nun ein neues group-Element namens Textbausteine einfügen.

Das ist kein Problem, wird aber zumindest interessanter, wenn wir es nicht einfach ganz hinten, sondern an einer bestimmten Position einfügen möchten – in unserem Fall gleich neben der wichtigsten Gruppe Einschließen, die sich ganz links befindet (s. Bild 12). In der Abbildung sehen Sie auch schon den zu erstellenden Eintrag.

Hier möchten wir landen.

Bild 12: Hier möchten wir landen.

Der Name dieses group-Elements ist in der Excel-Tabelle outlookmailitemcontrols.xlsx nun nicht mehr schwer zu finden – es folgt hinter dem soeben bereits ermittelten tab-Element TabInsert und heißt GroupInclude. Damit unsere Gruppe direkt hinter dieser Gruppe landet, fügen wir diesem Element das Attribut insertAfterMso den Namen der Gruppe als Wert hinzu.

Nun folgt das eigentliche Steuerelement, nämlich ein menu-Element mit der Beschriftung Text­bau­stein auswählen, dessen Größe mit dem Attribut size auf large eingestellt ist und dem wir mit dem image-Attribut ein Bild mit der Referenzbezeichnung text_32 zuweisen:

<menu label="Textbaustein auswählen" id="mnuTextbausteine" size="large" image="text_32">

Wie wir diese Bilder holen, erfahren Sie gleich im Anschluss. Erst werfen wir noch einen Blick auf einen der Menüeinträge, die etwa so definiert werden:

<button label="Textbaustein 1" id="btnTextbaustein1" onAction="onAction" image="text_16"/>

Die Menüeinträge werden als button-Elemente definiert, die zunächst eine Bezeichnung (label) und die eindeutige Kennzeichnung (id) aufweisen. Dann folgt das Attribut onAction, mit dem wir den Namen der Visual-Basic-Callback-Funktion angeben, die beim Anklicken dieses Elements ausgelöst werden soll. Und schließlich haben wir auch dem Menü-Eintrag wieder eine Bildreferenz zugewiesen, die diesmal text_16 heißt.

Bei Mausklick ...

Zunächst kommen wir zum onAction-Attribut. Die dort angegebene Funktion onAction legen Sie wie in Listing 3 im Klassenmodul Ribbon_Mail.vb an.

    Sub OnAction(control As Office.IRibbonControl)
         Dim objMail As Outlook.MailItem
         Select Case control.Id
             Case "btnTextbaustein1"
                 objMail = Globals.ThisAddIn.Application.ActiveInspector().CurrentItem()
                 objMail.Body = "Dies ist der Textbaustein mit der Nummer 1." & objMail.Body
             Case "btnTextbaustein2"
                 objMail = Globals.ThisAddIn.Application.ActiveInspector().CurrentItem()
                 objMail.Body = "Dies ist der Textbaustein mit der Nummer 2." & objMail.Body
             Case "btnTextbaustein3"
                 objMail = Globals.ThisAddIn.Application.ActiveInspector().CurrentItem()
                 objMail.Body = "Dies ist der Textbaustein mit der Nummer 3." & objMail.Body
             Case "btnTextbaustein4"
                 objMail = Globals.ThisAddIn.Application.ActiveInspector().CurrentItem()
                 objMail.Body = "Dies ist der Textbaustein mit der Nummer 4." & objMail.Body

Sie haben das Ende des frei verfügbaren Teils des Artikels erreicht. Lesen Sie weiter, um zu erfahren, wie Sie den vollständigen Artikel lesen und auf viele hundert weitere Artikel zugreifen können.

Sind Sie Abonnent?Jetzt einloggen ...
 

Kompletten Artikel lesen?

Einfach für den Newsletter anmelden, dann lesen Sie schon in einer Minute den kompletten Artikel und erhalten die Beispieldatenbanken.

E-Mail:

© 2003-2015 André Minhorst Alle Rechte vorbehalten.