{"id":55001317,"date":"2021-08-01T00:00:00","date_gmt":"2021-07-31T10:13:48","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1317"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/","title":{"rendered":"COM-Add-In: Ereignisprozedur zur Laufzeit anzeigen"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg07.met.vgwort.de\/na\/c8fc246312d94317852db2b8abb3c59a\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Bei unserer Arbeit mit Access passiert es immer wieder, dass wir schnell pr&uuml;fen wollen, was eine durch ein bestimmtes Ereignis ausgel&ouml;ste Prozedur &uuml;berhaupt erledigt. Dann muss man in den Entwurf wechseln, einen Haltepunkt setzen, wieder den Formularansicht aktivieren und dann das Ereignis ausl&ouml;sen. Wir w&auml;re es mit einem Add-In, das die Ereignisse des aktuell markierten Steuerelements direkt anzeigen k&ouml;nnte Ein solches COM-Add-In wollen wir in diesem Beitrag entwickeln und vorstellen. Das ist ein perfekter Anwendungszweck f&uuml;r die neue Entwicklungsumgebung twinBASIC, die wir in Ausgabe 3\/2021 im Detail vorgestellt haben.<\/b><\/p>\n<h2>Debuggen schwer gemacht<\/h2>\n<p>Kennen Sie das auch Sie geben testweise w&auml;hrend der Entwicklung einer Anwendung Daten ein oder bet&auml;tigen eine Schaltfl&auml;che, und es geschieht einfach nicht das, was Sie gerade erwarten. Also geht es ans Debuggen: wechseln in die Entwurfsansicht des Formulars, dort das betreffende Steuerelement anklicken, damit seine Eigenschaften im Eigenschaftenblatt erscheinen, die passende Ereignisprozedur ausw&auml;hlen und auf die Schaltfl&auml;che mit den drei Punkten klicken (siehe Bild 1).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2021_04\/pic_1317_002.png\" alt=\"&Uuml;blicher Weg zur Anzeige der Ereignisprozedur eines Steuerelements\" width=\"574,559\" height=\"350,7426\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: &Uuml;blicher Weg zur Anzeige der Ereignisprozedur eines Steuerelements<\/span><\/b><\/p>\n<p>Der VBA-Editor erscheint und zeigt die durch das Ereignis ausgel&ouml;ste Prozedur an. Hier setzen wir dann einen Haltepunkt, um den Prozedurablauf gleich im Detail ansehen zu k&ouml;nnen (siehe Bild 2).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2021_04\/pic_1317_003.png\" alt=\"Setzen eines Haltepunktes in der ersten Zeile einer Ereignisprozedur\" width=\"624,559\" height=\"306,9588\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Setzen eines Haltepunktes in der ersten Zeile einer Ereignisprozedur<\/span><\/b><\/p>\n<p>Damit sind die Arbeiten im VBA-Editor vorerst erledigt und wir k&ouml;nnen zum Access-Fenster zur&uuml;ckkehren. Dort wechseln wir im aktuellen Formular wieder in die Formularansicht und f&uuml;hren den Vorgang erneut aus.<\/p>\n<p>Gegebenenfalls ist es hierzu sogar noch notwendig, das Formular zu schlie&szlig;en und es anschlie&szlig;end &uuml;ber das Ribbon oder von einem anderen Formular aus erneut zu &ouml;ffnen, damit die ben&ouml;tigte Datenkonstellation wieder vorhanden ist.<\/p>\n<p>Wenn Sie das kennen, wissen Sie: Das ist anstrengend und wirkt irgendwie aufwendiger, als es sein muss. Das haben wir uns auch gedacht und ein COM-Add-In entwickelt, das beim Entwickeln einer Anwendung Folgendes erlaubt: Sie markieren einfach das zu untersuchende Steuerelement und w&auml;hlen per Ribbon-Befehl aus allen Ereignissen der aktuellen Situation das zu untersuchende aus, welches dann automatisch im VBA-Editor angezeigt wird.<\/p>\n<h2>Debuggen, die leichte Version<\/h2>\n<p>Nun schauen wir uns erst einmal an, was wir am Ende des Beitrags f&uuml;r eine L&ouml;sung erhalten. Wenn Sie nach der Installation des COM-Add-Ins ein Steuerelement markieren, k&ouml;nnen Sie einfach das Ribbon-Men&uuml; <b>Ereignisprozeduren anzeigen <\/b>in der Gruppe <b>Steuerelemente <\/b>des Tabs <b>amvAccessTools <\/b>anzeigen. Hier finden Sie ganz oben die Ereignisprozeduren f&uuml;r das aktuelle Hauptformular, in diesem Fall <b>Form_Load<\/b>. Darunter zeigt die Liste f&uuml;r dieses Beispiel die drei Ereignisprozeduren f&uuml;r das Steuerelement <b>ctlTreeView <\/b>(siehe Bild 3).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2021_04\/pic_1317_004.png\" alt=\"Anzeige der Ereignisprozedur per Ribbon-Befehl\" width=\"599,559\" height=\"330,4071\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Anzeige der Ereignisprozedur per Ribbon-Befehl<\/span><\/b><\/p>\n<p>W&auml;hlen Sie einen dieser Eintr&auml;ge aus, erscheint der VBA-Editor und die ausgew&auml;hlte Prozedur wird markiert angezeigt (siehe Bild 4). Wenn Sie ein Steuerelement in einem Unterformular selektieren, werden auch noch die Ereignisprozeduren des Unterformulars in der Liste angezeigt. F&uuml;r weitere Verschachtelungsebenen ist die L&ouml;sung in der hier vorgestellten Form jedoch nicht ausgelegt.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2021_04\/pic_1317_005.png\" alt=\"Anzeige und Markierung der Ereignisprozedur\" width=\"699,559\" height=\"290,1874\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Anzeige und Markierung der Ereignisprozedur<\/span><\/b><\/p>\n<h2>Programmieren des COM-Add-Ins<\/h2>\n<p>Das COM-Add-In programmieren wir mit dem neuen Tool twinBASIC, das wir im Beitrag <b>twinBASIC &#8211; VB\/VBA mit moderner Umgebung <\/b>(<b>www.access-im-unternehmen.de\/1303<\/b>) im Detail vorgestellt haben. Hier erfahren Sie auch, wie Sie twinBASIC installieren. Wie Sie ein COM-Add-In grunds&auml;tzlich programmieren, beschreibt der Beitrag <b>twinBASIC &#8211; COM-Add-Ins f&uuml;r Access <\/b>(<b>www.access-im-unternehmen.de\/1306<\/b>).<\/p>\n<p>Wir starten mit dem aktuellen Beispielprojekt f&uuml;r ein COM-Add-In f&uuml;r Access, das Sie im Download zu diesem Beitrag in der Zip-Datei <b>twinBASIC_myCOMAddin.zip <\/b>finden.<\/p>\n<h2>Projekt &ouml;ffnen<\/h2>\n<p>Nachdem Sie Visual Studio Code und twinBASIC wie im oben genannten Beitrag installiert haben, &ouml;ffnen Sie das Projekt durch einen Doppelklick auf die Datei <b>myCOMAddin.code-workspace<\/b>.<\/p>\n<h2>Projektelemente umbenennen<\/h2>\n<p>Als Erstes nehmen wir einige &Auml;nderungen bez&uuml;glich der Benennung von Projekt, Klasse et cetera vor. Dazu &ouml;ffnen Sie durch einen Mausklick auf den Eintrag <b>Settings <\/b>im Projekt-Explorer die Einstellungen des Projekts.<\/p>\n<p>Hier sehen Sie ganz oben die beiden Eintr&auml;ge <b>Project: Name <\/b>und <b>Project: Description<\/b>. Diese passen Sie wie in Bild 5 an. Wichtig: Merken Sie sich den Namen, den Sie f&uuml;r das Projekt vergeben, hier <b>amvEreignisprozedurAnzeigen<\/b>, &#8211; diesen ben&ouml;tigen wir gleich noch. Wichtig: Bet&auml;tigen Sie auf jeden Fall die Tastenkombination <b>Strg + S<\/b>, um die &Auml;nderungen zu speichern!<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2021_04\/pic_1317_006.png\" alt=\"Anpassen der Benennung von Elementen\" width=\"700\" height=\"285,308\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Anpassen der Benennung von Elementen<\/span><\/b><\/p>\n<h2>Klassenname &auml;ndern<\/h2>\n<p>Dann schauen wir uns die Klasse des Projekts an, was wir durch einen Klick auf den Eintrag <b>HelloWorld.twin <\/b>erreichen. Diesen Eintrag &auml;ndern wir, indem wir seinen Kontextmen&uuml;-Befehl <b>Umbenennen <\/b>aufrufen und dann etwa die Bezeichnung <b>EreignisprozedurenAnzeigen.twin <\/b>eingeben.<\/p>\n<p>Auch im Code der Klasse stellen wir den Namen wie folgt um:<\/p>\n<pre><span style=\"color:blue;\">Class<\/span> EreignisprozedurAnzeigen\r\n     Implements IDTExtensibility2\r\n      ...<\/pre>\n<h2>Verweise auf Bibliotheken anlegen<\/h2>\n<p>Schlie&szlig;lich ben&ouml;tigen wir f&uuml;r die nachfolgende Programmierung noch Verweise auf ein paar weitere Bibliotheken. Diese legen wir wieder im Bereich <b>Settings <\/b>an. Hier f&uuml;gen wir im Bereich <b>COM Type Library \/ ActiveX References <\/b>die beiden folgenden Verweise hinzu:<\/p>\n<ul>\n<li><b>Microsoft Access 16.0 Object Library<\/b><\/li>\n<li><b>Microsoft Visual Basic for Applications Extensibility 5.3<\/b><\/li>\n<\/ul>\n<p>Der Bereich sollte danach wie in Bild 6 aussehen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2021_04\/pic_1317_001.png\" alt=\"Hinzuf&uuml;gen von Verweisen\" width=\"574,559\" height=\"392,7722\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Hinzuf&uuml;gen von Verweisen<\/span><\/b><\/p>\n<h2>COM-Add-In f&uuml;r Access vorbereiten<\/h2>\n<p>Die Klasse <b>EreignisprozedurAnzeigen <\/b>enth&auml;lt nun bereits einige grundlegende Elemente. Zum Beispiel legt die Zeile <b>Implements IDTExtensibility2 <\/b>fest, dass die Klasse die angegebene Schnittstelle implementiert. Das bedeutet, dass wir die f&uuml;r die Schnittstelle vorgegebenen Ereignisprozeduren anlegen m&uuml;ssen.<\/p>\n<p>Die wichtigste Ereignisprozedur ist in unserem Fall <b>OnConnection<\/b>. Wenn Sie Access &ouml;ffnen, startet es die in der Registry angegebenen COM-Add-Ins (mehr zur Registrierung weiter unten). Dabei wird direkt <b>OnConnection <\/b>aufgerufen und der Parameter <b>Application <\/b>liefert einen Verweis auf die aufrufende Anwendung, in diesem Fall Access. Den Inhalt dieses Parameters schreiben wir direkt in die zuvor deklarierte Variable <b>objApplication<\/b>, die mit dem Datentyp <b>Access.Application <\/b>deklariert ist.<\/p>\n<p>Au&szlig;erdem implementiert die Klasse eine weitere Schnittstelle namens <b>IRibbonExtensibility<\/b>. Diese wird ben&ouml;tigt, um vom COM-Add-In aus Ribbon-Anpassungen vorzunehmen. Hier m&uuml;ssen wir zus&auml;tzlich noch die Eigenschaft <b>WithDispatchForwarding <\/b>voranstellen:<\/p>\n<pre>[WithDispatchForwarding]\r\nImplements IRibbonExtensibility<\/pre>\n<p>Schlie&szlig;lich ben&ouml;tigen wir noch eine Objektvariable, mit der wir die Ribbon-Erweiterung referenzieren k&ouml;nnen:<\/p>\n<pre><span style=\"color:blue;\">Public <\/span>objRibbon<span style=\"color:blue;\"> As <\/span>IRibbonUI<\/pre>\n<p>Das Grundger&uuml;st der Klasse haben wir in Listing 1 abgebildet.<\/p>\n<pre><span style=\"color:blue;\">Class<\/span> EreignisprozedurAnzeigen\r\n     Implements IDTExtensibility2\r\n     [WithDispatchForwarding]\r\n     Implements IRibbonExtensibility\r\n     \r\n     <span style=\"color:blue;\">Private <\/span>objApplication<span style=\"color:blue;\"> As <\/span>Access.Application\r\n    \r\n     Sub OnConnection(ByVal Application<span style=\"color:blue;\"> As Object<\/span>, ByVal ConnectMode<span style=\"color:blue;\"> As <\/span>ext_ConnectMode, _\r\n             ByVal AddInInst<span style=\"color:blue;\"> As Object<\/span>, ByRef custom<span style=\"color:blue;\"> As Variant<\/span>()) Implements IDTExtensibility2.OnConnection\r\n         <span style=\"color:blue;\">Set<\/span> objApplication = Application\r\n     End Sub\r\n     \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     \r\n     Sub OnAddInsUpdate(ByRef custom<span style=\"color:blue;\"> As Variant<\/span>()) Implements IDTExtensibility2.OnAddInsUpdate\r\n     End Sub\r\n     \r\n     Sub OnStartupComplete(ByRef custom<span style=\"color:blue;\"> As Variant<\/span>()) Implements IDTExtensibility2.OnStartupComplete\r\n     End Sub\r\n     \r\n     Sub OnBeginShutdown(ByRef custom<span style=\"color:blue;\"> As Variant<\/span>()) Implements IDTExtensibility2.OnBeginShutdown\r\n     End Sub\r\n     ...\r\n<span style=\"color:blue;\">End Class<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Grundstruktur des COM-Add-Ins<\/span><\/b><\/p>\n<h2>Aufruf &uuml;ber das Ribbon&nbsp;&nbsp;&nbsp;&nbsp;<\/h2>\n<p>Die Funktion des COM-Add-Ins soll, wie eingangs erw&auml;hnt, &uuml;ber einen Befehl beziehungsweise ein Men&uuml; im Ribbon bereitgestellt werden. Damit dieses erscheint, m&uuml;ssen wir die Ribbon-Erweiterung, die das COM-Add-In bereitstellt, &uuml;ber die ebenfalls beim Start des Add-Ins aufgerufene Funktion <b>GetCustomUI <\/b>zusammenstellen und als R&uuml;ckgabewert dieser Funktion definieren.<\/p>\n<p>In dieser stellen wir den kompletten XML-Ausdruck f&uuml;r die Ribbon-Erweiterung zusammen (siehe Listing 2).<\/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> _\r\n     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\/2006\/01\/customui\"\" 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 id=\"\"tabTest\"\" label=\"\"amvAccessTools\"\"&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strXML &= \"        &lt;group id=\"\"grpSteuerelemente\"\" label=\"\"Steuerelemente\"\"&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     strXML &= \"          &lt;dynamicMenu id=\"\"dmnEvents\"\" label=\"\"Ereignisprozeduren anzeigen\"\"\" _\r\n         & \" getContent=\"\"GetContent\"\" imageMso=\"\"CreateModule\"\" size=\"\"large\"\"\/&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<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Diese Funktion setzt das Ribbon zusammen.<\/span><\/b><\/p>\n<p>Dies liefert eine XML-Definition wie die Folgende:<\/p>\n<pre>&lt;customUI xmlns=\"http:\/\/schemas.microsoft.com\/ office\/2006\/01\/customui\" onLoad=\"OnLoad\"&gt;\r\n     &lt;ribbon startFromScratch=\"false\"&gt;\r\n     &lt;tabs&gt;\r\n       &lt;tab id=\"tabTest\" label=\"amvAccessTools\"&gt;\r\n         &lt;group id=\"grpSteuerelemente\"  label=\"Steuerelemente\"&gt;\r\n           &lt;dynamicMenu id=\"dmnEvents\"  label=\"Ereignisprozeduren anzeigen\"  getContent=\"GetContent\"  imageMso=\"CreateModule\" size=\"large\"\/&gt;\r\n         &lt;\/group&gt;\r\n       &lt;\/tab&gt;\r\n     &lt;\/tabs&gt;\r\n   &lt;\/ribbon&gt;\r\n&lt;\/customUI&gt;<\/pre>\n<p>Das Kernst&uuml;ck ist das <b>dynamicMenu<\/b>-Element, das mit der <b>getContent<\/b>-Callback-Funktion beim Aufklappen dynamisch die Ereignisprozeduren f&uuml;r die aktuell markierten Elemente zusammenstellen soll.<\/p>\n<p>Die dazu notwendige Funktion schauen wir uns weiter unten an.<\/p>\n<h2>Ribbon per Variable referenzieren<\/h2>\n<p>Wichtig ist auch noch, dass wir f&uuml;r das Attribut <b>onLoad <\/b>des Elements <b>customUI <\/b>eine Callback-Funktion angeben, die beim ersten Laden des Ribbons ausgel&ouml;st wird.<\/p>\n<p>Diese schreibt den mit dem Parameter <b>ribbon <\/b>gelieferten Verweis auf das Ribbon in die weiter oben deklarierte Variable <b>objRibbon<\/b>:<\/p>\n<pre><span style=\"color:blue;\">Sub <\/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 Sub<\/span><\/pre>\n<p>Warum ben&ouml;tigen wir dies Weil beim &Ouml;ffnen des <b>dynamicMenu<\/b>-Elements die Callbackfunktion zum Zusammenstellen des Men&uuml;s nur einmal aufgerufen wird &#8211; au&szlig;er, wir machen diese &#8222;ung&uuml;ltig&#8220;. Und dazu m&uuml;ssen wir eine Methode der Objektvariablen f&uuml;r das <b>IRibbonUI<\/b>-Objekt aufrufen.<\/p>\n<h2>dynamicMenu beim Aufklappen des Men&uuml;s f&uuml;llen<\/h2>\n<p>Nun kommt der spannende Teil. Wie f&uuml;llen wir das <b>dynamicMenu<\/b>-Element beim Aufklappen des Men&uuml;s Die erste Anmerkung ist f&uuml;r Programmierer, die bereits einmal <b>dynamicMenu<\/b>-Elemente unter Access verwendet haben.<\/p>\n<p>Hier unter twinBASIC nutzen Sie eine etwas andere Syntax als unter VBA. Unter VBA lautet die erste Zeile der Callbackfunktion:<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>GetContent(control<span style=\"color:blue;\"> As <\/span>IRibbonControl, ByRef XMLString)<\/pre>\n<p>Unter twinBASIC verwenden wir die Deklaration wie unter VB6, die etwas anders aussieht:<\/p>\n<pre><span style=\"color:blue;\">Function <\/span>GetContent(control<span style=\"color:blue;\"> As <\/span>IRibbonControl)<span style=\"color:blue;\"> As String<\/span><\/pre>\n<p><!--30percent--><\/p>\n<p>Danach deklariert die Funktion die notwendigen Variablen, von denen viele aus der Bibliothek <b>Microsoft Visual Basic for Applications Extensibility 5.3<\/b> stammen. Das bedeutet: Wir werden direkt auf den Code im VBA-Editor zugreifen, um die Ereignisprozeduren der Elemente zu ermitteln.<\/p>\n<h2>VBA-Projekt per Hilfsfunktion holen<\/h2>\n<p>Damit steigen wir nun in die Funktion <b>GetContent <\/b>aus Listing 3 ein (im Download finden Sie eine bereits weiterentwickelte Version). Hier nutzen wir als Erstes eine Hilfsfunktion namens <b>GetCurrentVBProject<\/b>, um das aktuelle VBA-Projekt zu referenzieren.<\/p>\n<pre><span style=\"color:blue;\">Function <\/span>GetContent(control<span style=\"color:blue;\"> As <\/span>IRibbonControl)<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objVBProject<span style=\"color:blue;\"> As <\/span>VBProject, objVBComponent<span style=\"color:blue;\"> As <\/span>VBComponent, objCodeModule<span style=\"color:blue;\"> As <\/span>CodeModule\r\n     <span style=\"color:blue;\">Dim <\/span>frm<span style=\"color:blue;\"> As <\/span>Form, sfm<span style=\"color:blue;\"> As <\/span>Form, ctl<span style=\"color:blue;\"> As <\/span>Control\r\n     <span style=\"color:blue;\">Dim <\/span>strVBComponent<span style=\"color:blue;\"> As String<\/span>, strContent<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strEventsForm<span style=\"color:blue;\"> As String<\/span>, strEventsSubform<span style=\"color:blue;\"> As String<\/span>, strEventsControl<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> objVBProject = GetCurrentVBProject\r\n     strContent = \"&lt;menu xmlns=\"\"http:\/\/schemas.microsoft.com\/office\/2006\/01\/customui\"\"&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> frm = objApplication.Screen.ActiveForm\r\n     On Error Goto 0\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> frm Is Nothing<span style=\"color:blue;\"> Then<\/span>\r\n         On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n         <span style=\"color:blue;\">Set<\/span> ctl = objApplication.Screen.ActiveControl\r\n         On Error Goto 0\r\n         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> ctl Is Nothing<span style=\"color:blue;\"> Then<\/span>\r\n             strVBComponent = frm.Name\r\n             <span style=\"color:blue;\">If <\/span>frm.HasModule<span style=\"color:blue;\"> Then<\/span>\r\n                 <span style=\"color:blue;\">Set<\/span> objVBComponent = objVBProject.VBComponents(\"Form_\" & strVBComponent)\r\n                 <span style=\"color:blue;\">Set<\/span> objCodeModule = objVBComponent.CodeModule\r\n                 strEventsForm = GetEventsForm(strVBComponent, objCodeModule)\r\n                 strContent = strContent & strEventsForm\r\n             <span style=\"color:blue;\">End If<\/span>\r\n             <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> ctl.Parent Is frm<span style=\"color:blue;\"> Then<\/span>\r\n                 <span style=\"color:blue;\">Set<\/span> sfm = ctl.Parent\r\n                 <span style=\"color:blue;\">If <\/span>sfm.HasModule<span style=\"color:blue;\"> Then<\/span>            \r\n                     strVBComponent = ctl.Parent.Name\r\n                     <span style=\"color:blue;\">Set<\/span> objVBComponent = objVBProject.VBComponents(\"Form_\" & strVBComponent)\r\n                     <span style=\"color:blue;\">Set<\/span> objCodeModule = objVBComponent.CodeModule\r\n                     strEventsSubForm = GetEventsForm(strVBComponent, objCodeModule)\r\n                     strContent = strContent & \"&lt;menuSeparator id=\"\"sep2\"\"\/&gt;\"\r\n                     strContent = strContent & strEventsSubform\r\n                 <span style=\"color:blue;\">End If<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">Else<\/span>\r\n             <span style=\"color:blue;\">MsgBox<\/span> \"Kein Steuerelement aktiviert.\", vbExclamation + vbOKOnly, \"Fehlende Selektion\"    \r\n         <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">If <\/span>ctl.Parent.HasModule<span style=\"color:blue;\"> Then<\/span>\r\n             strContent = strContent & \"&lt;menuSeparator id=\"\"sep3\"\"\/&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n             strEventsControl = GetEventsControl(strVBComponent, objCodeModule, ctl)\r\n             strContent = strContent & strEventsControl\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"Kein Formular aktiviert.\", vbExclamation + vbokonly, \"Fehlende Selektion\"\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     strContent = strContent & \" &lt;\/menu&gt;\"\r\n     objRibbon.Invalidate\r\n     Return strContent\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Diese Funktion setzt das dynamicMenu zusammen.<\/span><\/b><\/p>\n<p>Das ist n&ouml;tig, weil der VBA-Editor auch schon mal mehr als ein VBA-Projekt enth&auml;lt &#8211; beispielsweise, wenn ein Access-Add-In ge&ouml;ffnet ist. Diese Funktion durchl&auml;uft alle VBA-Projekte, bis es eines findet, dessen Dateipfad mit dem der aktuellen Access-Anwendung &uuml;bereinstimmt:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>GetCurrentVBProject()<span style=\"color:blue;\"> As <\/span>VBProject\r\n     <span style=\"color:blue;\">Dim <\/span>objVBProject<span style=\"color:blue;\"> As <\/span>VBProject\r\n     For Each objVBProject In objApplication.VBE.VBProjects\r\n         <span style=\"color:blue;\">If <\/span>(objVBProject.FileName =  objApplication.CurrentDb.Name)<span style=\"color:blue;\"> Then<\/span>\r\n             <span style=\"color:blue;\">Set<\/span> GetCurrentVBProject = objVBProject\r\n             <span style=\"color:blue;\">Exit Function<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> objVBProject\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<h2>Men&uuml; zusammenstellen<\/h2>\n<p>Dieses weisen wir der Variablen <b>objVBProject <\/b>zu. Dann schreibt die Prozedur die erste Zeile des <b>dynamicMenu<\/b>-Elements in die Variable <b>strContent<\/b>:<\/p>\n<pre>&lt;menu xmlns=\"http:\/\/schemas.microsoft.com\/office\/ 2006\/01\/customui\"&gt;<\/pre>\n<p>Wir ermitteln sodann bei abgeschalteter Fehlerbehandlung mit <b>Screen.ActiveControl <\/b>f&uuml;r das Access-Objekt aus <b>objApplication <\/b>das aktuell aktive Formular und referenzieren dieses mit der Variablen <b>frm<\/b>. Die Fehlerbehandlung schalten wir aus, weil ein Fehler ausgel&ouml;st w&uuml;rde, wenn aktuell kein Formular ge&ouml;ffnet ist. Ist ein Formular ge&ouml;ffnet, ist die Bedingung der folgenden <b>If&#8230;Then<\/b>-Bedingung wahr.<\/p>\n<p>Wir schalten erneut die Fehlerbehandlung aus und lesen das aktive Steuerelement aus, das in der Variablen <b>ctl <\/b>landet. Das kein Steuerelement aktiv ist, kommt nur dann vor, wenn das Formular kein Steuerelement enth&auml;lt, welches den Fokus erhalten kann. Ist <b>ctl <\/b>danach nicht leer, werden die Anweisungen im <b>If<\/b>-Zweig der folgenden <b>If&#8230;Then<\/b>-Bedingung abgearbeitet.<\/p>\n<p>Hier ermitteln wir den Namen des Formulars und tragen diesen in <b>strVBComponent<\/b> ein. Dann pr&uuml;fen wir mit der Eigenschaft <b>HasModule<\/b>, ob das Formular <b>frm <\/b>&uuml;berhaupt ein Klassenmodul hat. Falls nicht, liegen logischerweise auch keine Ereignisprozeduren f&uuml;r das Formular vor.<\/p>\n<p>Ist jedoch ein Klassenmodul vorhanden, referenzieren wir dieses &uuml;ber die Auflistung <b>VBComponents <\/b>des <b>VBProject<\/b>-Elements und dem aus dem Text <b>Form_ <\/b>und dem Formularnamen bestehenden Index. Die Variable <b>objCodeModule <\/b>f&uuml;llen wir mit einem Verweis auf das <b>CodeModule<\/b>-Objekt des <b>VBComponent<\/b>-Elements.<\/p>\n<p>Schlie&szlig;lich rufen wir eine Funktion namens <b>GetEventsForm <\/b>auf, der wie den Formularnamen und die Objektvariable <b>objCodeModule <\/b>&uuml;bergeben, und die uns beispielsweise die folgende Zeile zur&uuml;ckliefert &#8211; hier im Falle einer einzigen Prozedur f&uuml;r das Ereignis <b>Vor Aktualisierung <\/b>des Formulars:<\/p>\n<pre>&lt;button id=\"frmArtikel_Form_BeforeUpdate\" \r\n   imageMso=\"ChooseForm\" \r\n   label=\"Form_BeforeUpdate\" \r\n   onAction=\"OnAction\" \r\n   tag=\"Form_frmArtikel|Form_BeforeUpdate\"\/&gt;<\/pre>\n<p>Die ID soll immer eine Kombination aus dem Formularnamen und dem Namen der Ereignisprozedur sein. Als Bezeichnung (<b>label<\/b>) verwenden wir den Namen der Ereignisprozedur. F&uuml;r das Attribut <b>tag <\/b>legen wir au&szlig;erdem eine Zeichenkette fest, die aus dem Namen des Klassenmoduls und dem Namen der Ereignisprozedur besteht &#8211; getrennt durch das Pipe-Zeichen (<b>|<\/b>). Aus dem <b>tag<\/b>-Attribut lesen wir sp&auml;ter die beiden Informationen aus.<\/p>\n<p>Wie das Zusammenstellen gelingt, erkl&auml;ren wir weiter unten. Den R&uuml;ckgabewert speichern wir in der Variablen <b>strEventsForm<\/b>. Diesen h&auml;ngen wir anschlie&szlig;end an den Inhalt von <b>strContent<\/b> an, wo wir die einzelnen Zeilen des XML-Men&uuml;s sammeln.<\/p>\n<h2>Auf Unterformular pr&uuml;fen<\/h2>\n<p>Danach folgt eine wichtige Unterscheidung: Befindet sich das zu untersuchende Steuerelement eigentlich direkt in dem Formular aus <b>frm <\/b>oder ist es vielleicht ein Steuerelement in einem Unterformular In welchem Objekt sich ein Steuerelement befindet, finden wir &uuml;ber die Eigenschaft <b>Parent <\/b>heraus.<\/p>\n<p>Meist handelt es sich hierbei um ein Formular. Es kann sich auch um ein Registersteuerelement handeln &#8211; aber diesen Fall decken wir f&uuml;r diese L&ouml;sung nicht ab. Mit dem Vergleich von <b>ctl.Parent <\/b>mit <b>frm <\/b>pr&uuml;fen wir, ob sich das Steuerelement im aktuellen Hauptformular befindet. Falls nicht, untersuchen wir zus&auml;tzlich noch das Unterformular, in dem sich das Steuerelement befindet.<\/p>\n<p>Dieses ermitteln wir mit <b>ctl.Parent <\/b>und referenzieren es mit der Variablen <b>sfm<\/b>. Auch hier pr&uuml;fen wir wieder, ob das Formular ein Klassenmodul enth&auml;lt. Falls ja, f&uuml;hren wir &auml;hnliche Schritte durch wie f&uuml;r das Hauptformular &#8211; inklusive des Aufrufs der Funktion <b>GetEventsForm<\/b>, dessen Ergebnis wir dann, getrennt von den vorherigen Eintr&auml;gen, an die Variable <b>strContent <\/b>anh&auml;ngen.<\/p>\n<p>Sollte weiter oben kein Steuerelement aktiviert gewesen sein, erscheint eine entsprechende Meldung.<\/p>\n<h2>Steuerelement-Ereignisprozeduren einlesen<\/h2>\n<p>Schlie&szlig;lich lesen wir noch die Ereignisprozeduren f&uuml;r das Steuerelement mit dem Fokus ein. Dazu pr&uuml;fen wir nochmals das Vorhandensein eines Moduls, diesmal f&uuml;r das Formular, in dem sich das Steuerelement befindet. Dieses ermitteln wir mit <b>ctl.Parent<\/b>. Auch hier gilt: F&uuml;r Steuerelemente etwa auf Registerseiten funktioniert dies in der aktuellen Version nicht.<\/p>\n<p>Diesmal rufen wir die Funktion <b>GetEventsControl <\/b>auf, um die Men&uuml;-Eintr&auml;ge f&uuml;r das Steuerelement zu ermitteln. Diesem &uuml;bergeben wir den Namen des Formulars aus <b>strVBComponent<\/b>, das <b>CodeModule<\/b>-Element und zus&auml;tzlich den Verweis auf das Steurerelement mit <b>ctl<\/b>.<\/p>\n<p>Nach dem <b>Else<\/b>-Zweig der &auml;u&szlig;eren <b>If&#8230;Then<\/b>-Bedingung, der eine Meldung anzeigt, wenn kein Formular den Fokus hat, h&auml;ngt die Prozedur das schlie&szlig;ende <b>menu<\/b>-Element an <b>strContent <\/b>an.<\/p>\n<h2>Ribbon &#8222;ung&uuml;ltig&#8220; machen<\/h2>\n<p>Schlie&szlig;lich folgt noch der Aufruf einer wichtigen Methode: Wir haben weiter oben einen Verweis auf die Ribbon-Definition in der Variablen <b>objRibbon <\/b>gespeichert.<\/p>\n<p>Diesen machen wir nun mit der Methode <b>Invalidate <\/b>ung&uuml;ltig, damit die <b>GetContent<\/b>-Callbackfunktion beim n&auml;chsten Aufklappen des Men&uuml;s erneut aufgerufen wird. Wenn wir das nicht tun, beh&auml;lt das Men&uuml; die zuvor ermittelten Eintr&auml;ge. Danach fehlt nur noch die <b>Return<\/b>-Anweisung, mit der wir den Inhalt von <b>strContent <\/b>an die aufrufende Instanz zur&uuml;ckliefern.<\/p>\n<p>Hinweis: Von VBA kennen Sie es so, dass der R&uuml;ckgabewert einer Variablen mit dem Namen der Funktion zugewiesen wird. twinBASIC bietet einige Unterschiede zu VBA, zum Beispiel die R&uuml;ckgabe mit der etwas besser lesbaren Anweisung <b>Return<\/b>.<\/p>\n<h2>Ereignisprozeduren f&uuml;r Formular einlesen<\/h2>\n<p>Die Funktion <b>GetEventsForm<\/b>, die Sie in Listing 4 finden, &uuml;bernimmt die Kleinarbeit. Sie durchl&auml;uft alle Zeilen des mit <b>objCodeModule <\/b>&uuml;bergebenen Moduls in einer <b>For&#8230;Next<\/b>-Schleife. Dabei starten wir bei der Zeile, die mit <b>CountOfDeclarationLines <\/b>geliefert wird, also direkt hinter den Deklarationen im Modulkopf. Die letzte Zeile ist die mit <b>CountOfLines <\/b>ermittelte letzte Zeile des Moduls.<\/p>\n<pre><span style=\"color:blue;\">Function <\/span>GetEventsForm(strVBComponent<span style=\"color:blue;\"> As String<\/span>, objCodeModule<span style=\"color:blue;\"> As <\/span>CodeModule)<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strEventsForm<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strCurrentSub<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strPreviousSub<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngProcKind<span style=\"color:blue;\"> As <\/span>vbext_ProcKind\r\n     <span style=\"color:blue;\">Dim <\/span>l<span style=\"color:blue;\"> As Long<\/span>\r\n     For l = objCodeModule.CountOfDeclarationLines + 1 To objCodeModule.CountOfLines\r\n         strCurrentSub = objCodeModule.ProcOfLine(l, lngProcKind)\r\n         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> strCurrentSub = strPreviousSub<span style=\"color:blue;\"> Then<\/span>\r\n             <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Left<\/span>(strCurrentSub, 5) = \"Form_\"<span style=\"color:blue;\"> Then<\/span>\r\n                 strEventsForm = strEventsForm & \"&lt;button id=\"\"\" & strVBComponent & \"_\" & strCurrentSub _\r\n                     & \"\"\" imageMso=\"\"ChooseForm\"\" label=\"\"\" & strCurrentSub & \"\"\" onAction=\"\"OnAction\"\"\" _\r\n                     & \" tag=\"\"Form_\" & strVBComponent & \"|\" & strCurrentSub & \"\"\"\/&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\n         strPreviousSub = strCurrentSub\r\n     <span style=\"color:blue;\">Next<\/span> l\r\n     Return strEventsForm\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Diese Funktion liefert den XML-Code zur Anzeige der Ereignisprozeduren eines Formulars zur&uuml;ck.<\/span><\/b><\/p>\n<p>In dieser Schleife lesen wir den Namen der Prozedur ein, die sich in dieser Zeile befindet. Dazu verwenden wir die <b>ProcOfLine<\/b>-Funktion, welche die zu untersuchende Zeile entgegennimmt und mit dem zweiten Parameter <b>lngProc-Kind <\/b>den Typ der Prozedur zur&uuml;ckliefert. Die gefundene Prozedur speichern wir in der Variablen <b>strCurrentSub<\/b>.<\/p>\n<p>In der folgenden <b>If&#8230;Then<\/b>-Schleife vergleichen wir den Namen der Prozedur aus <b>strCurrentSub <\/b>mit dem Wert einer weiteren Variablen namens <b>strPreviousSub<\/b>. Diese ist beim ersten Durchlauf noch leer, daher ist die Bedingung wahr. In den folgenden Durchl&auml;ufen wird jeweils <b>strCurrentSub <\/b>in <b>strPreviousSub <\/b>geschrieben und die n&auml;chste Zeile eingelesen &#8211; bis <b>strCurrentSub <\/b>den Namen der folgenden Prozedur erh&auml;lt. Erst dann wird der Inhalt der <b>If&#8230;Then<\/b>-Bedingung erneut ausgef&uuml;hrt.<\/p>\n<p>Innerhalb der <b>If&#8230;Then<\/b>-Bedingung geschieht Folgendes: Die Prozedur pr&uuml;ft, ob der Name der Prozedur mit <b>Form_ <\/b>beginnt. Ist das der Fall, handelt es sich um eine Ereignisprozedur des Formulars. Dann h&auml;ngen wir an die Variable <b>strEventsForm <\/b>ein Element wie das weiter oben bereits vorgestellte an.<\/p>\n<p>Dabei werden die einzelnen Bestandteile aus den Variablen <b>strVBComponent <\/b>und <b>strCurrentSub <\/b>ermittelt. Nachdem auf diese Weise alle Prozeduren des Moduls durchlaufen wurden, gibt die Funktion das Ergebnis aus <b>strEventsControl <\/b>mit der <b>Return<\/b>-Anweisung zur&uuml;ck.<\/p>\n<h2>Ereignisprozeduren f&uuml;r Steuerelemente einlesen<\/h2>\n<p>Die Definition eines durch die Funktion <b>GetEventsControl <\/b>zusammengesetzten <b>button<\/b>-Elements f&uuml;r das <b>dynamicMenu <\/b>sieht beispielsweise wie folgt aus:<\/p>\n<pre>&lt;button id=\"frmArtikel_cmdPDFUndBeispieleUploaden_Click\" \r\n   imageMso=\"ActiveXButton\" \r\n   label=\"cmdPDFUndBeispieleUploaden_Click\" \r\n   onAction=\"OnAction\" \r\n   tag=\"Form_frmArtikel|cmdPDFUndBeispieleUploaden_Click\"\/&gt;<\/pre>\n<p>Das <b>button<\/b>-Element enth&auml;lt f&uuml;r das Attribut <b>id <\/b>den Namen des Formulars und den Namen der Ereignisprozedur, getrennt durch einen Unterstrich. Als Label verwenden wir den Namen der Ereignisprozedur.<\/p>\n<p>F&uuml;r das <b>tag<\/b>-Attribut legen wir den Namen des Klassenmoduls und den Namen der Ereignisprozedur fest, wiederum getrennt durch das Pipe-Zeichen.<\/p>\n<p>Die Funktion zum Zusammenstellen des <b>button<\/b>-Elements finden Sie in Listing 5. Sie arbeitet fast genauso wie die Funktion <b>Get-EventsForm<\/b>, allerdings sucht sie nach Ereignisprozeduren, die mit dem Namen des Steuerelements beginnen.<\/p>\n<pre><span style=\"color:blue;\">Function <\/span>GetEventsControl(strVBComponent<span style=\"color:blue;\"> As String<\/span>, objCodeModule<span style=\"color:blue;\"> As <\/span>CodeModule, ctl<span style=\"color:blue;\"> As <\/span>Control)<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strEventsControl<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strCurrentSub<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strPreviousSub<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngProcKind<span style=\"color:blue;\"> As <\/span>vbext_ProcKind\r\n     <span style=\"color:blue;\">Dim <\/span>strControlImage<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>l<span style=\"color:blue;\"> As Long<\/span>\r\n     For l = objCodeModule.CountOfDeclarationLines + 1 To objCodeModule.CountOfLines\r\n         strCurrentSub = objCodeModule.ProcOfLine(l, lngProcKind)\r\n         strControlImage = GetControlImage(ctl)\r\n         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> strCurrentSub = strPreviousSub<span style=\"color:blue;\"> Then<\/span>\r\n             <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Left<\/span>(strCurrentSub, <span style=\"color:blue;\">Len<\/span>(ctl.Name) + 1) = ctl.Name & \"_\"<span style=\"color:blue;\"> Then<\/span>\r\n                 strEventsControl = strEventsControl & \"&lt;button id=\"\"\" & strVBComponent & \"_\" & strCurrentSub _\r\n                     & \"\"\" imageMso=\"\"\" & strControlImage & \"\"\" label=\"\"\" & strCurrentSub _\r\n                     & \"\"\" onAction=\"\"OnAction\"\" tag=\"\"Form_\" & strVBComponent & \"|\" & strCurrentSub & \"\"\"\/&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\n         strPreviousSub = strCurrentSub\r\n     <span style=\"color:blue;\">Next<\/span> l\r\n     Return strEventsControl\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Diese Funktion liefert den XML-Code zur Anzeige der Ereignisprozeduren eines Steuerelements zur&uuml;ck.<\/span><\/b><\/p>\n<p>Der einzige Unterschied ist, dass sie eine Variable namens <b>strControlImage <\/b>verwendet, die sie mit der Funktion <b>GetControlImage <\/b>f&uuml;llt. Diese erh&auml;lt mit <b>ctl <\/b>einen Verweis auf das Steuerelement als Parameter und liefert den Namen des anzuzeigenden Icons als Ergebnis zur&uuml;ck.<\/p>\n<p>Den Inhalt dieser Variablen arbeitet die Funktion <b>Get-EventsControl <\/b>dann schlie&szlig;lich als Wert des Attributs <b>imageMso <\/b>ein.<\/p>\n<p>Die Funktion <b>GetEventsControl <\/b>finden Sie in Listing 6. Sie  pr&uuml;ft in einer <b>Select Case<\/b>-Bedingung mit <b>ctl.ControlType <\/b>den Typ des Steuerelements. Wir haben hier die Eintr&auml;ge f&uuml;r die g&auml;ngigsten Steuerelementtypen angegeben, alle anderen werden im Zweig <b>Case Else <\/b>abgehandelt. Das Ergebnis gibt wieder die <b>Return<\/b>-Anweisung zur&uuml;ck.<\/p>\n<pre><span style=\"color:blue;\">Function <\/span>GetControlImage(ctl<span style=\"color:blue;\"> As <\/span>Control)<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strControlImage<span style=\"color:blue;\"> As String<\/span>\r\n     Select Case ctl.ControlType\r\n         <span style=\"color:blue;\">Case <\/span>acTextBox\r\n             strControlImage = \"FormControlEditBox\"\r\n         <span style=\"color:blue;\">Case <\/span>acComboBox\r\n             strControlImage = \"ActiveXComboBox\"\r\n         <span style=\"color:blue;\">Case <\/span>acCommandButton\r\n             strControlImage = \"ActiveXButton\"\r\n         <span style=\"color:blue;\">Case <\/span>acListBox    \r\n             strControlImage = \"ActiveXListBox\"\r\n         <span style=\"color:blue;\">Case <\/span>acCheckBox    \r\n             strControlImage = \"ActiveXCheckBox\"\r\n         <span style=\"color:blue;\">Case <\/span>acOptionButton\r\n             strControlImage = \"ActiveXRadioButton\"\r\n         <span style=\"color:blue;\">Case <\/span>acOptionGroup\r\n             strControlImage = \"ActiveXFrame\"\r\n         <span style=\"color:blue;\">Case <\/span>acToggleButton\r\n             strControlImage = \"ActiveXToggleButton\"\r\n         <span style=\"color:blue;\">Case <\/span>acTabCtl\r\n             strControlImage = \"ControlTabControl\"\r\n         <span style=\"color:blue;\">Case <\/span>acPage\r\n             strControlImage = \"ControlPage\"\r\n         <span style=\"color:blue;\">Case Else<\/span>\r\n             strControlImage = \"ControlToolboxOutlook\"\r\n     <span style=\"color:blue;\">End Select<\/span>\r\n     Return strControlImage\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 6: Ermitteln des Steuerelementtyps und davon abh&auml;ngig Auswahl eines Icons<\/span><\/b><\/p>\n<h2>Anklicken eines der Eintr&auml;ge des dynamicMenu-Men&uuml;s<\/h2>\n<p>Damit kommen wir zum Finale: Was geschieht, wenn der Benutzer das Men&uuml; aufgeklappt hat und auf einen der Eintr&auml;ge klickt Das haben wir bereits weiter oben erl&auml;utert: Es soll die Ereignisprozedur angezeigt und markiert werden, die durch das Ereignis des entsprechenden Steuerelements ausgel&ouml;st wird. Im Detail stecken einige Zeilen Code dahinter.<\/p>\n<h2>Ereignis beim Klick auf einen Men&uuml;eintrag<\/h2>\n<p>Wie bei der Definition des Ribbons &uuml;blich, geben Sie f&uuml;r <b>button<\/b>-Elemente mit dem <b>action<\/b>-Attribut an, welche Prozedur beim Anklicken ausgel&ouml;st werden soll. In diesem Fall hei&szlig;t die Prozedur <b>OnClick <\/b>und wir definieren Sie in der twinBASIC-Klasse wie in Listing 7.<\/p>\n<pre>     <span style=\"color:blue;\">Public <\/span>Sub OnAction(Control<span style=\"color:blue;\"> As <\/span>IRibbonControl)\r\n         <span style=\"color:blue;\">Dim <\/span>objVBE<span style=\"color:blue;\"> As <\/span>VBE\r\n         <span style=\"color:blue;\">Dim <\/span>objVBProject<span style=\"color:blue;\"> As <\/span>VBProject\r\n         <span style=\"color:blue;\">Dim <\/span>objVBComponent<span style=\"color:blue;\"> As <\/span>VBComponent\r\n         <span style=\"color:blue;\">Dim <\/span>objCodeModule<span style=\"color:blue;\"> As <\/span>CodeModule\r\n         <span style=\"color:blue;\">Dim <\/span>objCodePane<span style=\"color:blue;\"> As <\/span>CodePane\r\n         <span style=\"color:blue;\">Dim <\/span>strVBComponent<span style=\"color:blue;\"> As String<\/span>\r\n         <span style=\"color:blue;\">Dim <\/span>lngStartLine<span style=\"color:blue;\"> As Long<\/span>\r\n         <span style=\"color:blue;\">Dim <\/span>lngEndLine<span style=\"color:blue;\"> As Long<\/span>\r\n         <span style=\"color:blue;\">Dim <\/span>lngProcKind<span style=\"color:blue;\"> As <\/span>vbext_ProcKind\r\n         <span style=\"color:blue;\">Dim <\/span>strSub<span style=\"color:blue;\"> As String<\/span>\r\n         <span style=\"color:blue;\">Set<\/span> objVBE = objApplication.VBE\r\n         strVBComponent = <span style=\"color:blue;\">Split<\/span>(Control.Tag, \"|\")(0)\r\n         strSub = <span style=\"color:blue;\">Split<\/span>(Control.Tag, \"|\")(1)\r\n         objApplication.RunCommand acCmdVisualBasicEditor \r\n         <span style=\"color:blue;\">Set<\/span> objVBProject = GetCurrentVBProject\r\n         <span style=\"color:blue;\">Set<\/span> objVBComponent = objVBProject.VBComponents(strVBComponent)\r\n         <span style=\"color:blue;\">Set<\/span> objCodeModule = objVBComponent.CodeModule\r\n         objCodeModule.CodePane.Show\r\n         lngStartLine = objCodeModule.ProcBodyLine(strSub, lngProcKind)\r\n         lngEndLine = objCodeModule.ProcCountLines(strSub, lngProcKind)\r\n         <span style=\"color:blue;\">Set<\/span> objCodePane = objCodeModule.CodePane\r\n         objCodePane.SetSelection lngStartLine, 1, lngStartLine + lngEndLine - 1, 255\r\n         objCodePane.TopLine = lngStartLine\r\n     End Sub<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 7: Callback-Prozedur, die beim Anklicken eines der Men&uuml;eintr&auml;ge ausgel&ouml;st wird<\/span><\/b><\/p>\n<p>Diese nimmt mit dem Parameter <b>Control <\/b>einen Verweis auf das angeklickte Steuerelement entgegen, dessen Eigenschaften wir gleich ben&ouml;tigen.<\/p>\n<p>Zuvor erstellt die Prozedur in <b>objVBE <\/b>eine Referenz auf den VBA-Editor. Dann lesen wir die Attribute des mit dem Parameter <b>Control <\/b>&uuml;bergebenen <b>IRibbonControl <\/b>ein. Das Attribut tag liefert dabei einen Wert wie <b>Form_frmArtikel|cmdPDFUndBeispieleUploaden_Click<\/b>, enth&auml;lt also die Namen von Klassenmodul und Ereignisprozedur, getrennt durch das Pipe-Zeichen.<\/p>\n<p>Wir teilen den Inhalt von <b>Control.Tag <\/b>mit der <b>Split<\/b>-Funktion an dem Pipe-Zeichen in ein Array auf und lesen mit dem Index <b>0 <\/b>den Teil vor dem Pipe-Zeichen und mit dem Index <b>1 <\/b>den Teil nach dem Pipe-Zeichen aus. Das Ergebnis landet in den Variablen <b>strVBComponent <\/b>und <b>strSub<\/b>.<\/p>\n<p>Danach &ouml;ffnen wir den VBA-Editor. Das haben wir &uuml;brigens zun&auml;chst mit <b>DoCmd.OpenModule <\/b>unter Angabe des zu &ouml;ffnenden Moduls versucht, was aber zur Laufzeit in vielen F&auml;llen einen Fehler lieferte. Also sind wir zu <b>RunCommand.acCmdVisualBasicEditor <\/b>&uuml;bergegangen.<\/p>\n<p>Mit <b>GetCurrentVBProject <\/b>ermitteln wir wieder das VB-Projekt der aktuell ge&ouml;ffneten Access-Datenbank. Mit dessen Auflistung <b>VBComponents<\/b> referenzieren wir dann das Klassenmodul aus <b>strVBComponent<\/b>. Dessen Eigenschaft <b>CodeModule <\/b>liefert das Modul, das wir mit <b>objCodeModule <\/b>referenzieren.<\/p>\n<p>Die Anzeige des Moduls realisieren wir mit der Methode <b>Show <\/b>des <b>CodePane<\/b>-Elements von <b>objCodeModule<\/b>. Nun wollen wir die erste und die letzte Zeile der gesuchten Prozedur ermitteln. Die erste Zeile erhalten wir mit der Eigenschaft <b>ProcBodyLine <\/b>f&uuml;r die Prozedur aus <b>strSub<\/b>. Den zweiten Parameter <b>lngProcKind<\/b>, der den Prozedurtyp zur&uuml;ckliefert, m&uuml;ssen wir der Vollst&auml;ndigkeit halber mit einer Variablen f&uuml;llen. Wir ben&ouml;tigen den damit zur&uuml;ckgegebenen Wert jedoch nicht.<\/p>\n<p>Die letzte Zeile der Prozedur lesen wir mit der Eigenschaft <b>ProcCountLines <\/b>mit den gleichen Parametern ein und schreiben diese in <b>lngEndLine<\/b>.<\/p>\n<p>Dann referenzieren wir das Codefenster &uuml;ber die Variable <b>objCodePane <\/b>mit der Eigenschaft <b>CodePane <\/b>des <b>CodeModule<\/b>-Objekts. Dieses bietet wiederum die Methode <b>SetSelection<\/b>, mit der wir den gew&uuml;nschten Bereich markieren k&ouml;nnen.<\/p>\n<p>In diesem Fall verwenden wir als ersten Parameter zur Angabe der ersten zu markierenden Zeile die Variable <b>lngStartLine<\/b>, f&uuml;r den zweiten zur Angabe der Startspalte der Markierung den Wert <b>1<\/b>, f&uuml;r den dritten den Wert <b>lngStartLine + lngEndLine &#8211; 1 <\/b>und f&uuml;r den vierten den Wert <b>255<\/b>, damit die letzte Zeile vollst&auml;ndig markiert wird.<\/p>\n<p>Dabei gehen wir davon aus, dass diese Zeile nicht l&auml;nger als 255 Zeichen ist. Das sollte bei Zeilen wie <b>End Sub <\/b>nicht passieren.<\/p>\n<p>Schlie&szlig;lich sorgen wir durch Einstellen der Eigenschaft <b>TopLine <\/b>noch daf&uuml;r, dass die erste Zeile der Prozedur als erste Zeile im Codefenster angezeigt wird.<\/p>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Mit dieser L&ouml;sung haben wir die M&ouml;glichkeiten von twinBASIC-COM-Add-Ins f&uuml;r die Benutzeroberfl&auml;che von Access demonstriert. Wir freuen uns &uuml;ber Feedback zu dieser L&ouml;sung unter der E-Mail-Adresse <b>info@access-im-unternehmen.de<\/b>!<\/p>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>myCOMAddin.code-workspace<\/p>\n<p>myCOMAddin.twinproj<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/5B074DF7-AA85-417F-8D66-D2E8F1D24AFA\/aiu_1317.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Bei unserer Arbeit mit Access passiert es immer wieder, dass wir schnell pr&uuml;fen wollen, was eine durch ein bestimmtes Ereignis ausgel&ouml;ste Prozedur &uuml;berhaupt erledigt. Dann muss man in den Entwurf wechseln, einen Haltepunkt setzen, wieder den Formularentwurf aktivieren und dann das Ereignis ausl&ouml;sen. Wir w&auml;re es mit einem Add-In, mit dem Sie die Ereignisse des aktuell markierten Steuerelements direkt anzeigen k&ouml;nnten Ein solches COM-Add-In wollen wir in diesem Beitrag entwickeln und vorstellen. Das ist ein perfekter Anwendungszweck f&uuml;r die neue Entwicklungsumgebung twinBASIC, die wir in Ausgabe 3\/2021 im Detail vorgestellt haben.<\/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":[662021,66042021,44000027],"tags":[],"class_list":["post-55001317","post","type-post","status-publish","format-standard","hentry","category-662021","category-66042021","category-Loesungen"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>COM-Add-In: Ereignisprozedur zur Laufzeit anzeigen - 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\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"COM-Add-In: Ereignisprozedur zur Laufzeit anzeigen\" \/>\n<meta property=\"og:description\" content=\"Bei unserer Arbeit mit Access passiert es immer wieder, dass wir schnell pr&uuml;fen wollen, was eine durch ein bestimmtes Ereignis ausgel&ouml;ste Prozedur &uuml;berhaupt erledigt. Dann muss man in den Entwurf wechseln, einen Haltepunkt setzen, wieder den Formularentwurf aktivieren und dann das Ereignis ausl&ouml;sen. Wir w&auml;re es mit einem Add-In, mit dem Sie die Ereignisse des aktuell markierten Steuerelements direkt anzeigen k&ouml;nnten Ein solches COM-Add-In wollen wir in diesem Beitrag entwickeln und vorstellen. Das ist ein perfekter Anwendungszweck f&uuml;r die neue Entwicklungsumgebung twinBASIC, die wir in Ausgabe 3\/2021 im Detail vorgestellt haben.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2021-07-31T10:13:48+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg07.met.vgwort.de\/na\/c8fc246312d94317852db2b8abb3c59a\" \/>\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=\"22\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"COM-Add-In: Ereignisprozedur zur Laufzeit anzeigen\",\"datePublished\":\"2021-07-31T10:13:48+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\\\/\"},\"wordCount\":3541,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/c8fc246312d94317852db2b8abb3c59a\",\"articleSection\":[\"2021\",\"4\\\/2021\",\"L\u00f6sungen\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\\\/\",\"name\":\"COM-Add-In: Ereignisprozedur zur Laufzeit anzeigen - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/c8fc246312d94317852db2b8abb3c59a\",\"datePublished\":\"2021-07-31T10:13:48+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/c8fc246312d94317852db2b8abb3c59a\",\"contentUrl\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/c8fc246312d94317852db2b8abb3c59a\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"COM-Add-In: Ereignisprozedur zur Laufzeit anzeigen\"}]},{\"@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":"COM-Add-In: Ereignisprozedur zur Laufzeit anzeigen - 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\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/","og_locale":"de_DE","og_type":"article","og_title":"COM-Add-In: Ereignisprozedur zur Laufzeit anzeigen","og_description":"Bei unserer Arbeit mit Access passiert es immer wieder, dass wir schnell pr&uuml;fen wollen, was eine durch ein bestimmtes Ereignis ausgel&ouml;ste Prozedur &uuml;berhaupt erledigt. Dann muss man in den Entwurf wechseln, einen Haltepunkt setzen, wieder den Formularentwurf aktivieren und dann das Ereignis ausl&ouml;sen. Wir w&auml;re es mit einem Add-In, mit dem Sie die Ereignisse des aktuell markierten Steuerelements direkt anzeigen k&ouml;nnten Ein solches COM-Add-In wollen wir in diesem Beitrag entwickeln und vorstellen. Das ist ein perfekter Anwendungszweck f&uuml;r die neue Entwicklungsumgebung twinBASIC, die wir in Ausgabe 3\/2021 im Detail vorgestellt haben.","og_url":"https:\/\/access-im-unternehmen.de\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/","og_site_name":"Access im Unternehmen","article_published_time":"2021-07-31T10:13:48+00:00","og_image":[{"url":"http:\/\/vg07.met.vgwort.de\/na\/c8fc246312d94317852db2b8abb3c59a","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"22\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"COM-Add-In: Ereignisprozedur zur Laufzeit anzeigen","datePublished":"2021-07-31T10:13:48+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/"},"wordCount":3541,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/#primaryimage"},"thumbnailUrl":"http:\/\/vg07.met.vgwort.de\/na\/c8fc246312d94317852db2b8abb3c59a","articleSection":["2021","4\/2021","L\u00f6sungen"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/","url":"https:\/\/access-im-unternehmen.de\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/","name":"COM-Add-In: Ereignisprozedur zur Laufzeit anzeigen - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/#primaryimage"},"thumbnailUrl":"http:\/\/vg07.met.vgwort.de\/na\/c8fc246312d94317852db2b8abb3c59a","datePublished":"2021-07-31T10:13:48+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/#primaryimage","url":"http:\/\/vg07.met.vgwort.de\/na\/c8fc246312d94317852db2b8abb3c59a","contentUrl":"http:\/\/vg07.met.vgwort.de\/na\/c8fc246312d94317852db2b8abb3c59a"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/COMAddIn_Ereignisprozedur_zur_Laufzeit_anzeigen\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"COM-Add-In: Ereignisprozedur zur Laufzeit anzeigen"}]},{"@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\/55001317","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=55001317"}],"version-history":[{"count":1,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001317\/revisions"}],"predecessor-version":[{"id":88072581,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001317\/revisions\/88072581"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001317"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001317"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001317"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}