Office Forum
www.Office-Loesung.de
Access :: Excel :: Outlook :: PowerPoint :: Word :: Office :: Wieder Online ---> provisorisches Office Forum <-
Formularsuche mit ADO
zurück: Listenfelder gruppieren weiter: RecordsetViewer - Anzeige von Recordsets beim Debuggen Unbeantwortete Beiträge anzeigen
Neues Thema eröffnen   Neue Antwort erstellen     Status: Tutorial Facebook-Likes Diese Seite Freunden empfehlen
Zu Browser-Favoriten hinzufügen
Autor Nachricht
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
02. Sep 2009, 18:50
Rufname:

Formularsuche mit ADO - Formularsuche mit ADO

Nach oben
       Version: Office 2007

Hallo zusammen,

das Thema "Suche" ist ja schon sicherlich häufig genug besprochen, die allgemeine Methode in einer Standard-Access-Datenbank ist DAO unter Verwendung von Bookmarks.

Eine ähnliche Methode funktioniert mit ADO (auch das nichts Neues):
Code:
    Dim rs As ADODB.Recordset
   
    Set rs = frm.RecordsetClone
    If Not (rs.BOF And rs.EOF) Then
        rs.MoveFirst
        rs.Find "IDFeld=123"
        If Not rs.EOF Then
            frm.Bookmark = rs.Bookmark
        End If
    End If
    rs.Close
    Set rs = Nothing
(frm ist eine Form mit einem ADO Recordset)

So wird es im Allgemeinen empfohlen - es geht jedoch auch mit einem einfachen Zweizeiler:
Code:
    frm.Requery
    frm.Recordset.Find "IDFeld=123"
Wenn man das ganze jedoch in einem Formular versucht, daß per ADO an eine Datenquelle gebunden ist (wie in Access Projekten im Allgemeinen üblich ist), wird man feststellen, daß beide Methoden nicht richtig funktionieren. Mal geht es, mal nicht, eine Ursache ist scheinbar nicht festzustellen.

Die Schwierigkeit ist, daß VBA hier bei großen Datenmengen, die in das Formular geladen werden, schlicht schneller ist als das Laden der Daten. Hat man also mit "Requery" ein Neuladen angestoßen und versucht danach sofort, per Find-Methode einen Datensatz zu finden (wie gesagt, egal mit welcher der Methoden oben), ist im Hintergrund noch das Laden der Daten in das Formular aktiv, der Find-Befehl findet dann u.U. nichts (wenn die betreffenden Daten eben noch nicht im Formular sind).

Da es im ADO Recordset aber einen Status gibt, kann man abfragen, ob das Laden der Daten schon erfolgt ist und dann geht auch die Suche in beiden Fällen wieder. Man muß VBA einfach ein bißchen warten lassen:
Code:
    frm.Requery
    Do While (frm.Recordset.State And adStateFetching) = adStateFetching
    Loop
    frm.Recordset.Find "IDField=123"
Die Schleife wartet nun solange, bis alle Daten geladen sind. Das Ausfiltern mit "And" dient dazu, nur den Fetching-Status auszulesen.

So ist es dann auch egal, wieviele Daten geladen werden, das Find funktioniert nun jedesmal.

Hier das ganze als Universalfunktion, die in jedem (ADO basierenden) Formular funktioniert, das eine ID als Primary Key verwendet:
Code:
Public Sub refreshForm(frm As Form, lngID As Long, strIDField As String)
On Error GoTo refreshForm_Error
    frm.Requery
    Do While (frm.Recordset.State And adStateFetching) = adStateFetching
    Loop
    frm.Recordset.Find strIDField & "=" & lngID
refreshForm_Exit:
    Exit Sub
refreshForm_Error:
    Select Case Err
      Case 2501, 2001 ' User canceled previous operation
        Resume refreshForm_Exit
      Case Else
        fnErr "modUtilities->refreshForm", True
        Resume refreshForm_Exit
    End Select
End Sub
Hat man zum Beispiel einen Refresh-Button im Formular, kann man hier hinterlegen:
Code:
    refreshForm Me, Me!IDFeld, "IDFeld"
Wenn man die Funktion für DAO basierende Formulare verwenden möchte, geht es auf diese Weise (der Aufruf ist identisch):
Code:
    frm.Requery
    frm.Recordset.FindFirst strIDField & "=" & lngID
Hier ist die Schleife nicht notwendig, VBA wird erst nach fertigem Requery wieder weiter ausgeführt.

Beides getestet mit einem Formular, das rd. 32000 Datensätze anzeigt.

Ist mit Office 2007 getestet, sollte aber auch in den meisten älteren Versionen identisch sein.

Viel Spaß beim Ausprobieren...Smile

Gruß

Christian
Bitsqueezer
Office-VBA-Programmierer


Verfasst am:
01. Okt 2009, 16:34
Rufname:


AW: Formularsuche mit ADO - AW: Formularsuche mit ADO

Nach oben
       Version: Office 2007

Hallo zusammen,

offenbar gibt es dabei Unterschiede zwischen der Access Vollversion und der Runtime: Die Access Runtime bleibt in der Do-While-Schleife endlos hängen, ein Test ergab, daß der Status "Fetching" zwar gesetzt, aber anscheinend nicht mehr entfernt wird. Im Test hat es mehr als 6 Minuten gebraucht, bis die Schleife wieder verlassen wurde. In der Vollversion von Access benötigt die Funktion weniger als eine Sekunde.

Die folgende Variante aktualisiert eine Form auf Basis der RecordCount-Eigenschaft: Während die Daten erneut heruntergeladen werden, ist RecordCount kleiner als die eigentlich maximale Anzahl Daten. Mit einem kontinuierlichen "MoveLast" wird so lange ans Ende gesprungen, bis sich der Wert der RecordCount-Eigenschaft nicht mehr ändert oder der gespeicherte Bookmark-Wert (der einfach die Datensatznummer in der Liste wiedergibt) kleiner oder gleich der geladenen Liste ist.

Diese Version benötigt auch nur den Parameter der Form (wobei bei Verwendung von Unterformularen das Unterformular übergeben werden muß, das aktualisiert werden soll).

Getestet mit einem Access Projekt unter Access 2007 in der Vollversion und Runtime mit einem Formular, das rund 99000 Datensätze anzeigt und damit zum Laden aller Datensätze bisweilen ein paar Sekunden länger braucht.

Code:
Public Sub refreshForm(frm As Form)
    Dim varBookmark As Variant
    Dim lngCurrentRecordCount As Long
   
   On Error GoTo refreshForm_Error
     
    Application.Echo False
   
    ' Hier kein "With" benutzen, da sonst die Unterobjekte von frm nicht funktionieren
    varBookmark = frm.Recordset.Bookmark
    frm.Refresh
   
    If Not (frm.Recordset.BOF And frm.Recordset.EOF) Then
        Do
           lngCurrentRecordCount = frm.Recordset.RecordCount
           Debug.Print lngCurrentRecordCount
           frm.Recordset.MoveLast
        Loop Until lngCurrentRecordCount = frm.Recordset.RecordCount Or _
                   CLng(varBookmark) <= frm.Recordset.RecordCount
        frm.Recordset.Bookmark = varBookmark
    End If

refreshForm_Exit:
    Application.Echo True
    Exit Sub

refreshForm_Error:
    Application.Echo True
    Select Case Err
        Case -2147217906    ' Bookmark is invalid
            Resume refreshForm_Exit
        Case 2501, 2001 ' User canceled previous operation
            Resume refreshForm_Exit
        Case -2147417848  ' Automation error, object has diconnected from its clients
            Resume refreshForm_Exit
        Case Else
            fnErr "modUtilities->refreshForm", True
            Resume refreshForm_Exit
    End Select

End Sub


(fnErr zeigt eine Fehlermeldung per MsgBox.)

Gruß

Christian
Neues Thema eröffnen   Neue Antwort erstellen Alle Zeiten sind
GMT + 1 Stunde

Diese Seite Freunden empfehlen

Seite 1 von 1
Gehe zu:  
Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum nicht posten
Du kannst Dateien in diesem Forum herunterladen

Verwandte Themen
Forum / Themen   Antworten   Autor   Aufrufe   Letzter Beitrag 
Keine neuen Beiträge Access Formulare: Formular mit ADO Recordset - Filtern und Sortieren 0 grelf111 221 14. Aug 2013, 12:46
grelf111 Formular mit ADO Recordset - Filtern und Sortieren
Keine neuen Beiträge Access Formulare: Formularsuche die II 18 elvira.r 497 09. Jul 2012, 14:15
kyron9000 Formularsuche die II
Keine neuen Beiträge Access Programmierung / VBA: Tabellen verknüpfen per ADO über ODBC 8 Manuel_ 3660 14. Okt 2009, 16:28
Manuel_ Tabellen verknüpfen per ADO über ODBC
Keine neuen Beiträge Access Programmierung / VBA: Grundsätzliche Tipps zu Umstellung DAO -> ADO 22 Speed Pete 4689 07. Okt 2009, 19:44
Bitsqueezer Grundsätzliche Tipps zu Umstellung DAO -> ADO
Keine neuen Beiträge Access Programmierung / VBA: Access2003: ADO - RecordCount 6 Thomas79 1613 02. Jul 2009, 10:02
Thomas79 Access2003: ADO - RecordCount
Keine neuen Beiträge Access Programmierung / VBA: SEEK mit ADO 5 Gast 1623 22. Dez 2008, 21:32
Nouba SEEK mit ADO
Keine neuen Beiträge Access Programmierung / VBA: Insert vs. DAO / ADO 8 wm_andi 1306 15. Dez 2008, 11:32
wm_andi Insert vs. DAO / ADO
Keine neuen Beiträge Access Programmierung / VBA: ADO Recordset geht nicht mit For-Next 7 Toadie 2426 31. März 2008, 15:56
Toadie ADO Recordset geht nicht mit For-Next
Keine neuen Beiträge Access Programmierung / VBA: DAO in ADO 4 yen 501 10. März 2008, 12:13
Gast DAO in ADO
Keine neuen Beiträge Access Programmierung / VBA: Access anbindung an mysql über ADO 0 ***SnEaKeR*** 1310 16. Jul 2007, 16:48
***SnEaKeR*** Access anbindung an mysql über ADO
Keine neuen Beiträge Access Programmierung / VBA: Problem mit ADO - Aktualisierung der Abfrage Fehler 3265 11 ozonHans 1907 10. Jul 2007, 16:06
rita2008 Problem mit ADO - Aktualisierung der Abfrage Fehler 3265
Keine neuen Beiträge Access Programmierung / VBA: ADO OLEDB anstatt ODBC Treiber 5 sofa1969 8990 23. Jan 2007, 17:37
Willi Wipp ADO OLEDB anstatt ODBC Treiber
 

----> Diese Seite Freunden empfehlen <------ Impressum - Besuchen Sie auch: Microsoft Excel-Formeln