{"id":55000436,"date":"2024-08-01T00:00:00","date_gmt":"2024-08-14T14:50:26","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=436"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"MenueSteuerelemente_per_VBA_programmieren","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/MenueSteuerelemente_per_VBA_programmieren\/","title":{"rendered":"Men&uuml;-Steuerelemente per VBA programmieren"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg08.met.vgwort.de\/na\/095d406f8a594dc6a600a910353cb6b4\" width=\"1\" height=\"1\" alt=\"\"><b>Im Artikel &#8220;Men&uuml;s per VBA programmieren&#8221; (www.vbentwickler.de\/435) haben wir uns bereits angesehen, wie wir die Men&uuml;struktur selbst im VBA-Editor per VBA programmieren k&ouml;nnen. Damit wissen wir nun, wie wir Hauptmen&uuml;leisten, Symbolleisten und Kontextmen&uuml;s erstellen und anzeigen k&ouml;nnen. Es fehlt allerdings noch das Salz in der Suppe, n&auml;mlich die Steuerelemente auf diesen Men&uuml;s. Welche es gibt und wie man diese hinzuf&uuml;gt und mit Aktionen versieht, schauen wir uns in diesem Artikel an.<\/b><\/p>\n<p>Wer den VBA-Editor mit eigenen Funktionen erweitern will und das beispielsweise mit COM-Add-Ins auf Basis von twinBASIC realisiert, m&ouml;chte die hinzugef&uuml;gten Funktionen auch auf irgendeine Weise f&uuml;r den Benutzer zug&auml;nglich machen. Dazu bietet sich das Men&uuml;system an. Damit k&ouml;nnen wir in der Men&uuml;leiste, den Symbolleisten und in Kontextmen&uuml;s Befehle zum Aufrufen der benutzerdefinierten Funktionen hinzuf&uuml;gen. Allerdings brauchen wir hier nicht nur die entsprechenden Elemente, sondern wir m&uuml;ssen auch noch Steuerelemente hinzuf&uuml;gen. Dies werden meist einfache Schaltfl&auml;chen sein. Wir schauen uns allerdings in diesem Artikel alle der wenigen verf&uuml;gbaren Steuerelemente f&uuml;r die Men&uuml;s des VBA-Editors an.<\/p>\n<h2>Steuerelemente des CommandBar-Elements<\/h2>\n<p>Dem <b>CommandBar<\/b>-Element k&ouml;nnen wir die folgenden Steuerelemente hinzuf&uuml;gen:<\/p>\n<ul>\n<li>Schaltfl&auml;che (<b>msoControlButton<\/b>)<\/li>\n<li>Auswahlfeld (<b>msoControlComboBox<\/b>)<\/li>\n<li>Untermen&uuml; (<b>msoControlPopup<\/b>)<\/li>\n<\/ul>\n<p>Um ein solches Steuerelement hinzuzuf&uuml;gen, verwenden wir die <b>Add<\/b>-Methode der <b>Controls<\/b>-Auflistung des <b>CommandBar<\/b>-Objekts. Das folgende, einfache Beispiel f&uuml;gt einfach jeweils ein Element des jeweiligen Typs zu einer neu erstellten Symbolleiste hinzu:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>AddControls()\r\n     <span style=\"color:blue;\">Dim <\/span>cbr<span style=\"color:blue;\"> As <\/span>CommandBar\r\n     <span style=\"color:blue;\">Dim <\/span>cbb<span style=\"color:blue;\"> As <\/span>CommandBarButton\r\n     <span style=\"color:blue;\">Dim <\/span>cbc<span style=\"color:blue;\"> As <\/span>CommandBarComboBox\r\n     <span style=\"color:blue;\">Dim <\/span>cbp<span style=\"color:blue;\"> As <\/span>CommandBarPopup\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     VBE.CommandBars(\"Symbolleiste mit Controls\").Delete\r\n     <span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n     <span style=\"color:blue;\">Set<\/span> cbr = VBE.CommandBars.Add( _\r\n         \"Symbolleiste mit Controls\")\r\n     <span style=\"color:blue;\">With<\/span> cbr\r\n         <span style=\"color:blue;\">Set<\/span> cbb = cbr.Controls.Add(msoControlButton)\r\n         <span style=\"color:blue;\">With<\/span> cbb\r\n             .Caption = \"Button\"\r\n             .Style = msoButtonCaption\r\n         End <span style=\"color:blue;\">With<\/span>\r\n         <span style=\"color:blue;\">Set<\/span> cbc = cbr.Controls.Add(msoControlComboBox)\r\n         <span style=\"color:blue;\">With<\/span> cbc\r\n             .Caption = \"ComboBox\"\r\n         End <span style=\"color:blue;\">With<\/span>\r\n         <span style=\"color:blue;\">Set<\/span> cbp = cbr.Controls.Add(msoControlPopup)\r\n         <span style=\"color:blue;\">With<\/span> cbp\r\n             .Caption = \"Popup\"\r\n         End <span style=\"color:blue;\">With<\/span>\r\n         .Visible = <span style=\"color:blue;\">True<\/span>\r\n     End <span style=\"color:blue;\">With<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die Prozedur l&ouml;scht zun&auml;chst eine gegebenenfalls bereits von einem vorherigen Test vorhandene Symbolleiste namens <b>Symbolleiste mit Controls <\/b>aus der <b>CommandBars<\/b>-Auflistung. F&uuml;r den Fall, dass dieses noch nicht angelegt oder zuvor auf andere Art und Weise gel&ouml;scht wurde, deaktivieren wir die eingebaute Fehlerbehandlung, damit dann kein Fehler ausgel&ouml;st wird.<\/p>\n<p>Dann legt sie ein neues <b>CommandBar<\/b>-Objekt mit diesem Namen an. Anschlie&szlig;end f&uuml;gen wir mit der <b>Add<\/b>-Methode der <b>Controls<\/b>-Auflistung zun&auml;chst eine Schaltfl&auml;che mit dem Typ <b>msoControlButton <\/b>an und stellen daf&uuml;r die Beschriftung ein. Damit diese auch erscheint, legen wir die Eigenschaft <b>Style <\/b>auf den Wert <b>msoButtonCaption <\/b>fest.<\/p>\n<p>Danach legt die Prozedur ein Auswahlfeld an und verwendet dazu den Typ <b>msoControlComboBox <\/b>als ersten Parameter der <b>Add<\/b>-Methode. Diesem f&uuml;gen wir auch gleich ein erstes Element hinzu.<\/p>\n<p>Schlie&szlig;lich folgt noch ein Untermen&uuml; mit dem Typ <b>msoControlPopup<\/b>. F&uuml;r dieses brauchen wir den Style nicht auf <b>msoButtonCaption <\/b>festzulegen, die Beschriftung wird automatisch angezeigt.<\/p>\n<p>Das Ergebnis sehen wir in Bild 1.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2024_04\/pic_436_007.png\" alt=\"Beispiel f&uuml;r Steuerelemente im CommandBar\" width=\"349,6267\" height=\"175,4422\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Beispiel f&uuml;r Steuerelemente im CommandBar<\/span><\/b><\/p>\n<h2>Schaltfl&auml;chen im CommandBar-Element<\/h2>\n<p>Nachdem wir eine Schaltfl&auml;che zu einem <b>CommandBar<\/b>-Element hinzuf&uuml;gt haben, ist erst einmal wichtig, dass wir dem Benutzer mitteilen, wozu er diese Schaltfl&auml;che verwenden kann. Dazu k&ouml;nnen wir prim&auml;r Symbole und\/oder Texte verwenden. Den Text stellen wir immer mit der Eigenschaft <b>Caption <\/b>ein. Damit die Beschriftung &uuml;berhaupt sichtbar ist, m&uuml;ssen wir die <b>Style<\/b>-Eigenschaft auf den entsprechenden Wert einstellen. Dazu haben wir die folgenden M&ouml;glichkeiten:<\/p>\n<ul>\n<li><b>msoButtonCaption<\/b>: Zeigt nur die Beschriftung an.<\/li>\n<li><b>msoButtonIcon<\/b>: Zeigt nur ein Symbol an.<\/li>\n<li><b>msoButtonIconAndCaption<\/b>: Zeigt Symbol und Text an.<\/li>\n<\/ul>\n<h2>Ereignisse von Schaltfl&auml;chen programmieren<\/h2>\n<p>Wer bereits einmal Men&uuml;leisten f&uuml;r die verschiedenen Office-Anwendungen mit der Version 2003 und &auml;lter programmiert hat oder auch Kontextmen&uuml;s f&uuml;r die aktuellen Versionen, der kennt die <b>OnAction<\/b>-Eigenschaft. F&uuml;r diese Eigenschaft eines <b>CommandBarButton<\/b>-Objekts hinterlegt man den Namen einer &ouml;ffentlichen VBA-Prozedur, die durch das Anklicken des Men&uuml;punktes ausgel&ouml;st werden soll.<\/p>\n<p>Dies funktioniert bei der Programmierung von Men&uuml;s f&uuml;r den VBA-Editor so nicht mehr. Hier m&uuml;ssen wir ein Ereignis programmieren. Leider k&ouml;nnen wir Ereignisse nur innerhalb von Klassenmodulen implementieren und nicht in Standardmodulen. Wir ben&ouml;tigen also eine Klasse, die einen Verweis auf unser <b>CommandBarButton<\/b>-Objekt enth&auml;lt und in der wir die Ereignisprozedur implementieren.<\/p>\n<p>Diese Klasse hei&szlig;t <b>clsCommandBarButton <\/b>und sieht wie in Listing 1 aus. Hier definieren wir als Erstes eine Objektvariable, mit der wir das <b>CommandBarButton<\/b>-Objekt referenzieren wollen. Wir f&uuml;gen der Deklaration das Schl&uuml;sselwort <b>WithEvents <\/b>hinzu, damit wir die Ereignisse dieses Objekts innerhalb der aktuellen Klasse implementieren k&ouml;nnen.<\/p>\n<pre><span style=\"color:blue;\">Private <\/span>WithEvents m_CommandBarButton<span style=\"color:blue;\"> As <\/span>CommandBarButton\r\n<span style=\"color:blue;\">Public Property <span style=\"color:blue;\">Set<\/span> <\/span>CommandBarButton(cbb<span style=\"color:blue;\"> As <\/span>CommandBarButton)\r\n     <span style=\"color:blue;\">Set<\/span> m_CommandBarButton = cbb\r\n<span style=\"color:blue;\">End Property<\/span>\r\n<span style=\"color:blue;\">Public Property Get <\/span>CommandBarButton()<span style=\"color:blue;\"> As <\/span>CommandBarButton\r\n     <span style=\"color:blue;\">Set<\/span> CommandBarButton = m_CommandBarButton\r\n<span style=\"color:blue;\">End Property<\/span>\r\n<span style=\"color:blue;\">Private Sub <\/span>m_CommandBarButton_Click(ByVal Ctrl<span style=\"color:blue;\"> As <\/span>Office.CommandBarButton, CancelDefault<span style=\"color:blue;\"> As Boolean<\/span>)\r\n     <span style=\"color:blue;\">MsgBox<\/span> \"CommandBarButton ''\" & m_CommandBarButton.Caption & \"'' angeklickt.\"\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Klassenmodul f&uuml;r die Ereignisse von CommandBarButton-Ereignissen<\/span><\/b><\/p>\n<p>Damit wir von au&szlig;en einen Verweis auf das <b>CommandBarButton<\/b>-Objekt &uuml;bergeben k&ouml;nnen, f&uuml;r das wir das Ereignis implementieren wollen, f&uuml;gen wir eine <b>Property Set<\/b>-Methode hinzu. Diese nimmt einen Verweis auf das <b>CommandBarButton<\/b>-Element entgegen. Au&szlig;erdem f&uuml;gen wir noch eine <b>Property Get<\/b>-Prozedur hinzu, mit der wir den Verweis auf dieses Steuerelement abfragen k&ouml;nnen.<\/p>\n<p>Um schlie&szlig;lich die Ereignisprozedur zu implementieren, w&auml;hlen wir im linken Kombinationsfeld des Codefensters den Eintrag <b>m_CommandBarButton <\/b>aus und den dann im rechten Fenster erscheinenden Eintrag <b>Click<\/b> (siehe Bild 2). Dies legt die Ereignisprozedur <b>m_CommandBarButton_Click <\/b>an, der wir im Beispiel einfach eine Meldungsfenster-Funktion hinzugef&uuml;gt haben.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2024_04\/pic_436_002.png\" alt=\"Anlegen der Ereignisprozedur f&uuml;r das Click-Ereignis\" width=\"649,627\" height=\"254,9293\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Anlegen der Ereignisprozedur f&uuml;r das Click-Ereignis<\/span><\/b><\/p>\n<p>Nun m&uuml;ssen wir noch das <b>CommandBarButton<\/b>-Objekt in einem Men&uuml; anzeigen, eine neue Instanz der Klasse <b>clsCommandBarButton <\/b>erzeugen und schlie&szlig;lich das Men&uuml; mit der Schaltfl&auml;che anzeigen.<\/p>\n<p>Um zu verhindern, dass die Instanz der Klasse <b>clsCommandBarButton <\/b>nach dem Durchlaufen der Prozedur zum Erstellen der CommandBar mit dem CommandBarButton verloren geht, weil wir die mit einer Variablen innerhalb der Prozedur referenziert haben, verschieben wir diese Deklaration mit der folgende Anweisung nach au&szlig;en (siehe Modul <b>mdlCommandBarButtonMitEvent<\/b>):<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>objCommandBarButton<span style=\"color:blue;\"> As <\/span>clsCommandBarButton<\/pre>\n<p>Die Prozedur selbst findest Du in Listing 2.<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>objCommandBarButton<span style=\"color:blue;\"> As <\/span>clsCommandBarButton\r\n<span style=\"color:blue;\">Public Sub <\/span>CommandBarButtonMitEvent()\r\n     <span style=\"color:blue;\">Dim <\/span>cbr<span style=\"color:blue;\"> As <\/span>CommandBar\r\n     <span style=\"color:blue;\">Dim <\/span>cbb<span style=\"color:blue;\"> As <\/span>CommandBarButton\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     VBE.CommandBars(\"CommandBarButtonMitEvent\").Delete\r\n     <span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n     <span style=\"color:blue;\">Set<\/span> cbr = VBE.CommandBars.Add(\"CommandBarButtonMitEvent\")\r\n     <span style=\"color:blue;\">With<\/span> cbr\r\n         <span style=\"color:blue;\">Set<\/span> cbb = cbr.Controls.Add(msoControlButton)\r\n         <span style=\"color:blue;\">With<\/span> cbb\r\n             .Style = msoButtonCaption\r\n             .Caption = \"Button mit Ereignis\"\r\n         End <span style=\"color:blue;\">With<\/span>\r\n         <span style=\"color:blue;\">Set<\/span> objCommandBarButton = <span style=\"color:blue;\">New<\/span> clsCommandBarButton\r\n         <span style=\"color:blue;\">Set<\/span> objCommandBarButton.CommandBarButton = cbb\r\n     End <span style=\"color:blue;\">With<\/span>\r\n     cbr.Visible = <span style=\"color:blue;\">True<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Anlegen eines CommandBarButtons mit Ereignis<\/span><\/b><\/p>\n<p>Diese deklariert ein <b>CommandBar<\/b>&#8211; und ein <b>CommandBarButton<\/b>-Element. Dann l&ouml;scht sie eine eventuell bereits unter dem Namen <b>CommandBarButtonMitEvent <\/b>vorhandene Men&uuml;leiste und legt diese erneut an. Dann f&uuml;gt sie mit der <b>Add<\/b>-Methode der <b>Controls<\/b>-Auflistung ein neues <b>CommandBarButton<\/b>-Element hinzu und stellt den Stil und die Beschriftung des Steuerelements ein.<\/p>\n<p>Dann folgen die f&uuml;r die Ereignisprozedur wichtigen Schritte: Wir legen ein neues Objekt auf Basis der Klasse <b>clsCommandBarButton<\/b> an und weisen der Eigenschaft <b>CommandBarButton <\/b>einen Verweis auf das soeben erstellte <b>CommandBarButton<\/b>-Objekt zu. Schlie&szlig;lich blenden wir das Men&uuml; noch ein.<\/p>\n<p>Klicken wir danach auf das einzige Steuerelement, erscheint die gew&uuml;nschte Meldungsbox (siehe Bild 3).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2024_04\/pic_436_003.png\" alt=\"Men&uuml; mit CommandBarButton und Ereignis\" width=\"424,6267\" height=\"237,9276\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Men&uuml; mit CommandBarButton und Ereignis<\/span><\/b><\/p>\n<h2>Symbole in Schaltfl&auml;chen<\/h2>\n<p>W&auml;hrend wir den Text auf einfache Weise mit der Caption-Eigenschaft zuweisen k&ouml;nnen, sieht das bei Symbolen schon anders aus. Hier haben wir grunds&auml;tzlich zwei M&ouml;glichkeiten:<\/p>\n<ul>\n<li>Wir f&uuml;gen eines der bereits vorhandenen Symbole hinzu, also eines der f&uuml;r die &uuml;brigen Steuerelemente verf&uuml;gbaren oder<\/li>\n<li>wir f&uuml;gen ein Bild im Format <b>StdPicture <\/b>&uuml;ber die Eigenschaft <b>Picture <\/b>hinzu.<\/li>\n<\/ul>\n<h2>Eingebaute Symbole hinzuf&uuml;gen<\/h2>\n<p>Der Einbau eingebauter Symbole ist etwas einfacher, weil wir keinen eigenen VBA-Code ben&ouml;tigen, um erst vorhandene Dateien in <b>StdPicture<\/b>-Objekte umwandeln zu m&uuml;ssen. Allerdings macht es dann Sinn, sich gut mit den eingebauten Symbolen auszukennen. Die eingebauten Symbole haben jeweils eine eindeutige Nummer, die wir &uuml;ber die Eigenschaft <b>FaceId <\/b>ermitteln k&ouml;nnen. Was wir also brauchen, ist eine &Uuml;bersicht aller Icons mit den jeweiligen Werten f&uuml;r die Eigenschaft <b>FaceId<\/b>. Diese erhalten wir am einfachsten, indem wir eine neue Symbolleiste erstellen, der wir alle Symbole der eingebauten Schaltfl&auml;chen hinzuf&uuml;gen.<\/p>\n<p>Dies erledigen wir in der Prozedur <b>AlleEingebautenIcons<\/b> aus Listing 3.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>AlleEingebautenIconsNachID()\r\n     <span style=\"color:blue;\">Dim <\/span>cbr<span style=\"color:blue;\"> As <\/span>CommandBar\r\n     <span style=\"color:blue;\">Dim <\/span>cbb<span style=\"color:blue;\"> As <\/span>CommandBarButton\r\n     <span style=\"color:blue;\">Dim <\/span>l<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objCommandBarButton<span style=\"color:blue;\"> As <\/span>clsCommandBarButtonFaceID\r\n     <span style=\"color:blue;\">Set<\/span> colCommandBarButtons = <span style=\"color:blue;\">New<\/span> Collection\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     VBE.CommandBars(\"AlleIcons\").Delete\r\n     <span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n     <span style=\"color:blue;\">Set<\/span> cbr = VBE.CommandBars.Add(\"AlleIcons\")\r\n     <span style=\"color:blue;\">With<\/span> cbr\r\n         For l = 1 To 6000\r\n             <span style=\"color:blue;\">If <\/span>IsNull(DLookup(\"FaceID\", \"tblEmptyFaceIDs\", \"FaceID = \" & l))<span style=\"color:blue;\"> Then<\/span>\r\n                 <span style=\"color:blue;\">Set<\/span> cbb = cbr.Controls.Add(msoControlButton)\r\n                 <span style=\"color:blue;\">With<\/span> cbb\r\n                     .FaceId = l\r\n                     .TooltipText = l\r\n                     .Tag = l\r\n                 End <span style=\"color:blue;\">With<\/span>\r\n                 <span style=\"color:blue;\">Set<\/span> objCommandBarButton = <span style=\"color:blue;\">New<\/span> clsCommandBarButtonFaceID\r\n                 <span style=\"color:blue;\">Set<\/span> objCommandBarButton.CommandBarButton = cbb\r\n                 colCommandBarButtons.Add objCommandBarButton\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">Next<\/span> l\r\n     End <span style=\"color:blue;\">With<\/span>\r\n     cbr.Visible = <span style=\"color:blue;\">True<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Funktion zum Schreiben aller Icons in eine Symbolleiste<\/span><\/b><\/p>\n<p>Hier finden wir gleich ein spannendes Beispiel f&uuml;r den Fall, dass wir viele Steuerelemente in einer Men&uuml;leiste mit einem Ereignis ausstatten wollen, das beim Anklicken die gleiche Funktion ausf&uuml;hren soll &#8211; gegebenenfalls noch mit kleinen Varianten durch spezielle Eigenschaften des <b>CommandBarButton<\/b>-Elements.<\/p>\n<p>Grundlage f&uuml;r diese Prozedur ist, dass es <b>FaceId<\/b>-Werte gibt, die bis 6.000 reichen. Wir wollen all diese Werte einmal durchlaufen und in ein einziges <b>CommandBar<\/b>-Objekt schreiben. Allerdings liefern nicht alle Werte von <b>FaceId <\/b>tats&auml;chlich ein Symbol. Deshalb wollen wir diejenigen, f&uuml;r die kein Symbol hinterlegt ist, auch nicht in das Men&uuml; aufnehmen. Daher haben wir &#8211; wir probieren dies hier in einer Access-Datenbank aus &#8211; eine Tabelle angelegt, in welcher wir die <b>FaceId<\/b>-Werte speichern, die kein Symbol enthalten (wir h&auml;tten das auch andersherum machen k&ouml;nnen, haben uns aber f&uuml;r diese Variante entschieden).<\/p>\n<p>Um die Steuerelemente ohne Symbol f&uuml;r die <b>FaceId <\/b>in die Tabelle <b>tblEmptyFaceIds <\/b>zu schreiben, haben wir wiederum eine Klasse mit einer Ereignisprozedur angelegt. Diese ist grunds&auml;tzlich genauso aufgebaut wie die zuvor beschriebene Klasse <b>clsCommandBarButton<\/b>.<\/p>\n<p>Sie hei&szlig;t jedoch <b>clsCommandBarButtonFaceID <\/b>und enth&auml;lt die folgende Ereignisprozedur:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>m_CommandBarButton_Click(ByVal Ctrl<span style=\"color:blue;\"> As <\/span>_\r\n         Office.CommandBarButton, CancelDefault<span style=\"color:blue;\"> As Boolean<\/span>)\r\n     CurrentDb.Execute \"INSERT INTO \" _\r\n         & \"tblEmptyFaceIDs(FaceID) VALUES(\" _\r\n         & m_CommandBarButton.Tag & \")\", dbFailOnError\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Diese tr&auml;gt einen neuen Datensatz mit der <b>FaceId <\/b>in die Tabelle <b>tblEmptyFaceIDs <\/b>ein.<\/p>\n<p>Diese Klasse deklarieren wir nun innerhalb der Prozedur und nicht au&szlig;erhalb wie im vorherigen Beispiel. Warum das? Weil wir mehr als eine Instanz dieser Klasse anlegen &#8211; genau genommen zun&auml;chst einmal 6.000 St&uuml;ck. Und da wir keine 6.000 Variablen deklarieren wollen, deklarieren wir nur eine tempor&auml;re. Die erzeugten Objekte f&uuml;gen wir dann einer Collection hinzu, die wir wie folgt im Kopf des Standardmoduls deklarieren:<\/p>\n<pre><span style=\"color:blue;\">Public <\/span>colCommandBarButtons<span style=\"color:blue;\"> As <\/span>Collection<\/pre>\n<p>Die Collection initialisieren wir im n&auml;chsten Schritt. Dann l&ouml;schen wir das Men&uuml; namens <b>AlleIcons <\/b>vorsichtshalber, um es im n&auml;chsten Schritt gleich wieder anzulegen. Dann durchlaufen wir in einer Schleife die Werte von 1 bis 6.000 und pr&uuml;fen zun&auml;chst per <b>DLookup<\/b>, ob die <b>FaceId <\/b>nicht leer ist und bereits in der Tabelle <b>tblEmptyFaceIDs <\/b>eingetragen ist. Ist das nicht der Fall, legen wir ein neues <b>CommandBarButton<\/b>-Element an und stellen die Eigenschaft <b>FaceId <\/b>auf den aktuellen Wert der Laufvariablen <b>l <\/b>ein. Au&szlig;erdem legen wir den <b>ToolTipText <\/b>und die Eigenschaft <b>Tag <\/b>auf den Wert dieser Variablen fest.<\/p>\n<p>Schlie&szlig;lich legen wir ein neues Objekt der Klasse <b>clsCommandBarButtonFaceIdD <\/b>an und weisen seiner Eigenschaft <b>CommandBarButton <\/b>die Schaltfl&auml;che aus <b>cbb <\/b>zu. Diese Objektvariable f&uuml;gen wir dann mit der <b>Add<\/b>-Methode der Collection <b>colCommandBarButtons <\/b>zu.<\/p>\n<p>Beim ersten Start sieht die in der Breite angepasste Men&uuml;leiste noch recht l&uuml;ckenhaft aus (siehe Bild 4).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2024_04\/pic_436_004.png\" alt=\"Alle FaceId-Elemente - auch solche ohne Symbol\" width=\"700\" height=\"297,7566\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Alle FaceId-Elemente &#8211; auch solche ohne Symbol<\/span><\/b><\/p>\n<p>Wenn wir nun eine der Schaltfl&auml;chen ohne Icon anklicken, wird diese in die Tabelle <b>tblEmptyFaceIds <\/b>eingetragen und beim n&auml;chsten &Ouml;ffnen des Men&uuml;s nicht mehr ber&uuml;cksichtigt.<\/p>\n<p>Nach einigen Minuten Arbeit, die Du nicht mehr zu erledigen braucht, da ich das schon gemacht habe, wird das Men&uuml; nur noch mit <b>CommandBarButton<\/b>-Elementen gef&uuml;llt, die ein Symbol aufweisen (siehe Bild 5).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2024_04\/pic_436_001.png\" alt=\"Alle Icon-Symbole\" width=\"700\" height=\"485,9299\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Alle Icon-Symbole<\/span><\/b><\/p>\n<p>Sicher gibt es hier das eine oder andere doppelte Icon, doch insgesamt kannst Du diese &Uuml;bersicht prima nutzen, um ein f&uuml;r Deinen Anwendungszweck passendes Icon herauszusuchen.<\/p>\n<h2>Benutzerdefinierte Symbole hinzuf&uuml;gen<\/h2>\n<p>Der zweite Weg ist, benutzerdefinierte Symbole einzuf&uuml;gen. Das geht grunds&auml;tzlich, ist aber mit einigen Hindernissen versehen. Das <b>CommandBarButton<\/b>-Element bietet dazu zwei Eigenschaften an:<\/p>\n<ul>\n<li><b>Picture<\/b>: Diese Eigenschaft k&ouml;nnen wir ein Objekt des Typs <b>StdPicture <\/b>zuweisen. Wenn wir eine Bilddatei haben, m&uuml;ssen wir diese allerdings erst einmal in ein <b>StdPicture<\/b>-Element umwandeln. Dazu gibt es verschiedene Wege. Der Haken an der Sache ist, dass die Schaltfl&auml;che die Bilder, die wir hier zuweisen, ohne Transparenz anzeigt. Wir haben nun zwei M&ouml;glichkeiten: Wir finden die Hintergrundfarbe der Men&uuml;leiste heraus und wandeln unsere Bilder so um, dass diese keinen transparenten Hintergrund erhalten, sondern einen Hintergrund in dem passenden Grauton. Das kann allerdings problematisch werden, wenn wir f&uuml;r eine Office-Version programmieren, Microsoft aber dann mit der n&auml;chsten Office-Version entscheidet, Men&uuml;leisten wieder mit einer anderen Hintergrundfarbe auszustatten. Die zweite M&ouml;glichkeit ist, die folgende Eigenschaft zu nutzen.<\/li>\n<li><b>Mask<\/b>: Dieser Eigenschaft k&ouml;nnen wir ebenfalls ein <b>StdPicture<\/b>-Objekt &uuml;bergeben. Mit diesem k&ouml;nnen wir festlegen, welche Teile des Bildes f&uuml;r die Eigenschaft <b>Picture <\/b>transparent dargestellt werden. Dazu erstellen wir in diesem Bild eine Maske nur mit den Farben Schwarz und Wei&szlig;. Der transparente Teil muss dabei wei&szlig; abgebildet sein. <\/li>\n<\/ul>\n<p>Der Teil mit der Transparenz funktioniert nicht optimal &#8211; in der Regel sieht man leichte Ausfransungen in den Randbereichen. Eine bessere L&ouml;sung w&auml;re daher, in Abh&auml;ngigkeit von der Menge der ben&ouml;tigten Icons, die Idee, die Icons direkt mit einem grauen Hintergrund in der entsprechenden Farbe zu versehen. Insgesamt schauen wir das Hinzuf&uuml;gen benutzerdefinierter Icons in einem weiteren Artikel namens <b>Icons f&uuml;r Kontextmen&uuml;befehle <\/b>(<b>www.vbentwickler.de\/371<\/b>) an.<\/p>\n<h2>Optische Unterteilung: BeginGroup<\/h2>\n<p>Manche CommandBars enthalten recht viele Elemente, sodass eine Gruppierung nach bestimmten Elementen sinnvoll ist. Dazu k&ouml;nnen wir einen Trennstrich nutzen, den wir auf einfache Weise einf&uuml;gen k&ouml;nnen. Dazu brauchen wir lediglich die Eigenschaft <b>BeginGroup <\/b>f&uuml;r das erste Element der Gruppe auf <b>True <\/b>einzustellen.<\/p>\n<h2>Vorhandene Schaltfl&auml;chen in eigenen Men&uuml;s wiederverwenden<\/h2>\n<p>Wir k&ouml;nnen in unseren eigenen Men&uuml;leisten auch eingebaute Befehle hinzuf&uuml;gen. Genau genommen ist das gar keine so schlechte Idee. Vielleicht ben&ouml;tigst Du nur wenige Befehle der eingebauten Men&uuml;- und Symbolleisten und m&ouml;chtest Dir eine einzige anlegen, die alle f&uuml;r Deinen t&auml;glichen Programmieralltag wichtigen Elemente enth&auml;lt und nur noch diese nutzen.<\/p>\n<p>Ein eingebautes Element kannst Du mit der folgenden Anweisung zu einem <b>CommandBar<\/b>-Element hinzuf&uuml;gen &#8211; hier f&uuml;r ein Kontextmen&uuml;:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>CreateCommandBar_Kontextmenue()\r\n     <span style=\"color:blue;\">Dim <\/span>cbr<span style=\"color:blue;\"> As <\/span>CommandBar\r\n     <span style=\"color:blue;\">Set<\/span> cbr = VBE.CommandBars.Add(, msoBarPopup)\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     VBE.CommandBars(\"Kontextmenueleiste\").Delete\r\n     <span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n     <span style=\"color:blue;\">With<\/span> cbr\r\n         .Name = \"Kontextmenueleiste\"\r\n         .Controls.Add , 19\r\n         .ShowPopup\r\n     End <span style=\"color:blue;\">With<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Damit zeigen wir ein Kontextmen&uuml; mit einem eingebauten Element wie in Bild 6 an.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2024_04\/pic_436_005.png\" alt=\"Anzeigen eines eingebauten Elements im Kontextmen&uuml;\" width=\"424,6267\" height=\"196,456\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Anzeigen eines eingebauten Elements im Kontextmen&uuml;<\/span><\/b><\/p>\n<p>Um gezielt eingebaute Elemente in ein benutzerdefiniertes Men&uuml; einzubauen, ben&ouml;tigen wir also die ID des jeweiligen Elements. Dazu erstellen wir uns eine kleine Hilfstabelle (siehe Bild 7).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2024_04\/pic_436_006.png\" alt=\"Tabelle zum Speichern von Controls und ihren IDs\" width=\"424,6267\" height=\"161,5546\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 7: Tabelle zum Speichern von Controls und ihren IDs<\/span><\/b><\/p>\n<p>Diese Tabelle f&uuml;llen wir mit drei Prozeduren, von denen wir zun&auml;chst die erste aus Listing 4 aufrufen. Diese durchl&auml;uft zun&auml;chst alle Elemente der <b>CommandBars<\/b>-Auflistung f&uuml;r den VBA-Editor und referenziert das jeweils aktuelle Element mit der Variablen <b>cbr<\/b>.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>EingebauteBefehle()\r\n     <span style=\"color:blue;\">Dim <\/span>cbr<span style=\"color:blue;\"> As <\/span>CommandBar\r\n     <span style=\"color:blue;\">Dim <\/span>ctl<span style=\"color:blue;\"> As Object<\/span>\r\n     For Each cbr In VBE.CommandBars\r\n         <span style=\"color:blue;\">If <\/span>cbr.BuiltIn<span style=\"color:blue;\"> Then<\/span>\r\n             For Each ctl In cbr.Controls\r\n                 <span style=\"color:blue;\">If <\/span>ctl.BuiltIn<span style=\"color:blue;\"> Then<\/span>\r\n                     Select Case TypeName(ctl)\r\n                         <span style=\"color:blue;\">Case <\/span>\"CommandBarButton\", \"CommandBarComboBox\", \"CommandBarControl\"\r\n                             <span style=\"color:blue;\">Call<\/span> WriteControl(ctl)\r\n                         <span style=\"color:blue;\">Case <\/span>\"CommandBarPopup\"\r\n                             <span style=\"color:blue;\">Call<\/span> EingebauteBefehle_Rek(ctl)\r\n                     <span style=\"color:blue;\">End Select<\/span>\r\n                 <span style=\"color:blue;\">End If<\/span>\r\n             <span style=\"color:blue;\">Next<\/span> ctl\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> cbr\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Durchlaufen aller Elemente der obersten Ebene der CommandBar-Elemente<\/span><\/b><\/p>\n<p>Dann pr&uuml;ft sie mit der Eigenschaft <b>BuiltIn<\/b>, ob das jeweilige Element ein eingebautes Element ist.<\/p>\n<p>Nur diese Elemente interessieren uns. Also durchlaufen wir f&uuml;r diese alle Steuerelemente im <b>CommandBar <\/b>in einer weiteren <b>For Each<\/b>-Schleife und referenzieren das jeweilige Steuerelement mit der Variablen <b>ctl<\/b>.<\/p>\n<p>Hier pr&uuml;fen wir in einer <b>Select Case<\/b>-Bedingung mit der <b>TypeName<\/b>-Funktion f&uuml;r das <b>ctl<\/b>-Element, ob es sich bei dem Steuerelement um eines der Typen <b>CommandBarButton<\/b>, <b>CommandBarComboBox <\/b>oder <b>CommandBarControl <\/b>handelt. Falls ja, rufen wir die Prozedur <b>WriteControl <\/b>auf, die einen Verweis auf das Steuerelement entgegennimmt (siehe Listing 5).<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>WriteControl(ctl<span style=\"color:blue;\"> As Object<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>lngID<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strCaption<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strType<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strSQL<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     lngID = ctl.Id\r\n     strCaption = ctl.Caption\r\n     strType = TypeName(ctl)\r\n     strSQL = \"INSERT INTO tblControls(ControlID, ControlCaption, ControlType) VALUES(\" & ctl.Id & \", ''\" _\r\n         & <span style=\"color:blue;\">Replace<\/span>(ctl.Caption, \"&\", \"\") & \"'', ''\" & strType & \"'')\"\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     db.Execute strSQL, dbFailOnError\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Schreiben der Control-Eigenschaften in die Tabelle tblControls<\/span><\/b><\/p>\n<p>Diese liest die ID, die Beschriftung und den Typ in die Variablen <b>lngID<\/b>, <b>strCaption <\/b>und <b>strType <\/b>ein. Dann stellt sie eine SQL-Anweisung zusammen, welche die Informationen zu dem Steuerelement in die Tabelle <b>tblControls <\/b>schreibt.<\/p>\n<p>Sollte es sich nicht um einen der genannten Steuerelementtyp handeln, bleibt noch der Typ <b>CommandBarPopup <\/b>&uuml;brig, den wir im n&auml;chsten <b>Case<\/b>-Zweig behandeln. Da ein Untermen&uuml; auch wieder Untermen&uuml;s enthalten kann und so weiter, wollen wir dazu eine rekursiv definierte Funktion nutzen. Diese finden wir in Listing 6.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>EingebauteBefehle_Rek(ctlPopup<span style=\"color:blue;\"> As Object<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>ctl<span style=\"color:blue;\"> As Object<\/span>\r\n     For Each ctl In ctlPopup.Controls\r\n         <span style=\"color:blue;\">If <\/span>ctl.BuiltIn = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n             Select Case TypeName(ctl)\r\n                 <span style=\"color:blue;\">Case <\/span>\"CommandBarButton\", \"CommandBarComboBox\", \"CommandBarControl\"\r\n                     <span style=\"color:blue;\">Call<\/span> WriteControl(ctl)\r\n                 <span style=\"color:blue;\">Case <\/span>\"CommandBarPopup\"\r\n                     <span style=\"color:blue;\">Call<\/span> EingebauteBefehle_Rek(ctl)\r\n             <span style=\"color:blue;\">End Select<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> ctl\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 6: Rekursive Funktion zum Ermitteln von Steuerelementen in Untermen&uuml;s<\/span><\/b><\/p>\n<p>Die Funktion nimmt das Untermen&uuml; mit der Variablen <b>ctlPopup <\/b>entgegen und durchl&auml;uft in einer <b>For Each<\/b>-Schleife alle in diesem Untermen&uuml; enthaltenen Steuerelemente, die sie dann mit <b>ctl <\/b>referenziert. Sie pr&uuml;ft wieder, ob es sich um eingebautes Element handelt, und falls ja, untersucht es mit Typename wieder den Objekttyp. Im Falle von <b>CommandBarButton<\/b>, <b>CommandBarComboBox <\/b>oder <b>CommandBarControl <\/b>wird wieder die bereits bekannte Prozedur <b>WriteControl <\/b>aufgerufen. Anderenfalls rufen wir die rekursive Prozedur erneut auf und durchlaufen so alle Men&uuml;ebenen.<\/p>\n<p>Danach haben wir alle Datens&auml;tze wie in Bild 8 in der Tabelle gespeichert.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2024_04\/pic_436_007.png\" alt=\"Tabelle mit eingebauten Men&uuml;elementen\" width=\"499,6267\" height=\"250,712\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 8: Tabelle mit eingebauten Men&uuml;elementen<\/span><\/b><\/p>\n<p>Nun wollen wir diese noch einmal alle anzeigen. Dazu nutzen wir die Prozedur <b>CreateCommandBar_Eingebaute <\/b>aus Listing 7. Diese l&ouml;scht ein eventuell bereits vorhandenes Men&uuml; namens <b>Kontextmenueleiste <\/b>und erstellt diese neu.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>CreateCommandBar_Eingebaute()\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>cbr<span style=\"color:blue;\"> As <\/span>CommandBar\r\n     <span style=\"color:blue;\">Dim <\/span>cbb<span style=\"color:blue;\"> As <\/span>CommandBarButton\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     <span style=\"color:blue;\">Set<\/span> rst = db.OpenRecordset(\"SELECT * FROM tblControls ORDER BY ControlID\", dbOpenDynaset)\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     VBE.CommandBars(\"Kontextmenueleiste\").Delete\r\n     <span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n     <span style=\"color:blue;\">Set<\/span> cbr = VBE.CommandBars.Add(, msoBarPopup)\r\n     <span style=\"color:blue;\">With<\/span> cbr\r\n         .Name = \"Kontextmenueleiste\"\r\n         <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rst.EOF\r\n             Select Case rst!Controlid\r\n                 <span style=\"color:blue;\">Case <\/span>830\r\n                 <span style=\"color:blue;\">Case Else<\/span>\r\n                     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n                     <span style=\"color:blue;\">Set<\/span> cbb = cbr.Controls.Add(, rst!Controlid)\r\n                     cbb.Caption = cbb.Caption & \" (\" & rst!Controlid & \")\"\r\n                     <span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n             <span style=\"color:blue;\">End Select<\/span>\r\n             rst.Move<span style=\"color:blue;\">Next<\/span>\r\n         <span style=\"color:blue;\">Loop<\/span>\r\n         .ShowPopup\r\n     End <span style=\"color:blue;\">With<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 7: Funktion zum Erstellen eines Kontextmen&uuml;s mit allen eingebauten Controls<\/span><\/b><\/p>\n<p>Dann durchl&auml;uft sie alle Eintr&auml;ge der Tabelle <b>tblControls <\/b>und legt f&uuml;r jedes ein neues Steuerelement an, wobei sie als zweiten Parameter die <b>ID <\/b>des eingebauten Steuerelements &uuml;bergibt.<\/p>\n<p>Nur f&uuml;r das Element mit der ID <b>830 <\/b>soll das nicht geschehen. Dieses l&ouml;ste bei uns regelm&auml;&szlig;ig einen Absturz von Access aus. Au&szlig;erdem f&uuml;gen wir der Beschriftung jeweils in Klammern die ID hinzu. Schlie&szlig;lich zeigen wir das Element noch mit <b>ShowPopup <\/b>an (siehe Bild 9).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2024_04\/pic_436_008.png\" alt=\"Kontextmen&uuml; mit allen eingebauten Steuerelementen\" width=\"424,6267\" height=\"292,846\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 9: Kontextmen&uuml; mit allen eingebauten Steuerelementen<\/span><\/b><\/p>\n<p>Hier k&ouml;nnen wir nun die eingebauten Elemente f&uuml;r unsere eigenen Men&uuml;leisten ermitteln.<\/p>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Dieser Artikel zeigt den Umgang mit den Steuerelementen, hier speziell mit dem CommandBarButton-Element, im Men&uuml;system des VBA-Editors.<\/p>\n<p>Es bildet die Grundlage f&uuml;r das Erstellen eigener COM-Add-Ins, mit denen man den VBA-Editor erweitern kann. Die Men&uuml;s sind das geeignete Werkzeug, um diese Funktionen aufzurufen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im Artikel &#8220;Men&uuml;s per VBA programmieren&#8221; (www.vbentwickler.de\/435) haben wir uns bereits angesehen, wie wir die Men&uuml;struktur selbst im VBA-Editor per VBA programmieren k&ouml;nnen. Damit wissen wir nun, wie wir Hauptmen&uuml;leisten, Symbolleisten und Kontextmen&uuml;s erstellen und anzeigen k&ouml;nnen. Es fehlt allerdings noch das Salz in der Suppe, n&auml;mlich die Steuerelemente auf diesen Men&uuml;s. Welche es gibt und wie man diese hinzuf&uuml;gt und mit Aktionen versieht, schauen wir uns in diesem Artikel an.<\/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":[662024,66042024,44000037,44000025],"tags":[],"yst_prominent_words":[],"class_list":["post-55000436","post","type-post","status-publish","format-standard","hentry","category-662024","category-66042024","category-VBAEditor_programmieren","category-VBAProgrammierung"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000436","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/comments?post=55000436"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000436\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000436"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000436"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000436"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000436"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}