Excel: Tabellenblatt in Array einlesen

    • Offizieller Beitrag

    Die Funktion _ExcelReadSheetToArray() macht wohl unter 64bit Probleme. Mir hatte sie in der Form noch nie gefallen und deshalb hatte ich eine eigene Variante erstellt. Diese habe ich jetzt mal noch komplettiert, sodass sie auch unter 64bit läuft und zusätzlich noch etwas komfortabler ist durch gezielte Auswahl eines Sheets (sonst aktuelles Sheet) und mit weniger Parametern derselbe Funktionsumfang gewährleistet wird.
    Ich bevorzuge die Zelladressierung mit Offset, da dies ideal für Schleifen ist. Ist auch einfacher zu händeln, als für jede Zelle die absolute Adresse zusammenzustellen.

    _ExcelSheetToArray
    [autoit]

    ;===================================================================================================
    ; Function Name: _ExcelSheetToArray
    ; Description:: Liest ein Tabellenblatt in ein Array
    ; Parameter(s): $oExcel Referenz auf eine geöffnete Exceldatei
    ; $vSheet Nummer oder Name des Tabellenblattes (Standard: 1)
    ; $sRange Auszulesender Bereich: ":" A1 bis letzte belegte Zelle (Standard)
    ; "SZ:" SpalteZeile bis letzte belegte Zelle
    ; ":SZ" A1 bis SpalteZeile
    ; Requirement(s): __LetterToColNr()
    ; Return Value(s): Erfolg: 2D-Array mit Inhalt des Tabellenblattes
    ; Fehler: @error 1 - $oExcel ist kein Objekt
    ; 2 - übergebener Bereich größer als belegte Zeilen/Spalten
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;===================================================================================================
    Func _ExcelSheetToArray(ByRef $oExcel, $vSheet=1, $sRange=':')
    ; by BugFix
    If Not IsObj($oExcel) Then Return SetError(1,0,0)
    $oExcel.ActiveWorkbook.Sheets($vSheet).Select()
    Local $iRowStart = 1, $vColStart = 1
    Local $iRowEnd = $oExcel.Worksheets($vSheet).UsedRange.Rows.Count
    Local $vColEnd = $oExcel.Worksheets($vSheet).UsedRange.Columns.Count
    Local $ret, $sTmp = StringSplit($sRange, ':')
    Select
    Case $sTmp[1] <> '' And $sTmp[2] = ''
    $ret = StringRegExp($sTmp[1], '([a-zA-Z]+)(\d+)', 3)
    $vColStart = __LetterToColNr($ret[0])
    $iRowStart = $ret[1]
    Case $sTmp[1] <> '' And $sTmp[2] <> ''
    $ret = StringRegExp($sTmp[1], '([a-zA-Z]+)(\d+)', 3)
    $vColStart = __LetterToColNr($ret[0])
    $iRowStart = $ret[1]
    $ret = StringRegExp($sTmp[2], '([a-zA-Z]+)(\d+)', 3)
    $vColEnd = __LetterToColNr($ret[0])
    $iRowEnd = $ret[1]
    Case $sTmp[1] = '' And $sTmp[2] <> ''
    $ret = StringRegExp($sTmp[2], '([a-zA-Z]+)(\d+)', 3)
    $vColEnd = __LetterToColNr($ret[0])
    $iRowEnd = $ret[1]
    EndSelect
    If $iRowStart > $iRowEnd Or $vColStart > $vColEnd Then Return SetError(2,0,0)
    Local $aOut[$iRowEnd-$iRowStart +1][$vColEnd-$vColStart +1]
    For $i = 0 To UBound($aOut) -1
    For $j = 0 To UBound($aOut,2) -1
    $aOut[$i][$j] = $oExcel.Range("A1").Offset($i +$iRowStart -1, $j +$vColStart -1).Value
    Next
    Next
    Return $aOut
    EndFunc ;==>_ExcelSheetToArray

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

    Func __LetterToColNr($sLetter) ; === Spaltenadresse zu Nummer
    ; by BugFix
    If Not StringRegExp($sLetter, '[a-zA-Z]{1,2}') Then Return SetError(1,0,-1)
    If StringLen($sLetter) = 1 Then Return Asc(StringUpper($sLetter)) -64
    Return (Asc(StringUpper(StringLeft($sLetter, 1)))-64)*26 + (Asc(StringUpper(StringRight($sLetter, 1)))-64)
    EndFunc

    [/autoit]