dennisvot
Goto Top

Makro-Quelltexte massenhaft durchsuchen

Guten Tag,

ich habe eine Sammlung von mehreren tausend Excel-Files in einem Ordner mit Unterordnern vorliegen, die größtenteils (ungeschützte) Makros enthalten. In einigen dieser Makros wird ein nicht mehr gültiger UNC-Pfade verwendet durch einen Aufruf in etwas wie nachfolgend (etwas verkürzt dargestellt):

Private Sub CommandButton1_Click()
Dim WBName As String
WBName = ActiveWorkbook.Name

On Error GoTo weiter
Workbooks.Open Filename:="\\Server\PC Software\V\Software.xlam"  

weiter:
Application.Run ("Software.xlam!Zeiterfassung"), WBName  

End Sub

Ich suche nach einer Möglichkeit, alle Excel-Files automatisch nach dem UNC-Pfad durchsuchen zu lassen. Die Korrektur der falschen Pfade kann anschließend von Hand geschehen, notwendig ist eine Übersicht der betroffenen Excel-Files. Der ungültige UNC-Pfad ist immer gleich.

Vielen Dank vorab für eure Hilfe,
Dennis

Content-ID: 3740737294

Url: https://administrator.de/contentid/3740737294

Ausgedruckt am: 19.11.2024 um 19:11 Uhr

8585040390
Lösung 8585040390 22.09.2023 um 07:28:44 Uhr
Goto Top
Ungetestetes Ergebnis von ChatGPT:

# Pfad zum Verzeichnis, in dem die Excel-Dateien gespeichert sind
$VerzeichnisPfad = "C:\Pfad\Zu\Deinem\Verzeichnis"  

# Der Text, nach dem du suchen möchtest
$ZuSuchenderText = "DeinSuchtext"  

# Datei, in der die Ergebnisse gespeichert werden
$ErgebnisDatei = "C:\Pfad\Zu\Deiner\Ergebnisdatei.txt"  

# Erstelle ein Excel-Anwendungsobjekt
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $false

# Erstelle eine Liste, um die Ergebnisse zu speichern
$Ergebnisse = @()

# Durchsuche alle Excel-Dateien im Verzeichnis
Get-ChildItem -Path $VerzeichnisPfad -Filter *.xls* | ForEach-Object {
    $Datei = $_.FullName

    # Öffne die Excel-Datei
    $Arbeitsmappe = $excel.Workbooks.Open($Datei)
    
    # Durchsuche alle Makros in der Arbeitsmappe
    $Arbeitsmappe.VBProject.VBComponents | ForEach-Object {
        $Modul = $_
        $Code = $Modul.CodeModule.Lines(1, $Modul.CodeModule.CountOfLines)

        # Überprüfe, ob der Text im Makro gefunden wurde
        if ($Code -like "*$ZuSuchenderText*") {  
            $Ergebnis = "Datei: $Datei - Modul: $($Modul.Name) - Zeile: $($Code.IndexOf($ZuSuchenderText) + 1)"  
            $Ergebnisse += $Ergebnis
        }
    }

    # Schließe die Arbeitsmappe
    $Arbeitsmappe.Close()
}

# Speichere die Ergebnisse in der Ergebnisdatei
$Ergebnisse | Out-File -FilePath $ErgebnisDatei

# Schließe die Excel-Anwendung
$excel.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | Out-Null
Remove-Variable excel

Write-Host "Die Suche wurde abgeschlossen. Die Ergebnisse wurden in $ErgebnisDatei gespeichert."  
7907292512
7907292512 22.09.2023 aktualisiert um 10:32:30 Uhr
Goto Top
### auf ChatGPT, so geht's wesentlich schneller ohne Com-Object wenn es Dateien im neuen Office-Format sind (Die alten *.xls sollte man sowieso schon mal konvertiert haben, schon aus Sicherheitsgründen empfehlenswert).
Könnte man auch noch multihreaded laufen lassen wenn man wollte, dann wäre es noch schneller.
Gibt die Pfade der Dateien aus bei denen es einen Treffer gibt.

Powershell:
# Dateiordner der rekursiv durchsucht wird
$folder = "D:\Ordner"  
# Zu verarbeitende Dateierweiterungen
$extensions = '*.xlsm','*.xltm'  
# Suchbegriff im VBA-Code
$searchstring = '\\Server\PC Software\V\Software.xlam'  
# ----------------
Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.Filesystem
$vbapfile = "$env:TEMP\vbaProject.bin"   
$log = foreach ($file in Get-ChildItem $folder -File -Recurse -Include $extensions){
    $zipfile = [System.IO.Compression.ZipFile]::Open($file.Fullname,[System.IO.Compression.ZipArchiveMode]::Read)
    $entry = $zipfile.Entries | ? Name -eq 'vbaProject.bin' | select -First 1  
    remove-item $vbapfile -Force -EA Ignore
    if ($entry){
        [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry,$vbapfile)
        $zipfile.Dispose()
        if (Select-String -Path $vbapfile -Pattern $searchstring -SimpleMatch -Quiet){
            $file.Fullname
        }
    }
}
$log

Sid.
DennisVot
DennisVot 29.09.2023 um 06:57:55 Uhr
Goto Top
Hallo himem.sys,

danke, bis auf wenige kleine Anpassungen hat das funktioniert und hat mir sehr weitergeholfen.

Gruß
Dennis
DennisVot
DennisVot 29.09.2023 um 06:59:35 Uhr
Goto Top
Hallo Sid,

der Ansatz ist gut und bestimmt effektiver/schneller. Jedoch sind tatsächlich viele der Excel-Files im alten Excel-Dateiformat abgespeichert und deswegen ist das Makro so für ich in diesem Fall nicht nutzbar.

Gruß
Dennis