{"id":55000344,"date":"2022-12-01T00:00:00","date_gmt":"2023-03-02T16:57:12","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=344"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"ExcelDatei_per_COMAddIn_als_xlsm_speichern","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/ExcelDatei_per_COMAddIn_als_xlsm_speichern\/","title":{"rendered":"Excel-Datei per COM-Add-In als .xlsm speichern"},"content":{"rendered":"<p><b>Wer viel mit Excel-Worksheets arbeitet und diesen regelm&auml;&szlig;ig VBA-Code hinzuf&uuml;gt, muss diese als .xlsm-Datei speichern, damit die &Auml;nderungen am VBA-Projekt beim Schlie&szlig;en nicht verlorengehen. Dazu muss man immer den Backstage-Bereich von Excel &ouml;ffnen und einige Mausklicks durchf&uuml;hren. Wie w&auml;re es, wenn man diese Aktion direkt im Backstage-Bereich finden w&uuml;rde &#8211; und nur noch einen Mausklick t&auml;tigen m&uuml;sste, damit das aktuelle Excel-Worksheet nicht nur unter dem gleichen Namen und der Dateiendung .xlsm gespeichert wird, sondern auch noch die urspr&uuml;ngliche .xlsx-Datei gel&ouml;scht wird? Wie das geht, zeigen wir in diesem Artikel.<\/b><\/p>\n<h2>Vorbereitung: twinBASIC<\/h2>\n<p>Wie Du twinBASIC herunterl&auml;dst und installierst, haben wir im Artikel <b>twinBASIC: Visual Basic f&uuml;r die Zukunft <\/b>(<b>www.vbentwickler.de\/310<\/b>) beschrieben.<\/p>\n<h2>COM-Add-In erstellen<\/h2>\n<p>Um das COM-Add-In zu erstellen, startest Du <b>twinBASIC <\/b>und w&auml;hlst im Startbildschirm unter <b>Samples <\/b>den Eintrag <b>Sample 5. MyCOMAddin <\/b>aus (siehe Bild 1). Danach speichern wir das neu angelegte Projekt erst einmal unter dem gew&uuml;nschten Namen, in diesem Fall <b>MakeXLSM<\/b>.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_06\/pic_344_001.png\" alt=\"Projekt auf Basis der Vorlage MyCOMAddin erstellen\" width=\"424,6267\" height=\"413,088\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Projekt auf Basis der Vorlage MyCOMAddin erstellen<\/span><\/b><\/p>\n<h2>Verweis auf die Excel-Bibliothek hinzuf&uuml;gen<\/h2>\n<p>Damit wir direkt per IntelliSense auf die Elemente der Excel-Bibliothek zugreifen k&ouml;nnen, f&uuml;gen wir dem Projekt einen entsprechenden Verweis hinzu. Dazu wechseln wir in twinBASIC zum Bereich Settings. Hier scrollen wir nach unten zum Bereich <b>COM Type Library \/ ActiveX References<\/b>.<\/p>\n<p>Unter <b>All Available COM References <\/b>aktivieren wir mit einem Klick auf das Lupe-Symbol ein Suchfeld und geben <b>Excel <\/b>ein.<\/p>\n<p>Der Eintrag <b>Microsoft Excel 16.0 Object Library <\/b>erscheint und wir f&uuml;gen einen Verweis auf diese Bibliothek hinzu, indem wir das K&auml;stchen vor diesem Eintrag anhaken (siehe Bild 2).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_06\/pic_344_002.png\" alt=\"Hinzuf&uuml;gen eines Verweises auf die Excel-Bibliothek\" width=\"549,6265\" height=\"322,6841\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Hinzuf&uuml;gen eines Verweises auf die Excel-Bibliothek<\/span><\/b><\/p>\n<h2>Name und Beschreibung des Projekts anpassen<\/h2>\n<p>Wenn wir schon die Einstellungen anpassen, k&ouml;nnen wir auch gleich den Namen und die Beschreibung des Projekts &auml;ndern. Dazu passen wir die beiden Eigenschaften <b>Project: Name <\/b>und <b>Project: Description <\/b>im oberen Bereich der Einstellungen an (siehe Bild 3).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_06\/pic_344_003.png\" alt=\"Einstellen von Projektname und -beschreibung\" width=\"549,6265\" height=\"330,3088\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Einstellen von Projektname und -beschreibung<\/span><\/b><\/p>\n<h2>Einstellungen speichern<\/h2>\n<p>Diese &Auml;nderungen speichern wir mit der Tastenkombination <b>Strg + S<\/b>, was in der Regel einen Neustart von twinBASIC ausl&ouml;st.<\/p>\n<h2>Projektdateien anpassen<\/h2>\n<p>Schlie&szlig;lich &auml;ndern wir auch noch den Dateinamen von der Vorgabe <b>COMAddIn.twin <\/b>in <b>MakeXLSM.twin <\/b>und den Klassennamen von <b>COMAddIn <\/b>in <b>MakeXLSM <\/b>(siehe Bild 4).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_06\/pic_344_004.png\" alt=\"Einstellen des Klassennamens und des Dateinamens\" width=\"549,6265\" height=\"299,3973\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Einstellen des Klassennamens und des Dateinamens<\/span><\/b><\/p>\n<h2>Die Klasse MakeXLSM anpassen<\/h2>\n<p>In der Klasse <b>MakeXLSM<\/b>, die beispielsweise die Implementierung der Schnittstellen <b>IDTExtensibility2 <\/b>und <b>IRibbonExtensibility <\/b>&uuml;bernimmt, nehmen wir einige &Auml;nderungen vor. Die wichtigsten fassen wir nachfolgend zusammen.<\/p>\n<p>Wir deklarieren eine Variable namens <b>objExcel <\/b>mit dem Datentyp <b>Excel.Application<\/b>, der wir in der Ereignismethode <b>OnConnection <\/b>den Verweis auf die Excel-Instanz zuweisen, durch die das COM-Add-In aufgerufen wird:<\/p>\n<pre><span style=\"color:blue;\">Private <\/span>objExcel<span style=\"color:blue;\"> As <\/span>Excel.Application<\/pre>\n<p>Au&szlig;erdem deklarieren wir eine Variable, mit der wir sp&auml;ter die Ribbondefinition referenzieren wollen. Dies hat den Nutzen, dass wir dann die Methode <b>Invalidate <\/b>aufrufen k&ouml;nnen, um unsere Ribbon-Steuerelemente per Code zu aktualisieren. Die Deklaration sieht wie folgt aus:<\/p>\n<pre><span style=\"color:blue;\">Public <\/span>objRibbon<span style=\"color:blue;\"> As <\/span>IRibbonUI<\/pre>\n<h2>Referenz zur Excel-Anwendung herstellen<\/h2>\n<p>Die Variable <b>objExcel <\/b>f&uuml;llen wir wie folgt in der Prozedur <b>OnConnection<\/b>:<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>OnConnection(ByVal Application<span style=\"color:blue;\"> As Object<\/span>, _\r\n         ByVal ConnectMode<span style=\"color:blue;\"> As <\/span>ext_ConnectMode, _\r\n         ByVal AddInInst<span style=\"color:blue;\"> As Object<\/span>, _\r\n         ByRef custom<span style=\"color:blue;\"> As Variant<\/span>()) _\r\n         Implements IDTExtensibility2.OnConnection\r\n     <span style=\"color:blue;\">Set<\/span> objExcel = Application\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Befehl zum Backstagebereich hinzuf&uuml;gen<\/h2>\n<p>Bevor wir uns um die eigentliche Funktion k&uuml;mmern, wollen wir uns erst einmal in die Benutzeroberfl&auml;che von Excel einnisten, und zwar in den Backstage-Bereich. Hier wollen wir den Befehl <b>In .xlsm umwandeln <\/b>direkt links in der Liste der &uuml;brigen Befehle zum &Ouml;ffnen der verschiedenen Bereiche oder zum Aufrufen von Funktionen integrieren.<\/p>\n<p>Dazu definieren wir in der Funktion <b>GetCustomUI<\/b> die ben&ouml;tigte Ribbon-Anpassung. Die Funktion sieht anschlie&szlig;end wie in Listing 1 aus.<\/p>\n<pre><span style=\"color:blue;\">Private Function <\/span>GetCustomUI(ByVal RibbonID<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As String<\/span> Implements IRibbonExtensibility.GetCustomUI\r\n     <span style=\"color:blue;\">Dim <\/span>strXML<span style=\"color:blue;\"> As String<\/span>\r\n     strXML &= \"&lt;?xml version=\"\"1.0\"\"?&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strXML &= \"&lt;customUI xmlns=\"\"http:\/\/schemas.microsoft.com\/office\/2009\/07\/customui\"\" loadImage=\"\"loadImage\"\" \" _\r\n         & \"onLoad=\"\"onLoad\"\"&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strXML &= \"  &lt;backstage&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strXML &= \"    &lt;button id=\"\"btnMakeXLSM\"\" onAction=\"\"onAction\"\" insertAfterMso=\"\"TabInfo\"\" \" _\r\n         & \"getEnabled=\"\"getEnabled\"\" label=\"\"In .xlsm umwandeln\"\" image=\"\"console.ico\"\"\/&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strXML &= \"  &lt;\/backstage&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strXML &= \"&lt;\/customUI&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     Return strXML\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Die Funktion LoadCustomUI l&auml;dt die in strXML zusammengestellte Ribbondefinition.<\/span><\/b><\/p>\n<p>Die Anpassung f&uuml;gt im Wesentlichen einen Eintrag zum <b>Backstage<\/b>-Bereich von Excel hinzu. Dieser erh&auml;lt die Beschriftung <b>In .xlsm umwandeln <\/b>und soll das Icon <b>console.ico <\/b>anzeigen, welches wir gleich zum Projekt hinzuf&uuml;gen. Au&szlig;erdem soll das neue Backstage-Element bei mir relativ weit oben angezeigt werden, weil ich es oft ben&ouml;tige. Wenn Du es lieber an einer anderen Position ablegen m&ouml;chtest, kannst Du den Wert des Attributs <b>insertAfterMso <\/b>nutzen und die <b>idMso <\/b>des jeweiligen Elements dort eintragen. Wie findest Du die <b>idMso<\/b>? Indem Du in den Excel-Optionen zum Bereich <b>Men&uuml;band anpassen <\/b>wechselst, unter <b>Befehle ausw&auml;hlen <\/b>den Eintrag <b>Registerkarte &#8220;Datei&#8221; <\/b>selektierst und mit der Maus &uuml;ber den Befehl f&auml;hrst, vor oder hinter dem Du das neue Steuerelement einf&uuml;gen m&ouml;chtest (siehe Bild 5). Aber Achtung: Es funktioniert leider nicht f&uuml;r alle Elemente. Zumindest <b>FileSave <\/b>haben wir aber noch erfolgreich ausprobiert.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_06\/pic_344_005.png\" alt=\"Ermitteln der idMso f&uuml;r ein Backstage-Element\" width=\"549,6265\" height=\"352,3017\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Ermitteln der idMso f&uuml;r ein Backstage-Element<\/span><\/b><\/p>\n<p>Ein weiteres wichtiges Element in der Ribbondefinition des <b>button<\/b>-Elements ist das Attribut <b>onAction<\/b>, f&uuml;r das wir den Namen der VBA-Prozedur angeben, die dadurch aufgerufen werden soll und die wir weiter unten beschreiben.<\/p>\n<p>Das Attribut <b>getEnabled <\/b>ben&ouml;tigen wir, weil wir das <b>button<\/b>-Element dynamisch aktivieren oder deaktivieren wollen. Die f&uuml;r dieses Attribut hinterlegte Funktion liefert den Wert <b>True <\/b>oder <b>False <\/b>und aktiviert oder deaktiviert so die Schaltfl&auml;che. Warum sollten wir den Button deaktivieren? Weil es passieren kann, dass das geladene Excel-Workbook bereits das Format <b>.xlsm <\/b>aufweist. Dann ben&ouml;tigen wir den Befehl nat&uuml;rlich nicht mehr.<\/p>\n<p>Auch im Element <b>customUI <\/b>haben wir noch zwei Attribute definiert. F&uuml;r das Attribut <b>loadImages <\/b>hinterlegen wir den Namen der Funktion, die f&uuml;r jedes Element, welches das Attribut <b>image <\/b>aufweist, das jeweilige Icon zur&uuml;ckliefert. Und f&uuml;r <b>onLoad <\/b>legen wir die die Funktion fest, die beim Laden der Ribbondefinition ausgel&ouml;st wird und mit der wir eine Objektvariable mit einem Verweis auf die Ribbondefinition f&uuml;llen k&ouml;nnen. Die Variable namens <b>objRibbon<\/b> haben wir weiter oben bereits deklariert. Nun fehlt noch die Definition der Funktion <b>onLoad<\/b>, die wie folgt aussieht:<\/p>\n<pre><span style=\"color:blue;\">Function <\/span>OnLoad(ribbon<span style=\"color:blue;\"> As <\/span>IRibbonUI)\r\n     <span style=\"color:blue;\">Set<\/span> objRibbon = ribbon\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<h2>Icon hinzuf&uuml;gen<\/h2>\n<p>Damit wir mit unserem Befehl ein Icon anzeigen k&ouml;nnen (siehe Bild 6), f&uuml;gen wir dieses zuerst zum Ordner <b>Resources|ICON <\/b>hinzu.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2022_06\/pic_344_006.png\" alt=\"Unser Befehl im Backstage-Bereich\" width=\"549,6265\" height=\"335,5616\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Unser Befehl im Backstage-Bereich<\/span><\/b><\/p>\n<p>Dazu w&auml;hlen wir per Rechtsklick den Kontextmen&uuml;befehl <b>Add|Import File&#8230; <\/b>dieses Ordners aus und selektieren dann die gew&uuml;nschte <b>.ico<\/b>-Datei.<\/p>\n<div class=\"rcp_restricted\"><p><span style=\"color: #ff0000;\">M&ouml;chten Sie weiterlesen? Dann l&ouml;sen Sie Ihr Ticket!<\/span><br \/>\n<span style=\"color: #ff0000;\">Hier geht es zur Bestellung des Jahresabonnements des Magazins <strong>Visual Basic Entwickler<\/strong>:<\/span><br \/>\n<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/shop.minhorst.com\/magazine\/363\/visual-basic-entwickler-jahresabonnement?c=77\">Zur Bestellung ...<\/a><\/span><br \/>\n<span style=\"color: #ff0000;\">Danach greifen Sie sofort auf <strong>alle rund 200 Artikel<\/strong> unseres Angebots zu - auch auf diesen hier!<\/span><br \/>\n<span style=\"color: #000000;\">Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:<\/span><\/p>\n<\/div>\n\n\t\n\t<form id=\"rcp_login_form\"  class=\"rcp_form\" method=\"POST\" action=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000344\/\">\n\n\t\t\n\t\t<fieldset class=\"rcp_login_data\">\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_login\">Username or Email<\/label>\n\t\t\t\t<input name=\"rcp_user_login\" id=\"rcp_user_login\" class=\"required\" type=\"text\"\/>\n\t\t\t<\/p>\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_pass\">Password<\/label>\n\t\t\t\t<input name=\"rcp_user_pass\" id=\"rcp_user_pass\" class=\"required\" type=\"password\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t\t<p>\n\t\t\t\t<input type=\"checkbox\" name=\"rcp_user_remember\" id=\"rcp_user_remember\" value=\"1\"\/>\n\t\t\t\t<label for=\"rcp_user_remember\">Remember me<\/label>\n\t\t\t<\/p>\n\t\t\t<p class=\"rcp_lost_password\"><a href=\"\/data\/wp\/v2\/posts\/55000344?rcp_action=lostpassword\"><\/a><\/p>\n\t\t\t<p>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_action\" value=\"login\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_redirect\" value=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000344\/\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_login_nonce\" value=\"e5ea4c0d5c\"\/>\n\t\t\t\t<input id=\"rcp_login_submit\" class=\"rcp-button\" type=\"submit\" value=\"Login\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t<\/fieldset>\n\n\t\t\n\t<\/form>\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wer viel mit Excel-Worksheets arbeitet und diesen regelm&auml;&szlig;ig VBA-Code hinzuf&uuml;gt, muss diese als .xlsm-Datei speichern, damit die &Auml;nderungen am VBA-Projekt beim Schlie&szlig;en nicht verlorengehen. Dazu muss man immer den Backstage-Bereich von Excel &ouml;ffnen und einige Mausklicks durchf&uuml;hren. Wie w&auml;re es, wenn man diese Aktion direkt im Backstage-Bereich finden w&uuml;rde &#8211; und nur noch einen Mausklick t&auml;tigen m&uuml;sste, damit das aktuelle Excel-Worksheet nicht nur unter dem gleichen Namen und der Dateiendung .xlsm gespeichert wird, sondern auch noch die urspr&uuml;ngliche .xlsx-Datei gel&ouml;scht wird? Wie das geht, zeigen wir in diesem Artikel.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662022,66062022,44000034],"tags":[],"yst_prominent_words":[],"class_list":["post-55000344","post","type-post","status-publish","format-standard","hentry","category-662022","category-66062022","category-COMAddIns_programmieren"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000344","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/comments?post=55000344"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000344\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000344"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000344"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000344"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000344"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}