Schnelle Schaltflächen mit Stil

Je fixer ich Ergebnisse beim Programmieren erhalten möchte, desto ungeduldiger werde ich, wenn mich kleinteilige, sich ständig wiederholende Aufgaben aufhalten. In diesem Fall ist vom Anlegen von Schaltflächen die Rede. Ich hätte gern so schnell wie möglich Schaltflächen, welche die von mir gewünschte Beschriftung, einen passenden Namen und je nach Situation ein Icon enthalten. Diese sollen auch noch nach meinen Wünschen gestaltet sein – also beispielsweise mit transparentem Hintergrund und ohne Rahmen, sodass nur das Icon und die Beschriftung erscheinen und die Schriftfarbe und Schriftbreite diese als Schaltfläche von den Beschriftungen abhebt. Schließlich sollte auch noch direkt der VBA-Editor mit der passenden Ereignisprozedur geöffnet werden. Das alles umfasst einige Schritte, und auch wenn man eine Schaltfläche einmal formatiert hat und diese dann kopiert und als Vorlage für eine neue Schaltfläche verwendet, muss man noch einige Aspekte selbst hinzufügen. In diesem Beitrag stelle ich daher einen Assistenten vor, mit dem wir Schaltflächen wesentlich schneller und komfortabler anlegen können.

Individuelles Schaltflächendesign

Bild 1: Individuelles Schaltflächendesign

Schaltflächen – der Standardweg

Wenn ich in einem Formular eine neue Schaltfläche wie die aus Bild 1 erstellen möchte, sind einige Schritte nötig:

Individuelles Schaltflächendesign

Bild 1: Individuelles Schaltflächendesign

  • Klick auf den Ribbon-Eintrag Formularentwurf|Steuerelemente|Schaltfläche
  • Klick auf die Stelle im Formularentwurf, wo die Schaltfläche angelegt werden soll
  • Anpassen der Beschriftung
  • Wechsel zur Registerseite Andere im Eigenschaftenblatt und Anpassen des Steuerelementnamens
  • Anlegen der Ereignisprozedur durch Wechsel zur Registerseite Ereignisse im Eigenschaftenblatt, Klick in die Eigenschaft Beim Klicken, Klick auf die Schaltfläche mit den drei Punkten
  • Hinzufügen des Codes, der durch die Schaltfläche ausgelöst werden soll
  • Hinzufügen eines Icons über den Ribbonbefehl Bild einfügen, hier gegebenenfalls noch Auswählen des gewünschten Bildes
  • Einstellen der Eigenschaft Anordnung der Bildbeschriftung auf Rechts
  • Hinzufügen eines Leerzeichens links von der Bildbeschriftung, damit diese ausreichend Abstand vom Icon hat
  • Einstellen der Eigenschaft Hintergrundfarbe auf die Farbe des Formulars
  • Einstellen der Eigenschaft Rahmenart auf Transparent
  • Einstellung der Eigenschaften Farbe beim Daraufzeigen und Farbe für gedrückten Zustand auf die gewünschten Farben
  • Einstellen der Eigenschaft Schriftbreite auf Fett

Damit ist die erste Schaltfläche angelegt.

Für die folgenden Schaltflächen wird es etwas einfacher, weil wir nun eine Schaltfläche haben, die wir bereits kopieren und als neue Schaltfläche einfügen können. Dennoch müssen wir dann folgende Einstellungen erneut vornehmen:

  • Beschriftung einstellen
  • Steuerelementname einstellen
  • Icon auswählen
  • Ereignisprozedur anlegen

Schaltflächen einfacher hinzufügen

Mit der nachfolgend beschriebenen Lösung wollen wir diese Schritte erheblich vereinfachen.

Dazu wollen wir ein Formular programmieren, das die wichtigsten Konfigurationsmöglichkeiten für eine neue Schaltfläche enthält. In weiteren Beiträgen (siehe Ende des Beitrags) zeigen wir, wie die Lösung in einen Steuerelement-Wizard umgewandelt wird.

Damit wollen wir nur noch die sich unterscheidenden Merkmale anpassen – und auch das wollen wir vereinfachen. Wir wollen hier nur noch die folgenden Aktionen durchführen müssen:

  • Angabe der Beschriftung
  • Auswahl des Icons
  • Anschließend Ergänzen der bereits angelegten Ereignisprozedur

Wenn wir die Beschriftung eingegeben haben, wollen wir daraus automatisch einen Steuerelementnamen ableiten. Wenn die Beschriftung etwa Weitersuchen lautet, soll automatisch der Steuerelementname cmdWeitersuchen vorgeschlagen werden.

Wenn sich die Beschriftung aus mehreren Wörtern zusammensetzt, soll der Steuerelementname aus dem gleichen Text bestehen – allerdings werden Leerzeichen entfernt, Umlaute und Sonderzeichen werden ersetzt und jedes neue Wort wird großgeschrieben. Aus der Beschriftung Nächste Fundstelle wird so cmdNaechsteFundstelle.

Dieser Steuerelementname soll natürlich angepasst werden können, bevor das Steuerelement angelegt wird.

Funktionsweise der Lösung

Die Lösung besteht aus dem Formular aus Bild 2. In das Feld Beschriftung geben wir den Text ein, der auf der Schaltfläche angezeigt werden soll. Daraus wird automatisch der Name für das Steuerelement generiert, den wir anschließend nach Bedarf anpassen können.

Das Formular frmButtonWizard

Bild 2: Das Formular frmButtonWizard

Über die Schaltfläche Auswahl können wir einen Dateidialog öffnen, mit dem wir Icons auswählen, die für die zu erstellenden Schaltflächen verwendet werden sollen. Diese werden anschließend in den Bildsteuerelementen darunter angezeigt. Mit dem Feld Filter können wir gezielt nach den Namen der Bild-Dateien suchen. Wenn mehr Bilder vorhanden sind, als angezeigt werden können, erlauben die beiden Schaltflächen mit dem Pfeil nach oben und dem Pfeil nach unten das Blättern in den Icons.

Die Vorschau zeigt an, wie die fertige Schaltfläche später aussehen wird. Mit einem Klick auf Schaltfläche anlegen erstellen wir schließlich vollautomatisch die gewünschte Schaltfläche.

Bild 3 zeigt einige Beispiele für solche Schaltflächen.

Einige Beispielschaltflächen, die mit der Lösung aus diesem Beitrag erstellt wurden

Bild 3: Einige Beispielschaltflächen, die mit der Lösung aus diesem Beitrag erstellt wurden

Formular zum Anlegen von Steuerelementen

Um die gewünschten Einstellungen vorzunehmen, stellen wir ein entsprechendes Formular bereit. Dieses legen wir in einer neuen, leeren Datenbankdatei unter dem Namen frmButtonWizard an.

Hier wollen wir zuerst die Beschriftung des Steuerelements abfragen und daraus direkt bei der Eingabe den Namen des Steuerelements ableiten. Dazu fügen wir die Steuerelemente aus Bild 4 hinzu.

Erster Entwurf des Formulars

Bild 4: Erster Entwurf des Formulars

Die erste Schaltfläche heißt txtBeschriftung, die zweite txtSteuerelementname. Die Schaltfläche nennen wir cmdAktualisieren.

Der Benutzer soll die Beschriftung der Schaltfläche in txtBeschriftung eingeben. Dadurch lösen wir bei der Eingabe eines jeden einzelnen Zeichens das Ereignis Bei Änderung aus. Für dieses hinterlegen wir die folgende Ereignisprozedur:

Private Sub txtBeschriftung_Change()
     Call SteuerelementnameAktualisieren( _
         Me.txtBeschriftung.Text)
End Sub

Diese ruft die Prozedur SteuerelementnameAktualisieren auf und übergibt dieser den aktuellen Text des Textfeldes txtBeschriftung als Parameter.

In dieser Prozedur (siehe Listing 1) erzeugen wir mit Split aus den einzelnen Wörtern der Beschriftung ein Array namens strWoerter – dieses kann auch nur ein Element enthalten. Danach durchlaufen wir alle Elemente des Arrays und fügen diese aneinander. Dabei wird das erste Zeichen eines jeden Wortes großgeschrieben und bei den übrigen wird die Schreibweise beibehalten. So wird aus Datensatz anlegen der Text DatensatzAnlegen.

Private Sub SteuerelementnameAktualisieren(strBeschriftung As String)
     Dim strTemp As String
     Dim strWoerter() As String
     Dim i As Integer
     If Not Len(strBeschriftung) = 0 Then
         strWoerter = Split(strBeschriftung, " ")
         For i = LBound(strWoerter) To UBound(strWoerter)
             strTemp = strTemp & StrConv(Left(strWoerter(i), 1), vbUpperCase) & Mid(strWoerter(i), 2)
         Next i
         strTemp = Replace(strTemp, " ", "")
         strTemp = Replace(strTemp, "ä", "ae")
         strTemp = Replace(strTemp, "ö", "oe")
         strTemp = Replace(strTemp, "ü", "ue")
         strTemp = Replace(strTemp, "Ä", "Ae")
         strTemp = Replace(strTemp, "Ö", "Oe")
         strTemp = Replace(strTemp, "Ü", "Ue")
         strTemp = Replace(strTemp, "ß", "ss")
         strTemp = AlphanumerischBereinigt(strTemp)
         strTemp = "cmd" & strTemp
     Else
         strTemp = ""
     End If
     Me.txtSteuerelementname = strTemp
End Sub

Listing 1: Aktualisieren des Steuerelementnamens

Danach ersetzt die Prozedur die Umlaute und das scharfe ß durch die entsprechenden Umschreibungen. Schließlich lassen wir den aktuellen Text noch durch die Funktion AlphanumerischBereinigen laufen, in der alle Zeichen außer a-z, A-Z und 0-9 entfernt werden. Diese Funktion sehen wir in Listing 2.

Private Function AlphanumerischBereinigt(ByVal strEingabe As String) As String
     Dim i As Long
     Dim strErgebnis As String
     Dim strZeichen As String
     For i = 1 To Len(strEingabe)
         strZeichen = Mid$(strEingabe, i, 1)
         If strZeichen Like "[A-Za-z0-9]" Then
             strErgebnis = strErgebnis & strZeichen
         End If
     Next i
     AlphanumerischBereinigt = strErgebnis
End Function

Listing 2: Entfernen nicht-alphanumerischer Zeichen

Es kann auch sein, dass der Benutzer den so generierten Steuerelementnamen manuell anpassen möchte. Das kann er tun und wir stellen dann den Wert einer Variablen namens bolManuellGeaendert, die wir wie folgt deklarieren, auf True ein:

Private bolManuellGeaendert As Boolean

Bei einer Änderung im Textfeld txtSteuerelementname wird die folgende Ereignisprozedur ausgelöst, welche bolManuellGeaendert auf True einstellt, den aktuellen Text in einer TempVar-Variablen speichert (so kann diese beispielsweise bei Laufzeitfehlern nicht gelöscht werden) und anschließend die Routine VorschauAktualisieren aufruft, die wir weiter unten beschreiben:

Private Sub txtSteuerelementname_Change()
     bolManuellGeaendert = True
     TempVars("Steuerelementname") = _
         Me.txtSteuerelementname.Text
     Call VorschauAktualisieren
End Sub

Schließlich fehlt noch die Schaltfläche cmdAktualisieren. Diese soll, falls der Benutzer den Steuerelementnamen bereits manuell angepasst hat, die automatische Aktualisierung wieder aktivieren, indem sie erstens eine initiale Aktualisierung durchführt und bolManuellGeaendert wieder auf False einstellt.

Dadurch werden folgende Änderungen in txtBeschriftung wieder in txtSteuerelementname übertragen:

Private Sub cmdAktualisieren_Click()    
     Me.txtFilter.SetFocus
     Call SteuerelementnameAktualisieren( _
         Nz(Me.txtBeschriftung, ""))
     bolManuellGeaendert = False
End Sub

Icon auswählen

Nun folgt ein spannender Teil. Wie wollen wir die Auswahl eines Icons realisieren? Wir könnten einfach einen Dateiauswahl-Dialog öffnen und den Benutzer das gewünschte Icon auswählen lassen. Dieses würden wir anschließend in der Tabelle MSysResources der Zieltabelle speichern und für die Schaltfläche verwenden.

Praktischer wäre es jedoch, wenn wir die einmal verwendeten Icons direkt auch in unserer Lösung speichern und für die weitere Verwendung direkt zur Auswahl anbieten – zum Beispiel, wenn wir ein Add-In aus dieser Lösung erstellen. Dann hätte der Benutzer einen Schritt weniger bei bereits verwendeten Icons und könnte diese direkt auswählen.

Also legen wir dazu eine neue Tabelle namens tblResources an, die genauso aufgebaut ist wie die Tabelle MSysResources. Genau genommen haben wir diese einfach kopiert und unter dem Namen tblResources wieder eingefügt. Den Entwurf dieser Tabelle sehen Sie in Bild 5.

Tabelle zum Speichern der Icons

Bild 5: Tabelle zum Speichern der Icons

Damit kommen wir zur Schaltfläche cmdBilderAuswaehlen, die im Entwurf aus Bild 6 markiert ist.

Vollständiger Entwurf des Formulars frmButtonWizard

Bild 6: Vollständiger Entwurf des Formulars frmButtonWizard

Diese soll einen Dateiauswahl-Dialog anzeigen und die Bilder anschließend in der Tabelle tblResources speichern. Dazu deklarieren wir eine Konstante, welche die dabei zu verwendende Tabelle enthält:

Private Const cStrResourcesTable As String _
     = "tblResources"

Die Prozedur cmdBilderAuswaehlen ruft die Funktion ChooseFiles auf, die im Modul mdlFileDialog enthalten ist und den Standard-Office-Dialog zum Auswählen von Dateien verwendet. Sie speichert die ausgewählten Dateipfade in der Variablen strFileList. Wenn diese nicht leer ist, unterteilt sie diese Liste jeweils am Pipe-Zeichen (|) und schreibt die einzelnen Pfade in ein Array namens strFiles.

Für jede Datei ruft sie einmal die Routine BildInRessourcenSpeichern auf und übergibt dieser den Dateipfad und den Namen der Tabelle, in der das Icon gespeichert werden soll.

Nachdem alle Icons gespeichert sind, ruft sie die Prozedur LoadImages auf, die dafür sorgt, dass die aktuell in der Tabelle tblResources gespeicherten Icons in der Matrix im Formular angezeigt werden.

Private Sub cmdBilderAuswaehlen_Click()
     Dim strFilelist As String
     Dim strFiles() As String
     Dim var As Variant
     
     Me.txtFilter.SetFocus
     strFilelist = ChooseFiles
     If Len(strFilelist) > 0 Then
         strFiles = Split(strFilelist, "|")
         For Each var In strFiles
             BildInRessourcenSpeichern CStr(var), _
                 cStrResourcesTable
         Next var
         Call LoadImages
     End If
End Sub

Wie die Routine LoadImages funktioniert, erläutern wir im Detail im Beitrag Icons in der Datenbank verwalten (www.access-im-unternehmen.de/1564).

Und wie wir die Matrix aus Bild-Steuerelementen erzeugen, die Sie im Formularentwurf sehen, beschreiben wir im Beitrag Schaltflächen-Matrix per VBA erzeugen (www.access-im-unternehmen.de/1562).

Vorschau der Schaltfläche anzeigen

Damit haben wir nun die Textfelder, in denen die Beschriftung und der Steuerelementname gespeichert sind. Außerdem haben wir eine Funktion, mit der wir die als Icons zu verwendenden Bilder in die Tabelle tblResources laden können und eine Matrix aus Bild-Steuerelementen, mit denen wir die verfügbaren Icons anzeigen. Außerdem haben im oben angegebenen Artikel beschrieben, wie wir zwischen den Bildern navigieren können, wenn die Tabelle tblResources mehr Bilder enthält, als auf einen Blick angezeigt werden können.

Damit kommen wir zur Anzeige der Vorschau für die zu erstellende Schaltfläche. Diese soll immer aktualisiert werden, wenn wir eine Änderung an der Beschriftung oder dem gewählten Icon vornehmen.

Die dadurch ausgelöste Prozedur heißt VorschauAktualisieren (siehe Listing 3). Sie referenziert die als Beispielschaltfläche angelegte Schaltfläche namens cmdVorschau. Dann holt sie mit der Funktion Schriftabmessungen die Breite und die Höhe für die anzuzeigende Beschriftung und liefert diese mit den beiden Parametern lngBreite und lngHoehe zurück (diese Funktion beschreiben wir im Anschluss).

Private Sub VorschauAktualisieren()
     Dim lngHoehe As Long
     Dim lngBreite As Long
     Dim varPictureData As String
     Dim bolAktivieren As Boolean
     With Me.cmdVorschau
         Call Schriftabmessungen(lngBreite, lngHoehe)
         .Height = 480        
         Me.Paining = False
         If Len(TempVars("Picture")) = 0 Then
             .PictureData = Null
             .Caption = Nz(TempVars("Beschriftung"), "")
             .Width = lngBreite + 480
             .Alignment = 2
             If Not Len(.Caption) = 0 Then
                 bolAktivieren = True
             End If
         Else
             If GetPictureDataFromResourcesByName(TempVars("Picture"), varPictureData, cStrResourcesTable) = True Then
                 .PictureData = varPictureData
                 .PictureType = 2
                 If Not Len(TempVars("Beschriftung")) = 0 Then
                     .Caption = "  " & TempVars("Beschriftung")
                     .Width = lngBreite + 600
                     .Alignment = 1
                 Else
                     .Caption = ""
                     .Width = 480
                     .Alignment = 2
                 End If
                 bolAktivieren = True
             End If
         End If        
         Me.Painting = True
         cmdVorschau.Requery        
     End With
     If Len(Nz(TempVars("Steuerelementname"), "")) = 0 Then
         bolAktivieren = False
     End If
     If bolAktivieren = True Then
        Me.cmdSchaltflaecheAnlegen.Enabled = True
     Else
        Me.cmdSchaltflaecheAnlegen.Enabled = False
     End If
End Sub

Listing 3: Aktualisieren der Schaltflächen-Vorschau

Als Höhe des Steuerelements legen wir 480 Pixel fest. Mit Me.Painting = False verhindern wir während des Vorgangs das Neuzeichnen des Formulars, damit es nicht zu unnötigem Flackern kommt.

Dann lesen wir aus der TempVar-Variablen Picture den zuvor zwischengespeicherten Namen des zu verwendenden Icons aus. Hat diese Zeichenkette die Länge 0, leeren wir die Eigenschaft PictureData der Schaltfläche, tragen die Beschriftung ein, legen die Breite auf 480 plus der ermittelten Breite für die Beschriftung aus lngWidth fest und stellen die Ausrichtung auf linksbündig ein. Schließlich legen wir für die Variable bolAktivieren den Wert True fest. Dieser wird später ausgewertet, um die Schaltfläche zum Anlegen der neuen Schaltfläche zu aktivieren oder zu deaktivieren.

Wenn die TempVar-Variable gefüllt ist, gelangen wir in den Else-Zweig der Bedingung. Hier rufen wir die Funktion GetPictureDataFromResourcesByName auf, die wir im Modul mdlPictureData finden. Dieser Funktion übergeben wir den Namen des einzulesenden Icons, die Tabelle, in der sich das Icon befindet (hier tblResources) und eine leere Variant-Variable, die wir mit dem zu verwendenden Bild-Objekt füllen. Liefert die Funktion den Wert True als Ergebnis zurück, konnte das Bild erfolgreich eingelesen werden.

Dann weisen wir den Inhalt von varPictureData der Eigenschaft PictureData der Vorschau-Schaltfläche zu und stellen PictureType auf 2 ein.

Enthält die TempVar-Variable Beschriftung einen Text, wird dieser für die Eigenschaft Caption als Beschriftung eingetragen. Außerdem wird die Breite auf 600 Pixel plus der zuvor ermittelten Breite der Beschriftung eingestellt und bolAktivieren erhält den Wert True.

bolAktivieren hat anschließend nur den Wert False, wenn weder eine Bildbeschriftung vorliegt noch ein Bild ausgewählt wurde.

Danach aktivieren wir mit Me.Painting = True das Neuzeichnen des Formulars wieder und aktualisieren die Anzeige der Vorschau-Schaltfläche.

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar