Hallo zusammen,
ich drehe mich (mal wieder) im Kreis und finde keine Erklärung zu meinem Effekt/Fehler. Daher wende ich mich hier ans Forum und hoffe auf einen Tip oder gar eine Lösung.
Beschreibung / Ziel des Ganzen:
- Rekursiver Vergleich/Suche von Files über zwei beliebig zu wählende Startpunkte
Tools:
- UDF - _RecursiveFileListToArray()
Ablauf (schematisch):
- Start des Scripts – öffnet GUI zur Auswahl der StartVerzeichnisse und ggf. Filter
- Suche läuft
- Ergebnisanzeige mittels _ArrayDispaly()
Ergebnis:
Die Differenz der gefundenen Dateien (je nach gesetztem Filter).
Im Ergebnis Array wird in einer Spalte der Name der Datei aufgeführt und in einer zweiten Spalte in welchem Verzeichnis sich das File befindet
Problem:
wie oben beschrieben funktioniert das auch soweit. Die Suche funktioniert mit allen möglichen Filtern (von *.*, über eigene nicht in der Listbox aufgeführte Filter).
Das Problem taucht nur beim Einsatz genau eines Filters auf – dem für die Excel Files auf (der Letzte der Liste) - WARUM - ich sehe bzw. verstehe es nicht !
Die Filter (RegEx Format) sehen wie folgt aus:
.+\.(txt|TXT) - OK
.+\.(doc|DOC|docx|DOCX) ) - OK
.+\.(nsf|NSF|ntf|NTF) ) - OK
.+\.(xls|XLS|xlsx|XLSX|xlsm|XLSM) - FEHLERHAFTER FILTER !
Fehler:
(Der Abbruch wird im Script an folgender Stelle erzeugt (Zeile 124))
..\cde_file_search_compare_testGUI.au3 (124) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
$aResult[$iNew][0] = $aReturn2[$i] ^ ERROR ->11:19:38 AutoIT3.exe ended.rc:1
ScriptSnip Fehlerstelle:
;~ _ArrayDisplay($aResult)
For $i = 1 To $aReturn2[0]
$aResult[$iNew][0] = $aReturn2[$i]
$aResult[$iNew][3] = "nur auf '" & $cde_Verz2 & "' vorhanden" ;Kenzeichnung dass Datei nur in 2
$iNew += 1
Next
$aResult[0][0] = $iNew - 1
ReDim $aResult[$iNew][4]
$aResult[0][1] = $cde_Verz1
$aResult[0][2] = $cde_Verz2
$aResult[0][3] = "Differenz"
Return $aResult
EndFunc ;==>_Check
(Anm.: Natürlich sind in den Testverzeichnissen entsprechende Files (in beliebiger Kombination) vorgehalten.)
Script:
[autoit]
#include <Array.au3>
#include <ButtonConstants.au3>
#include <Date.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
Opt("GUIDataSeparatorChar", "¦")
[/autoit][autoit][/autoit][autoit]$pattern1 = "*.txt"
$pattern2 = "*.doc | docx"
$pattern3 = "*.nsf | ntf"
$pattern4 = "*.xls | xlsx | xlsm"
;~ '.+\.(txt|TXT)'
;~ '.+\.(doc|DOC|docx|DOCX)'
;~ '.+\.(xls|XLS|xlsx|XLSX|xlsm|XLSM)'
;~ '.+\.(nsf|NSF|ntf|NTF)'
$Form1 = GUICreate("DirSync / Compare", 317, 232, 471, 156)
$LabelVZ1 = GUICtrlCreateLabel("Set Directory 1: ", 24, 48, 93, 20)
GUICtrlSetFont(-1, 9, 800, 0, "Century Gothic")
$LabelVz2 = GUICtrlCreateLabel("Set Directory 2: ", 24, 80, 93, 20)
GUICtrlSetFont(-1, 9, 800, 0, "Century Gothic")
$InputVz1 = GUICtrlCreateInput("d:\test1", 120, 48, 153, 21)
$InputVz2 = GUICtrlCreateInput("d:\test2", 120, 80, 153, 21)
;~ $InputPattern = GUICtrlCreateInput("*.*", 120, 120, 153, 21)
$LabelFilter = GUICtrlCreateLabel("Set Filter:", 43, 126, 54, 20)
GUICtrlSetFont(-1, 9, 800, 0, "Century Gothic")
$FilterCombo = GUICtrlCreateCombo("*.*", 120, 120, 153, 21)
GUICtrlSetFont(-1, 9, 400, 0, "Century Gothic")
GUICtrlSetData(-1, $pattern1 & '¦' & $pattern2 & '¦' & $pattern3 & '¦' & $pattern4) ; add other item and set a new default
GUICtrlSetFont(-1, 8, 800, 0, "Century Gothic")
$GroupEingaben1 = GUICtrlCreateGroup(" Recursive Search - Parameter ", 8, 16, 289, 193)
GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif")
$Button1OK = GUICtrlCreateButton("Start", 40, 168, 97, 25)
$Button2Cancel = GUICtrlCreateButton("Cancel", 176, 168, 97, 25)
GUICtrlCreateGroup("", -99, -99, 1, 1)
GUISetState(@SW_SHOW)
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $Button1OK
$cde_Verz1 = (GUIctrlread($InputVz1))
$cde_Verz2 = (GUIctrlread($InputVz2))
$cde_FileExt = (GUIctrlread($FilterCombo))
If $cde_FileExt = "*.txt" Then
$cde_FileExtStr = ".+\.(txt|TXT)"
ElseIf $cde_FileExt = "*.doc | docx" Then
$cde_FileExtStr = ".+\.(doc|DOC|docx|DOCX)"
ElseIf $cde_FileExt = "*.xls | xlsx | xlsm" Then
;~ $cde_FileExtStr = ".+\.(xls|xlsx)"
$cde_FileExtStr = ".+\.(xls|xlsx|XLS|XLSX)"
ElseIf $cde_FileExt = "*.nsf | ntf" Then
$cde_FileExtStr = ".+\.(nsf|NSF|ntf|NTF)"
ElseIf $cde_FileExt = "*.*" Then
$cde_FileExtStr = ""
Else
MsgBox(0,"",$cde_FileExt)
$cde_FileExt = StringReplace($cde_FileExt,'*.', '.+\.')
MsgBox(0,"",$cde_FileExt)
$cde_FileExtStr = $cde_FileExt
EndIf
If $cde_FileExtStr="" Then
MsgBox(0,"","Vz1 : " & $cde_Verz1 & @CRLF & "Vz2 : " & $cde_Verz2 & @CRLF & "Filter : <NUL>")
Else
MsgBox(0,"","Vz1 : " & $cde_Verz1 & @CRLF & "Vz2 : " & $cde_Verz2 & @CRLF & "Filter : " & $cde_FileExtStr)
EndIf
$aChecked = _Check($cde_Verz1, $cde_Verz2, 0)
If $cde_FileExtStr = "" Then
_ArrayDisplay($aChecked,"Datei Abgleich - Filter: [*.*]")
Else
_ArrayDisplay($aChecked,"Datei Abgleich - Filter: [" & $cde_FileExtStr & "]")
EndIf
Case $Button2Cancel
ExitLoop
Case $GUI_EVENT_CLOSE
Exit
[/autoit][autoit][/autoit][autoit]EndSwitch
WEnd
Func _Check($cde_Verz1, $cde_Verz2, $iDays)
;~ $aReturn1 = _RecursiveFileListToArray($cde_Verz1, '.+\.(txt|TXT|jpg)', 1, 1, @CRLF, $cde_Verz1) ; Alle Dateien im ausgewählten Ordner und Unterordnern)
;~ $aReturn2 = _RecursiveFileListToArray($cde_Verz2, '.+\.(txt|TXT|jpg)', 1, 1, @CRLF, $cde_Verz2) ; Alle Dateien im ausgewählten Ordner und Unterordnern)
$aReturn1 = _RecursiveFileListToArray($cde_Verz1, $cde_FileExtStr, 1, 1, @CRLF, $cde_Verz1) ; Alle Dateien im ausgewählten Ordner und Unterordnern)
$aReturn2 = _RecursiveFileListToArray($cde_Verz2, $cde_FileExtStr, 1, 1, @CRLF, $cde_Verz2) ; Alle Dateien im ausgewählten Ordner und Unterordnern)
Local $aResult[$aReturn1[0] + $aReturn2[0]][4]
$iNew = 1
_ArrayDisplay($aReturn1,"Array Vrz1")
_ArrayDisplay($aReturn2,"Array Vrz2")
For $i = 1 To $aReturn1[0]
$iPos = _ArraySearch($aReturn2, $aReturn1[$i])
If $iPos > -1 Then ;datei existiert auch um 2. Verzeichnis
_ArrayDelete($aReturn2, $iPos) ;damit in $aReturn2 nur Dateien übrigbleiben die nicht i $aReturn1 sind
$aReturn2[0] -= 1
Else
$aResult[$iNew][0] = $aReturn1[$i]
$aResult[$iNew][2] = ''
$aResult[$iNew][3] = "nur auf '" & $cde_Verz1 & "' vorhanden" ;Kenzeichnung dass Datei nur in 1
$iNew += 1
EndIf
Next
;~ _ArrayDisplay($aResult)
For $i = 1 To $aReturn2[0]
$aResult[$iNew][0] = $aReturn2[$i]
$aResult[$iNew][3] = "nur auf '" & $cde_Verz2 & "' vorhanden" ;Kenzeichnung dass Datei nur in 2
$iNew += 1
Next
$aResult[0][0] = $iNew - 1
ReDim $aResult[$iNew][4]
$aResult[0][1] = $cde_Verz1
$aResult[0][2] = $cde_Verz2
$aResult[0][3] = "Differenz"
Return $aResult
EndFunc ;==>_Check
;===============================================================================
; Function Name: _RecursiveFileListToArray($sPath, $sPattern, $iFlag = 0, $iFormat = 1, $sDelim = @CRLF)
; Description:: gibt Verzeichnisse und/oder Dateien (rekursiv) zurück, die
; einem RegExp-Pattern entsprechen
; Parameter(s): $sPath = Startverzeichnis
; $sPattern = ein beliebiges RexExp-Pattern für die Auswahl
; $iFlag = Auswahl
; 0 = Dateien & Verzeichnisse
; 1 = nur Dateien
; 2 = nur Verzeichnisse
; $iFormat = Rückgabeformat
; 0 = String
; 1 = Array mit [0] = Anzahl
; 2 = Nullbasiertes Array
; $sDelim = Trennzeichen für die String-Rückgabe
; Requirement(s): AutoIt 3.3.0.0
; Return Value(s): Array/String mit den gefundenen Dateien/Verzeichnissen
; Author(s): Oscar (http://www.autoit.de)
; Anregungen von: bernd670 (http://www.autoit.de)
;modified: autoBert um den ursprünglich übergebenen Ordner wegzulassen
;===============================================================================
;~ Pattern zum Filtern - cde ^(([a-zA-Z]:)|(\\{2}\w+)\$?)(\\(\w[\w ]*))+\.(nsf|NSF|ntf|NTF)$
;~ ^([a-zA-z]:((\\([-*\.*\w+\s+\d+]+)|(\w+)\\)+)(\w+.nsf)|(\w+.NSF)|(\w+.ntf)|(\w+.NTF))$
;~ .+\.(nsf|ntf)
Func _RecursiveFileListToArray($sPath, $sPattern, $iFlag = 0, $iFormat = 1, $sDelim = @CRLF, $sExlude = '')
Local $hSearch, $sFile, $sReturn = ''
If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
$hSearch = FileFindFirstFile($sPath & '*.*')
If @error Or $hSearch = -1 Then Return SetError(1, 0, $sReturn)
While True
$sFile = FileFindNextFile($hSearch)
If @error Then ExitLoop
If StringInStr(FileGetAttrib($sPath & $sFile), 'D') Then
If StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim
$sReturn &= _RecursiveFileListToArray($sPath & $sFile & '\', $sPattern, $iFlag, 0, $sDelim, $sExlude)
ContinueLoop
EndIf
If StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim
WEnd
FileClose($hSearch)
$sReturn = StringReplace($sReturn, $sExlude, "")
If $iFormat Then Return StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat)
Return $sReturn
EndFunc ;==>_RecursiveFileListToArray
Jetzt hoffe ich mal auf das Wissen hier und bedanke mich schon mal
Gruss
ugt100