Da es zu meinem vorherigen Tutorial sehr viel positives Feedback gab, habe ich mich entschlossen eine Version 2 des Tutorials aufzusetzen.
In dieser Version möchte ich allerdings mehr auf die eigentliche Programmierung, sprich den VBA Quelltext selbst, eingehen. Wie man eine Eingabemaske entsprechend im VBA-Editor erstellt, ist im
vorherigen Tutorial zu sehen.
Dieses Tutorial ist etwas anspruchsvoller als das vorherige. Ich versuche Ihnen jedoch so viel Quelltext-Erläuterungen wie
möglich an die Hand zu geben, so dass Sie den Beispiel-Code auch möglichst vollständig verstehen. Für Einsteiger und nicht so fortgeschrittene Benutzer
empfehle ich einen Blick in die VBA Grundlagen, denn alles kann ich in einem Tutorial nicht ausführlich erläutern, dafür ist die Materie zu umfangreich.
Aber auch zu den Grundlagen von VBA gibt es im Netz und hier auf Online-VBA.de kostenloses Einsteiger-Material.
Hinweis: Für dieses Tutorial wurde Microsoft® Office Professional Version 2016 verwendet.
Als Betriebssystem wurde Windows® 10 verwendet. Wenn Sie eine andere Version verwenden, kann
es Unterschiede im Erscheinungsbild geben! Verwenden Sie Microsoft® Office für Mac®? Hier gibt es einige
weitere Unterschiede, welche ich in diesem Tutorial aber nicht weiter ansprechen möchte.
Ich habe für alle das unten folgende Beispiel als fertige Datei zum Download
bereitgestellt. Sie finden den Download-Link am Ende dieses Tutorials.
Unser Ziel ist eine flexiblere Programmierung für die einfache Adressliste aus dem ersten Tutorial zu bauen.
Dabei möchte ich tiefer auf die Programmierung eingehen und zusätzlich noch etwas mehr Parametrisierung ins Spiel bringen.
Trotzdem: In diesem Tutorial geht es lediglich um Grundlagenwissen.
Komplizierte Eingabeprüfungen und Fehlerbehandlungsroutinen werde ich auch hier nicht ansprechen.
Zusätzliche Anforderungen im Vergleich zum ersten Tutorial:
Schauen wir uns die Ausgangslage bzw. die Tabelle aus dem ersten Tutorial noch einmal kurz an.
A | B | C | D | E | F | G | H | I | |
---|---|---|---|---|---|---|---|---|---|
1 | Name | Telefon | Adresse | PLZ | Ort | ||||
2 | Marc | 12345 | info@wershovenonline.de | Musterstrasse 16 | 12345 | Musterhausen | |||
3 | Anika | 54321 | keine vorhanden | Beispielweg 2 | 54321 | Musterort | |||
4 | Max Mustermann | 33445 | max@mustermann.de | Muster-Haupt-Str. 3 | 22334 | Mustermetropole | |||
5 | |||||||||
6 |
Wir verwenden die gleiche Eingabemaske wie im ersten Tutorial.
Nur die Liste (ListBox1) können Sie etwas breiter gestalten, da wir mehrere Spalten anzeigen möchten.
Um unserer Benutzeroberfläche "das Leben einzuhauchen" Doppel-Klicken Sie bitte auf die "Beenden"-Schaltfläche, unserem CommandButton_4 auf unserer UserForm1. Der Quellcode Editor wird geöffnet und Sie sehen schon etwas Quelltext bzw. den alten Quelltext aus dem ertsten Tutorial. Löschen Sie den gesamten Quelltext vollständig und fügen Sie den folgenden neuen Quelltext der Version 2 vollständig ein.
Wie der Quelltext genau funktioniert, erfahren Sie direkt im Folge-Kapitel, im Anschluss an den Quelltext.
Der Quelltext...
Option Explicit
Option Compare Text
' ************************************************************************************************
' Autor/en: http://www.online-vba.de - Marc Wershoven
' Verwendung der Quelltexte auf eigene Gefahr!
' Es gelten die Nutzungsbedingungen von www.online-vba.de!
' Original-Quelltext: www.online-vba.de/vba_tutorialuserform2.php
' ************************************************************************************************
' ************************************************************************************************
' KONSTANTEN / PARAMETRISIERUNG
' ************************************************************************************************
'Wie viele TextBoxen sind auf der UserForm platziert?
Private Const iCONST_ANZAHL_EINGABEFELDER As Integer = 6
'In welcher Zeile starten die Eingaben?
Private Const lCONST_STARTZEILENNUMMER_DER_TABELLE As Long = 2
' ************************************************************************************************
' EREIGNISROUTINEN DER USERFORM
' ************************************************************************************************
'Neuer Eintrag Schaltfläche Ereignisroutine
Private Sub CommandButton1_Click()
Call EINTRAG_ANLEGEN 'Aufruf der entsprechenden Verarbeitungsroutine
End Sub
'Löschen Schaltfläche Ereignisroutine
Private Sub CommandButton2_Click()
Call EINTRAG_LOESCHEN 'Aufruf der entsprechenden Verarbeitungsroutine
End Sub
'Speichern Schaltfläche Ereignisroutine
Private Sub CommandButton3_Click()
Call EINTRAG_SPEICHERN 'Aufruf der entsprechenden Verarbeitungsroutine
End Sub
'Beenden Schaltfläche Ereignisroutine
Private Sub CommandButton4_Click()
Unload Me
End Sub
'Klick auf die ListBox Ereignisroutine
Private Sub ListBox1_Click()
Call EINTRAG_LADEN_UND_ANZEIGEN 'Aufruf der entsprechenden Verarbeitungsroutine
End Sub
'Diese Ereignisroutine wird beim Anzeigen der UserForm ausgeführt
Private Sub UserForm_Activate()
If ListBox1.ListCount > 0 Then ListBox1.ListIndex = 0 '1. Eintrag selektieren
End Sub
'Startroutine, wird ausgeführt bevor die Eingabemaske angezeigt wird
Private Sub UserForm_Initialize()
Call LISTE_LADEN_UND_INITIALISIEREN 'Aufruf der entsprechenden Verarbeitungsroutine
End Sub
' ************************************************************************************************
' VERARBEITUNGSROUTINEN
' ************************************************************************************************
'Diese Routine wird aufgerufen um die Liste (ListBox1) zu leeren, einzustellen und neu zu füllen
Private Sub LISTE_LADEN_UND_INITIALISIEREN()
Dim lZeile As Long
Dim lZeileMaximum As Long
Dim i As Integer
'Alle TextBoxen leer machen
For i = 1 To iCONST_ANZAHL_EINGABEFELDER
Me.Controls("TextBox" & i) = ""
Next i
ListBox1.Clear 'Liste leeren
'4 Spalten einrichten
'Spalte 1: Zeilennummer des Datensatzes
'Spalte 2: Name (Spalte A)
'Spalte 3: Telefon (Spalte B)
'Spalte 4: E-Mail (Spalte C)
ListBox1.ColumnCount = 4
'Spaltenbreiten der Liste anpassen (0=ausblenden, nichts=automatisch)
'"<Breite Spalte 1>;<Breite Spalte 2>;<Breite Spalte 3>;<Breite Spalte 4>"
ListBox1.ColumnWidths = "0;;;"
'Feste Breiten: ListBox1.ColumnWidths = "0;100;100;100"
'Um eine Schleife für alle Datensätze zu erhalten, benötigen wir die letzte verwendete Zeile
lZeileMaximum = Tabelle1.UsedRange.Rows.Count 'Benutzer Bereich auslesen
For lZeile = lCONST_STARTZEILENNUMMER_DER_TABELLE To lZeileMaximum
'Nur wenn die Zeile benutzt / nicht leer ist, zeigen wir etwas an:
If IST_ZEILE_LEER(lZeile) = False Then
'Spalte 1 der Liste mit der Zeilennummer füllen
ListBox1.AddItem lZeile
'Spalten 2 bis 4 der Liste füllen
ListBox1.List(ListBox1.ListCount - 1, 1) = CStr(Tabelle1.Cells(lZeile, 1).Text)
ListBox1.List(ListBox1.ListCount - 1, 2) = CStr(Tabelle1.Cells(lZeile, 2).Text)
ListBox1.List(ListBox1.ListCount - 1, 3) = CStr(Tabelle1.Cells(lZeile, 3).Text)
End If
Next lZeile
End Sub
Private Sub EINTRAG_LADEN_UND_ANZEIGEN()
Dim lZeile As Long
Dim i As Integer
'Eingabefelder resetten
For i = 1 To iCONST_ANZAHL_EINGABEFELDER
Me.Controls("TextBox" & i) = ""
Next i
'Nur wenn ein Eintrag selektiert/markiert ist
If ListBox1.ListIndex >= 0 Then
'Die Zeilennummer des Datensatzes steht in der ersten ausgeblendeten Spalte der Liste,
'somit können wir direkt zugreifen.
lZeile = ListBox1.List(ListBox1.ListIndex, 0)
For i = 1 To iCONST_ANZAHL_EINGABEFELDER
Me.Controls("TextBox" & i) = CStr(Tabelle1.Cells(lZeile, i).Text)
Next i
End If
End Sub
Private Sub EINTRAG_SPEICHERN()
Dim lZeile As Long
Dim i As Integer
'Wenn kein Datensatz in der ListBox markiert wurde, wird die Routine beendet
If ListBox1.ListIndex = -1 Then Exit Sub
'Zum Speichern benötigen wir die Zeilennummer des ausgewählten Datensatzes
lZeile = ListBox1.List(ListBox1.ListIndex, 0)
For i = 1 To iCONST_ANZAHL_EINGABEFELDER
Tabelle1.Cells(lZeile, i) = Me.Controls("TextBox" & i)
Next i
'Der Benutzer könnte die angezeigten Werte in der Liste geändert haben,
'daher aktualisieren wir den ausgewählten Eintrag entsprechend.
ListBox1.List(ListBox1.ListIndex, 1) = TextBox1
ListBox1.List(ListBox1.ListIndex, 2) = TextBox2
ListBox1.List(ListBox1.ListIndex, 3) = TextBox3
End Sub
Private Sub EINTRAG_LOESCHEN()
Dim lZeile As Long
'Wenn kein Datensatz in der ListBox markiert wurde, wird die Routine beendet
If ListBox1.ListIndex = -1 Then Exit Sub
'Beim Löschen fragen wir zuerst den Benutzer noch einmal sicherheitshalber:
If MsgBox("Sie möchten den markierten Datensatz wirklich löschen?", _
vbQuestion + vbYesNo, "Sicherheitsabfrage!") = vbYes Then
'Nur wenn er mit <JA> antwortet, löschen wir auch!
'Zum Löschen benötigen wir die Zeilennummer des ausgewählten Datensatzes
lZeile = ListBox1.List(ListBox1.ListIndex, 0)
'Die ganze Zeile wird nun gelöscht
Tabelle1.Rows(CStr(lZeile & ":" & lZeile)).Delete
'Und den Eintrag in der Liste müssen wir auch noch entfernen
ListBox1.RemoveItem ListBox1.ListIndex
End If
End Sub
Private Sub EINTRAG_ANLEGEN()
Dim lZeile As Long
lZeile = lCONST_STARTZEILENNUMMER_DER_TABELLE
'Schleife bis eine leere ungebrauchte Zeile gefunden wird
Do While IST_ZEILE_LEER(lZeile) = False
lZeile = lZeile + 1 'Nächste Zeile bearbeiten
Loop
'Nach Durchlauf dieser Schleife steht lZeile in der ersten leeren Zeile von Tabelle1
Tabelle1.Cells(lZeile, 1) = CStr("Neuer Eintrag Zeile " & lZeile)
'Und neuen Eintrag in die UserForm eintragen
ListBox1.AddItem lZeile
ListBox1.List(ListBox1.ListCount - 1, 1) = CStr("Neuer Eintrag Zeile " & lZeile)
ListBox1.List(ListBox1.ListCount - 1, 2) = ""
ListBox1.List(ListBox1.ListCount - 1, 3) = ""
'Den neuen Eintrag markieren mit Hilfe des ListIndex
ListBox1.ListIndex = ListBox1.ListCount - 1
'Durch das Click Ereignis der ListBox werden die Daten automatisch geladen
'Und dem Benutzer direkt noch den Cursor in das erste Eingabefeld stellen und alles vorselektieren,
'so kann der Benutzer direkt loslegen mit der Dateneingabe.
TextBox1.SetFocus
TextBox1.SelStart = 0
TextBox1.SelLength = Len(TextBox1)
End Sub
' ************************************************************************************************
' HILFSFUNKTIONEN
' ************************************************************************************************
'Ermittelt, ob eine Zeile in Benutzung ist...
Private Function IST_ZEILE_LEER(ByVal lZeile As Long) As Boolean
Dim i As Long
Dim sTemp As String
'Hilfsvariable initialisieren
sTemp = ""
'Um zu erkennen, ob eine Zeile komplett leer/ungebraucht ist
'verketten wir einfach alle Spalteninhalte der Zeile miteinander.
'Ist die zusammengesetzte Zeichenkette aller Spalten leer,
'ist die Zeile nicht genutzt...
For i = 1 To iCONST_ANZAHL_EINGABEFELDER
sTemp = sTemp & Trim(CStr(Tabelle1.Cells(lZeile, i).Text))
Next i
'Rückgabewert festlegen
If Trim(sTemp) = "" Then
'Die Zeile ist leer
IST_ZEILE_LEER = True
Else
'Die Zeile ist mindestens in einer Spalte gefüllt
IST_ZEILE_LEER = False
End If
End Function
Hinweis zu den folgenden Abschnitten
Ich versuche auf so viele Grundlagen-Informationen und Techniken einzugehen wie möglich. Die vollständigen Grundlagen sind jedoch für ein kleines Tutorial viel zu umfangreich.
Wenn Sie noch nicht so lange mit VBA arbeiten, werfen Sie vorher lieber einen Blick in die VBA Grundlagen und grundlegenden Programmiertechniken.
In den folgenden erläuternden Abschnitten habe ich alle Kommentare im Quelltext (grüne Schrift) zur besseren Lesbarkeit entfernt.
So sehen Sie auch, dass gar nicht viel Quelltext benötigt wird.
Parametrisierung im Detail
Zuerst möchte ich auf das Thema Parametrisierung eingehen. In unserem kleinen Beispiel haben wir zwei sogenannte Konstanten im Einsatz.
Schauen wir uns den dazugehörigen Quelltext-Ausschnitt an:
Private Const iCONST_ANZAHL_EINGABEFELDER As Integer = 6
Private Const lCONST_STARTZEILENNUMMER_DER_TABELLE As Long = 2
Die Liste-Laden-Routine im Detail
Schauen wir uns wieder zuerst den dazugehörigen Quelltext-Ausschnitt an:
Private Sub LISTE_LADEN_UND_INITIALISIEREN()
Dim lZeile As Long
Dim lZeileMaximum As Long
Dim i As Integer
For i = 1 To iCONST_ANZAHL_EINGABEFELDER
Me.Controls("TextBox" & i) = ""
Next i
ListBox1.Clear
ListBox1.ColumnCount = 4
ListBox1.ColumnWidths = "0;;;"
lZeileMaximum = Tabelle1.UsedRange.Rows.Count
For lZeile = lCONST_STARTZEILENNUMMER_DER_TABELLE To lZeileMaximum
If IST_ZEILE_LEER(lZeile) = False Then
ListBox1.AddItem lZeile
ListBox1.List(ListBox1.ListCount - 1, 1) = CStr(Tabelle1.Cells(lZeile, 1).Text)
ListBox1.List(ListBox1.ListCount - 1, 2) = CStr(Tabelle1.Cells(lZeile, 2).Text)
ListBox1.List(ListBox1.ListCount - 1, 3) = CStr(Tabelle1.Cells(lZeile, 3).Text)
End If
Next lZeile
End Sub
Die Eintrag-Laden-Routine im Detail
Werfen wir erneut einen Blick auf den betroffenen Quelltext-Ausschnitt:
Private Sub EINTRAG_LADEN_UND_ANZEIGEN()
Dim lZeile As Long
Dim i As Integer
For i = 1 To iCONST_ANZAHL_EINGABEFELDER
Me.Controls("TextBox" & i) = ""
Next i
If ListBox1.ListIndex >= 0 Then
lZeile = ListBox1.List(ListBox1.ListIndex, 0)
For i = 1 To iCONST_ANZAHL_EINGABEFELDER
Me.Controls("TextBox" & i) = CStr(Tabelle1.Cells(lZeile, i).Text)
Next i
End If
End Sub
Die Eintrag-Speichern-Routine im Detail
Werfen wir wieder einen Blick auf den betroffenen Quelltext-Ausschnitt:
Private Sub EINTRAG_SPEICHERN()
Dim lZeile As Long
Dim i As Integer
If ListBox1.ListIndex = -1 Then Exit Sub
lZeile = ListBox1.List(ListBox1.ListIndex, 0)
For i = 1 To iCONST_ANZAHL_EINGABEFELDER
Tabelle1.Cells(lZeile, i) = Me.Controls("TextBox" & i)
Next i
ListBox1.List(ListBox1.ListIndex, 1) = TextBox1
ListBox1.List(ListBox1.ListIndex, 2) = TextBox2
ListBox1.List(ListBox1.ListIndex, 3) = TextBox3
End Sub
Die Eintrag-Hinzufügen-Routine im Detail
Werfen wir erneut einen Blick auf den betroffenen Quelltext-Ausschnitt:
Private Sub EINTRAG_ANLEGEN()
Dim lZeile As Long
lZeile = lCONST_STARTZEILENNUMMER_DER_TABELLE
Do While IST_ZEILE_LEER(lZeile) = False
lZeile = lZeile + 1
Loop
Tabelle1.Cells(lZeile, 1) = CStr("Neuer Eintrag Zeile " & lZeile)
ListBox1.AddItem lZeile
ListBox1.List(ListBox1.ListCount - 1, 1) = CStr("Neuer Eintrag Zeile " & lZeile)
ListBox1.List(ListBox1.ListCount - 1, 2) = ""
ListBox1.List(ListBox1.ListCount - 1, 3) = ""
ListBox1.ListIndex = ListBox1.ListCount - 1
TextBox1.SetFocus
TextBox1.SelStart = 0
TextBox1.SelLength = Len(TextBox1)
End Sub
Die Eintrag-Löschen-Routine im Detail
Und zu guter Letzt noch einmal der betroffene Quelltext-Ausschnitt:
Private Sub EINTRAG_LOESCHEN()
Dim lZeile As Long
If ListBox1.ListIndex = -1 Then Exit Sub
If MsgBox("Sie möchten den markierten Datensatz wirklich löschen?", _
vbQuestion + vbYesNo, "Sicherheitsabfrage!") = vbYes Then
lZeile = ListBox1.List(ListBox1.ListIndex, 0)
Tabelle1.Rows(CStr(lZeile & ":" & lZeile)).Delete
ListBox1.RemoveItem ListBox1.ListIndex
End If
End Sub
Auch hier möchte ich auf das
erste Tutorial
verweisen.
Dort ist ausführlich mit Screenshots erläutert, wie man eine entsprechende Start-Schaltfläche erstellen kann.
Nun ist es soweit! Wir probieren das Ganze aus.
Klicken Sie auf unsere Start-Schaltfläche um
die Eingabemaske zu öffnen und probieren Sie alles in Ruhe aus.
Ich hoffe, ich konnte Ihnen an diesem etwas ausführlicheren Quelltext-Beispiel Version 2 die zweiten Schritte zur eigenen Eingabemaske etwas genauer erläutern. Selbstverständlich gibt es noch viele weitere Möglichkeiten, Erweiterungen und Verschönerungen, die man einbauen kann.
Ich wünsche Ihnen Viel Erfolg und Spass bei Ihrer ersten eigenen Eingabemaske Version 2!
Zu guter Letzt habe ich Ihnen die in diesem Tutorial als Beispiel verwendete Datei auch wieder als Download bereitgestellt.
Den Link dazu finden Sie hier: Beispieldatei-Download
(Dateiformat: *.xlsm - Erstellt mit Microsoft® Excel® Version 2016 -
Diese Datei ist kompatibel mit Microsoft® Excel® Version 2007 oder neuer - Dateigröße: ca. 31 KiloBytes)
Wichtiger Hinweis: Als kostenlosen Service stellen die Autoren von
www.Online-VBA.de Dateien zum Download bereit. Dieser Download erfolgt stets auf eigene Gefahr.
Bitte beachten Sie die Nutzungsbedingungen und das Impressum von www.Online-VBA.de, bevor Sie die Datei herunterladen.
Ein kostenloser Support oder Service für die unter www.Online-VBA.de veröffentlichen Werke kann leider nicht angeboten werden!
Autor: Marc Wershoven (Oktober 2017)
VBA Programmierer gesucht?
http://www.WershovenOnline.de
Sie haben beispielsweise eine Frage zu einer Ihrer eigenen Makroprogrammierungen in VBA? Oder Sie suchen Unterstützung und Informationen über eine bestimmte Microsoft® Excel® Formel? Bei nahezu allen Fragen und Problemen rund um Microsoft® Office und VBA Makros steht Ihnen unser individueller Quick E-Mail Support zur Verfügung. Einfach, schnell und unkompliziert Ihre Frage in einer E-Mail formulieren, mit oder ohne Screenshots oder einer Beispieldatei absenden und kurze Zeit später haben Sie eine vollständige Lösung inkl. ausführlicher Erklärung vom Profi in Ihrem Postfach!
Zusätzlich besteht die Option, dass wir uns mittels Fernwartung (selbstverständlich nach Ihrem Einvertändnis) direkt "live" mit Ihnen zusammen an Ihrem Bildschirm gemeinsam Fragen und Problemstellungen anschauen und lösen können!
Weitere Informationen zu diesem kostenpflichtigen Angebot finden Sie auf der Anbieterseite von WershovenOnline® auf www.wershovenonline.de.
Zum Anbieter des Quick-E-Mail-Support...