Bei meinem Vortrag auf dem .NET Summercamp 2007 habe ich dieses kleine Smart Tag Beispiel vorgestellt. Die Idee des Smart Tags ist folgende: Wird ein Datum in Word eingegeben, so kann das Smart Tag den Outlook Kalender nach Terminen an diesem Datum durchsuchen und diese ausgeben. Das Ganze soll die Einfachheit demonstrieren, mit der ein Smart Tag erstellt werden kann und aufzeigen, wie leicht eine Interoperabilität zwischen Office Applikationen hergestellt werden kann. Auf geht es...
Ich habe das Beispiel mit VS 2008 Beta 2 erstellt. Es sollte aber auch mit VS 2005 & VSTO 2005 SE klappen. Zuerst wird ein WordDocument Projekt benötigt:
Nachdem das Projekt geladen ist, muss als erstes die COM Referenz "Microsoft Outlook 12.0 Object Library" hinzugefügt werden. Diese wird für den Zugriff auf Outlook benötigt. Weiterhin ist folgendes Namespaces für das Projekt erforderlich:
using System.Text.RegularExpressions;
using Outlook = Microsoft.Office.Interop.Outlook;
using Microsoft.Office.Tools.Word;
using System.Reflection;
Danach wird der Smart Tag erstellt. Dies wird in der Methode "ThisDocument_Startup" in der ThisDocument.cs getan:
Man initialisiert den Smart Tag und gibt diesem einen Menüpunkt, welcher ein Click-Event bekommt.
Microsoft.Office.Tools.Word.SmartTag st =
new Microsoft.Office.Tools.Word.SmartTag("http://SmartTag/ST#SmartTagDate",
"Datum in Outlook nachschlagen");
Microsoft.Office.Tools.Word.Action menue1 =
new Microsoft.Office.Tools.Word.Action("Datum in Outlook nachschlagen");
st.Actions = new Microsoft.Office.Tools.Word.Action[] { menue1 };
menue1.Click += new ActionClickEventHandler(menue1_Click);
Danach fügt man dem Smart Tag einen Regexpression hinzu, welcher die Kombination von zz.zz.zz(zz) [25.09.07] erkennt und highlightet.
st.Expressions.Add(new Regex("\\d{1,2}.\\d{1,2}.\\d{2,4}"));
Durch die Möglichkeit, Regexpression zu übergeben, hat man an dieser Stelle eine sehr performante Möglichkeit auf bestimmte Zeichenkombinationen zu reagieren. Alternative kann man dem Smart Tag mit "st.Terms.Add("String");" einen String übergeben, welcher erkannt wird. Für beides gilt, zu viele Terms bzw. Regexpression machen das Dokument langsam.
Wenden wir uns nun dem Click-Event zu, welches oben definiert wurde. Als erstes muss man das Datum parsen, welches der Benutzer eingegeben hat.
DateTime dt = DateTime.ParseExact(e.Text, "dd.MM.yy", null);
Danach muss man eine Outlook Instanz erstellen und sich bei dieser anmelden:
Outlook.Application oApp = new Outlook.Application();
Outlook.NameSpace oNS = oApp.GetNamespace("mapi");
//Login
oNS.Logon(Missing.Value, Missing.Value, true, true);
Nun muss man sich ein Kalender-Ordner Objekt besorgen und diesem eine Restriktion übergeben. Diese wird benötigt, damit man nicht über alle Kalendereintäge iteriert, sondern nur über das eine eingegebene Datum. Dazu benötigt man einen Filter:
//Kalender Ordner
Outlook.Folder folder = oApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar)
as Outlook.Folder;
if (folder != null)
{
//Nach dem Datum filtern
string filter = "[Start] >= '" + dt.ToString("g", culture)
+ "' And [End] <= '" + dt.AddDays(1).ToString("g", culture) + "'";
Outlook.Items calenderItems = folder.Items.Restrict(filter);
calenderItems.Sort("[Start]", System.Type.Missing);
calenderItems.IncludeRecurrences = true;
Der Filter benutzt die JET Notation, alternativ könnte dies auch in DASL gefiltert werden. Nach der Übergabe des Filters sortiert man die Items nach dem [Start] Element und zieht dabei auch Wiederholungen in den gefundenen Treffern mit ein (IncludeRecurrences ist das Stichwort). Achtung! Nachdem man IncludeRecurrences auf True gesetzt hat, funktioniert der Zugriff auf Outlook.Items.Count nicht mehr, so dass man keine For-Schleife benutzen kann. Es muss mit Foreach iteriert werden. (weitere Infos dazu hier).
Jetzt kümmern wir uns noch um die Ausgabe unserer gefundenen Ergebnisse:
//Ausgabe vorbereiten
StringBuilder sb = new StringBuilder();
sb.AppendLine("Folgende Termine sind an dem Tag vermerkt:\n\n");
//Nicht Outlook.Items.Count verwenden
foreach (Outlook.AppointmentItem appItem in calenderItems)
{
sb.AppendFormat("Titel:\t {0}\n", appItem.Subject);
sb.AppendFormat("Uhrzeit:\t {0} - {1}\n", appItem.Start.ToShortTimeString(),
appItem.End.ToShortTimeString());
sb.AppendLine();
}
//Ausgabe
MessageBox.Show(sb.ToString(),"Terminübersicht für den "
+ dt.ToShortDateString(),MessageBoxButtons.OK, MessageBoxIcon.Information);
Wenn man nun das Projekt startet und den Smart Tag ausprobieren möchte, wird man feststellen, dass dieser nicht funktioniert. Das liegt daran, dass man den Smart Tag in Word erst aktivieren muss.
Dies macht man in Word unter "Word Optionen"-> Add-Ins-> gehe zu "Smarttags" auswählen. Jetzt kann man den Smart Tag aktivieren.
Damit die Aktivierung funktioniert, muss das Projekt erneut gestartet werden.
Wenn man nun ein Datum in Word eingibt, sollte dieses gehighlightet werden. Sobald man mit der Maus drüberfährt, sollte unser neu erstellter Smart Tag sichtbar werden.

Das Beispiel ist als Prototype zu verstehen und soll nur das "Doing" aufzeigen. Man benötigt natürlich noch ein umfangreiches Errorhandling etc 
Das Projekt kann hier runtergeladen werden: Download