Datum aus xls mit ADO geht leer aus

  • Ich hab mal wieder ein kleines Problem mit einer kleinen funktion. Die funktion soll alle Zellen einer xls-Tabelle in einen Array einlesen.
    Das klappt auch alles wunderbar. Mit der einen ausnahme das alle Zellen in denen in der xls-Tabelle ein Datum drin steht im Recordset leer sind.

    Unten findet ihr die funktion und ich hoffentlich ein paar schlaue ideen von euch :)

    [autoit]

    Func _excel2array($src_dir, $tableName, $columes) ; liest aus der xls in $src_dir aus dem Tabellenblatt $tableName $columes spalten aus

    [/autoit][autoit][/autoit][autoit]

    ; SchemaEnum
    Const $adSchemaTables = 20

    [/autoit][autoit][/autoit][autoit]

    ; CursorLocationEnum
    Const $adUseClient = 3

    [/autoit][autoit][/autoit][autoit]

    ; Instanziirung der Connection-Klasse. Mit diesem Objekt wird eine dauerhafte Verbindung
    ; zu einer Datenquelle hergestellt.
    Dim $cn = ObjCreate('ADODB.Connection')

    [/autoit][autoit][/autoit][autoit]

    ; OLEDB-Provider für die Verbindung festlegen.
    $cn.Provider = 'Microsoft.Jet.OLEDB.4.0'

    [/autoit][autoit][/autoit][autoit]

    ; Es wird eine Verbindungszeichenfolge(Connection String auch Init String) erwartet. Die Zeichenfolge ist
    ; eine Reihenfolge von Attribut-Wert-Zuweisungen.
    $cn.ConnectionString = 'Data Source=' & $src_dir & ';Extended Properties=Excel 8.0;'

    [/autoit][autoit][/autoit][autoit]

    ; Speicherort der Cursorbibliothekt setzen.
    $cn.CursorLocation = $adUseClient

    [/autoit][autoit][/autoit][autoit]

    ; Eine Verbindung zur Datenquelle öffnen.
    $cn.Open()
    ConsoleWrite("open connection to database" & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    Dim $rsTables = $cn.OpenSchema($adSchemaTables)

    Dim $criterias[4]
    $criterias[2] = $tableName

    [/autoit][autoit][/autoit][autoit]

    Dim $rsColumns = $cn.OpenSchema(4, $criterias)

    [/autoit][autoit][/autoit][autoit]

    Dim $rs = $cn.Execute('[' & $tableName & '$]')

    Dim $array[$columes][$rs.RecordCount]

    ; Iteration über alle Spalten
    ConsoleWrite("read " & $columes & " columns" & @CRLF)
    ConsoleWrite("read " & $rs.RecordCount & " rows" & @CRLF)
    For $c = 0 To $columes - 1

    [/autoit][autoit][/autoit][autoit]

    ; Springt zum ersten Datensatz
    $rs.MoveFirst()

    [/autoit][autoit][/autoit][autoit]

    ; Iteration über alle Datensätze

    [/autoit][autoit][/autoit][autoit]

    For $r = 0 To $rs.RecordCount - 1

    [/autoit][autoit][/autoit][autoit]

    ; Ausgabe der Werte zur Kontrolle
    ;ConsoleWrite(' ' & $rs.Fields($c).Value & @CRLF)
    $array[$c][$r] = $rs.Fields($c).Value

    [/autoit][autoit][/autoit][autoit]

    ; zum nächsten Datensatz springen
    $rs.MoveNext()
    Next ; r <-- Daten

    [/autoit][autoit][/autoit][autoit]

    ; zur nächsten Datenspalte springen
    ;$rsColumns.MoveNext()
    Next ; $c <-- Spalten

    [/autoit][autoit][/autoit][autoit]

    ConsoleWrite("done with reading" & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    ; Geöffnete Verbindungen schliesen
    $rs.Close()
    $rsColumns.Close()
    $rsTables.Close()
    $cn.Close()

    [/autoit][autoit][/autoit][autoit]

    ConsoleWrite("connection succesfully closed" & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    Return $array

    [/autoit][autoit][/autoit][autoit]

    EndFunc ;==>_excel2array

    [/autoit]

    Einmal editiert, zuletzt von warhwolf (17. Oktober 2013 um 19:11)

  • Das Skript spricht nicht die value property eines Excel Range Objektes an, sondern die eines ADO Recordset Objektes. Und da gibt es keine formula property.

    @warhwolf: Gibt es einen Grund, warum Du ADO verwendest um auf Excel zuzugrefien?

  • jap den gibt es. das skript soll minimale anforderungen haben und für die integrierten excel funktionen brauche ich excel :)

    also ich habe auch schon ein wenig herumexperimentiert und festgestellt dass es anscheinend an der excel tabelle liegt. aber warum es leer ist weiß ich immer noch nicht ...

  • Könntest Du die XLS als XLSX (= XML) abspeichern? Um die ohne Excel zu lesen gibt es eine UDF im engl. Forum.

  • das geht leider nicht. die quelltabelle ist immer eine xls die leider auch schreibgeschützt ist.

    ich glaube allerdings dass ich das problem langsam gefunden habe. beim rumprobieren mit teilen der tabelle und einer "virgin"-xls bin ich drauf gestossen, dass der auslesewert leider doch etwas mit dem typ der daten zu tun hat.

    ab eines bestimmten verhältnisses von datums zu text zellen gibt er entweder die eine oder die andere nur noch als leer aus. ich meine das mir da noch etwas im hinterkopf rumspuckt das bei dem zugriff über ado im connection string irgendso eine option erwähnt wurde.

    wenn jemand weiß ob und wie man sie abstellt wäre das hervoragend zu wissen. ansonsten such ich noch ein wenig rum.

  • Gut ich hab mein Problem selbst lösen können. Nochmal sonst für alle:

    Bei xls Tabelle kann ado den Datentyp der Zelle nur über die Spalte erahnen. Das bedeutet wenn mehrere Verschiedene Datentypen in einer Spalte sind, wird nur eine Sorte erkannt. Wenn also (wie bei mir) auf 400 Zeilen Text 5 Zeilen Datum kommt, dann wird das Datum nicht erkannt. Über den SCANNROWS Parameter kann bestimmt werden in welchem Suchbereich der Datentyp bestimmt wird.

    Bei mir hat es aber nur funktioniert nachdem ich mit:

    [autoit]

    Dim $rs = $cn.Execute('[' & $tableName & '$' & $column & $row & ':' & $column & $row & ']')

    [/autoit]

    eine einzelne Zelle ausgelesen habe. Da gibt es dann nur einen Datentyp.

    Also merke eine Spalte ein Datentyp :)

    Danke nochmal an alle :rock: