| U bevindt zich > Oude forum > Visual Basic 6.0 > Databases ... (VB 6.0) > Zoekfunctie middels TextBox (.MDB) |
| Gepost door Hydra gepost op 04/04/2005 om 09:44 |
Hi,
Bij het laden van mijn formulier wordt er connectie gemaakt met een AccesDB. Deze gegevens worden gelijk in een ComboBox geladen. Met een paar 1000 records is dat erg goed te doen, zonder zichtbare vertraging op te lopen.
Maar nu hebben we het over 611.711 records. Das niet mis..!!! Het probleem zit hem niet in de connectie, maar dat het ruim 30 seconden duurt voordat alles is geladen. Dus moet er een andere oplossing komen.
Zelf dacht ik dit op te kunnen lossen door gebruik te gaan maken van een TextBox, maar ik kom er niet uit. Wellicht veel gevraagd, maar hebben jullie een eventuele oplossing met code? |
| Gepost door Mibe gepost op 04/04/2005 om 09:55 |
Hmm, zelf zou ik dit doen met een Ado controller en de combobox daaraan linken met de gepaste methode.
Op welke manier werkt u nu? Waarschijnlijk met een code en een lus? |
| Gepost door malloc gepost op 04/04/2005 om 09:59 |
Hallo,
Zoveel records in een combobox, daar is de gebruiker niets mee. Je moet
niet alle data laden, maar slechts het deel dat je nodig hebt.
Als de gebruiker iets moet kunnen selecteren uit die meer dan 600.000
records dan kan je hem misschien eerst een andere selectie laten maken
zodat je een iets meer gefilterde recordset kan opbouwen om je combobox
te vullen.
Groeten,
|
| Gepost door Hydra gepost op 04/04/2005 om 10:01 |
Bedankt voor de reply mibe, maar zoals ik al aan heb gegeven duurt het laden veel te lang in een combobox. Onderstaand de code die ik gebruik voor het laden en verwerking naar de ListBox.
Code:
| Option Explicit
Dim cn As New ADODb.Connection Dim rs As New ADODb.Recordset Dim strPlaats As String
Private Sub Form_Load()
Set cn = New ADODb.Connection
With cn .Provider = "Microsoft.Jet.OLEDB.4.0" .ConnectionString = _ "Data Source = C:Program FilesR.A.D. 2005 3rd EditionDatabasesPostcodepTabel.mdb;" _ & "Persist Security Info = False" .Open End With
Set rs = New ADODb.Recordset
With rs .ActiveConnection = cn .CursorLocation = adUseServer .CursorType = adOpenDynamic .Source = "POSTCODETABEL" .Open End With
strPlaats = "|"
Do Until rs.EOF If InStr(1, strPlaats, "|" & rs!Plaats & "|") = 0 Then Combo1.AddItem rs!Plaats strPlaats = strPlaats & rs!Plaats & "|" End If rs.MoveNext Loop rs.Close Set rs = Nothing End Sub |
Code:
| Private Sub Combo1_Click()
List1.Clear
Set rs = New ADODb.Recordset
rs.Open "SELECT * FROM POSTCODETABEL where PLAATS = '" & Combo1.Text & "'", cn, adOpenDynamic, adLockReadOnly
If Not rs.EOF Then rs.MoveFirst Do While Not rs.EOF List1.AddItem rs!Straat rs.MoveNext Loop End If End Sub | |
| Gepost door Hydra gepost op 04/04/2005 om 10:04 |
Ha die Malloc,
De manier die jij voor stelt had ik ook al in gedachte, maar zou niet weten hoe dat te doen. Vandaar mijn gedachte uit ging naar een textbox. Pas bij het wijzigen van de TextBox naar het gedeelte gaan van de eerste letter in de TextBox (Als je begrijpt wat ik bedoel) |
| Gepost door Mibe gepost op 04/04/2005 om 10:04 |
malloc zei:
Zoveel records in een combobox, daar is de gebruiker niets mee. Je moet niet alle data laden, maar slechts het deel dat je nodig hebt. |
Ben ik volledig mee eens .
Maar mocht het u toch nodig zijn, ik zou probern met ene datacontroller (ado controller). Deze zal de database volledig meeladen en de gegevens outputten in een datagrid of in uw geval, een combobox dmv Datafield en datasource eigenschappen. Veel meer kan ik u niet over vertellen, want zelf werk ik ook altijd met uw methode. |
| Gepost door Mibe gepost op 04/04/2005 om 10:06 |
Hydra, het systeem u aanbrengt zal ook veel traffic veroorzaken, want zoiets is ook met combobox, maar gewoon andere eigenschap...
Wat Malloc wil zeggen: Eerst vb een gemeente kiezen, dan straat, dan klant... in die aard voor sorteren en selecteren |
| Gepost door Hydra gepost op 04/04/2005 om 10:06 |
| Das jammer Mibe, maar ondanks dat bedankt voor de reply's. |
| Gepost door Hydra gepost op 04/04/2005 om 10:09 |
| Mibe, wat jij voor stelt gebeurd namelijk al. Alleen heb ik de Gemeente niet tot mijn beschikking. De mensen typen een woonplaats in die wordt gefilterd. Dus de combo wodt niet gevuld met dubbele namen. Na de Combo_Click Event worden de gegevens in een ListBox gevuld. De vertraging zit hem overigens niet in de filter, daardoor werkt het vullen zelfs 2 keer zo snel. |
| Gepost door Mibe gepost op 04/04/2005 om 10:14 |
| Das dan na die inlading van 611.000 records? Wanneer worden die records precies ingeladen, en welke gegevens bevatten deze precies? |
| Gepost door malloc gepost op 04/04/2005 om 10:29 |
Hydra zei:
Code:
With rs .ActiveConnection = cn .CursorLocation = adUseServer .CursorType = adOpenDynamic .Source = "POSTCODETABEL" .Open End With
strPlaats = "|"
Do Until rs.EOF If InStr(1, strPlaats, "|" & rs!Plaats & "|") = 0 Then Combo1.AddItem rs!Plaats strPlaats = strPlaats & rs!Plaats & "|" End If rs.MoveNext Loop rs.Close Set rs = Nothing End Sub | |
Als ik het goed voorheb is het de bedoeling enkel unieke gemeenten toe te voegen aan de combobox.
Dit kan beter. In plaats van zelf te kijken of de gemeente al is
toegevoegd vraag je aan de database enkel unieke gemeenten. Dit gaat
sneller.
Zoiets als:Code:
| SELECT DISTINCT Plaats FROM POSTCODETABEL; |
|
| Gepost door Hydra gepost op 04/04/2005 om 10:40 |
Zoals Malloc opmerkt, is het de bedoeling dat alleen maar unieke gegevens worden geladen. Na keuze van de plaatsnaam worden alle straatnamen, betreffende plaatst, weggeschreven naar ListBox1.
Het "probleem" is dat het laden gelijk bij het openen van het bestand gebeurd.
Wat bedoel je precies Malloc? Door de code van jouw worden ook alleen maar unieke eigenschappen geladen? (Volgens mij gaat dat alleen maar gebeuren als de DataBase op volgorde is met jouw code, maar dat weet ik niet zeker.)
Voorbeeldje? |
| Gepost door malloc gepost op 04/04/2005 om 10:49 |
Code:
rs.open "SELECT DISTINCT Plaats FROM POSTCODETABEL", cn, adOpenForwardOnly, adReadOnly
Do until rs.eof
combo1.additem rs[Plaats]
rs.MoveNext
loop
rs.Close Set rs = Nothing |
Deze code
haalt de unieke plaatsen uit de tabel door de DISTINCT clausule. De
tabel moet niet gesorteerd zijn. (waarschijnlijk gaat het nog sneller
als je in de database een index maakt op het veld plaats.) Door de
recordset te openen met adOpenForwardOnly en adReadOnly zou het nog
sneller moeten gaan dacht ik.
Je doet daarna ongeveer hetzelfde voor het laden van unieke straatnamen.
|
| Gepost door Hydra gepost op 04/04/2005 om 11:03 |
Hé Malloc,
Ik kan wel huilen van blijdschap. Door dat stukje code van jouw zie je helemaal geen vertraging Wordt wordt echt SUPERSNEL geladen. Als ik een pet op had, dan had ik deze NU voor je afgezet. Proficiat!!!  |
| Gepost door malloc gepost op 04/04/2005 om 11:12 |
Graag gedaan!
|
| Gepost door Hydra gepost op 04/04/2005 om 11:27 |
Wellicht leuk voor een ander om een Postcodeboek te maken. Dit is de volledige code om snel en makkelijk een dergelijk iets te maken. Wellicht leuk om ook even naar dit topic te verwijzen in een eventuele dank. 
Ingrediënten:
- 1 ComboBox
- 1 ListBox
- 1 Label
- Acces Database
o Veldnaam PLAATS (Geïndexeerd)
o Veldnaam STRAAT
o Veldnaam POSTCODE
Plaats onderstaande code volledig in het formulier:
Code:
| Option Explicit
Dim cn As New ADODb.Connection Dim rs As New ADODb.Recordset
Private Sub Form_Load()
Set cn = New ADODb.Connection
With cn .Provider = "Microsoft.Jet.OLEDB.4.0" .ConnectionString = _ "Data Source = C:pTabel.mdb;" _ 'naam van tabel & "Persist Security Info = False" .Open End With
Set rs = New ADODb.Recordset
rs.Open "SELECT DISTINCT Plaats FROM POSTCODETABEL", cn, adOpenForwardOnly, adLockReadOnly
Do Until rs.EOF Combo1.AddItem rs!Plaats rs.MoveNext Loop rs.Close Set rs = Nothing End Sub
Private Sub Combo1_Click()
List1.Clear
Set rs = New ADODb.Recordset
rs.Open "SELECT * FROM POSTCODETABEL where PLAATS = '" & Combo1.Text & "'", cn, adOpenDynamic, adLockReadOnly
If Not rs.EOF Then rs.MoveFirst Do While Not rs.EOF List1.AddItem rs!Straat 'naam van veld in de tabel rs.MoveNext Loop End If End Sub
Private Sub Combo1_KeyPress(KeyAscii As Integer) Select Case KeyAscii Case 8, 32, 65 To 90 Case 97 To 122 KeyAscii = Asc(LCase(Chr(KeyAscii))) Case 13 Call Combo1_Click Case Else KeyAscii = 0 End Select End Sub
Private Sub Combo1_Change() If Combo1.Text = "" Or Empty Then List1.Clear lblPostcode.Caption = "" End If End Sub
Private Sub Combo1_KeyUp(Keycode As Integer, Shift As Integer) Dim i As Integer Dim OriginalTextLength As Integer If Keycode = 8 Or Keycode = 16 Or Keycode = 36 Or Keycode = 46 Or Keycode = 48 Or Combo1.Text = "" Then Exit Sub For i = 0 To Combo1.ListCount - 1 If LCase(Combo1.Text) = LCase(Left(Combo1.List(i), Len(Combo1.Text))) Then OriginalTextLength = Len(Combo1.Text) Combo1.Text = Combo1.List(i) Combo1.SelStart = OriginalTextLength Combo1.SelLength = Len(Combo1.Text) - OriginalTextLength Exit For End If Next i End Sub
Private Sub List1_Click() Set rs = New ADODb.Recordset rs.Open "SELECT * FROM POSTCODETABEL where STRAAT = '" & List1.Text & "'", cn, adOpenDynamic, adLockReadOnly If Not rs.EOF And Not rs.BOF Then lblPostcode.Caption = rs.Fields("POSTCODE").Value End Sub
Private Sub mNieuw_Click() Combo1.Text = Empty Combo1.SetFocus End Sub
Private Sub mSluiten_Click() Unload Me End Sub | |
| Gepost door Hydra gepost op 04/04/2005 om 11:50 |

Even een screenshot van mijn proggy..  |
| Gepost door Mibe gepost op 06/04/2005 om 10:43 |
Beste Hydra,
Ik heb uw code bij de VBIB Faq's gestoken op
http://faqvbib.mibenet.be/goto.php?id=22
Met dank ;-) |
| Gepost door Hydra gepost op 06/04/2005 om 10:57 |
| Hallo Mibe. Das natuurlijk een hele goeie oplossing. Bedankt namens iedereen. |
| Gepost door Hydra gepost op 06/04/2005 om 12:29 |
| Hé mibe... Nog even een kleine aanpassing in de code. Aangezien het forumlier een ander formulier is dan waar ik mee opstart heb ik bij de Event "Private Sub mSluiten_Click()" Unload Me gezet. Zou u daar op uw forum wel End van willen maken? |