Shared Add-ins
Wenn man eine Aufgabe in einer Microsoft Office-Anwendung wiederholt ausführt, kann man den Ablauf mit einem Makro automatisieren. Ein Makro besteht aus einer Reihe von Visual Basic for Application (VBA)-Prozeduren und Funktionen, die in einem VBA-Modul gespeichert sind und jedes Mal ausgeführt werden, wenn man die Aufgabe durchführt. Damit nicht alle Anwendungsdateien den VBA-Programmcode enthalten müssen, empfiehlt sich die Implementierung der gewünschten Funktionalität innerhalb von Add-ins. Als Add-in bezeichnet man ein zusätzliches Programm zum Hinzufügen benutzerdefinierter Befehle oder Features zu Microsoft Office. Die Add-ins der ersten Generation waren anwendungsspezifisch (Excel: *.xla, Word: *.wll, Access: *.mda etc.). Erst mit der Einführung von Microsoft Office 2000 wurde mit der Component Object Model (COM)-Architektur eine einheitliche Architektur zur Verfügung gestellt, die die Entwicklung von Add-ins ermöglicht, die gemeinsam in verschiedenen Office-Anwendungen ihre Arbeit verrichten. Office-COM-Add-ins können mit Microsoft Visual Studio 6.0 oder mit der Office Developer Edition entwickelt werden. Darüber hinaus lassen sich mit Visual Studio .NET managed COM-Add-ins erzeugen, so genannte Shared Add-ins. Der Namenszusatz Shared deutet darauf hin, dass diese Add-ins von verschiedenen Office-Anwendungen gemeinsam genutzt werden können. Die Verbindung zwischen COM und .NET wird mit COM Interop realisiert, das so genannte Callable Wrappers beinhaltet, die eine Brücke zwischen der .NET- und der COM-Welt schlagen. Die Entwicklung von Shared Add-ins bietet den Vorteil, dass der Sprachumfang von C# oder Visual Basic .NET dem von VBA bei weitem überlegen ist. Shared Add-ins müssen die IDTExensibility2-Schnittstelle implementieren. Das IDTExtensibility2-Interface bezeichnet einen Satz von fünf Methoden, die die Einstiegspunkte eines Add-ins bereitstellen:- OnConnection: wird ausgelöst, wenn das Add-in geladen wird.
- OnDisconnection: wird kurz vor dem Entladen aus dem Speicher ausgelöst, d.h. bei der Deaktivierung des Add-ins.
- OnAddInsUpdate: wird ausgelöst, wenn sich die Add-in-Einträge in der Registry ändern, d.h. wenn ein Add-in installiert oder entfernt wird.
- OnStartupComplete: wird ausgelöst, sobald die Host-Anwendung (z.B. Excel XP) den Startvorgang beendet hat (nur wenn das Add-in so konfiguriert wurde, dass es beim Laden der Hostanwendung geladen wird).
- OnBeginShutdown: wird ausgelöst, sobald der Entladevorgang der Hostanwendung (z.B. Excel XP) eingeleitet wird.
Find and Replace
Die in diesem Artikel vorgestellte Beispielanwendung Find and Replace words in Excel oder kurz FAR ist ein Shared Add-in für Excel XP. Das Add-in besitzt die Funktionalität, Suchzeichenketten innerhalb der Zellinhalte des aktiven Arbeitsblatts (bzw. aller Arbeitsblätter der aktiven Arbeitsmappe) durch Ersetzungszeichenketten auszutauschen. Die Liste der Such- und Ersetzungszeichenketten ist wie folgt aufgebaut:Suchzeichenkette1#Ersetzungszeichenkette1Suchzeichenkette2#Ersetzungszeichenkette2Suchzeichenkette3#Ersetzungszeichenkette3
Projekt-Wizard
Der Einstieg in die Entwicklung eines Shared Add-Ins erfolgt über den Shared Add-in Projekt-Wizard.
FAR implementieren
Zu Beginn muss eine Referenz auf die Excel-Bibliothek anleget werden, die sich unter dem Komponentennamen Microsoft Excel 10.0 Object Library versteckt (COM). Der vom Wizard erzeugte Verweis Office wird gelöscht, da mit dem Verweis auf die Excel-Bibliothek auch die neue Referenz Microsoft.Office.Core aus den Office XP Primary Interop Assemblies hinzugefügt wurde. Unsere Architektur orientiert sich an einem Vorschlag von Simon Guest and Siew-Moi Khor [2]. Die vom Wizard erzeugte Projektstruktur wird hiernach um folgende Klassen ergänzt:- Die Klasse OfficeUI.cs ist verantwortlich für das Menü-Handling.
- In der Actions.cs-Klasse wird die Aktion des Menü-Ereignisses implementiert.
- Das Windows Form Einstellung.cs enthält den Dialog für die FAR-Optionen.
- Die Klasse FAR.cs verwendet den Algorithmus für das Suchen und Ersetzen in Excel.
namespace FAR{using System;using System.Runtime.InteropServices;using Excel = Microsoft.Office.Interop.Excel;[GuidAttribute("5A4C03D5-5578-46BF-BB0A-F668845C28F9"), ProgId("FAR.Connect")]public class Connect : Object, Extensibility.IDTExtensibility2{public Connect(){}public void OnConnection(object application,Extensibility.ext_ConnectMode connectMode,object addInInst, ref System.Array custom){applicationObject = (Excel.Application)application;addInInstance = addInInst;}public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode,ref System.Array custom){}public void OnAddInsUpdate(ref System.Array custom){}public void OnStartupComplete(ref System.Array custom){OfficeUI.CreateMenu();}public void OnBeginShutdown(ref System.Array custom){}public static Excel.Application applicationObject;private object addInInstance;}}
using System;using System.Reflection;using System.Diagnostics;using Microsoft.Office.Core;namespace FAR{public class OfficeUI{public static CommandBarPopup objMenu;public static CommandBarButton objMenuButton;public static String strMenuText = "FAR";public static String strMenuButtonText = "Öffnen";public static void CreateMenu(){try{DeleteMenu();objMenu = (CommandBarPopup)Connect.applicationObject.CommandBars[1].Controls.Add(MsoControlType.msoControlPopup,Missing.Value,Missing.Value,Missing.Value,Missing.Value);objMenu.Caption = strMenuText;objMenuButton = (CommandBarButton)objMenu.Controls.Add(MsoControlType.msoControlButton,Missing.Value,Missing.Value,Missing.Value,Missing.Value);objMenuButton.Caption = strMenuButtonText;objMenuButton.Click +=new _CommandBarButtonEvents_ClickEventHandler(Actions.MenuButtonClicked);}catch (Exception e){Debug.Write(e.ToString());}}public static void DeleteMenu(){try{Connect.applicationObject.CommandBars[1].Controls[strMenuText].Delete(Missing.Value);}catch (Exception e){Debug.Write("Menü konnte nicht gelöscht werden, da es nicht dawar");Debug.Write(e.ToString());}}}}
using System;using System.Diagnostics;using Microsoft.Office.Core;using System.Windows.Forms;namespace FAR{public class Actions{public static void MenuButtonClicked(CommandBarButton cmd, ref bool action){try{Einstellung frmEinstellungen = new Einstellung();frmEinstellungen.ShowDialog();}catch (Exception e){Debug.Write(e.ToString());}}}}
private void btnPickList_Click(object sender, System.EventArgs e){openFileDialog1 = new OpenFileDialog();if(openFileDialog1.ShowDialog() == DialogResult.OK){txtPickList.Text = openFileDialog1.FileName.ToString();}}private void btnStartFAR_Click(object sender, System.EventArgs e){try{FAR.FAR_FindReplaceListe(txtPickList.Text, chkAllSheets.Checked);}catch (Exception ex){Debug.Write(ex.ToString());}finally{Close();}
using System;using System.IO;using System.Reflection;using System.Windows.Forms;using Excel = Microsoft.Office.Interop.Excel;namespace FAR{public class FAR{public static void FAR_FindReplaceListe(string KeyValueFile,bool bolAllSheets){if (!File.Exists(KeyValueFile)){MessageBox.Show(KeyValueFile + " does not exist!");}else{StreamReader sr = File.OpenText(KeyValueFile);string input, findWord, replaceWord;while ((input=sr.ReadLine())!=null){string [] split = input.Split(new Char [] {'#'});findWord = split[0];replaceWord = split[1];if (bolAllSheets){foreach (Excel.Worksheet farSheet inConnect.applicationObject.Sheets){FAR_ExcelSheet(findWord,replaceWord,farSheet);}}else{FAR_ExcelSheet(findWord,replaceWord,(Excel.Worksheet)Connect.applicationObject.ActiveSheet);}}sr.Close();MessageBox.Show("Fertig mit FAR");}}private static void FAR_ExcelSheet(string strFind, string strReplace,Excel.Worksheet farSheet){farSheet.Cells.Replace(strFind, strReplace,Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value);}}}
Ausblick
Die Zukunft der Office-Programmierung ist aus Sicht der Autoren nicht mehr in der integrierten VBA-Umgebung, sondern in Visual Studio .NET zu suchen. Dies ist auch daran zu erkennen, dass Microsoft neben Office 2003 ein Programmierwerkzeug für die Bürosoftware anbieten wird, die Visual Studio Tools for Office. Eine Beta-Version ist bereits verfügbar (siehe msdn.microsoft.com/vstudio/office/). Die hiermit erstellten Programme steuern Office-Anwendungen nicht von außen, wie es bei den Primary Interop Assemblies von Office XP der Fall ist, sondern laufen wie VBA-Code hinter den Dokumenten ab. Diese Art von Add-in wird von der Common Language Runtime (CLR) ausgeführt. Mittels des Trusted Code-Konzepts können zum Beispiel die eingebauten Sicherheitsfunktionen des .NET Frameworks auch auf Office-Dateien ausgeweitet werden. Dies hätte unter anderem die Eindämmung von Makro-Viren zur Folge. Geschäftslogik für Office wird zukünftig mit dem Visual Studio .NET implementiert - any time, any place and on any device.Matthias Frerichs (Matthias.Frerichs@mummert.de) und Mathias Offner (Mathias.Offner@mummert.de) sind Berater bei Mummert Consulting im Geschäftsfeld Integrated Business Consulting. Sie beschäftigen sich seit Mitte 2000 mit der .NET-Technologie und eine halbe Ewigkeit mit MS Office Integration.
Links und Literatur
- [1] Christian Bleske, Bürotäter; dot.net magazin 3.2003
- [2] Simon Guest and Siew-Moi Khor, Developing .NET Smart Clients for Microsoft Office XP, 2002: msdn.microsoft.com/library/default.asp?url=/library/en-us/dnoxpta/html/odc_dnscof.asp






