Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1364to1368
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Effiziente Suchfunktion für Datenbank

Effiziente Suchfunktion für Datenbank
24.06.2014 10:35:33
Pascal
Guten Tag
ich habe eine grosse Excel-Datenbank mit unzähligen Tabellenblättern.
Nun möchte ich ab einer UserForm dem User eine effiziente Suchmaske anbieten.
Und zwar stell ich mir das so vor:
Noch während der User in ein Textfeld einen Begriff schreibt, so werden ihm unten dran auf der UserForm die bereits gefundenen Treffer aufgelistet.
Also z.B.
User sucht nach "Artikel"
Es werden unten dran... während er schreibt... alle Treffer mit dem enthaltenen Wort "Artikel" aufgelistet.
Ziel soll es sein, dass der User dann aus der Trefferliste einen Treffer auswählen kann und dann zur entsprechenden Zelle gesprungen wird.
Geht das irgendwie ?
Die Excel-Tabelle selber sieht der User nicht. die ist hinter der Userform ausgeblendet.
Die ganze Suche soll ähnlich wie die Suche in Microsoft OneNote oder Dateiexplorer sein.
wäre Super, wenn hier jemand helfen könnte, sowas für meine Datenbank zu verwirklichen.
im voraus HERZLICHEN DANK !
Pascal

25
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Effiziente Suchfunktion für Datenbank
24.06.2014 10:46:48
Rudi
Hallo,
ich habe eine grosse Excel-Datenbank mit unzähligen Tabellenblättern.
soll in allen Blättern oder nur in einem gesucht werden?
Eine Mustermappe wäre hilfreich.
Gruß
Rudi

AW: Effiziente Suchfunktion für Datenbank
24.06.2014 11:38:44
Pascal
Hallo Rudi
ich hab mal versucht eine ganz kleine, simple Beispielsmappe aufzubauen.
Hier nur mit drei Tabellenblättern. (meine echte Datenbank hat über 200)
Die Userform hab ich mal als Beispiel eingefügt, damit man sieht, wie ich mir das vorstelle.
https://www.herber.de/bbs/user/91245.zip
also... wenn jetzt als Beispiel jemand in das Suchfenster "Artikel" reinschreibt, so werden alle gefundenen Treffer in welchem das Wort "Artikel" enthalten ist noch während dem Schreibvorgang aufgelistet.
Also wenn ich im Suchfeld beginne zu schreiben mit Buchstaben A... dann stehen darunter schon mal alle Treffer mit einem A....
Weiter geht mit Ar....
Also mit jedem weiteren Buchstaben wird die Trefferliste sozusagen anders aussehen.
natürlich währe es 1. Sahne, wenn in der Trefferliste die gefundenen Wörter gleich auch noch farbig hervorgehoben dargestellt würden.
(ganz nach Vorbild von Microsoft OneNote - Suche)

Anzeige
AW: Effiziente Suchfunktion für Datenbank
24.06.2014 11:52:06
Rudi
Hallo,
das ist keine Datenbank sondern Murks.
Leere Spalte/ Zeilen haben in Listen nichts zu suchen.
Arbeitsblatt 'Abkuerzungen'
BCD
1Fehlermeldung Bedeutung / Bezeichnung
2Aw Aktionsware
3BLR Bestell- Lieferrhythmus
4BV Bestell-Vorschlag
5CGR Geschäftspartner Raiting
6CPS Produktions System
7CTS Traiding System
8ELKZ Endlieferkennzeichen
9Gui Graphic User Interface
10HE Handelseinheiten
11Idoc Intermediate Document
12LE - WM Logistics Execution Warehouse Management
13MM - IM Material Management Inventory
14PLU Public Logistic Unit
15POS Point of Sales
16SBO Sales Based Ordering

Markiere eine Zelle in B und sortiere. Alles im A....
Vielleicht findet sich ja jemand, der sich damit beschäftigt. Ich nicht.
Gruß
Rudi

Anzeige
AW: Effiziente Suchfunktion für Datenbank
24.06.2014 12:05:45
EtoPHG
Hallo Pascal,
Ich schliesse mich der Meinung von Rudi an.
Warum willst du da eine Userform basteln.
Die Anforderung mit jedem eingebenen Buchstaben die Suche neu zu starten/bwz erweitern/einschränken ist ein völliger Overkill. Der Anwender sollte schon wissen, nach was er/sie suchen will. Wenn du also von diesem Overkill absiehst, dann lässt sich das Ganze ohne VBA und Userforms ganz einfach mit der Standard-Suchfunktion von Excel ausführen. Warum sollte jemand das Rad neu erfinden? Ist es dir zu unrund?
Gruess Hansueli

AW: Effiziente Suchfunktion für Datenbank
24.06.2014 13:18:55
Pascal
Hallo allerseits!
Tja... so wirklich unrecht habt Ihr ja nicht. Die Leerzellen ... die (ich weiss) gehören eigentlich nicht in eine Datenbank. Aber ... diese wurden halt so erwünscht von den Users um einen besseren Überblick zu haben.
klar doch:
diese Leeren Spalten könnte man bestimmt rauslöschen.
aber... da für den User das Excel ausgeblendet und somit "gesperrt" ist, ist eben der Wunsch nach einer tollen Suche über VBA entstanden.
geht das wirklich nicht ohne riiesigen Aufwand ?

Anzeige
AW: Effiziente Suchfunktion für Datenbank
24.06.2014 13:58:42
Rudi
Hallo,
so erwünscht von den Users um einen besseren Überblick zu haben.
wozu, wenn nix sichtbar ist?
geht das wirklich nicht ohne riiesigen Aufwand ?
Nein.
Wobei der Aufwand das kleinere Problem ist. Dir geht die Performance so in den Keller, dass sinnvolles Arbeiten nicht mehr möglich ist. In 200 Tabellen alle Zellen zu durchsuchen dauert eben.
Gruß
Rudi

AW: Effiziente Suchfunktion für Datenbank
24.06.2014 14:43:36
Pascal
Grummel! .... dann werde ich wohl oder übel irgendwann mal unsere Datenbank sterben lassen müssen.
Die Users wünschen eine effiziente Suche für diese Datenbank

AW: Effiziente Suchfunktion für Datenbank
24.06.2014 14:57:09
Daniel
Hi
dann muss man die Datenbank vernünftig ausbauen
Sortieren hilft manchmal viel und im Sortieren ist Excel recht schnell
seit Excel 2007 hat Excel ein paar Zeilen und Spalten mehr und von daher lassen sich jetzt deutlich grössere Datenbanken im selben Tabellenblatt realisieren als früher.
Leerspalten zur strukturierung der Tabelle schaden dann nicht, wenn man zumindest die Überschriftenzeile mit einem Wert füllt.
Gruß Daniel

Anzeige
AW: Effiziente Suchfunktion für Datenbank
30.06.2014 23:00:20
Peter
gib mir mal bis morgen Zeit, ich habe das Problem schon mal gehabt
Leere Spğalten und Zeilen interessieren ich nicht die Bohne.
Die baue ich zwecks besserer Übersicht auch schon mal ein.
Wo soll da das Problem sein? dem Makro ist das völllig wurscht!
gruss Peter S.

AW: Effiziente Suchfunktion für Datenbank
24.06.2014 10:54:56
Nepumuk
Hallo,
da kann ich dir schon eins sagen, eine Live-Suche wie in einer Datenbank wird das nicht. Denn eine Suche per VBA in "unzähligen Tabellenblättern" bekommst du nicht in wenigen Millisekunden hin sondern ist eher eine Sache von Sekunden. Nach jedem eingegebenen Buchstaben wird also Excel mehrere Sekunden gelähmt sein in der es die Tabellen abklappert. Das wäre für mich als User nicht akzeptabel und die Mappe würde auf meiner Festplatte garantiert Spinnweben ansetzen.
Gruß
Nepumuk

Anzeige
gebastelt
24.06.2014 16:24:32
Rudi
Hallo,
funktioniert mit 170 Tabellen und ca. 85.000 Zellinhalten ganz gut. Nur der erste Aufruf dauert ca 4 Sek.
UF mit TextBox txtSuche und ListBox lbxFund.
In der UF:
Option Explicit
Dim arrWerte, bolCode As Boolean, sLast
Private Sub UserForm_Initialize()
sLast = txtSuche
arrWerte = DasArray
End Sub
Private Sub lbxFund_Click()
If Not bolCode Then
With lbxFund
Worksheets(.Column(0)).Activate
Range(.Column(1)).Select
End With
lbxFund.ListIndex = -1
Hide
End If
End Sub
Private Sub txtSuche_Change()
Dim i As Long, j As Integer, oTmp As Object, arrList, oT, n As Long, arrTmp
bolCode = True
If txtSuche = "" Then
lbxFund.Clear
sLast = ""
Exit Sub
End If
If sLast  "" Then
If txtSuche Like sLast & "*" Then
arrTmp = lbxFund.List
Else
arrTmp = arrWerte
End If
Else
arrTmp = arrWerte
End If
Set oTmp = CreateObject("Scripting.dictionary")
j = LBound(arrTmp, 2)
For i = LBound(arrTmp) To UBound(arrTmp)
If LCase(arrTmp(i, j + 2)) Like "*" & LCase(txtSuche) & "*" Then
oTmp(i) = Array(arrTmp(i, j), arrTmp(i, j + 1), arrTmp(i, j + 2))
End If
Next
If oTmp.Count Then
ReDim arrList(1 To oTmp.Count, 1 To 3)
For Each oT In oTmp
n = n + 1
arrList(n, 1) = oTmp(oT)(0)
arrList(n, 2) = oTmp(oT)(1)
arrList(n, 3) = oTmp(oT)(2)
Next
lbxFund.List = arrList
sLast = txtSuche
Else
lbxFund.Clear
sLast = ""
End If
bolCode = False
End Sub
Private Function DasArray()
Dim oCells As Object, wks As Worksheet, rngC As Range
Dim oKey, arrTmp, n As Long
Set oCells = CreateObject("Scripting.dictionary")
For Each wks In Worksheets
For Each rngC In wks.UsedRange.Cells
If rngC  "" Then
oCells(rngC) = rngC.Value
End If
Next
Next
ReDim arrTmp(1 To oCells.Count, 1 To 3)
For Each oKey In oCells
n = n + 1
arrTmp(n, 1) = oKey.Parent.Name
arrTmp(n, 2) = oKey.Address
arrTmp(n, 3) = oCells(oKey)
Next
DasArray = arrTmp
End Function

Und irgendwo ein Button zum Starten.
Gruß
Rudi

Anzeige
AW: gebastelt
25.06.2014 06:09:24
Pascal
Guten Morgen Rudi!
was währe der Rudi ohne einen tollen Lösungsvorschlag ? :-)
Besten Dank schon mal!!!!
werde mir den Code gleich mal rauskopieren, einbauen und mal ausgiebig austesten.
Feedback folgt dann selbstverständlich.
Grüsse:
Pascal

AW: gebastelt
25.06.2014 07:10:11
Pascal
guten Morgen lieber Rudi
Das funktioniert ja schon mal Klasse !
nun hab ich aber versucht, den Code irgendwie so anzupassen, dass mir in der Listbox statt des Worksheets (auf welchem der Suchbegriff gefunden wurde) gleich der gefundene Text angezeigt wird.
... habs bisher leider nicht fertiggebracht.
vermutlich werde ich aber bloss was kleines, am richtigen Ort ändern/einbauen müssen um zu bewirken, dass statt der Tabellenblätter auf welchem der Begriff gefunden wurde- gleich der gefundene Begriff in der Liste erscheint ?
Grüsse: Pascal

Anzeige
AW: gebastelt
25.06.2014 09:18:18
Rudi
Hallo,
in den Eigenschaften der Listbox ColumnCount auf 3 setzen und ColumnWidths auf 0;0;
Gruß
Rudi

alternativ...
25.06.2014 09:47:08
Rudi
Hallo,
die Eigenschaften im Initialize festlegen.
Private Sub UserForm_Initialize()
sLast = txtSuche
arrWerte = DasArray
With lbxFund
.ColumnCount = 3
.ColumnWidths = "0;0;"
End With
End Sub

Gruß
Rudi

AW: alternativ...
25.06.2014 10:02:38
Pascal
Hallo Rudi
... toll ! herzlichen dank !
ich werds gleich ausprobieren und wieder Feeback geben.
Gruss: Pascal

AW: alternativ...
25.06.2014 13:08:14
Pascal
hallo nochmals !
Ich versuche ... nachdem der code in der Testmappe sehr zufriedenstellend läuft ... den Code in die "scharfe" Datenbank einzufügen.
Nun hab ich folgenden Code hinter meiner Userform:
Private Sub TextBox1_Change()
Dim i As Long, j As Integer, oTmp As Object, arrList, oT, n As Long, arrTmp
'Workbooks(Workbookname_WDB).Activate
bolCode = True
If Frm_Zielsuche.TextBox1 = "" Then
Frm_Zielsuche.ListBox1.Clear
sLast = ""
Exit Sub
End If
If sLast  "" Then
If Frm_Zielsuche.TextBox1 Like sLast & "*" Then
arrTmp = Frm_Zielsuche.ListBox1.List
Else
arrTmp = arrWerte
End If
Else
arrTmp = arrWerte
End If
Set oTmp = CreateObject("Scripting.dictionary")
j = LBound(arrTmp, 2)
For i = LBound(arrTmp) To UBound(arrTmp)
If LCase(arrTmp(i, j + 2)) Like "*" & LCase(Frm_Zielsuche.TextBox1) & "*" Then
oTmp(i) = Array(arrTmp(i, j), arrTmp(i, j + 1), arrTmp(i, j + 2))
End If
Next
If oTmp.Count Then
ReDim arrList(1 To oTmp.Count, 1 To 3)
For Each oT In oTmp
n = n + 1
arrList(n, 1) = oTmp(oT)(0)
arrList(n, 2) = oTmp(oT)(1)
arrList(n, 3) = oTmp(oT)(2)
Next
Frm_Zielsuche.ListBox1.List = arrList
sLast = Frm_Zielsuche.TextBox1
Else
Frm_Zielsuche.ListBox1.Clear
sLast = ""
End If
bolCode = False
End Sub

Egal was ich tue... sobald ich einen Buchstaben in das Feld TextBox1 setze, so erhalte ich einen Laufzeitfehler 13 - Typen unverträglich bei der Zeile:
j = LBound(arrTmp, 2)
Was mach ich falsch ?

Anzeige
AW: alternativ...
25.06.2014 20:27:04
Mullit
Hallo,
den Fehler erhalte ich auch, wenn ich die Hälfte vom Code weglasse;
Du mußt schon alles einfügen.
Außerdem brauchst Du den Namen der Form nicht im Code ergänzen,
die Objecte beziehen sich ja bereits auf die sie enthaltene Klasse:
Option Explicit
      Dim arrWerte, bolCode As Boolean, sLast
      
      Private Sub UserForm_Initialize()
        sLast = txtSuche
        arrWerte = DasArray
        With lbxFund
            .ColumnCount = 3
            .ColumnWidths = "0;0;"
        End With
      End Sub
      
      Private Sub lbxFund_Click()
        If Not bolCode Then
          With lbxFund
            Worksheets(.Column(0)).Activate
            Range(.Column(1)).Select
          End With
          lbxFund.ListIndex = -1
          Hide
        End If
      End Sub
      
      Private Sub txtSuche_Change()
        Dim i As Long, j As Integer, oTmp As Object, arrList, oT, n As Long, arrTmp
        bolCode = True
        If txtSuche = "" Then
          lbxFund.Clear
          sLast = ""
          Exit Sub
        End If
        If sLast <> "" Then
          If txtSuche Like sLast & "*" Then
            arrTmp = lbxFund.List
          Else
            arrTmp = arrWerte
          End If
        Else
          arrTmp = arrWerte
        End If
        Set oTmp = CreateObject("Scripting.dictionary")
        j = LBound(arrTmp, 2)
        For i = LBound(arrTmp) To UBound(arrTmp)
          If LCase(arrTmp(i, j + 2)) Like "*" & LCase(txtSuche) & "*" Then
            oTmp(i) = Array(arrTmp(i, j), arrTmp(i, j + 1), arrTmp(i, j + 2))
          End If
        Next
        If oTmp.Count Then
          ReDim arrList(1 To oTmp.Count, 1 To 3)
          For Each oT In oTmp
            n = n + 1
            arrList(n, 1) = oTmp(oT)(0)
            arrList(n, 2) = oTmp(oT)(1)
            arrList(n, 3) = oTmp(oT)(2)
          Next
          lbxFund.List = arrList
          sLast = txtSuche
        Else
          lbxFund.Clear
          sLast = ""
        End If
        bolCode = False
      End Sub
      
      Private Function DasArray()
        Dim oCells As Object, wks As Worksheet, rngC As Range
        Dim oKey, arrTmp, n As Long
        Set oCells = CreateObject("Scripting.dictionary")
        For Each wks In Worksheets
          For Each rngC In wks.UsedRange.Cells
            If rngC <> "" Then
              oCells(rngC) = rngC.Value
            End If
          Next
        Next
        ReDim arrTmp(1 To oCells.Count, 1 To 3)
        For Each oKey In oCells
          n = n + 1
          arrTmp(n, 1) = oKey.Parent.Name
          arrTmp(n, 2) = oKey.Address
          arrTmp(n, 3) = oCells(oKey)
        Next
        DasArray = arrTmp
      End Function


Übrigens klasse gemacht von Rudi...!
Gruß,

Anzeige
AW: alternativ...
26.06.2014 07:01:25
Pascal
Guten Tag allerseits
wie auch immer ich es versuche... ich krieg den tollen Code von Rudi nicht in meiner "scharfen" Datenbank zum laufen :-(
Ständig Fehlermeldung
Laufzeitfehler 13 - Typen unverträglich bei der Zeile:
j = LBound(arrTmp, 2)
vielleicht muss ich folgendes erwähnen:
Ich habe natürlich in meiner "scharfen" Datenbank bereits eine relativ aufwendige Userform mit diversen weiteren Feldern, Textboxen, Optionbuttons, etc....
Diese UserForm heisst bei mir Frm_Zielsuche
auf dieser Zielsuche hab ich jetzt mal meine bestehende Listbox1 rausgelöscht und durch eine Listbox mit Namen lbxFund ersetzt.
Ebenso hab ich auf meiner Userform Frm_Zielsuche das bereits bestehende Textfeld rausgelöscht und durch ein Feld mit Namen txtSuche ersetzt.
Den ganzen Code von Rudi hab ich natürlich entsprechend hinter die richtigen Teile meines bereits bestehenden Codes kopiert.
Für mich stellt sich die Frage:
wo genau kommt die Variablen-Deklaration rein ?
in den Allgemeinen Teil oder wo genau ?
Wenn ich dann (nachdem ich alle Code-Teile von Rudi in den bestehenden Code implementiert hab) im txtSuche was reinschreibe so bricht das Teil sofort ab mit Fehler
Laufzeitfehler 13 - Typen unverträglich bei der Zeile:
j = LBound(arrTmp, 2)
Was mach ich falsch ?

AW: alternativ...
26.06.2014 10:26:54
Rudi
Hallo,
setz dir mal einen Haltepunkt vor
If sLast "" Then
geh den Code mit F8 durch und schau nach was passiert.
Gruß
Rudi

AW: alternativ...
26.06.2014 12:25:52
Pascal
Hallo Rudi
werde das mal probieren.
hab jetzt mal eine neue Userform mit exakt Deinem Code in die Datenbank eingefügt.
so läufts !
jetzt gilt es, Die Felder dieser Userform auf meine bestehende Userform zu zügeln.
Ob das geht ?
Meine Userform hat schon unzählige Buttons, Befehle etc... drauf und logischerweise auch schon ne Menge Code.
Jetzt heisst es, Deinen code an die richtige Stelle einzubauen.
Ob das gelingt ?
... ich werde Feedback geben.

AW: alternativ...
27.06.2014 11:29:53
Pascal
Hallo miteinander
Endlich hab ich den sensationellen Code von Rudi auch in meiner "scharfen" Datenbank korrekt zum laufen gebracht und implementieren können.
Nun ... wie könnte es ander sein ? ... dazu gleich eine kleine Ergänzungsfrage:
Kann ich den code so anpassen, dass mir zwar die ganze Datenbank durchsucht wird, aber auf den einzelnen Tabellenblättern jeweils nur in ganz bestimmten Spalten gesucht wird ?
Beispiel:
es soll immer nur Spalte A; F; H; L; nach dem Begriff durchsucht werden.
Geht das irgendwie ?
HERZLICHEN DANK für die Hilfe

Nur A, F, H, L
27.06.2014 12:13:49
Rudi
Hallo,
mal ganz einfach:
Private Function DasArray()
Dim oCells As Object, wks As Worksheet, rngC As Range
Dim oKey, arrTmp, n As Long
Set oCells = CreateObject("Scripting.dictionary")
For Each wks In Worksheets
For Each rngC In wks.UsedRange.Cells
If rngC  "" Then
        Select Case rngC.Column
Case 1, 6, 8, 12: oCells(rngC) = rngC.Value
End Select
End If
Next
Next
ReDim arrTmp(1 To oCells.Count, 1 To 3)
For Each oKey In oCells
n = n + 1
arrTmp(n, 1) = oCells(oKey)
arrTmp(n, 2) = oKey.Parent.Name
arrTmp(n, 3) = oKey.Address
Next
DasArray = arrTmp
End Function

Gruß
Rudi

AW: Nur A, F, H, L: Korrektur
27.06.2014 12:20:58
Rudi
Hallo,
Die Function stammt aus einer weiter entwickelten Version, in der das Array anders belegt ist.
Für deine Version:
Private Function DasArray()
Dim oCells As Object, wks As Worksheet, rngC As Range
Dim oKey, arrTmp, n As Long
Set oCells = CreateObject("Scripting.dictionary")
For Each wks In Worksheets
For Each rngC In wks.UsedRange.Cells
If rngC  "" Then
Select Case rngC.Column
Case 1, 6, 8, 12: oCells(rngC) = rngC.Value
End Select
End If
Next
Next
ReDim arrTmp(1 To oCells.Count, 1 To 3)
For Each oKey In oCells
n = n + 1
arrTmp(n, 1) = oKey.Parent.Name
arrTmp(n, 2) = oKey.Address
arrTmp(n, 3) = oCells(oKey)
Next
DasArray = arrTmp
End Function

Gruß
Rudi

AW: Nur A, F, H, L: Korrektur
27.06.2014 12:39:51
Pascal
Hallo Rudi !
Du weisst gar nicht wie sehr dankbar ich Dir bin. Woher nimmtst du nun all dieses Know-How ?
ich wünschte, ich hätte ein auch soo grosses VBA Wissen.
Werde das gleich mal testen und ... Feeback folgt
Pascal

Links zu Excel-Dialogen

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige