Live-Forum - Die aktuellen Beiträge
Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender

Forumthread: Listbox schnell mit vielen Einträgen füllen

Listbox schnell mit vielen Einträgen füllen
20.01.2020 07:15:15
Klaus
Hallo VBA-Profis,
ich suche eine Möglichkeit, eine Listbox sehr schnell mit vielen Einträgen zu füllen.
Hintergrund: Ich habe in einer Userform eine TextBox1. Bei jeder Änderung der TextBox1 möchte ich, dass ListBox1 geleert und dann mit allen Einträgen %like% TextBox1 gefüllt wird.
Die Einträge kommen aus einer Access Datenbank.
Momentan funktioniert es so:

Sub Listbox_SQL(mySql As String)
On Error GoTo hell
Dim t
t = Timer
Const pfad As String = "C:\Pfad"          'Access DB PFad
Const myAccessDB As String = "MyAccDB.mdb"                'Access DB Dateiname
Const APPNAME = "mod_Access / Gefilter_laden_SQL"
'ACCESS Tabelle per SQL Kommando filtern und gefilterte laden
Dim cmd As ADODB.Command
Dim con As ADODB.Connection
Dim rs As ADODB.Recordset
Dim spalte As Long
Debug.Print "DIM after: " & Timer - t
Set con = New ADODB.Connection
con.Open ConnectionString:= _
"Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & pfad & "\" & myAccessDB & ";" & _
"Mode=Share Exclusive"
Set cmd = New ADODB.Command
cmd.ActiveConnection = con
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseServer
'rs.Index = "Primarykey"
Debug.Print "SET Con after: " & Timer - t
rs.Open mySql, _
ActiveConnection:=con, _
CursorType:=adOpenStatic, _
LockType:=adLockPessimistic, _
Options:=adCmdTableDirect
Debug.Print "RS after: " & Timer - t
UF_Wahl.ListBox1.Clear
If Not rs.BOF Or rs.EOF Then
rs.MoveFirst
Do While Not rs.EOF
UF_Wahl.ListBox1.AddItem rs.Fields(0).Value
rs.MoveNext
Loop
End If
Debug.Print "Listbox after: " & Timer - t
'*** Fehlerbehandlung
hell:
If Err.Number = -2147467259 Then Resume     'Datenbank wird bereits verwendet
Err.Clear
Set cmd = Nothing
con.Close
Set con = Nothing
End Sub
Private Sub TextBox_Model_Change()
Call Listbox_SQL("Select Tier from Tierreich as mytab where [mytab.Tier] like '%" & UF_Wahl. _
TextBox_Model & "%'")
End Sub
'DIM after: 0
'SET Con after: 0,125
'RS after: 0,4375
'Listbox after: 1,109375
Wie ihr seht, dauert das füllen der Listbox (es sind etwas über 1000 Einträge) über 0,6 sekunden. Das klingt wenig, ist aber extrem störend wenn in TextBox1 getippt wird.
Gibt es eine Möglichkeit, die Listbox schneller und möglichst ohne Schleife komplett zu füllen? Bis dahin behelfe ich mir damit, das Makro auf "TextBox1_Exit" statt "_change" zu legen, finde es aber nur halb so elegant.
LG,
Klaus M.
Anzeige

12
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Listbox schnell mit vielen Einträgen füllen
20.01.2020 07:52:59
Daniel
Hi
Das befüllen der Listbox könnte schneller gehen, wenn der vollständige Inhalt in einem 1- oder 2-Dimensionalen Array bereit steht. Dann reicht:
Listbox1.List = DeinArray
Gruß Daniel
AW: Listbox schnell mit vielen Einträgen füllen
20.01.2020 08:02:05
Klaus
Hallo Daniel,
danke für die schnelle Antwort. Wie bekomme ich die Access ADOB.Recordset denn am schnellsten in ein Array - oder ist rs bereits das Array?
LG,
Klaus M.
Anzeige
AW: Listbox schnell mit vielen Einträgen füllen
20.01.2020 08:10:12
Daniel
Keine Ahnung.
Mit den ADODB-Funktionen kennen ich mich nicht aus.
Da hast du mehr Ahnung als ich.
Gruß Daniel
Array schnell mit ADOB.Recordset füllen
20.01.2020 08:41:03
Klaus
Hallo Daniel,
danke schonmal für deine Hilfe - das Beschreiben der Listbox per Array geht rasend schnell, aber das beschreiben des Arrays per Schleife aus dem Recordset dauert genauso lange, als wenn ich es direkt in die Listbox schreibe.
Ich stelle mal auf offen, in der Hoffnung dass sich jemand mit ADOB.Recordset auskennt.
    Dim MyArr(1000) As String
Dim i As Long
i = 0
UF_Wahl.ListBox1.Clear
If Not rs.BOF Or rs.EOF Then
rs.MoveFirst
Do While Not rs.EOF
'UF_Wahl.ListBox1.AddItem rs.Fields(0).Value
MyArr(i) = rs.Fields(0).Value
i = i + 1
rs.MoveNext
Loop
End If
UF_Wahl.ListBox1.List = MyArr()
LG,
Klaus M.
Anzeige
AW: Array schnell mit ADOB.Recordset füllen
20.01.2020 08:44:02
Klaus
Wenn ich RS in ein Tabellenblatt schreibe geht es rasend schnell, selbst wenn rs tausende Einträge hat:
  Tabelle1.Range("A1").CopyFromRecordset Data:=rs
Wenn ich mit "CopyFromRecordset" direkt in ein Array schreiben könnte, wäre mein Problem gelöst. Bekomme es leider nicht hin, "myArr = CopyFromRecordset Data:=rs" geht natürlich nicht.
LG,
Klaus M.
Anzeige
Du könntest es...
20.01.2020 08:48:57
Case
Hallo, :-)
... mal so probieren: ;-)
Dim varArr As Variant
varArr = rs.GetRows
ListBox1.List = varArr
Servus
Case

AW: Du könntest es...
20.01.2020 09:12:36
Klaus
Hallo Case,
leider nein - dies schreibt mir nur den ersten (oder den nullten?) Eintrag in die Listbox, aber keine weiteren.
LG,
Klaus M.
Anzeige
AW: Du könntest es...
20.01.2020 14:35:28
Luschi
Hallo Klaus,
wenn ich mir Deine Technologie so anschaue, dann willst Du bei jedem Tastenschlag in der TextBox folgendes machen:
- AdoDB-Connection definieren und öffnen
- Recordset definieren
- diese beiden Sachen gehören da nicht hin
- sondern in das Ereignis 'Initialisieren der Userform'
- denn es wird ja die Datenquelle während der gesamten Zeit nicht gewechselt
- das Schließen der AdoDB-Connection und des Recordsets
  kommt in das Ereignis 'Schließen der Userform' (Terminate)
- damit ist schon mal sehr viel Zeit gewonnen durch das nicht
  immer wiederkehrende Öffnen/Schließen der Datenquelle
- ich habe im I-Net ein VB-Script gefunden
  wie man 1 Recordset in ein Array umschaufelt
- teste es gerade in Vba und 1er Access-DB
- also noch ein bißchen Geduld
Gruß von Luschi
aus klein-Paris
Anzeige
AW: Du könntest es...
20.01.2020 17:30:22
Klaus
Luschi,
Öffnen / Schließen der ADOB Connection in Initialise und Close zu verlagern ist eine gute Idee - das ist auf jedem Fall sauberer. Ich habe überhaupt nicht darüber nachgedacht und ganz Script-Kiddie mäßig das vorhanden SQL-Script kopiert und benutzt wie es ist.
Aber es wird nicht helfen - die Recordsets laden dauert ja nur eine zehntel Sekunde, das langsame an dem ganzen Vorgang ist die Schleife zum befüllen der Listbox. Ich warte aber ganz geduldig auf dein Array-Script :-)
Offtopic: Ich benutze die ADOB-Connection Makros eigentlich immer so:
sub hochladen()
for i = 1 to 1000
call AccessMakro(i)
next i
end sub
sub Accesmakro(i as long)
recordset erstellen
rs!eintrag = cells(i,1).value
recordset schließen
end sub

Also Adob auf / zu / auf / zu und das tausend mal. Ist trotzdem rasend schnell! Wenn es deutlich mehr als 5000 Einträge werden, nehme ich aber ein optimiertes Makro.
LG,
Klaus M.
Anzeige
AW: Du könntest es...
21.01.2020 13:52:39
Klaus
Hallo Luschi,
ich habe zwar jetzt eine 1a Lösung von Daniel, aber aus rein akademischen Gründen wäre ich an deiner Lösung trotzdem interessiert! :-)
LG,
Klaus M.
AW: Listbox schnell mit vielen Einträgen füllen
20.01.2020 17:56:05
Daniel
Hi
wie veränderlich ist denn die Datenbank?
ggf ist es schneller, wenn du einmalig (z.B. im Initialize-Event der Userform) alle Daten in ein eindimensionales Array schreibst und dann für die Befüllung der Listbox die FILTER-Funktion verwendest:
Listbox1.List = Filter(ArrayVollständig, Textbox1.Text, True)
Gruß Daniel
Anzeige
AW: Listbox schnell mit vielen Einträgen füllen
21.01.2020 08:43:55
Klaus
genial. Mega schnell. FETTES DANKE an Daniel!
LG,
Klaus M.
;

Forumthreads zu verwandten Themen

Entdecke relevante Threads

Schau dir verwandte Threads basierend auf dem aktuellen Thema an

Alle relevanten Threads mit Inhaltsvorschau entdecken
Anzeige
Anzeige

Infobox / Tutorial

Listbox schnell mit vielen Einträgen füllen


Schritt-für-Schritt-Anleitung

Um eine Listbox in Excel VBA effizient mit vielen Einträgen zu füllen, kannst du die folgenden Schritte befolgen:

  1. Verbindung zur Access-Datenbank herstellen: Verwende ADODB, um auf die Datenbank zuzugreifen.
  2. SQL-Abfrage ausführen: Erstelle eine SQL-Abfrage, um die gewünschten Daten abzurufen.
  3. Daten in ein Array laden: Statt die Listbox direkt in einer Schleife zu füllen, kannst du die Daten in ein Array laden.
  4. Listbox füllen: Übertrage das Array in die Listbox.

Hier ist ein Beispiel für den VBA-Code:

Sub Listbox_SQL(mySql As String)
    Dim con As ADODB.Connection
    Dim rs As ADODB.Recordset
    Dim varArr As Variant

    Set con = New ADODB.Connection
    con.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Pfad\MyAccDB.mdb;"

    Set rs = New ADODB.Recordset
    rs.Open mySql, con, adOpenStatic

    varArr = rs.GetRows() ' Daten in ein Array laden
    UF_Wahl.ListBox1.List = Application.Transpose(varArr) ' Listbox füllen

    rs.Close
    con.Close
End Sub

Häufige Fehler und Lösungen

  • Fehler beim Füllen der Listbox: Wenn die Listbox nur den ersten Eintrag anzeigt, überprüfe, ob du das Array korrekt überträgst. Achte darauf, dass du Application.Transpose verwendest, um das Array in die richtige Form zu bringen.

  • Langsame Datenbankverbindung: Stelle sicher, dass die Verbindung zur Datenbank im Initialize-Ereignis der Userform geöffnet wird und im Terminate-Ereignis geschlossen wird, um wiederholtes Öffnen und Schließen zu vermeiden.


Alternative Methoden

  • Direktes Füllen aus einem Array: Du kannst die Listbox direkt aus einem Array befüllen, was die Leistung erheblich steigert. Beispiel:
Dim myArray(1 To 1000) As String
' Fülle myArray mit Daten
UF_Wahl.ListBox1.List = myArray
  • Verwendung der FILTER-Funktion: Wenn du alle Daten in ein Array geladen hast, kannst du die FILTER-Funktion nutzen, um die Listbox basierend auf Eingaben in der TextBox zu filtern:
UF_Wahl.ListBox1.List = Filter(myArray, UF_Wahl.TextBox1.Text, True)

Praktische Beispiele

Wenn du eine Listbox in einer Userform füllen möchtest, um beispielsweise Tiernamen anzuzeigen, könntest du folgenden Code verwenden:

Private Sub TextBox_Model_Change()
    Dim mySql As String
    mySql = "SELECT Tier FROM Tierreich WHERE Tier LIKE '%" & TextBox_Model & "%'"
    Call Listbox_SQL(mySql)
End Sub

Tipps für Profis

  • Vermeide wiederholte Datenbankzugriffe: Halte die Daten in einem Array, um die Performance zu verbessern. Lade die Daten einmal und filtere sie bei Bedarf.
  • Nutze GetRows für schnellere Ergebnisse: Das Abrufen von Daten über GetRows ist schneller als das Füllen der Listbox in einer Schleife.
  • Teste deine Abfragen: Verwende das Immediate Window in der VBA-Umgebung, um SQL-Abfragen zu testen, bevor du sie im Code verwendest.

FAQ: Häufige Fragen

1. Wie kann ich eine Listbox effizient mit Daten aus einer Access-Datenbank füllen? Du kannst die Daten zuerst in ein Array laden und dann die Listbox mit dem gesamten Array füllen, um die Performance zu steigern.

2. Warum ist das Füllen der Listbox mit einer Schleife langsam? Das wiederholte Hinzufügen von Elementen zur Listbox in einer Schleife ist ineffizient. Stattdessen solltest du alle Daten auf einmal in die Listbox übertragen.

3. Kann ich die Listbox basierend auf einer TextBox filtern? Ja, du kannst die FILTER-Funktion verwenden, um die Listbox-Einträge dynamisch basierend auf der Eingabe in der TextBox zu aktualisieren.

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Entdecke mehr
Finde genau, was du suchst

Die erweiterte Suchfunktion hilft dir, gezielt die besten Antworten zu finden

Suche nach den besten Antworten
Unsere beliebtesten Threads

Entdecke unsere meistgeklickten Beiträge in der Google Suche

Top 100 Threads jetzt ansehen
Anzeige