Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

RecordCount bei ADODB

Forumthread: RecordCount bei ADODB

RecordCount bei ADODB
05.09.2016 12:01:33
Hendrik
Hallo zusammen,
ein Makro macht automatisiert SQL-Abfragen. Hier ein Codeschnipsel dazu:

strConnectionString = "Provider=MSDASQL.1;Driver=SQL Server;Server=" & strServer & ";Database="  _
_
& strDatenbank & ";Trusted_Connection=Yes"
Set objConn = New ADODB.Connection
objConn.CommandTimeout = glIntTimeout
objConn.ConnectionString = strConnectionString
objConn.Open
Set objRec = New ADODB.Recordset
objRec.Open strSql, objConn, adOpenStatic
If objRec.RecordCount > 0 Then
If objRec.RecordCount > glIntMaxFehler Then
lngDatensatz = glIntMaxFehler
Else
lngDatensatz = objRec.RecordCount
End If
ReDim glStrArr(lngDatensatz - 1, objRec.Fields.Count - 1)
objRec.MoveFirst
For i = 0 To lngDatensatz - 1
For j = 0 To objRec.Fields.Count - 1
If Not IsNull(objRec(j)) Then
glStrArr(i, j) = objRec(j)
Else
glStrArr(i, j) = "{NULL}"
End If
Next j
objRec.MoveNext
Next i
End If

Da das SQL eigentlich recht schnell ausgeführt ist, wenn ich es manuell in einem anderen Tool absetze, habe ich die Stelle debugt und herausgefunden, dass fast 30 Sekunden vergehen, bis ich die Antwort auf "If objRec.RecordCount > 0" bekomme. Kann es sein, dass der alle (in diesem Fall 250.000) Sätze einzeln zählt? Habt Ihr hier Verbesserungsvorschläge?
Danke und Grüße
Anzeige

10
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: RecordCount bei ADODB
05.09.2016 12:16:13
Luschi
Hallo Hendrik,
nach dem Erstellen des Recordsets gibt es keine vernünftoge Aussage, wieviele Datensätze im Recordset vorhanden sind.
Deshalb muß erst zum letzen DS (objRec.MoveLast) gesprungen werden und dann die Anzahl der DS ermittelt werden.
Gruß von luschi
aus klein-öParis
AW: RecordCount bei ADODB
05.09.2016 12:32:39
Hendrik
Hallo luschi,
danke für die Info. Du siehst also keine Optimierungsmöglichkeit?
Anzeige
AW: RecordCount bei ADODB
05.09.2016 12:19:43
EtoPHG
Hallo Hendrik,
Zitat: wenn ich es manuell in einem anderen Tool absetze,
heisst noch lange nicht, dass dir das andere Tool den Recordcount bereits zurückgeben könne. So arbeiten viele Tools mit einem 'Paging'-Verfahren, dass z.B. immer nur eine bestimmte Anzahl Rows (z.B. 100) zurückliefern. Bei ADODB (bzw. ODBC) muss der gesamte RowSet zur Verfügung stehen, damit der Count abgefragt werden kann und bei 1/4 Mio Rows finde ich 30 Sec. nicht sehr langsam!
Wenn du nur den Count willst, dann modifizere deinen SQL dahingehend.
Gruess Hansueli
Anzeige
AW: RecordCount bei ADODB
05.09.2016 13:04:23
Hendrik
Nein, ich möchte nicht nur die Anzahl haben. Meine Verwunderung war nur dahingehend, dass das eigentliche Abfrageergebnis schneller da ist, als die Weiterverarbeitung (also hier das Zählen) dauert.
AW: RecordCount bei ADODB
05.09.2016 13:22:17
EtoPHG
Hallo Hendrik,
Nochmals: das eigentlich Abfrageergebnis sind deine 250'000 Rows und nicht das, was du in deinem Tool als erstes angezeigt bekommst (z.B. 100 Rows), bewege dich doch mal ein deinem Tool an das Ende des Rowsets. Geht das auch blitzschnell?
...und nein eine Optimierungsmethode sehe ich nicht und wenn dann nur im SQL als solches, aber den sehe ich nicht und zudem nicht, wie deine DB-Table(s) aufgebaut sind (z.B. Indices).
Gruess Hansueli
Anzeige
AW: RecordCount bei ADODB
05.09.2016 13:43:29
snb
Versuch mal:
Sub Access_query_snb()
With CreateObject("ADODB.recordset")
.Open "SELECT * FROM Q_test", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=G:\Access\fiets. _
mdb"
MsgBox "recordcount:  " & UBound(.GetRows, 2) + 1
End With
End Sub

AW: RecordCount bei ADODB
05.09.2016 23:17:10
Hendrik
Um die genaue Anzahl der Sätze geht es ja gar nicht. Mir würde ja die Info reichen, ob die Abfrage funktioniert hat und ob es überhaupt Datensätze gibt.
Ja, die Abfrage geht sehr viel schneller, alsdas spätere Zählen.
Grüße
Anzeige
AW: RecordCount bei ADODB
06.09.2016 10:20:06
EtoPHG
Hallo Hendrik,
Schliesse doch bitte diese Diskussion. In meinen Augen ist sie komplett fruchtlos, da du nicht begreifst, wie eine SQL-Abfrage funktioniert, bzw. was ein DBMS aufgrund einer Solchen durchführen muss. Deine Aussage: Ja, die Abfrage geht sehr viel schneller, alsdas spätere Zählen. ist z.B. völlig unverständlich, da nicht klar ist, auf welche Abfrage du dich beziehst und was du mit späterem Zählen meinst. Wenn eine Abfrage nicht funktioniert, wie du dich auszudrücken pflegst, dann wir dir das in Millisekunden mitgeteilt. Wenn sie aber funktioniert, dann muss der Anfrager auf die Aufbereitung des Recordsets warten und das kann je nach Abfrage zwischen Nullkommanix und sehr lange dauern.
Falls du wirklich glaubst noch eine brauchbare Antwort auf deine Anfrage zu erhalten, sage ich dir voraus, dass das mit grösster Wahrscheinlichkeit nicht der Fall sein wird und du noch ewig darauf warten kannst...
Gruess Hansueli
Anzeige
AW: RecordCount bei ADODB
06.09.2016 16:11:13
Luschi
Hallo Hendrik,
wenn die Abfrage tatsächlich 200.000 DS liefert, dann würde ich:
- die gesamte Filterei per Parameter-Abfrage auf dem DB-Server einrichten
- und diese dann per PowerQuery mir ins Excel-Power-Pivot-Datenmodell holen
- denn dann passiert die Datenzusammenstellung auf dem Server, der das
  wesentlich schneller kann, da hardwaremäßig besser ausgestattet
und für solche Specials gut gerüstet ist
Gruß von Luschi
aus klein-Paris
Anzeige
AW: RecordCount bei ADODB
07.09.2016 09:25:03
Hendrik
Danke, Luschi.
;
Anzeige

Infobox / Tutorial

RecordCount bei ADODB in Excel VBA


Schritt-für-Schritt-Anleitung

  1. Verbindung zur Datenbank herstellen: Erstelle eine ADODB-Verbindung mit folgendem Code:

    strConnectionString = "Provider=MSDASQL.1;Driver=SQL Server;Server=" & strServer & ";Database=" & strDatenbank & ";Trusted_Connection=Yes"
    Set objConn = New ADODB.Connection
    objConn.ConnectionString = strConnectionString
    objConn.Open
  2. Recordset öffnen: Führe die SQL-Abfrage aus und öffne das Recordset:

    Set objRec = New ADODB.Recordset
    objRec.Open strSql, objConn, adOpenStatic
  3. RecordCount ermitteln: Um die Anzahl der Datensätze zu erhalten, kannst du die RecordCount-Eigenschaft verwenden. Beachte, dass du möglicherweise zuerst zum letzten Datensatz springen musst:

    objRec.MoveLast
    If objRec.RecordCount > 0 Then
       ' Verarbeitung der Datensätze
    End If
  4. Daten verarbeiten: Iteriere über die Datensätze und speichere sie in ein Array:

    ReDim glStrArr(objRec.RecordCount - 1, objRec.Fields.Count - 1)
    objRec.MoveFirst
    For i = 0 To objRec.RecordCount - 1
       For j = 0 To objRec.Fields.Count - 1
           If Not IsNull(objRec(j)) Then
               glStrArr(i, j) = objRec(j)
           Else
               glStrArr(i, j) = "{NULL}"
           End If
       Next j
       objRec.MoveNext
    Next i

Häufige Fehler und Lösungen

  • Langsame Abfragezeiten: Wenn die RecordCount-Abfrage sehr lange dauert, könnte es daran liegen, dass das gesamte Recordset geladen werden muss. Du kannst die Leistung verbessern, indem du die SQL-Abfrage so anpasst, dass nur die benötigten Daten abgerufen werden.

  • Falscher RecordCount: Wenn du eine adodb.recordset verwendest und der RecordCount immer noch nicht korrekt ist, stelle sicher, dass der CursorType auf adOpenStatic eingestellt ist, da andere Typen unter Umständen nicht den vollständigen Count liefern.


Alternative Methoden

  1. SQL-Anpassung: Wenn du nur die Anzahl der Datensätze benötigst, kannst du die SQL-Abfrage ändern:

    SELECT COUNT(*) FROM DeineTabelle

    Dies gibt dir direkt die Anzahl der Datensätze zurück, ohne das gesamte Recordset zu laden.

  2. Verwendung von GetRows: Du kannst die GetRows-Methode verwenden, um alle Datensätze in ein Array zu laden, was ebenfalls die Performance verbessern kann:

    Dim arrData As Variant
    arrData = objRec.GetRows()
    MsgBox "Anzahl der Datensätze: " & UBound(arrData, 2) + 1

Praktische Beispiele

Hier ein Beispiel für die Verwendung des adodb.recordset in einem Excel VBA-Skript:

Sub Beispiel_RecordCount()
    Dim conn As Object
    Dim rec As Object
    Dim sql As String
    Dim count As Long

    Set conn = CreateObject("ADODB.Connection")
    conn.Open "Provider=MSDASQL.1;Data Source=DeineDatenbank"

    Set rec = CreateObject("ADODB.Recordset")
    sql = "SELECT * FROM DeineTabelle"
    rec.Open sql, conn

    rec.MoveLast
    count = rec.RecordCount
    MsgBox "Es gibt " & count & " Datensätze."

    rec.Close
    conn.Close
End Sub

Tipps für Profis

  • Verwenden von Parameterabfragen: Reduziere die Anzahl der abgerufenen Datensätze durch die Verwendung von WHERE-Klauseln in deinen SQL-Abfragen.
  • Optimierung der Datenbank: Stelle sicher, dass deine Datenbank gut indiziert ist, um die Abfragegeschwindigkeit zu erhöhen.
  • Vermeidung von MoveLast: Wenn du nur den Count benötigst, vermeide MoveLast, da dies die Performance stark beeinträchtigen kann. Nutze stattdessen COUNT(*) in deiner SQL-Abfrage.

FAQ: Häufige Fragen

1. Warum dauert die Ermittlung der RecordCount so lange?
Das liegt daran, dass das gesamte Recordset geladen werden muss. Eine Anpassung der SQL-Abfrage kann hier helfen.

2. Gibt es eine Möglichkeit, die Anzahl der Datensätze schneller zu ermitteln?
Ja, du kannst die SQL-Abfrage so anpassen, dass sie nur die Anzahl der Datensätze zurückgibt, z.B. mit SELECT COUNT(*) FROM DeineTabelle.

3. Wie kann ich sicherstellen, dass mein RecordCount korrekt ist?
Stelle sicher, dass der CursorType für das Recordset korrekt eingestellt ist (z.B. adOpenStatic), und dass du nach dem Öffnen des Recordsets, falls nötig, zu MoveLast springst.

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige