none
Excel 2003 VBA ADODB Recordset transponiert Texte Zahlen RRS feed

  • Frage

  • Hallo Experten!

    Wir möchten ein Excel-Blatt per ADO-Recordset öffnen und damit eine Listbox füllen. Das geht so:

    Dim cn As new ADODB.Connection
    Dim rs As new ADODB.Recordset

    cn.Provider = "Microsoft.Jet.OLEDB.4.0"
    cn.ConnectionString = "Data Source=U:\myFile.xls;" & "Extended Properties=Excel 8.0;"
    cn.Open

    rs.Open "Select * from [mySheet$]", cn, adOpenStatic

    UserForm1.ListBox1.List() = rs.GetRows

    ------------------------------------------------------------------

    Bereits beim ADO-Recordset treten jedoch zwei Probleme auf (nicht erst bei der Listbox):

    Prob1: Die Daten kommen "transponiert", d.h. die Zeilen werden um 90 Grad in Zeilen gekippt. Das bedeutet für den Erfasser der Excel-Datei, dass er seine "Datensätze" transponiert erfassen muss, was die Sache sehr unübersichtlich macht, und bei 255 Datensätzen wäre dann Schluss.

    Prob2: Jede Spalte muss komplett nur aus Zahlen oder nur aus Text bestehen, ADO nimmt als Maßstab die ersten gefundenen Werte. Wenn danach was anderes kommt, streikt der Recordset. Umformatieren nützt nichts, selbst "Inhalte einfügen / Werte" nützt nichts. Die einzige Möglichkeit ist, in eine textformatierte Zelle die Zahlen per Hand einzutippen, was wir unserem User natürlich nicht zumuten können.

    (Außerdem wird immer erst ab der zweiten Zeile gelesen. Das kann man aber leicht durch einen Lückenfüller in der ersten Zeile umgehen.)

    Hat jemand eine Idee zu den Probs ?

    Schönen Dank schon mal im Voraus

    Raimund Gryszik, Berlin

    Donnerstag, 8. Dezember 2011 16:42

Antworten

  • Hallo Raimund,
    Ich würde erst den Inhalt des Recordsets in einem Array schreiben und dann in das Liste-Objekt einfügen. So kommen die Daten aus Excel nicht mehr transponiert und ist die Zahl der Zeilen nicht mehr eingegrenzt:
    Private Sub CommandButton1_Click()
        Dim cn As New ADODB.Connection
        Dim rs As New ADODB.Recordset
        
        cn.Provider = "Microsoft.Jet.OLEDB.4.0"
        cn.ConnectionString = "Data Source=C:\Documents and Settings\Administrator\Desktop\data.xls;" & "Extended Properties=Excel 8.0;"
        cn.Open
     
        rs.Open "Select * from [Sheet1$]", cn, adOpenStatic
        
        Dim a() As Variant
        Dim i As Long
        Dim j As Long
        Dim intFieldsCount As Integer
        Dim lngRecordsCount As Integer
        
        i = 0
        
        intFieldsCount = rs.Fields.Count
        rs.MoveLast
        rs.MoveFirst
        lngRecordsCount = rs.RecordCount
        ReDim Preserve a(lngRecordsCount, intFieldsCount - 1)
        
        Do While Not rs.EOF
            For j = 0 To rs.Fields.Count - 1
                a(i, j) = rs.Fields(j).Value
            Next j
            i = i + 1
            rs.MoveNext
        Loop
            
        ListBox1.List = a
        
    End Sub
    

     
    Viele Grüße,
    Bogdan

    Ich bin gerne bei den Foren. Es kommt von Herzen. Es wird aber keine implizite oder sonstige Garantie für die geposteten Antworte / Informationen gewährt. Hier auch die Forenregeln.
    Freitag, 9. Dezember 2011 09:02

Alle Antworten

  • Hallo Raimund,
    Ich würde erst den Inhalt des Recordsets in einem Array schreiben und dann in das Liste-Objekt einfügen. So kommen die Daten aus Excel nicht mehr transponiert und ist die Zahl der Zeilen nicht mehr eingegrenzt:
    Private Sub CommandButton1_Click()
        Dim cn As New ADODB.Connection
        Dim rs As New ADODB.Recordset
        
        cn.Provider = "Microsoft.Jet.OLEDB.4.0"
        cn.ConnectionString = "Data Source=C:\Documents and Settings\Administrator\Desktop\data.xls;" & "Extended Properties=Excel 8.0;"
        cn.Open
     
        rs.Open "Select * from [Sheet1$]", cn, adOpenStatic
        
        Dim a() As Variant
        Dim i As Long
        Dim j As Long
        Dim intFieldsCount As Integer
        Dim lngRecordsCount As Integer
        
        i = 0
        
        intFieldsCount = rs.Fields.Count
        rs.MoveLast
        rs.MoveFirst
        lngRecordsCount = rs.RecordCount
        ReDim Preserve a(lngRecordsCount, intFieldsCount - 1)
        
        Do While Not rs.EOF
            For j = 0 To rs.Fields.Count - 1
                a(i, j) = rs.Fields(j).Value
            Next j
            i = i + 1
            rs.MoveNext
        Loop
            
        ListBox1.List = a
        
    End Sub
    

     
    Viele Grüße,
    Bogdan

    Ich bin gerne bei den Foren. Es kommt von Herzen. Es wird aber keine implizite oder sonstige Garantie für die geposteten Antworte / Informationen gewährt. Hier auch die Forenregeln.
    Freitag, 9. Dezember 2011 09:02
  • Hallo Bogdan,

    recht herzlichen Dank für deine Antwort. Die Routine funktioniert prima, und wird wahrscheinlich auch so zum Einsatz kommen.

    Klar hätte ich mir das auch selbst schreiben können. Aber ich hatte gehofft, dass es irgendeine fertig implementierte ADO-Methode gibt, die das Problem selber löst (oder einen Parameter, einen Trick oder sowas).

    Danke!

    Raimund

    Freitag, 9. Dezember 2011 14:37