Excel - alle Arbeitsblätter auslesen

  • Hallo,

    ich bitte um Unterstützung.
    In dem folgenden Auszug wird über WinList() die aktuell geöffneten Excelfenster ermittelt. Anschließend sollen die Arbeitsblätter dieses Excelfensters ermittelt werden.
    In diesem Moment weiß ich den Pfad der Datei nicht um diese über _ExcelBookOpen zu öffnen. Mit _ExcelBookAttach finde ich auch nicht die funktionierende Lösung.
    Ziel ist es, dass die Arbeitsblätter der jeweiligen geöffneten Datei ausgelesen werden.

    Vorbereitung: verschiedene Exceldateien öffnen

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    #include <Excel.au3>

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

    Local $var = WinList()

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

    For $i = 1 To $var[0][0]
    ; Listet nur die sichtbaren Fenster auf, die einen Titel haben
    If $var[$i][0] <> "" And IsVisible($var[$i][1]) And StringInStr($var[$i][0],"- Excel") Then
    MsgBox(0, "Details", "Titel=" & $var[$i][0] & @LF & "Handle=" & $var[$i][1])

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

    $oExcel = _ExcelBookAttach($var[$i][0],"Title")
    $aArray = _ExcelSheetList($oExcel)
    _ArrayDisplay($aArray,"alle sheets")

    EndIf
    Next

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

    Func IsVisible($handle)
    If BitAND(WinGetState($handle), 2) Then
    Return 1
    Else
    Return 0
    EndIf

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

    EndFunc ;==>IsVisible

    [/autoit]

    Ist das so verständlich?
    Danke und Gruß

    Einmal editiert, zuletzt von qwert23 (3. August 2014 um 09:01)

  • Mit der aktuellen AutoIt Version (=> 3.3.12.0) wird eine völlig neu geschriebene Excel UDF ausgeliefert. Die ist zwar nicht mehr kompatibel zur Version von AutoIt 3.3.8.1, enthält aber viele neue Funktionen.
    _Excel_BookList würde Dein Problem lösen.

  • Hallo water,
    den Umstieg werde ich noch schaffen. Aktuell arbeitet mein Programm mit der "alten" Version. Ich habe nur den betreffenden Auszug dargestellt.

    Eigentlich ist es mit _ExcelSheetList kein Problem, wenn der Pfad\Datei.xlsx bekannt ist. Durch WinList() kenne ich nur die Fenstertitel und Handle. Und hier beginnt mein Problem: Wie gebe ich _ExcelSheetList nun bekannt, das der Fenstertitel zum Ermitteln der Arbeitsblätter genutzt wird.

  • _ExcelBookAttach("Durch den Titel des Fenster ersetzen", "title")

  • Dann must Du ein paar Fehleprüfungen einbauen.
    Wird die MsgBox angezeigt?
    Was ist der Returnwert bzw. @error nach _ExcelBookAttach?

  • Ja, die MsgBox wird angezeigt, dann folgt diese Fehlermeldung:
    C:\AutoIt3\Include\excel.au3 (1063) : ==> The requested action with this object has failed.:
    Local $iTemp = $oExcel.ActiveWorkbook.Sheets.Count
    Local $iTemp = $oExcel.ActiveWorkbook^ ERROR

    Verkürze ich den Titel mit StringTrimRight (um den Zusatz " - Excel" zu entfernen) wird 0 und @error=1 zurückgegeben.

  • Der Fehler tritt in _Excel_SheetList auf.
    Das liegt sicher daran, dass _ExcelBookAttach nicht fehlerfrei durchlief.
    Muss ich mal testen.

  • Das hier funktioniert nun. Aber nur mit einer Excel Instanz (= einem Excel Prozess). Liegt am alten UDF das nur mit dem aktiven Workbook arbeiten kann.
    Die neue UDF hat diese Einschränkungen nicht.
    Das Problem lag daran, dass _ExcelBookAttach ein Workbook zurückgibt, _ExcelSheetList aber ein Applikations objekt erwartet.

    [autoit]

    #include <Array.au3>
    #include <Excel.au3>

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

    Opt("WinTitleMatchMode", 2)
    Global $sTitle = "Microsoft Excel - "
    Global $aWindows = WinList($sTitle)
    _ArrayDisplay($aWindows)
    For $i = 1 To $aWindows[0][0]
    ; Listet nur die sichtbaren Fenster auf, die einen Titel haben
    If $aWindows[$i][0] <> "" And IsVisible($aWindows[$i][1]) And StringInStr($aWindows[$i][0], $sTitle) Then
    MsgBox(0, "Details", "Titel=" & $aWindows[$i][0] & @LF & "Handle=" & $aWindows[$i][1])
    $oWorkbook = _ExcelBookAttach($aWindows[$i][0], "Title")
    $aSheets = _ExcelSheetList($oWorkbook.Parent)
    _ArrayDisplay($aSheets, "alle sheets")
    EndIf
    Next

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

    Func IsVisible($handle)
    If BitAND(WinGetState($handle), 2) Then
    Return 1
    Else
    Return 0
    EndIf
    EndFunc ;==>IsVisible

    [/autoit]