Artikel

August 2003 | Artikel

Gemeinschaftseinrichtung

(Link zum Artikel: http://www.it-republik.de/dotnet/artikel/0410)

Shared Add-ins für Office XP mit Visual Studio .NET entwickeln

Text: von Matthias Frerichs und Mathias Offner
Shared Add-ins sind weder Hexerei, noch bedarf es besonderer Fähigkeiten sie zu entwickeln. Und dennoch sind ihre Möglichkeiten, Office funktional zu erweitern, schier unbegrenzt. Die einheitliche, COM-basierende Architektur ermöglicht das Entwickeln von anwendungsübergreifendem Code. Businesslogik kann auf diese Weise in verschieden Office-Anwendungen gemeinsam verwendet werden.

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:
  1. Suchzeichenkette1#Ersetzungszeichenkette1
  2. Suchzeichenkette2#Ersetzungszeichenkette2
  3. Suchzeichenkette3#Ersetzungszeichenkette3
Das #-Symbol dient als eindeutiges Trennzeichen zwischen den beiden Zeichenketten, die später mit der Split-Methode getrennt werden.

Für den Aufruf der Add-in-Funktionalität wird das Hauptmenü von Excel um den Eintrag FAR erweitert, der wiederum den Menü-Button Öffnen enthält. Hiermit lässt sich die Dialogmaske für FAR aktivieren. Für die Implementierung müssen Visual Studio .NET ab Version 2002, Office XP (mindestens Excel XP) und die Office XP Primary Interop Assemblies installiert sein [1].
Projekt-Wizard
Der Einstieg in die Entwicklung eines Shared Add-Ins erfolgt über den Shared Add-in Projekt-Wizard.
Der Visual Studio Shared Add-in Project Wizard besteht aus fünf Dialogen, in denen die grundlegenden Einstellungen vorgenommen werden. Zu Beginn wird die Programmiersprache festgelegt. Zur Auswahl stehen Visual Basic .NET und C#. Obgleich es triftige Gründe gibt, die bei der Entwicklung von Add-ins gegen den Einsatz von C# sprechen [1], haben sich die Autoren der hier vorgestellten Anwendung für C# entschieden. Add-ins wurden lange genug mit Visual Basic erstellt.

Im zweiten Dialog werden die Office-Applikationen gewählt, die die Funktionalität des Add-ins in Anspruch nehmen. Für das vorgestellte FAR-Projekt wird lediglich Excel ausgewählt. Der dritte Dialog dient der Namensgebung des Add-ins sowie der Angabe einer Beschreibungszeile. Der Name FAR und die Beschreibung Find and Replace words in Excel liegen hier nahe.

Aktiviert man im vierten Dialog das Feld Das Add-in laden, wenn die Hostanwendung geladen wird, braucht man für ein manuelles Starten des Add-ins nicht mehr zu sorgen. Darüber hinaus lässt sich wählen, ob das Add-in für alle Benutzer des Computers verfügbar sein soll. Für das vorliegende Beispiel-Add-in werden beide Optionen aktiviert. Mit einer Zusammenfassung im Abschlussdialog beendet der Wizard seine Dienste und man erhält die in Abpictureung 2 zu sehende Projektstruktur.
Man sieht, dass der Wizard zusätzlich zu dem Add-in-Projekt ein Setup-Projekt erzeugt hat. Für die Implementierung der Extensibility.IDTExtensibility2-Schnittstelle wurde die Klasse Connect.cs vorbereitet, die die genannten Methodenrümpfe enthält.
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.
Das Ergebnis ist in Abpictureung 3 zu sehen. Wie bereits erwähnt dient die Klasse Connect.cs (Listing 1) dem Shared Add-in als Einstiegspunkt. Im Listing sind die notwendigen Erweiterungen dargestellt. Das Attribut GuidAttribute gibt einen expliziten GUID (Globally Unique Identifier) an, der einen für jedes Shared Add-in erforderlichen CLSID (Class Identifier) darstellt und von Visual Studio .NET automatisch erzeugt wird. Das Attribut ProgId ist eine für Programmierer und Benutzer lesbare Version des erforderlichen CLSID.

Listing 1
  1. namespace FAR
  2. {
  3. using System;
  4. using System.Runtime.InteropServices;
  5. using Excel = Microsoft.Office.Interop.Excel;
  6. [GuidAttribute("5A4C03D5-5578-46BF-BB0A-F668845C28F9"), ProgId("FAR.Connect")]
  7. public class Connect : Object, Extensibility.IDTExtensibility2
  8. {
  9. public Connect()
  10. {}
  11. public void OnConnection(object application,
  12. Extensibility.ext_ConnectMode connectMode,
  13. object addInInst, ref System.Array custom)
  14. {
  15. applicationObject = (Excel.Application)application;
  16. addInInstance = addInInst;
  17. }
  18. public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode,
  19. ref System.Array custom)
  20. {}
  21. public void OnAddInsUpdate(ref System.Array custom)
  22. {}
  23. public void OnStartupComplete(ref System.Array custom)
  24. {
  25. OfficeUI.CreateMenu();
  26. }
  27. public void OnBeginShutdown(ref System.Array custom)
  28. {}
  29. public static Excel.Application applicationObject;
  30. private object addInInstance;
  31. }
  32. }
Die Implementierung für die Menüstruktur sowie das Event-Handling wird in Listing 2 (OfficeUI.cs) gezeigt. Die rudimentäre Fehlerbehandlung bitten die Autoren zu entschuldigen.

Listing 2
  1. using System;
  2. using System.Reflection;
  3. using System.Diagnostics;
  4. using Microsoft.Office.Core;
  5. namespace FAR
  6. {
  7. public class OfficeUI
  8. {
  9. public static CommandBarPopup objMenu;
  10. public static CommandBarButton objMenuButton;
  11. public static String strMenuText = "FAR";
  12. public static String strMenuButtonText = "Öffnen";
  13. public static void CreateMenu()
  14. {
  15. try
  16. {
  17. DeleteMenu();
  18. objMenu = (CommandBarPopup)Connect.applicationObject.
  19. CommandBars[1].Controls.Add(
  20. MsoControlType.msoControlPopup,Missing.Value,
  21. Missing.Value,Missing.Value,Missing.Value);
  22. objMenu.Caption = strMenuText;
  23. objMenuButton = (CommandBarButton)objMenu.Controls.Add(
  24. MsoControlType.msoControlButton,Missing.Value,
  25. Missing.Value,Missing.Value,Missing.Value);
  26. objMenuButton.Caption = strMenuButtonText;
  27. objMenuButton.Click +=
  28. new _CommandBarButtonEvents_ClickEventHandler
  29. (Actions.MenuButtonClicked);
  30. }
  31. catch (Exception e)
  32. {
  33. Debug.Write(e.ToString());
  34. }
  35. }
  36. public static void DeleteMenu()
  37. {
  38. try
  39. {
  40. Connect.applicationObject.CommandBars[1].
  41. Controls[strMenuText].Delete(Missing.Value);
  42. }
  43. catch (Exception e)
  44. {
  45. Debug.Write("Menü konnte nicht gelöscht werden, da es nicht da
  46. war");
  47. Debug.Write(e.ToString());
  48. }
  49. }
  50. }
  51. }
Das Click-Ereignis des Menü-Buttons Öffnen wird innerhalb der Klasse Actions.cs (Listing 3) implementiert.

Listing 3
  1. using System;
  2. using System.Diagnostics;
  3. using Microsoft.Office.Core;
  4. using System.Windows.Forms;
  5. namespace FAR
  6. {
  7. public class Actions
  8. {
  9. public static void MenuButtonClicked
  10. (CommandBarButton cmd, ref bool action)
  11. {
  12. try
  13. {
  14. Einstellung frmEinstellungen = new Einstellung();
  15. frmEinstellungen.ShowDialog();
  16. }
  17. catch (Exception e)
  18. {
  19. Debug.Write(e.ToString());
  20. }
  21. }
  22. }
  23. }
Das Windows Form Einstellungs.cs ist in Abpictureung 4 dargestellt. Es werden eine Textbox und ein Suchbutton für die Angabe der Such- und Ersetzungszeichenketten-Liste benötigt. Darüber hinaus enthält der Dialog eine Checkbox, mit deren Hilfe sich einstellen lässt, ob der Such- und Ersetzungsvorgang auf alle Arbeitsblätter der aktiven Arbeitsmappe ausgedehnt werden soll. Ein Startbutton sollte ebenfalls nicht fehlen.
In Listing 4 (Einstellung.cs) wird die Implementierung für die Click-Ereignisse des Such- und des Startbuttons gezeigt.

Listing 4
  1. private void btnPickList_Click(object sender, System.EventArgs e)
  2. {
  3. openFileDialog1 = new OpenFileDialog();
  4. if(openFileDialog1.ShowDialog() == DialogResult.OK)
  5. {
  6. txtPickList.Text = openFileDialog1.FileName.ToString();
  7. }
  8. }
  9. private void btnStartFAR_Click(object sender, System.EventArgs e)
  10. {
  11. try
  12. {
  13. FAR.FAR_FindReplaceListe(txtPickList.Text, chkAllSheets.Checked);
  14. }
  15. catch (Exception ex)
  16. {
  17. Debug.Write(ex.ToString());
  18. }
  19. finally
  20. {
  21. Close();
  22. }
Die eigentliche Logik des FAR Shared Add-Ins befindet sich in der Klasse FAR.cs (Listing 5). Hier wird die Such- und Ersetzungszeichenketten-Liste in die zu suchenden und zu ersetzenden Wörter aufgelöst und an die Excel Replace-Funktion übergeben.

Listing 5
  1. using System;
  2. using System.IO;
  3. using System.Reflection;
  4. using System.Windows.Forms;
  5. using Excel = Microsoft.Office.Interop.Excel;
  6. namespace FAR
  7. {
  8. public class FAR
  9. {
  10. public static void FAR_FindReplaceListe(string KeyValueFile,
  11. bool bolAllSheets)
  12. {
  13. if (!File.Exists(KeyValueFile))
  14. {
  15. MessageBox.Show(KeyValueFile + " does not exist!");
  16. }
  17. else
  18. {
  19. StreamReader sr = File.OpenText(KeyValueFile);
  20. string input, findWord, replaceWord;
  21. while ((input=sr.ReadLine())!=null)
  22. {
  23. string [] split = input.Split(new Char [] {'#'});
  24. findWord = split[0];
  25. replaceWord = split[1];
  26. if (bolAllSheets)
  27. {
  28. foreach (Excel.Worksheet farSheet in
  29. Connect.applicationObject.Sheets)
  30. {
  31. FAR_ExcelSheet(findWord,
  32. replaceWord,farSheet);
  33. }
  34. }
  35. else
  36. {
  37. FAR_ExcelSheet(findWord,replaceWord,
  38. (Excel.Worksheet)
  39. Connect.applicationObject.
  40. ActiveSheet);
  41. }
  42. }
  43. sr.Close();
  44. MessageBox.Show("Fertig mit FAR");
  45. }
  46. }
  47. private static void FAR_ExcelSheet(string strFind, string strReplace,
  48. Excel.Worksheet farSheet)
  49. {
  50. farSheet.Cells.Replace(strFind, strReplace,Missing.Value,
  51. Missing.Value,Missing.Value,Missing.Value,Missing.Value,
  52. Missing.Value);
  53. }
  54. }
  55. }
Um die Beispielanwendung zu debuggen, sind noch einige Einstellungen im FAR-Projekt notwendig. Zuerst wird die Konfiguration für das Debuggen im Eigenschaftsdialog des FAR-Projekts modifiziert. In den Startaktionen wird die Excel-Anwendung eingestellt und in den Startoptionen das Office-Verzeichnis auf das Arbeitsverzeichnis gesetzt (siehe Abb. 5).
Anschließend fügt man einen Breakpoint in der Klasse Connect.cs ein. Mit F5 lässt sich die Applikation nun starten.
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


Anzeige

Kommentare

zurück zum Seitenanfang