Auflistung von Excel-Makros

  • Bei der Excel.au3 gibt es ja die Funktion _ExcelSheetList($oExcel)

    Ich suche nun eine Funktion, wir man bei einer geöffneten Excel.Datei, die z.B. in Modul 1 bestehenden Makros/Prozeduren auflisten kann. Hintergund ist der, dass der Anwender per Listbox ein entsprechendes Makros sich aussuchen soll, dass dann per Autoit gestartet wird.

    Unter Excel gibt es den Befehl:
    ThisWorkbook.VBProject.VBComponents("Modul1").CodeModule

    Aber leider funktioniert eine entsprechende Anpassung der obigen Excel-Funktion von Autoit3 nicht.

    Wie kann man bestehende Makros abfragen? ?(

    Grüße

    Mike32

    3 Mal editiert, zuletzt von Mike32 (19. Juni 2012 um 18:15)

  • Schonmal so versucht?

    [autoit]

    $oBook.VBProject.VBComponents("Modul1").CodeModule

    [/autoit]
  • Ja, habe ich. Klappt leider nicht.

    [autoit]


    $ExcelVar = ObjGet("Excel.Application")
    $ExcelVar = _ExcelBookOpen("C:\Test.xls", 1)
    $temp=$ExcelVar.VBE.ActiveVBProject.Name
    $temp=$ExcelVar.VBProject.VBComponents("Modul1").VBModul.CodeModul
    $temp=$ExcelVar.VBE.ActiveVBProject.VBComponents.VBModul.CodeModul

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


    Die erste Zeile "$temp=$ExcelVar.VBE.ActiveVBProject.Name" funktioniert einwandfrei. Die beiden anderen Zeilen sowie div. Versionen davon leider nicht.
    Leider komme ich mit der Zeile, die funktioniert, nicht weiter, da sie mir nur den VBProjectnamen verrät, aber nicht die Module bzw. Prozeduren darin.

    Grüße

    Mike32

  • Und so?

    [autoit]

    $ExcelVar = _ExcelBookOpen("C:\Test.xls", 1)
    $Makros = $ExcelVar.VBE.ActiveVBProject.VBComponents.Item("Modul1").CodeModule
    For $Makro In $Makros
    MsgBox(0, "", $Makro)
    Next

    [/autoit]


    Ich weiß jetzt nicht wie er die Makros zurückgibt.

  • Vielen Dank,

    funktioniert leider auch nicht. ?(
    Er bleibt wieder andiesem Befehl hängen und bricht ab.
    Irgendwie kann Autoit nicht auf das Modul bzw. auf die Prozeduren zugreifen. Funktioniert bei dir der Befehl (bei einer Exceltestdatei)?

    Grüße

    Mike32

    • Offizieller Beitrag

    Es ist etwas aufwändiger. :rolleyes:
    Ich habe mal das Excel-Object-Model auf MSDN durchforstet und bin zu dieser Lösung gekommen:

    [autoit]

    Const $vbext_ct_ClassModule = 2
    Const $vbext_ct_Document = 100
    Const $vbext_ct_StdModule = 1
    Const $vbext_pk_Proc = 0

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

    Local $sPath = 'Deine_Excel.xls'
    Local $oExcel, $oBook, $oProj, $oComp, $Makro, $aMakro[1] = ['']

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

    $oExcel = ObjCreate('Excel.Application')
    $oExcel.Visible = 1
    $oBook = $oExcel.Workbooks.Open($sPath)
    $oProj = $oBook.VBProject
    $oComp = $oProj.VBComponents

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

    For $Komponente In $oComp
    If $Komponente.Type = $vbext_ct_ClassModule Or $Komponente.Type = $vbext_ct_Document Or _
    $Komponente.Type = $vbext_ct_StdModule Then
    With $Komponente.CodeModule
    For $i = 1 To .CountOfLines
    If .ProcOfLine($i, $vbext_pk_Proc) > "" Then
    $Makro = .ProcOfLine($i, $vbext_pk_Proc)
    If $Makro <> $aMakro[UBound($aMakro)-1] Then
    If $aMakro[UBound($aMakro)-1] <> '' Then ReDim $aMakro[UBound($aMakro)+1]
    $aMakro[UBound($aMakro)-1] = $Makro
    EndIf
    EndIf
    Next
    EndWith
    EndIf
    Next
    For $i = 0 To UBound($aMakro)-1
    ConsoleWrite($aMakro[$i] & @CRLF)
    Next

    [/autoit]

    Edit: Kannst die Makros ja z.B. in einer ComboBox anzeigen und das vom User gewählte Makro so starten:

    [autoit]

    $oExcel.Application.Run('Makro_Name')

    [/autoit]
  • BugFix

    Vielen Dank für deine umfangreiche Antwort. :D

    Bei "$oComp = $oProj.VBComponents" will Auoit nicht mehr. Könnte es sein, dass hier noch irgendein Parameter fehlt oder funktioniert bei dir ggf. der Code?

    Grüße

    Mike32

  • Hei BugFix,

    so ich habe mal das Problem eingegrenzt. Bei Excel 2007 (Tabelle .xlsm) läuft es tadellos. :thumbup:

    Die gleiche Datei als Excel 97-2003 (.xls) abgespeichert und ich habe das beschriebene Problem. Kann es sein, dass die VBA-Struktur dann anders ist? - Und wenn ja, wie?

    Grüße

    Mike32

    • Offizieller Beitrag

    Die gleiche Datei als Excel 97-2003 (.xls) abgespeichert und ich habe das beschriebene Problem. Kann es sein, dass die VBA-Struktur dann anders ist? - Und wenn ja, wie?

    Das übersteigt mein Wissen in dem Bereich.
    Aber falls es dir reicht, den normalen Makro-Dialog anzuzeigen - das geht so:

    [autoit]

    Const $xlDialogRun = 17
    Local $oExcel, $sPath = 'Deine_Excel.xls'

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

    $oExcel = ObjCreate('Excel.Application')
    $oExcel.Visible = 1
    $oExcel.Workbooks.Open($sPath)
    $oExcel.Application.Dialogs($xlDialogRun).Show

    [/autoit]
  • @ BugFix

    Super, dass du immer so prompt eine Antwort hast. Ich bin der Sache mal weitergegenagen und habe festgestellt, dass mir ein Fehler unterlaufen ist. Dein Code funktioniert bei allen Excel-Versionen. Ich habe nur vergessen beim VBProjekt das Passwort rauszunehmen. ;(
    So konnte Autoit bei deinem Code gar nicht darauf zugreifen. - Sorry!!!!

    Könntest du mir noch netterweise kurz mitteilen, wie ich per Autoit beim Projekt das Passwort eingebe bzw. den Schutz temporär aufhebe und nachher wieder einschalte?

    Vielen Dank! :D

    Grüße

    Mike32

    • Offizieller Beitrag

    Könntest du mir noch netterweise kurz mitteilen, wie ich per Autoit beim Projekt das Passwort eingebe bzw. den Schutz temporär aufhebe und nachher wieder einschalte?


    Also für das Workbook geht das (wenn ich mich recht erinnere) mit:

    [autoit]

    $oExcel.Workbooks.Open($sPath)
    $oExcel.Workbooks.Unprotect('Passwort')

    [/autoit]


    Aber wenn das Project PW-geschützt ist.. ich glaube, die Protection.Property ist ReadOnly. :S
    Mal suchen, ob es da eine Lösungsmöglichkeit gibt.

  • @ Bugfix,

    ich muss leider ein altes Thema/Problem ausgraben.

    Ich dachte, dass der Code vom Beitrag Nr. 6 laufen würde. War mein Fehler. - Beim heutigen Testen kam folgende Fehlermeldung in Autoit
    : ==> Error in expression.:
    If .ProcOfLine($i, $vbext_pk_Proc) > "" Then
    If .ProcOfLine($i, $vbext_pk_Proc) ^ ERROR

    Ich habe ein einfache Excel-Testdatei mit drei Tabellen und einem VBA-Modul, welches drei kleine Makros enthält. Die Datei wird von Autoit geöffnet und dann kommt die obige Fehlermeldung bei Zeile 20 des Codes.
    Woran könnte dies liegen?
    Thx

    Grüße

    Mike

    2 Mal editiert, zuletzt von Mike32 (19. Juni 2012 um 18:27)

  • So der Fehler wurde vermutlich eingegrenzt.
    Es muss noch ein Verweis auf "Visual Basic for Applications Extensibility 5.3" gesetzt werden, damit .ProcofLine funktioniert.
    Die COM-Datei heißt: Vbe6ext.olb und ist unter "c:\Programme\Gemeinsame Dateien\Microsoft Shared\VBA\VBA6" zu finden.


    Weiß jemand, wie man einen Verweis setzen kann bzw. diese Datei irgendwie einbindet? Bei VB gibt es ja eine Möglichkeit dafür.

    Thx

    Grüße

    Mike

    Einmal editiert, zuletzt von Mike32 (20. Juni 2012 um 14:12)

  • Für alle Interessierten hier die (behelfsmäßige) Lösung.

    Ohne Verweis bei Autoit (ich habe hierfür keinerlei Möglichkeit gefunden, dass dies irgendwie geht), kommt man nur bis zur "Ebene" VBComponents. D.h. man kann nicht auf ProcofLine zugreifen. Um dies zu umgehen habe ich mit.Export die entsprechenden Module temporär exportiert und dann mit StringinString analysiert, da die .bas-Dateien einfache Textdateien sind. Dies klappt nun hervorragend.
    Und hier der Code, der teilweise auf Bugfix's Code basiert (s.o.).


    Grüße

    Mike :)