{"id":55001555,"date":"2025-08-01T00:00:00","date_gmt":"2025-08-03T11:25:37","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1555"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Suchen_und_Ersetzen_mit_COMAddIn","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/","title":{"rendered":"Suchen und Ersetzen mit COM-Add-In"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg01.met.vgwort.de\/na\/cf66c01874e44b598f5984e27e887f41\" width=\"1\" height=\"1\" alt=\"\"><b>Im Beitrag &#8222;Besserer Suchen und Ersetzen-Dialog&#8220; haben wir den Dialog zum Suchen und Ersetzen in Access-Formularen nachgebaut und um einige Features erg&auml;nzt. Nun wollen wir unseren selbst gebauten Dialog noch f&uuml;r jede Access-Anwendung verf&uuml;gbar machen. Was liegt da n&auml;her, als diesen &uuml;ber das Ribbon aufzurufen? Um eine solche Erweiterung f&uuml;r jede ge&ouml;ffnete Anwendung verf&uuml;gbar zu machen und so flexibel wie m&ouml;glich zu sein, verwenden wir dazu ein COM-Add-In. Dieses enth&auml;lt lediglich die Erweiterung des Ribbons um die ben&ouml;tigten Befehlsschaltfl&auml;chen sowie den Code, um von dort aus den &#8222;Suchen und Ersetzen&#8220;-Dialog zu starten.<\/b><\/p>\n<h2>COM-Add-Ins erstellen mit twinBASIC<\/h2>\n<p>Unsere erste Wahl f&uuml;r das komfortable Erstellen von COM-Add-Ins f&uuml;r Microsoft Access ist twinBASIC. Diese Entwicklungsumgebung ist in der 32-Bit-Version kostenlos und 64-Bit-DLLs k&ouml;nnen ebenfalls damit erstellt werden &#8211; in der kostenlosen Version erscheint hier allerdings ein Splash-Screen des Herstellers.<\/p>\n<p>Den jeweils aktuellen Release kann man hier herunterladen:<\/p>\n<pre>https:\/\/github.com\/twinbasic\/twinbasic\/releases<\/pre>\n<p>Hier klickt man auf den gew&uuml;nschten Release und l&auml;dt beispielsweise f&uuml;r den Release mit der Nummer 784 die Datei <b>twinBASIC_IDE_BETA_784.zip <\/b>herunter.<\/p>\n<p>Den Inhalt entpackt man in ein neues, leeres Verzeichnis. Es ist keine weitere Installation notwendig, wir brauchen einfach nur die Datei <b>twinBASIC.exe <\/b>zu starten. Nach dem Start erscheint ein Startdialog, in dem wir zur Registerseite Samples wechseln. Hier finden wir den Eintrag <b>Sample 5. MYCOMAddIn<\/b>, den wir doppelt anklicken (siehe Bild 1).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1555_002.png\" alt=\"Anlegen eines COM-Add-In-Projekts mit Beispiel\" width=\"649,559\" height=\"508,3505\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Anlegen eines COM-Add-In-Projekts mit Beispiel<\/span><\/b><\/p>\n<p>Danach erscheint ein weiterer Dialog namens <b>twinBASIC New Project Options<\/b>. Hier passen wir den Projektnamen an, in diesem Fall auf <b>amvSuchenUndErsetzen <\/b>(siehe Bild 2).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1555_003.png\" alt=\"Angeben des Projektnamens\" width=\"549,559\" height=\"275,3368\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Angeben des Projektnamens<\/span><\/b><\/p>\n<p>twinBASIC erstellt nun in wenigen Augenblicken das neue Projekt und &ouml;ffnet das Modul <b>MyCOMAddin.twin<\/b>.<\/p>\n<h2>Verweise hinzuf&uuml;gen<\/h2>\n<p>Da wir ein COM-Add-In erstellen wollen, f&uuml;gen wir diesem zun&auml;chst einen Verweis auf die Objektbibliothek von Microsoft Access hinzu.<\/p>\n<p>Dazu &ouml;ffnen wir den <b>References<\/b>-Bereich mit dem Men&uuml;befehl <b>Project|References<\/b>&#8230; (siehe Bild 3).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1555_004.png\" alt=\"&Ouml;ffnen der Referenzen\" width=\"549,559\" height=\"247,5384\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: &Ouml;ffnen der Referenzen<\/span><\/b><\/p>\n<p>Dort angekommen, wechseln wir zur Registerseite <b>Available COM References <\/b>und geben im Suchbereich <b>microsoft access <\/b>ein. Dies bringt den Verweis auf die Bibliothek <b>Microsoft Access 16.0 Object Library <\/b>zum Vorschein, die wir nun aktivieren (siehe Bild 4). Anschlie&szlig;end klicken wir auf <b>Save Changes<\/b>.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1555_005.png\" alt=\"Hinzuf&uuml;gen eines Verweises auf die Access-Bibliothek\" width=\"700\" height=\"331,1377\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Hinzuf&uuml;gen eines Verweises auf die Access-Bibliothek<\/span><\/b><\/p>\n<h2>Einstellungen anpassen<\/h2>\n<p>Danach &ouml;ffnen wir mit <b>Project|Project Settings <\/b>weitere Einstellungen, wo wir jeweils den Namen unseres Projekts eingeben k&ouml;nnen (siehe Bild 5).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1555_006.png\" alt=\"Einstellen von Name, Description und Application Title\" width=\"700\" height=\"320,6586\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Einstellen von Name, Description und Application Title<\/span><\/b><\/p>\n<h2>.twin-Datei umbenennen<\/h2>\n<p>Nun klicken wir mit der rechten Maustaste links auf den Eintrag <b>Sources|MyCOMAddin.twin <\/b>und w&auml;hlen aus dem Kontextmen&uuml; den Befehl <b>Rename <\/b>aus (siehe Bild 6). Wir k&ouml;nnen den Namen von <b>MyCOMAddin.twin <\/b>nun bearbeiten und &auml;ndern diesen auf <b>SuchenUndErsetzen.twin<\/b>.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1555_007.png\" alt=\"Umbenennen der Code-Datei\" width=\"474,5589\" height=\"551,033\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Umbenennen der Code-Datei<\/span><\/b><\/p>\n<p><b>Achtung: <\/b>Die Datei muss zu diesem Zweck geschlossen sein.<\/p>\n<h2>Prozeduren zum Registrieren des COM-Add-Ins<\/h2>\n<p>Wie sehen neben der frisch umbenannten Datei <b>SuchenUndErsetzen.twin <\/b>noch eine weitere Datei namens <b>DllRegistration.twin<\/b>. Wenn wir diese &ouml;ffnen, sehen wir verschiedene Elemente, die wir durch den Inhalt aus Listing 1 ersetzen.<\/p>\n<pre>Module DllRegistration\r\n     Const AddinProjectName<span style=\"color:blue;\"> As String<\/span> = VBA.Compilation.CurrentProjectName\r\n     Const AddinClassName<span style=\"color:blue;\"> As String<\/span> = \"SuchenUndErsetzen\"\r\n     Const AddinQualifiedClassName<span style=\"color:blue;\"> As String<\/span> = AddinProjectName & \".\" & AddinClassName\r\n     Const RootRegistryFolder<span style=\"color:blue;\"> As String<\/span> = \"HKCU\\SOFTWARE\\Microsoft\\Office\\Access\\Addins\\\" & AddinQualifiedClassName & \"\\\"\r\n     <span style=\"color:blue;\">Public <\/span>Function DllRegisterServer()<span style=\"color:blue;\"> As Boolean<\/span>\r\n         <span style=\"color:blue;\">On Error GoTo<\/span> RegError\r\n         <span style=\"color:blue;\">Dim <\/span>wscript<span style=\"color:blue;\"> As Object<\/span> = CreateObject(\"wscript.shell\")\r\n         wscript.RegWrite RootRegistryFolder & \"FriendlyName\", AddinProjectName, \"REG_SZ\"\r\n         wscript.RegWrite RootRegistryFolder & \"Description\", AddinProjectName, \"REG_SZ\"\r\n         wscript.RegWrite RootRegistryFolder & \"LoadBehavior\", 3, \"REG_DWORD\"\r\n         Return <span style=\"color:blue;\">True<\/span>\r\n     RegError:\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"DllRegisterServer -- An error occured trying to write to the system registry:\" & <span style=\"color:blue;\">vbCrLf<\/span> & _\r\n                 Err.Description & \" (\" & Hex(Err.Number) & \")\"\r\n         Return <span style=\"color:blue;\">False<\/span>\r\n     End Function\r\n     <span style=\"color:blue;\">Public <\/span>Function DllUnregisterServer()<span style=\"color:blue;\"> As Boolean<\/span>\r\n         <span style=\"color:blue;\">On Error GoTo<\/span> RegError\r\n         <span style=\"color:blue;\">Dim <\/span>wscript<span style=\"color:blue;\"> As Object<\/span> = CreateObject(\"wscript.shell\")\r\n         wscript.RegDelete RootRegistryFolder & \"FriendlyName\"\r\n         wscript.RegDelete RootRegistryFolder & \"Description\"\r\n         wscript.RegDelete RootRegistryFolder & \"LoadBehavior\"\r\n         wscript.RegDelete RootRegistryFolder\r\n         Return <span style=\"color:blue;\">True<\/span>\r\n     RegError:\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"DllUnregisterServer -- An error occured trying to delete from the system registry:\" & <span style=\"color:blue;\">vbCrLf<\/span> & _\r\n                 Err.Description & \" (\" & Hex(Err.Number) & \")\"\r\n         Return <span style=\"color:blue;\">False<\/span>\r\n     End Function\r\nEnd Module<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Prozeduren zum Registrieren des COM-Add-Ins<\/span><\/b><\/p>\n<p>Hier sehen wir verschiedene Elemente. Ganz oben finden wir einige Konstanten, die unter anderem mit dem Projektnamen gef&uuml;llt werden (<b>AddinProjectName<\/b>) oder mit dem Namen der zu verwendenden Klasse (<b>SuchenUndErsetzen<\/b>).<\/p>\n<p>Darunter finden wir zwei Funktionen. Diese Funktionen werden ausgef&uuml;hrt, wenn wir das COM-Add-In registrieren oder die Registrierung aufheben wollen, zum Beispiel &uuml;ber die Kommandozeile.<\/p>\n<p>Die erste Funktion <b>DllRegisterServer <\/b>nimmt die f&uuml;r den Einsatz notwendigen Eintr&auml;ge in der Registry vor, die zweite Funktion <b>DllUnregisterServer <\/b>entfernt diese wieder.<\/p>\n<h2>Code der COM-DLL<\/h2>\n<p>Nun m&uuml;ssen wir nur noch den Code erstellen, mit dem wir die gew&uuml;nschten Eintr&auml;ge zum Ribbon hinzuf&uuml;gen und daf&uuml;r sorgen, dass das COM-Add-In &uuml;berhaupt ausgef&uuml;hrt wird, wenn wir Access starten.<\/p>\n<p>Dazu ben&ouml;tigen wir die Schnittstelle <b>IDTExtensibility<\/b>, die wir durch Hinzuf&uuml;gen mit dem Schl&uuml;sselwort <b>Implements <\/b>zur Klasse <b>SuchenUndErsetzen <\/b>bekannt geben.<\/p>\n<p>Au&szlig;erdem ben&ouml;tigen wir noch eine zweite Schnittstelle, damit wir &uuml;ber eine Funktion die Ribbondefinition &uuml;bergeben k&ouml;nnen. Diese machen wir durch Anh&auml;ngen von Implements <b>IRibbonExtensibility <\/b>und dem zus&auml;tzlichen Hinweis <b>[WithDispathForwarding] <\/b>f&uuml;r die Klasse bekannt.<\/p>\n<h2>IDTExensibility2-Schnittstelle implementieren<\/h2>\n<p>Durch das Implementieren diese Schnittstellen m&uuml;ssen wir die dadurch definierten Methoden, Ereignisse und Eigenschaften ebenfalls im Code implementieren. Bei der Schnittstelle <b>IDTExtensibility2 <\/b>bedeutet dies, dass wir einige Ereignisprozeduren anlegen m&uuml;ssen, die beim Laden des COM-Add-Ins durch Access ausgel&ouml;st werden, andere werden zu anderen Zeitpunkten aktiviert. Die wichtigste f&uuml;r uns ist die Ereignisprozedur <b>OnConnection<\/b>, die beim Start von Access ausgel&ouml;st wird und mit der Access uns mit dem Parameter <b>Application <\/b>einen Verweis auf die aktuelle Access-Instanz &uuml;bergibt. Diesen Verweis speichern wir in der Variablen <b>objAccess<\/b>, damit wir sp&auml;ter dar&uuml;ber auf die Access-Instanz zugreifen k&ouml;nnen. Das ist in diesem Fall streng genommen gar nicht n&ouml;tig, aber wir f&uuml;hren diesen Code immer mit, weil er f&uuml;r die meisten COM-Add-Ins, die direkt Aktionen mit dem Access-Objekt ausf&uuml;hren sollen, n&ouml;tig ist.<\/p>\n<p>Diesen Teil des Codes finden Sie in Listing 2.<\/p>\n<pre>[ClassId(\"DC8E7154-FAC8-43B7-88E5-A93527539222\")]\r\n<span style=\"color:blue;\">Class<\/span> SuchenUndErsetzen\r\n     Implements IDTExtensibility2\r\n     [WithDispatchForwarding]\r\n     Implements IRibbonExtensibility\r\n     <span style=\"color:blue;\">Private <\/span>objAccess<span style=\"color:blue;\"> As <\/span>Access.Application\r\n     <span style=\"color:blue;\">Private <\/span>objRibbon<span style=\"color:blue;\"> As <\/span>IRibbonUI\r\n     Sub OnConnection(ByVal Application<span style=\"color:blue;\"> As Object<\/span>, ByVal ConnectMode<span style=\"color:blue;\"> As <\/span>ext_ConnectMode, ByVal AddInInst<span style=\"color:blue;\"> As Object<\/span>, _\r\n             ByRef custom<span style=\"color:blue;\"> As Variant<\/span>()) Implements IDTExtensibility2.OnConnection\r\n         <span style=\"color:blue;\">Set<\/span> objAccess = Application\r\n     End Sub\r\n     Sub OnDisconnection(ByVal RemoveMode<span style=\"color:blue;\"> As <\/span>ext_DisconnectMode, ByRef custom<span style=\"color:blue;\"> As Variant<\/span>()) _\r\n             Implements IDTExtensibility2.OnDisconnection\r\n     End Sub\r\n     Sub OnAddInsUpdate(ByRef custom<span style=\"color:blue;\"> As Variant<\/span>()) Implements IDTExtensibility2.OnAddInsUpdate\r\n     End Sub\r\n     Sub OnStartupComplete(ByRef custom<span style=\"color:blue;\"> As Variant<\/span>()) Implements IDTExtensibility2.OnStartupComplete\r\n     End Sub\r\n     Sub OnBeginShutdown(ByRef custom<span style=\"color:blue;\"> As Variant<\/span>()) Implements IDTExtensibility2.OnBeginShutdown\r\n     End Sub\r\n     ...<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Code des COM-Add-Ins, Teil 1<\/span><\/b><\/p>\n<h2>Ribbon erweitern<\/h2>\n<p>In unserem Fall wollen wir das COM-Add-In nur nutzen, um dem Ribbon von Access einige neue Elemente hinzuzuf&uuml;gen. Dazu implementieren wir die Funktion <b>GetCustomUI <\/b>der Schnittstelle <b>IRibbonUI<\/b>. Diese wird von Access aus aufgerufen und wir bekommen so die Gelegenheit, Access eine Anpassung des Ribbons zu &uuml;bergeben. Wir tun das wie in Listing 3, wo wir die passende Ribbon-Definition in der Variablen <b>strXML <\/b>zusammenstellen. Wer genau hinschaut, sieht, dass wir hier nicht <b>strXML = strXML &#038; &#8230; <\/b>verwenden, sondern dass wir hier einen anderen Operator verwenden, um die Zeilen zusammenzuf&uuml;gen, n&auml;mlich <b>&#038;=<\/b>.<\/p>\n<pre>     <span style=\"color:blue;\">Private <\/span>Function 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;customUI xmlns=\"\"http:\/\/schemas.microsoft.com\/office\/2009\/07\/customui\"\" \" _\r\n             & \"loadImage=\"\"LoadImage\"\" onLoad=\"\"onLoad\"\"&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n         strXML &= \"  &lt;ribbon startFromScratch=\"\"false\"\"&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n         strXML &= \"    &lt;tabs&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n         strXML &= \"      &lt;tab idMso=\"\"TabHomeAccess\"\"&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n         strXML &= \"        &lt;group idMso=\"\"GroupFindAccess\"\" visible=\"\"false\"\" \/&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n         strXML &= \"        &lt;group id=\"\"grpSuchenUndErsetzen\"\" insertAfterMso=\"\"GroupFindAccess\"\" \" _\r\n             & \"label=\"\"amvSuchenUndErsetzen\"\"&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n         strXML &= \"          &lt;button id=\"\"btnSuchen\"\" imageMso=\"\"FindDialog\"\" size=\"\"large\"\" \" _\r\n             & \"onAction=\"\"onAction\"\" label=\"\"Suchen\"\"\/&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n         strXML &= \"          &lt;button id=\"\"btnErsetzen\"\" imageMso=\"\"ReplaceDialog\"\" size=\"\"normal\"\" \" _\r\n             & \"onAction=\"\"onAction\"\" label=\"\"Ersetzen\"\"\/&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n         strXML &= \"          &lt;control idMso=\"\"GoToMenuAccess\"\" size=\"\"normal\"\" \/&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n         strXML &= \"          &lt;control idMso=\"\"SelectMenuAccess\"\" size=\"\"normal\"\" \/&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n         strXML &= \"        &lt;\/group&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n         strXML &= \"      &lt;\/tab&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n         strXML &= \"    &lt;\/tabs&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n         strXML &= \"  &lt;\/ribbon&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     End Function\r\n     Function OnLoad(ribbon<span style=\"color:blue;\"> As <\/span>IRibbonUI)\r\n         <span style=\"color:blue;\">Set<\/span> objRibbon = ribbon\r\n     End Function\r\n     <span style=\"color:blue;\">Public <\/span>Sub OnAction(control<span style=\"color:blue;\"> As <\/span>IRibbonControl)\r\n         Select Case control.Id\r\n             <span style=\"color:blue;\">Case <\/span>\"btnSuchen\"\r\n                 objAccess.Run Environ(\"AppData\") & \"\\Microsoft\\AddIns\\amvSuchenUndErsetzen.amvSuchen\"\r\n             <span style=\"color:blue;\">Case <\/span>\"btnErsetzen\"\r\n                 objAccess.Run Environ(\"AppData\") & \"\\Microsoft\\AddIns\\amvSuchenUndErsetzen.amvErsetzen\"\r\n                 <span style=\"color:blue;\">Case Else<\/span>\r\n                 <span style=\"color:blue;\">MsgBox<\/span> \"OnAction nicht behandelt: \" & control.Id\r\n         <span style=\"color:blue;\">End Select<\/span>\r\n     End Sub\r\n<span style=\"color:blue;\">End Class<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Code des COM-Add-Ins, Teil 2<\/span><\/b><\/p>\n<p>Was genau erledigen wir mit dieser Ribbondefinition? Wir definieren das <b>customUI<\/b>-Element, das <b>ribbon<\/b>-Element und das <b>tabs<\/b>-Element wie in jeder herk&ouml;mmlichen Ribbonerweiterung.<\/p>\n<p>Danach f&uuml;gen wir ein <b>tab<\/b>-Element mit dem Wert <b>TabHomeAccess <\/b>f&uuml;r das Attribut <b>idMso<\/b> hinzu. Damit referenzieren wir das Ribbontab mit der Beschriftung <b>Start<\/b>.<\/p>\n<p>Darunter referenzieren wir ein <b>group<\/b>-Element, das den Wert <b>GroupFindAccess <\/b>f&uuml;r das Attribut <b>idMso <\/b>enth&auml;lt. Das entspricht dem eingebauten Bereich mit den Funktionen <b>Suchen <\/b>und <b>Ersetzen <\/b>(siehe Bild 7). Dieses wollen wir ausblenden und durch unsere eigene Version ersetzen, also stellen wir das Attribut <b>visible <\/b>auf <b>false <\/b>ein.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1555_008.png\" alt=\"Das zu ersetzende Ribbon-Element\" width=\"700\" height=\"114,5454\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 7: Das zu ersetzende Ribbon-Element<\/span><\/b><\/p>\n<p>Danach legen wir unsere eigene Struktur f&uuml;r diesen Zweck an. Das erledigen wir mit einem benutzerdefinierten <b>group<\/b>-Element mit der ID <b>grpSuchenUndErsetzen <\/b>und der Beschriftung <b>amvSuchenUndErsetzen<\/b>.<\/p>\n<p>Damit diese Gruppe an der gleichen Stelle angezeigt wird wie die zuvor ausgeblendete Gruppe, f&uuml;gen wir diese &uuml;ber das Attribut <b>insertAfterMso <\/b>genau dort ein &#8211; und zwar mit dem Wert <b>GroupFindAccess<\/b>.<\/p>\n<p>Schlie&szlig;lich f&uuml;gen wir zun&auml;chst zwei rein benutzerdefinierte <b>button<\/b>-Elemente namens <b>btnSuchen <\/b>und <b>btnErsetzen <\/b>ein &#8211; samt entsprechenden Beschriftungen.<\/p>\n<p>Wie im Original soll die <b>Suchen<\/b>-Schaltfl&auml;che gro&szlig; dargestellt werden und die <b>Ersetzen<\/b>-Schaltfl&auml;che klein. Damit die gleichen Icons wie beim Original erscheinen, stellen wir die Eigenschaft <b>imageMso <\/b>jeweils auf die Namen dieser Elemente ein, n&auml;mlich <b>FindDialog <\/b>und <b>ReplaceDialog<\/b>.<\/p>\n<p>Danach replizieren wir noch die beiden &uuml;brigen Steuerelemente aus der Originalgruppe, indem wir <b>button<\/b>-Elemente anlegen, deren Attribut <b>idMso <\/b>wir mit den Werten <b>GoToMenuAccess <\/b>und <b>SelectMenuAccess <\/b>f&uuml;llen.<\/p>\n<p>Danach f&uuml;gen wir die fehlenden schlie&szlig;enden Elemente hinzu wie zum Beispiel <b><\/group><\/b>.<\/p>\n<p>Die Anweisung <b>Return strXML <\/b>gibt die Zeichenkette aus <b>strXML <\/b>als Funktionswert an Access zur&uuml;ck.<\/p>\n<p>Schlie&szlig;lich fehlen noch die Aktionen, die beim Anklicken der beiden benutzerdefinierten <b>button<\/b>-Elemente ausgel&ouml;st werden sollen.<\/p>\n<p>Dazu nutzen wir die Prozedur <b>OnAction<\/b>, die wir bereits f&uuml;r das gleichnamige Attribut der beiden button-Elemente hinterlegt haben (<b>onAction=&#8220;onAction&#8220;<\/b>).<\/p>\n<p>Diese erh&auml;lt nach dem Ausl&ouml;sen durch Bet&auml;tigen einer der Schaltfl&auml;chen mit dem Parameter <b>control <\/b>einen Verweis auf das ausl&ouml;sende Element.<\/p>\n<p>Dieses liefert mit der Eigenschaft <b>Id <\/b>den Namen des passenden <b>button<\/b>-Elements, den wir in einer Select Case-Bedingung auswerten.<\/p>\n<p>Lautet dieser <b>btnSuchen<\/b>, f&uuml;hren wir die folgende Anweisung aus:<\/p>\n<pre>objAccess.Run Environ(\"AppData\") & \"\\Microsoft\\AddIns\\amvSuchenUndErsetzen.amvSuchen\"<\/pre>\n<p>Mit <b>Environ(&#8222;AppData&#8220;) <\/b>holen wir den Pfad zum Benutzerverzeichnis, indem sich die Unterordner <b>Microsoft <\/b>und <b>AddIns <\/b>befinden. In diesen Ordner, der auch die &uuml;brigen Access-Add-Ins enth&auml;lt, wollen wir auch die Access-Add-In-Datenbank <b>amvSuchenUndErsetzen.accda <\/b>speichern.<\/p>\n<p>Damit daraus die Funktion <b>amvSuchen <\/b>aufgerufen wird, f&uuml;gen wir diese statt der Dateiendung <b>.accda <\/b>an den Namen der Datenbankdatei an. Es ist wichtig, dass die Datenbankdatei die Dateiendung aufweist &#8211; anderenfalls findet <b>Application.Run <\/b>diese so nicht.<\/p>\n<p>Zum Aufrufen der Funktion <b>amvErsetzen <\/b>h&auml;ngen wir entsprechend den Namen dieser Funktion an den Parameter der Anweisung <b>Application.Run <\/b>an.<\/p>\n<p>Damit ist der Code f&uuml;r das COM-Add-In bereits vollst&auml;ndig. <\/p>\n<h2>COM-Add-In erstellen und registrieren<\/h2>\n<p>Nun m&uuml;ssen wir nur noch die COM-Add-In-DLL erstellen und gleichzeitig registrieren. Beides erledigen wir von twinBASIC aus &uuml;ber den Befehl <b>File|Build <\/b>(siehe Bild 8).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1555_009.png\" alt=\"Erstellen und Registrieren des COM-Add-Ins\" width=\"424,5589\" height=\"373,6118\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 8: Erstellen und Registrieren des COM-Add-Ins<\/span><\/b><\/p>\n<p>Dadurch sollte im Bereich <b>DEBUG CONSOLE<\/b> von twinBASIC die Ausgabe aus Bild 9 erscheinen. Hier sehen wir, dass die Datei <b>amvSuchenUndErsetzen_win32.dll <\/b>erstellt und registriert wurde. Werden hier Fehler gemeldet, kann das verschiedene Ursachen haben.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1555_010.png\" alt=\"Ausgabe beim Erstellen und Registrieren des COM-Add-Ins\" width=\"549,559\" height=\"230,4601\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 9: Ausgabe beim Erstellen und Registrieren des COM-Add-Ins<\/span><\/b><\/p>\n<ul>\n<li>Es kann zum Beispiel sein, dass man die DLL erneut erzeugen m&ouml;chte, w&auml;hrend diese bereits von Access aus verwendet wird. Diese kann dann nicht &uuml;berschrieben werden, was zu einem Fehler f&uuml;hrt.<\/li>\n<li>Es kann auch passieren, dass der Code nicht vollst&auml;ndig kompiliert werden kann &#8211; in diesem Fall werden die Fehler jedoch ebenfalls angezeigt.<\/li>\n<\/ul>\n<h2>Testen des COM-Add-Ins<\/h2>\n<p>Um das COM-Add-In nach der Erstellung Registrierung zu testen, starten wir Access. Im Ribbontab <b>Start <\/b>sollte nun unsere Gruppe <b>amvSuchenUndErsetzen <\/b>erscheinen statt dem eingebauten <b>Suchen und Ersetzen<\/b>-Reiter.<\/p>\n<p>Damit k&ouml;nnen wir nun bereits den Dialog <b>Suchen und Ersetzen <\/b>&ouml;ffnen (siehe Bild 10).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1555_011.png\" alt=\"Ausprobieren des neu installierten COM-Add-Ins in Kombination mit der Access-Add-In-Datenbank\" width=\"700\" height=\"382,3956\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 10: Ausprobieren des neu installierten COM-Add-Ins in Kombination mit der Access-Add-In-Datenbank<\/span><\/b><\/p>\n<h2>Registrierung aufheben und COM-Add-In-Datei l&ouml;schen<\/h2>\n<p>Wenn wieder die gewohnte <b>Suchen<\/b>-Gruppe erscheinen soll, m&uuml;ssen wir alle Access-Instanzen schlie&szlig;en, die eventuell bereits auf das COM-Add-In zugreifen. Danach k&ouml;nnen wir in twinBASIC den Befehl <b>File|Clean <\/b>aufrufen. Dadurch werden die Registry-Eintr&auml;ge wieder entfernt und die DLL-Datei wird gel&ouml;scht.<\/p>\n<p>Eigentlich entspricht dies dem Deinstallieren der Anwendung mit dem Befehl <b>RegSvr32.exe <\/b>mit dem Parameter <b>-u<\/b>.<\/p>\n<h2>Erstellen eines Setups f&uuml;r das COM-Add-In und die Access-AddIn-Datenbank<\/h2>\n<p>Nun fehlt noch ein letzter Schritt: Es sind einige Aufgaben zu erledigen, wenn wir das Add-In auf einem anderen Rechner zum Laufen bringen wollen, auf dem sich keine twinBASIC-Installation befindet, mit der man dies &uuml;ber die Entwicklungsumgebung erledigen k&ouml;nnte:<\/p>\n<ul>\n<li>Wir m&uuml;ssen die Datei <b>amvSuchenUndErsetzen.accda <\/b>im Add-In-Verzeichnis des aktuellen Benutzers speichern.<\/li>\n<li>Auch die COM-Add-In-Datei <b>amvSuchenUndErsetzen.dll <\/b>wollen wir ebenfalls in einem entsprechenden Verzeichnis unterbringen.<\/li>\n<li>Au&szlig;erdem m&uuml;ssen wir noch die Registrierung dieser Datei durchf&uuml;hren.<\/li>\n<\/ul>\n<p>Dies alles k&ouml;nnen wir mit einem kleinen Setup auf Basis von Inno Setup schnell erledigen.<\/p>\n<p>Dazu &ouml;ffnen wir Inno Setup &#8211; falls noch nicht installiert: <b>https:\/\/jrsoftware.org\/isinfo.php<\/b>.<\/p>\n<p>Hier legen wir eine neue Installationsdatei an und f&uuml;gen den Code aus Listing 4 ein.<\/p>\n<pre>#define AppName \"amvSuchenUndErsetzen\"\r\n#define AppDLLSource \"amvSuchenUndErsetzen_win32.dll\"\r\n#define AppDLLDest \"amvSuchenUndErsetzen.dll\"\r\n#define AppAccessAddIn \"amvSuchenUndErsetzen.accda\"\r\n#define AppVersion \"1.0.0.0\"\r\n#define AppPublisher \"Andr&eacute; Minhorst\"\r\n#define AppURL \"http:\/\/andreminhorst.de\/amvSuchenUndErsetzen\"\r\n[Setup]\r\nAppName={#AppName}\r\nAppVersion={#AppVersion}\r\nAppPublisher={#AppPublisher}\r\nAppPublisherURL={#AppURL}\r\nDefaultDirName={commonpf}\\{#AppName}\r\nOutputBaseFilename={#AppName}_Setup\r\nSetupIconFile=Images\\am01.ico\r\nWizardSmallImageFile=Images\\setup.bmp\r\nWizardImageFile=Images\\AM_last.bmp\r\nUninstallDisplayIcon={app}\\am02.ico,1\r\nPrivilegesRequired=admin\r\n[Files]\r\nSource: \"{#AppAccessAddIn}\"; DestDir: \"{userappdata}\\Microsoft\\AddIns\"; Flags: ignoreversion;\r\nSource: \"Build\\{#AppDLLSource}\"; DestDir: \"{app}\"; DestName: \"{#AppDLLDest}\"; Flags: regserver ignoreversion;\r\n[Languages]\r\nName: \"german\"; MessagesFile: \"compiler:Languages\\German.isl\"\r\n[UninstallRun]\r\nFilename: \"{sys}\\regsvr32.exe\"; Parameters: \"\/u \/s \"\"{app}\\{#AppDLLDest}\"\"\"; Flags: runhidden;\r\n[UninstallDelete]\r\nType: files; Name: \"{app}\\{#AppDLLDest}\"<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Code der Inno Setup-Datei f&uuml;r das COM-Add-In plus Access-Add-In<\/span><\/b><\/p>\n<p>In diesem legen wir zun&auml;chst einige Konstanten fest, die wir im unteren Teil verwenden werden. Auf diese Weise kann man dieses Setup f&uuml;r andere Konstellationen schnell anpassen.<\/p>\n<p>Hier definieren wir den Namen der Anwendung, die Quellen f&uuml;r die DLL und die <b>.accda<\/b>-Datei sowie den Namen, unter dem die DLL gespeichert werden soll.<\/p>\n<p>Dies hat den Hintergrund, dass wir die DLL sowohl in 32-Bit als auch in 64-Bit anlegen k&ouml;nnen, aber auf dem Zielsystem immer die gleiche Benennung vorfinden wollen. Dies ist eher f&uuml;r DLLs wichtig, die als COM-DLLs per Verweis in das VBA-Projekt von Anwendungen eingebunden werden.<\/p>\n<p>Au&szlig;erdem definieren wir mit den Konstanten die Version, den Hersteller und eine Webseite.<\/p>\n<p>Danach beginnt der Teil <b>[Setup]<\/b>. Hier weisen wir die Konstanten den entsprechenden Eigenschaften zu. Mit <b>DefaultDirName <\/b>legen wir das Verzeichnis fest, in dem die zu installierenden Dateien landen sollen &#8211; hier mit <b>{commonpf}\\{appname} <\/b>das Verzeichnis <b>Programme<\/b> mit dem Anwendungsnamen als Unterverzeichnis.<\/p>\n<p>Mit <b>OutputBaseFilename <\/b>legen wir fest, wie die erstellte Setupdatei hei&szlig;en soll. Diese landet im Verzeichnis <b>Output <\/b>des Verzeichnisses, indem auch unsere Inno Setup-Datei gespeichert ist.<\/p>\n<p>Au&szlig;erdem haben wir noch ein paar Icons im Verzeichnis Images hinterlegt, die wir dem Setup hinzuf&uuml;gen.<\/p>\n<p>Danach folgt der Bereich <b>[Files]<\/b>. Hier legen wir in jeweils einer Zeile mit Source die Quelldatei und mit <b>DestDir <\/b>das Zielverzeichnis fest. Das Flag <b>ignoreversion <\/b>sorgt daf&uuml;r, dass vorhandene Dateien auf jeden Fall &uuml;berschrieben werden.<\/p>\n<p>Bei der zu schreibenden DLL geben wir zus&auml;tzlich noch den Dateinamen an, unter dem diese gespeichert werden soll. Diese hat unter <b>flags<\/b> auch noch den Eintrag <b>regserver<\/b>, was bedeutet, dass diese registriert werden soll.<\/p>\n<p>Die Registrierung haben wir bereits durch die Funktionen im Modul <b>DllRegistration.twin <\/b>vorbereitet.<\/p>\n<p>Schlie&szlig;lich folgen noch Informationen zum Deinstallieren der Datei.<\/p>\n<h2>Erstellen des Setups<\/h2>\n<p>Nachdem wir diesen Code in Inno Setup hinterlegt haben, k&ouml;nnen wir diesen nun in eine Setup-Datei kompilieren.<\/p>\n<p>Voraussetzung daf&uuml;r ist, dass alle angegebenen Dateien am angegebenen Ort liegen. Also muss zum Beispiel die COM-Add-In-DLL im Verzeichnis <b>Build <\/b>liegen und die Bilder im Verzeichnis <b>Images<\/b>. Die Datenbankdatei <b>amvSuchenUndErsetzen.accda <\/b>muss im gleichen Verzeichnis liegen wie die Inno Setup-Datei.<\/p>\n<p>Danach k&ouml;nnen wir die Kompilierung des Setups wie in Bild 11 starten.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_04\/pic_1555_012.png\" alt=\"Aufrufen des Kompilierungsvorgangs\" width=\"549,559\" height=\"243,9368\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 11: Aufrufen des Kompilierungsvorgangs<\/span><\/b><\/p>\n<p>Fehlermeldungen wie fehlende Dateien et cetera werden gew&ouml;hnlich gut verst&auml;ndlich ausgegeben.<\/p>\n<p>Noch ein wichtiger Hinweis: Wenn Sie DropBox oder &auml;hnliche Dienste verwenden, die regelm&auml;&szlig;ig Dateien sichern und diese dazu sperren, stellt sich Inno Setup gelegentlich quer. Sollten nicht erkl&auml;rbare Fehler auftauchen, lohnt es sich, die Synchronisierung eines solchen Dienstes kurzzeitig auszuschalten.<\/p>\n<h2>Testen des Setups<\/h2>\n<p>Bevor wir das Setup testen, sollten wir alle Access-Instanzen schlie&szlig;en und in twinBASIC die aktuelle Registrierung mit <b>File|Clean <\/b>aufheben. Anderenfalls wissen wir anschlie&szlig;end beim Testen nicht, ob wir nun mit der von twinBASIC oder vom Setup erstellten DLL arbeiten.<\/p>\n<p>Starten wir also die Datei <b>amvSuchenUndErsetzen_Setup.exe<\/b>, durchlaufen wir einen gew&ouml;hnlichen Installationsvorgang.<\/p>\n<p>Danach ist das COM-Add-In im ausgew&auml;hlten Verzeichnis installiert und registriert und das Access-Add-In landet im Add-In-Verzeichnis des aktuellen Benutzers.<\/p>\n<p>Starten wir nun Access, sollten wir die angepassten Ribbonbefehle dort vorfinden.<\/p>\n<h2>Variante zum Ersetzen der Ribbongruppe<\/h2>\n<p>Weiter oben haben wir gezeigt, wie wir die Ribbongruppe Suchen einfach ausblenden und durch unsere eigene ersetzen. Wir k&ouml;nnen dies auch noch ein wenig eleganter machen, wenn tats&auml;chlich nur die Funktionen der beiden Ribbonbutton <b>Suchen <\/b>und <b>Ersetzen <\/b>ersetzt werden sollen.<\/p>\n<p>Wir k&ouml;nnen dann einfach die Funktionen &uuml;berschreiben. Dazu nutzen wir jeweils ein <b>command<\/b>-Element, das wir direkt unterhalb des <b>customUI<\/b>-Elements unter einem weiteren Element namens <b>commands <\/b>einf&uuml;gen.<\/p>\n<p>F&uuml;r die beiden <b>command<\/b>-Elemente geben wir mit <b>idMso <\/b>den Namen des eingebauten Elements an. Au&szlig;erdem legen wir jeweils den Wert <b>onAction_Command <\/b>f&uuml;r das <b>onAction<\/b>-Element fest. Hier hinterlegen wir den Code, der statt der eingebauten Funktion ausgef&uuml;hrt werden soll. Dies sieht anschlie&szlig;end wie in Listing 5 aus und ist wesentlich kompakter als die zun&auml;chst vorgestellte L&ouml;sung.<\/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;customUI xmlns=\"\"http:\/\/schemas.microsoft.com\/office\/2009\/07\/customui\"\" \" _\r\n         & \"loadImage=\"\"LoadImage\"\" onLoad=\"\"onLoad\"\"&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strXML &= \"  &lt;commands&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strXML &= \"      &lt;command idMso=\"\"FindDialog\"\" onAction=\"\"onAction_Command\"\" \/&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strXML &= \"      &lt;command idMso=\"\"ReplaceDialog\"\" onAction=\"\"onAction_Command\"\" \/&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strXML &= \"  &lt;\/commands&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 5: Code f&uuml;r das Ersetzen der Funktionen von eingebauten Ribbonbuttons<\/span><\/b><\/p>\n<p>Die Ereignisprozedur <b>onAction_Command <\/b>unterscheidet sich durch einen zweiten Parameter von der oben verwendeten Funktion <b>onAction<\/b> (siehe Listing 6). Mit diesem k&ouml;nnen wir angeben, ob die eingebaute Funktion dennoch ausgef&uuml;hrt werden soll. Das wollen wir nicht &#8211; wir wollen nur unseren eigenen <b>Suchen und Ersetzen<\/b>-Dialog sehen. Deshalb stellen wir nach dem Aufrufen dieses Dialogs jeweils den Wert von <b>CancelDefault <\/b>auf <b>True <\/b>ein.<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>onAction_command(control<span style=\"color:blue;\"> As <\/span>IRibbonControl, ByRef CancelDefault)\r\n     Select Case control.Id\r\n         <span style=\"color:blue;\">Case <\/span>\"FindDialog\"\r\n             objAccess.Run Environ(\"AppData\") & \"\\Microsoft\\AddIns\\amvSuchenUndErsetzen.amvSuchen\"\r\n             CancelDefault = <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">Case <\/span>\"ReplaceDialog\"\r\n             objAccess.Run Environ(\"AppData\") & \"\\Microsoft\\AddIns\\amvSuchenUndErsetzen.amvErsetzen\"\r\n             CancelDefault = <span style=\"color:blue;\">True<\/span>\r\n         <span style=\"color:blue;\">Case Else<\/span>\r\n             <span style=\"color:blue;\">MsgBox<\/span> \"OnAction nicht behandelt: \" & control.Id\r\n     <span style=\"color:blue;\">End Select<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 6: Spezielle onAction-Prozedur f&uuml;r command-Elemente<\/span><\/b><\/p>\n<p>Diese Vorgehensweise hat den Vorteil, dass wir weniger Code ben&ouml;tigen und die eingebauten Elemente nutzen k&ouml;nnen. Allerdings sind nun auch keine Anpassungen der Bezeichnungen mehr m&ouml;glich &#8211; was in diesem Fall aber nicht relevant ist.<\/p>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>In diesem Beitrag haben wir gezeigt, wie wir ein COM-Add-In f&uuml;r den Aufruf unseres Access-Add-Ins per Ribbonbutton erstellen k&ouml;nnen. Au&szlig;erdem haben wir eine Installationsroutine mit Inno Setup erstellt, welche die beiden notwendigen Dateien auf dem System installiert und das COM-Add-In auch gleich registriert.<\/p>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>amvSuchenUndErsetzen.accda<\/p>\n<p>amvSuchenUndErsetzen_32.iss<\/p>\n<p>amvSuchenUndErsetzen_64.iss<\/p>\n<p>amvSuchenUndErsetzen_32_Setup.exe<\/p>\n<p>amvSuchenUndErsetzen_64_Setup.exe<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/C6AF80E5-FC3E-4FE3-8E45-06E31602A4AA\/aiu_1555.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im Beitrag &#8222;Besserer Suchen und Ersetzen-Dialog&#8220; haben wir den Dialog zum Suchen und Ersetzen in Access-Formularen nachgebaut und um einige Features erg&auml;nzt. Nun wollen wir unseren selbst gebauten Dialog noch f&uuml;r jede Access-Anwendung verf&uuml;gbar machen. Was liegt da n&auml;her, als diessn &uuml;ber das Ribbon aufzurufen? Um eine solche Erweiterung f&uuml;r jede ge&ouml;ffnete Anwendung verf&uuml;gbar zu machen und so flexibel wie m&ouml;glich zu sein, verwenden wir dazu ein COM-Add-In. Dieses enth&auml;lt lediglich die Erweiterung des Ribbons um die ben&ouml;tigten Befehlsschaltlf&auml;chen sowie den Code, um von dort aus den &#8222;Suchen und Ersetzen&#8220;-Dialog zu starten.<\/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":[662025,66042025,44000027],"tags":[],"class_list":["post-55001555","post","type-post","status-publish","format-standard","hentry","category-662025","category-66042025","category-Loesungen"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Suchen und Ersetzen mit COM-Add-In - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Suchen und Ersetzen mit COM-Add-In\" \/>\n<meta property=\"og:description\" content=\"Im Beitrag &quot;Besserer Suchen und Ersetzen-Dialog&quot; haben wir den Dialog zum Suchen und Ersetzen in Access-Formularen nachgebaut und um einige Features erg&auml;nzt. Nun wollen wir unseren selbst gebauten Dialog noch f&uuml;r jede Access-Anwendung verf&uuml;gbar machen. Was liegt da n&auml;her, als diessn &uuml;ber das Ribbon aufzurufen? Um eine solche Erweiterung f&uuml;r jede ge&ouml;ffnete Anwendung verf&uuml;gbar zu machen und so flexibel wie m&ouml;glich zu sein, verwenden wir dazu ein COM-Add-In. Dieses enth&auml;lt lediglich die Erweiterung des Ribbons um die ben&ouml;tigten Befehlsschaltlf&auml;chen sowie den Code, um von dort aus den &quot;Suchen und Ersetzen&quot;-Dialog zu starten.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2025-08-03T11:25:37+00:00\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"18\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Suchen_und_Ersetzen_mit_COMAddIn\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Suchen_und_Ersetzen_mit_COMAddIn\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Suchen und Ersetzen mit COM-Add-In\",\"datePublished\":\"2025-08-03T11:25:37+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Suchen_und_Ersetzen_mit_COMAddIn\\\/\"},\"wordCount\":2837,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Suchen_und_Ersetzen_mit_COMAddIn\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/cf66c01874e44b598f5984e27e887f41\",\"articleSection\":[\"2025\",\"4\\\/2025\",\"L\u00f6sungen\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Suchen_und_Ersetzen_mit_COMAddIn\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Suchen_und_Ersetzen_mit_COMAddIn\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Suchen_und_Ersetzen_mit_COMAddIn\\\/\",\"name\":\"Suchen und Ersetzen mit COM-Add-In - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Suchen_und_Ersetzen_mit_COMAddIn\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Suchen_und_Ersetzen_mit_COMAddIn\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/cf66c01874e44b598f5984e27e887f41\",\"datePublished\":\"2025-08-03T11:25:37+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Suchen_und_Ersetzen_mit_COMAddIn\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Suchen_und_Ersetzen_mit_COMAddIn\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Suchen_und_Ersetzen_mit_COMAddIn\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/cf66c01874e44b598f5984e27e887f41\",\"contentUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/cf66c01874e44b598f5984e27e887f41\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Suchen_und_Ersetzen_mit_COMAddIn\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Suchen und Ersetzen mit COM-Add-In\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Suchen und Ersetzen mit COM-Add-In - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/","og_locale":"de_DE","og_type":"article","og_title":"Suchen und Ersetzen mit COM-Add-In","og_description":"Im Beitrag \"Besserer Suchen und Ersetzen-Dialog\" haben wir den Dialog zum Suchen und Ersetzen in Access-Formularen nachgebaut und um einige Features erg&auml;nzt. Nun wollen wir unseren selbst gebauten Dialog noch f&uuml;r jede Access-Anwendung verf&uuml;gbar machen. Was liegt da n&auml;her, als diessn &uuml;ber das Ribbon aufzurufen? Um eine solche Erweiterung f&uuml;r jede ge&ouml;ffnete Anwendung verf&uuml;gbar zu machen und so flexibel wie m&ouml;glich zu sein, verwenden wir dazu ein COM-Add-In. Dieses enth&auml;lt lediglich die Erweiterung des Ribbons um die ben&ouml;tigten Befehlsschaltlf&auml;chen sowie den Code, um von dort aus den \"Suchen und Ersetzen\"-Dialog zu starten.","og_url":"https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/","og_site_name":"Access im Unternehmen","article_published_time":"2025-08-03T11:25:37+00:00","author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"18\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Suchen und Ersetzen mit COM-Add-In","datePublished":"2025-08-03T11:25:37+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/"},"wordCount":2837,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/cf66c01874e44b598f5984e27e887f41","articleSection":["2025","4\/2025","L\u00f6sungen"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/","url":"https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/","name":"Suchen und Ersetzen mit COM-Add-In - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/cf66c01874e44b598f5984e27e887f41","datePublished":"2025-08-03T11:25:37+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/#primaryimage","url":"http:\/\/vg01.met.vgwort.de\/na\/cf66c01874e44b598f5984e27e887f41","contentUrl":"http:\/\/vg01.met.vgwort.de\/na\/cf66c01874e44b598f5984e27e887f41"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Suchen_und_Ersetzen_mit_COMAddIn\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Suchen und Ersetzen mit COM-Add-In"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001555","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55001555"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001555\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001555"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001555"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001555"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}