Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Anzeige
Inhaltsverzeichnis

VBA Dateien in anderen Ordner kopieren mit Bedingung

Forumthread: VBA Dateien in anderen Ordner kopieren mit Bedingung

VBA Dateien in anderen Ordner kopieren mit Bedingung
16.01.2025 23:46:16
Christian
Hallo,

ich versuche seit Stunden mit Chatgpt ein Makro zu erstellen, aber es funktioniert einfach nicht.

Eigentlich ganz simpel, ich will alle Dateien von E:\Videos nach E:\U30 kopieren, die die beiden folgenden Bedingungen erfüllen.

1. Einer der 30 Texte in Rechnung!H2:H31 muss im Dateinamen enthalten sein.
2. Es darf keine Datei mit demselben Namen bereits vorhanden sein. Wobei ich bei den Dateinamen im Ordner U30 das letze Wort entweder ganz gelöscht habe oder durch entweder das wort löschen oder das Wort gesehen ersetzt habe. Das Makro muss also das letzte Wort des Dateinamens im Ordner Videos unter den Tisch kehren, weil es beim Dateinamen im Ordner U30 entweder gelöscht wurde oder durch "löschen" oder "gesehen" ersetzt wurde.

ABer alles was Chatgpt zustande bringt ist ein Makro dass entweder gar nichts kopiert oder alle Dateien, die einen der 30 Texte im Namen haben.

Das ist nach vielen Fehlersuchen der Stand der Dinge:

Sub CopyMatchingFiles()

Dim sourceFolder As String
Dim destinationFolder As String
Dim fileSystem As Object
Dim sourceFile As Object
Dim fileName As String
Dim baseFileName As String
Dim modifiedBaseFileName As String
Dim modifiedBaseFileNameWithReplace As String
Dim modifiedBaseFileNameWithSeen As String
Dim destinationFiles As Object
Dim destinationFile As Object
Dim matchFound As Boolean
Dim searchTermDict As Object
Dim key As Variant
Dim ws As Worksheet
Dim lastWord As String

' Bildschirmaktualisierung und Berechnung ausschalten
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False

On Error GoTo Cleanup

' Ordnerpfade festlegen
sourceFolder = "E:\Videos"
destinationFolder = "E:\U30"
Set ws = Worksheets("Rechnung")

' Suchbegriffe aus Rechnung!H2:H31 in ein Dictionary laden
Set searchTermDict = CreateObject("Scripting.Dictionary")
For Each cell In ws.Range("H2:H31")
If cell.Value > "" Then
searchTermDict(cell.Value) = True
End If
Next cell

' Dateisystemobjekt erstellen
Set fileSystem = CreateObject("Scripting.FileSystemObject")

' Zielordner-Dateien zwischenspeichern
Set destinationFiles = CreateObject("Scripting.Dictionary")
For Each destinationFile In fileSystem.GetFolder(destinationFolder).Files
destinationFiles(fileSystem.GetBaseName(destinationFile.Name)) = True
Next destinationFile

' Dateien im Quellordner durchlaufen
For Each sourceFile In fileSystem.GetFolder(sourceFolder).Files
fileName = sourceFile.Name
' Basis-Dateinamen ermitteln (ohne Nummer und Dateiendung)
baseFileName = fileSystem.GetBaseName(fileName)

' Basis-Dateinamen modifizieren (letztes Wort entfernen, durch "löschen" oder "gesehen" ersetzen)
lastWord = GetLastWord(baseFileName)
modifiedBaseFileName = RemoveLastWord(baseFileName) ' Letztes Wort entfernen
modifiedBaseFileNameWithReplace = ReplaceLastWordWith(baseFileName, "löschen") ' Letztes Wort durch "löschen" ersetzen
modifiedBaseFileNameWithSeen = ReplaceLastWordWith(baseFileName, "gesehen") ' Letztes Wort durch "gesehen" ersetzen

' Debugging: Geben Sie die Dateinamen aus, um zu sehen, welche Varianten erstellt werden
Debug.Print "Quelle: " & baseFileName
Debug.Print "Modifiziert: " & modifiedBaseFileName
Debug.Print "Mit 'löschen': " & modifiedBaseFileNameWithReplace
Debug.Print "Mit 'gesehen': " & modifiedBaseFileNameWithSeen

' Prüfen, ob der modifizierte Basisname mit einem der Suchbegriffe übereinstimmt
matchFound = False
For Each key In searchTermDict.Keys
If InStr(1, modifiedBaseFileName, key, vbTextCompare) > 0 Or _
InStr(1, modifiedBaseFileNameWithReplace, key, vbTextCompare) > 0 Or _
InStr(1, modifiedBaseFileNameWithSeen, key, vbTextCompare) > 0 Then
matchFound = True
Exit For
End If
Next key

' Weitere Übereinstimmungen prüfen, wenn die Datei im Zielordner existiert
If matchFound Then
If destinationFiles.Exists(modifiedBaseFileName) Or _
destinationFiles.Exists(modifiedBaseFileNameWithReplace) Or _
destinationFiles.Exists(modifiedBaseFileNameWithSeen) Then
' Datei kopieren, wenn Übereinstimmung gefunden wurde
Debug.Print "Kopieren: " & fileName ' Debugging: Ausgabe der zu kopierenden Datei
fileSystem.CopyFile sourceFile.Path, fileSystem.BuildPath(destinationFolder, fileName)
Else
Debug.Print "Keine Übereinstimmung für: " & fileName ' Debugging: Wenn keine Übereinstimmung gefunden wird
End If
End If

' DoEvents hier aufrufen, um Excel reaktionsfähig zu halten
DoEvents
Next sourceFile

Cleanup:
' Bildschirmaktualisierung und Berechnung wieder einschalten
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True

MsgBox "Der Kopiervorgang ist abgeschlossen.", vbInformation
End Sub

' Funktion, um das letzte Wort aus einem Dateinamen zu entfernen
Function RemoveLastWord(baseName As String) As String
Dim words() As String
Dim i As Long
Dim result As String

' Namen in Wörter aufteilen
words = Split(baseName, " ")

' Wenn es nur ein Wort gibt, bleibt der Name gleich
If UBound(words) = 0 Then
RemoveLastWord = baseName
Exit Function
End If

' Alle Wörter außer dem letzten zusammenfügen
For i = LBound(words) To UBound(words) - 1
If result > "" Then result = result & " "
result = result & words(i)
Next i

RemoveLastWord = result
End Function

' Funktion, um das letzte Wort im Dateinamen durch einen angegebenen Wert zu ersetzen
Function ReplaceLastWordWith(baseName As String, replacement As String) As String
Dim words() As String
Dim i As Long
Dim result As String

' Namen in Wörter aufteilen
words = Split(baseName, " ")

' Wenn es nur ein Wort gibt, bleibt der Name gleich
If UBound(words) = 0 Then
ReplaceLastWordWith = baseName
Exit Function
End If

' Alle Wörter außer dem letzten zusammenfügen und das letzte Wort durch den angegebenen Ersatz ersetzen
For i = LBound(words) To UBound(words) - 1
If result > "" Then result = result & " "
result = result & words(i)
Next i

ReplaceLastWordWith = result & " " & replacement
End Function

' Funktion, um das letzte Wort aus einem Dateinamen zu extrahieren
Function GetLastWord(baseName As String) As String
Dim words() As String
words = Split(baseName, " ")
GetLastWord = words(UBound(words))
End Function




Ich hoffe ihr könnt mir helfen.
Christian
Und vielen Dank
Anzeige

20
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: VBA Dateien in anderen Ordner kopieren mit Bedingung
17.01.2025 01:43:07
Klexy
Gib dem Bereich Rechnung!H2:H31 mit dem Namens-Manager den Namen "Solltexte_Liste".
Das Makro geht davon aus, dass keine dieser Zelle leer ist. Wenn doch, musst du das gesondert abfangen.
Kopier das Makro in ein Modul deiner Datei.
Und lass es krachen.



Option Explicit

Sub VideoDateien_kopieren()

Dim objFileSystem As Object
Dim QuellVerzeichnis As Object, ZielVerzeichnis As Object
Dim QuellDateien As Object, ZielDateien As Object
Dim QuellDatei As Object, DateiNameOhneLetztesWort As String, ZielDatei As Object
Dim QuellDateiEndung As String, QuellDateiName As String, ZielDateiName As String
Dim QuellPfad As String, ZielPfad As String
Dim Text As Range, TextNichtEnthalten As Boolean, SchonVorhanden As Boolean, x As Integer, y As Integer, z As Integer
' Pfade definieren
QuellPfad = "E:\Videos\"
ZielPfad = "E:\U30\"
x = 0 ' Zähler ohne Stichwort
y = 0 ' Zähler schon vorhanden
z = 0 ' Zähler kopierte

Set objFileSystem = CreateObject("scripting.FileSystemObject")
Set QuellVerzeichnis = objFileSystem.GetFolder(QuellPfad)
Set ZielVerzeichnis = objFileSystem.GetFolder(ZielPfad)
Set QuellDateien = QuellVerzeichnis.Files ' alle Dateien im Quellverzeichnis
Set ZielDateien = ZielVerzeichnis.Files ' alle Dateien im Zielverzeichnis

For Each QuellDatei In QuellDateien ' Quellverzeichnis durchgehen
QuellDateiName = QuellDatei.Name
QuellDateiEndung = Mid(QuellDateiName, InStrRev(QuellDateiName, "."), 10)
DateiNameOhneLetztesWort = Left(QuellDateiName, InStrRev(QuellDateiName, " ") - 1)
ZielDateiName = DateiNameOhneLetztesWort & QuellDateiEndung

TextNichtEnthalten = False
For Each Text In Range("Solltexte_Liste") ' Liste der 30 Texte durchgehen
If InStr(QuellDateiName, Text.Value) > 0 Then
' wenn Text in Dateiname enthalten --> weiter zum kopieren
TextNichtEnthalten = True
Exit For
Else
' wenn Text in Dateiname nicht enthalten --> nix
End If
Next Text

If TextNichtEnthalten = False Then
' wenn Text in Dateiname nicht enthalten --> nächste Quelldatei
x = x + 1
GoTo NaechsteDatei
End If

If ZielDateien.Count = 0 Then
' wenn ZielVerzeichnis noch leer ist (sicherheitshalber) --> Datei kopieren
objFileSystem.copyfile QuellPfad & QuellDateiName, ZielPfad & ZielDateiName
z = z + 1
Else
SchonVorhanden = False
For Each ZielDatei In ZielDateien ' Zielverzeichnis durchgehen
If ZielDatei.Name = ZielDateiName Then
' wenn der Name schon vorhanden ist --> nächste Quelldatei
SchonVorhanden = True
y = y + 1
Exit For
Else
' wenn der Name noch nicht vorhanden ist --> nix
End If
Next ZielDatei

If SchonVorhanden = False Then
' wenn der Name noch nicht vorhanden ist --> Datei kopieren
objFileSystem.copyfile QuellPfad & QuellDatei.Name, ZielPfad & ZielDateiName
z = z + 1
End If
End If
NaechsteDatei:
Next QuellDatei

MsgBox z & " Dateien kopiert" & vbCr & y & " schon vorhanden" & vbCr & x & " ohne Stichwort"

End Sub
Anzeige
AW: VBA Dateien in anderen Ordner kopieren mit Bedingung
17.01.2025 08:44:51
Christian
Hallo Klexy,

sei mir bitte nicht böse, aber es ist garantiert, dass keine der Zellen in Rechnung!H2:H31 leer ist. Außerdem es gab ja Versuche, in denen Dateien kopiert wurden, nur zu viele. Jedoch die Unterscheidung ob einer dieser Texte im Dateinamen enthalten ist, hat da jedes Mal funktioniert und ich habe diesen Teil dann auch nicht mehr geändert.
Das Problem wird also höchstwahrscheinlich bei der zweiten Bedingung liegen.

Danke
Christian
Anzeige
Testergebnis
17.01.2025 21:31:31
Christian
Hallo Klexy,

vielen Dank für deine Mühe.

ich kann mir 2 Dinge leider nicht erklären.

Zum einen (und das ist wirklich nur dieser eine Fall) wird die Datei MRS 06770 Another Me (04.09.2014) - Sophie Turner (21.02.1996) 18-196 204.mp4 kopiert, obwohl bereits eine Datei MRS 06770 Another Me (04.09.2014) - Sophie Turner (21.02.1996) 18-196.mp4 vorhanden ist.... in allen anderen Fällen funktioniert der Vergleich...
Kann es damit zusammenhängen, dass dies die erste Datei in der Liste steht, in der einer der 30 Begriffe gefunden wird?

Zum anderen gibt es z.B. 5 Dateien die mit MRS 07674 I Still See You (12.10.2018) - Bella Thorne (08.10.1997) 21-4 beginnen und sich nur durch das letzte Wort unterscheiden. Das Ganze war so gemeint, dass alle 5 kopiert werden. Im Moment sieht es für mich so aus, dass nur eine Datei kopiert wird, das letzte Wort vom Dateinamen abgeschnitten wird und dann bei den nächsten 4 Versuchen der Dateiname als bereits vorhanden angesehen wird.

Überhaupt hatte ich nicht die Absicht dass das Makro Dateinamen ändert, in keiner der beiden Verzeichnisse.

Gruß
Christian
Anzeige
AW: VBA Dateien in anderen Ordner kopieren mit Bedingung
17.01.2025 13:46:51
Klexy
Sorry, ich hab mir deinen Code überhaupt nicht angeschaut. Ich hatte schon ähnliche Aufgabenstellungen und hab dir einen von Grund auf neuen Code geschrieben, der deiner Beschreibung entspricht. Und getestet. Und funktioniert.
Das mit den leeren Zellen hab ich nur erwähnt, weil meine Erfahrung mit Aufgabenbeschreibungen mich lehrt, dass solche Sachen gern mal vergessen werden.
Was ich auch nicht abgefangen hab, ist dass der Dateiname nur ein Wort hat und somit kein "letztes" Wort.
Anzeige
AW: VBA Dateien in anderen Ordner kopieren mit Bedingung
17.01.2025 14:00:45
Christian
Hallo Klexy,

lezteres brauchst du auch nicht abfangen, der Dateiname hat immer mehr als 1 Wort.

Fange jetzt an ne Bsp Datei zu basteln.

Gruß
Christian
Korrektur
17.01.2025 01:57:25
Klexy
Alles gilt wie oben schon gesagt.
Die neu kopierten Dateien werden ohne das letzte Wort kopiert.
In der letzten Version hatte ich aber nicht auf "löschen" oder "gesehen" oder auf ein versehentlich stehengebliebenes Leerzeichen vor der Dateiendung geprüft.
Wenn du den neu kopierten Dateien standardmäßig das "gesehen" anhängen willst, musst du in den beiden Zeilen
objFileSystem.copyfile QuellPfad & QuellDatei.Name, ZielPfad & ZielDateiName

jeweils das ZielDateiName durch ZielDateiNameGesehen ersetzen.

 

Option Explicit

Sub VideoDateien_kopieren()

Dim objFileSystem As Object
Dim QuellVerzeichnis As Object, ZielVerzeichnis As Object
Dim QuellDateien As Object, ZielDateien As Object
Dim QuellDatei As Object, DateiNameOhneLetztesWort As String, ZielDatei As Object
Dim QuellDateiEndung As String, QuellDateiName As String
Dim ZielDateiName As String, ZielDateiNameLoeschen As String, ZielDateiNameGesehen As String, ZielDateiNameLeerEnde As String
Dim QuellPfad As String, ZielPfad As String
Dim Text As Range, TextNichtEnthalten As Boolean, SchonVorhanden As Boolean, x As Integer, y As Integer, z As Integer
' Pfade definieren
QuellPfad = "E:\Videos\"
ZielPfad = "E:\U30\"
x = 0 ' Zähler ohne Stichwort
y = 0 ' Zähler schon vorhanden
z = 0 ' Zähler kopierte

Set objFileSystem = CreateObject("scripting.FileSystemObject")
Set QuellVerzeichnis = objFileSystem.GetFolder(QuellPfad)
Set ZielVerzeichnis = objFileSystem.GetFolder(ZielPfad)
Set QuellDateien = QuellVerzeichnis.Files ' alle Dateien im Quellverzeichnis
Set ZielDateien = ZielVerzeichnis.Files ' alle Dateien im Zielverzeichnis

For Each QuellDatei In QuellDateien ' Quellverzeichnis durchgehen
QuellDateiName = QuellDatei.Name
QuellDateiEndung = Mid(QuellDateiName, InStrRev(QuellDateiName, "."), 10)
DateiNameOhneLetztesWort = Left(QuellDateiName, InStrRev(QuellDateiName, " ") - 1)
ZielDateiName = DateiNameOhneLetztesWort & QuellDateiEndung
ZielDateiNameLoeschen = DateiNameOhneLetztesWort & " löschen" & QuellDateiEndung
ZielDateiNameGesehen = DateiNameOhneLetztesWort & " gesehen" & QuellDateiEndung
ZielDateiNameLeerEnde = DateiNameOhneLetztesWort & " " & QuellDateiEndung

TextNichtEnthalten = False
For Each Text In Range("Solltexte_Liste") ' Liste der 30 Texte durchgehen
If InStr(QuellDateiName, Text.Value) > 0 Then
' wenn Text in Dateiname enthalten --> weiter zum kopieren
TextNichtEnthalten = True
Exit For
Else
' wenn Text in Dateiname nicht enthalten --> nix
End If
Next Text

If TextNichtEnthalten = False Then
' wenn Text in Dateiname nicht enthalten --> nächste Quelldatei
x = x + 1
GoTo NaechsteDatei
End If

If ZielDateien.Count = 0 Then
' wenn ZielVerzeichnis noch leer ist (sicherheitshalber) --> Datei kopieren
objFileSystem.copyfile QuellPfad & QuellDateiName, ZielPfad & ZielDateiName
z = z + 1
Else
SchonVorhanden = False
For Each ZielDatei In ZielDateien ' Zielverzeichnis durchgehen
If ZielDatei.Name = ZielDateiName Or _
ZielDatei.Name = ZielDateiNameLoeschen Or _
ZielDatei.Name = ZielDateiNameGesehen Or _
ZielDatei.Name = ZielDateiNameLeerEnde Then
' wenn der Name schon vorhanden ist --> nächste Quelldatei
SchonVorhanden = True
y = y + 1
Exit For
Else
' wenn der Name noch nicht vorhanden ist --> nix
End If
Next ZielDatei

If SchonVorhanden = False Then
' wenn der Name noch nicht vorhanden ist --> Datei kopieren
objFileSystem.copyfile QuellPfad & QuellDatei.Name, ZielPfad & ZielDateiName
z = z + 1
End If
End If
NaechsteDatei:
Next QuellDatei

MsgBox z & " Dateien kopiert" & vbCr & y & " schon vorhanden" & vbCr & x & " ohne Stichwort"

End Sub

Anzeige
AW: Korrektur
17.01.2025 21:09:34
Christian
Hallo Klexy,

sorry nochmal für das Misverständnis, dass ich dachte du hättest nur den Bereich mit der Prüfung H2:H31 angepasst.
Habe jetzt versucht das zweite Makro zu testen, bislang unverändert, so wie es da steht.

Ich bekomme in der Zeile For Each Text In Range("Solltexte_Liste") ' Liste der 30 Texte durchgehen

Die Methode `Range` für das Objekt `_global` ist fehlgeschlagen

Laufzeitfehler 1004

Schaust du bitte nochmal
Christian
Anzeige
ok, das mit dem namensmanager muss ich noch machen owt
17.01.2025 21:11:03
Christian
AW: Korrektur
17.01.2025 21:59:17
Klexy
Bin grad ohne Computer.
Ich schau heut nacht.
AW: Korrektur
17.01.2025 22:41:14
Christian
kein Problem,

schau dir aber bitte auch meine andere Antwort an, was passiert ist, nach dem ich den Fehler mit der fehlgeschlagenen Methode behoben hatte.

Gruß
Christian
Anzeige
AW: Korrektur
17.01.2025 23:46:10
Klexy
Ich hab den Überblick verloren in den vielen Beiträgen.
Meine Testdatei funktioniert einwandfrei.
Häng mal deine Datei, in der der Fehler auftritt an und schreib nochmal explizit dazu, was nicht passt.
scheine jetzt eine funktionierende Lösung zu haben
18.01.2025 17:51:21
Christian
danke für deine Mühe und noch ein schönes Wochenende

Sub CopyMp4Files()

Dim sourceFolder As String
Dim destinationFolder As String
Dim keywords As Variant
Dim fileSystem As Object
Dim sourceFile As Object
Dim file As Object
Dim keyword As Variant
Dim fileName As String
Dim matchesCriteria As Boolean
Dim modifiedName As String
Dim lastSpace As Long
Dim existingFiles As Object
Dim destFile As Object
Dim ws As Worksheet
Dim keywordRange As Range

' Festlegen der Ordnerpfade
sourceFolder = "E:\Videos\"
destinationFolder = "E:\U30\"

' Festlegen des Bereichs mit Schlüsselwörtern
Set ws = ThisWorkbook.Sheets("Rechnung")
Set keywordRange = ws.Range("H2:H31")
keywords = keywordRange.Value

' Zugriff auf das Dateisystem
Set fileSystem = CreateObject("Scripting.FileSystemObject")
Set sourceFile = fileSystem.GetFolder(sourceFolder)

' Überprüfen, welche Dateien bereits im Zielordner vorhanden sind (Nur einmal zu Beginn)
Set existingFiles = CreateObject("Scripting.Dictionary")
For Each destFile In fileSystem.GetFolder(destinationFolder).Files
' Nur die vollständigen Namen (mit .mp4)
existingFiles.Add Left(destFile.Name, Len(destFile.Name) - 4), True
Next destFile

' Durchlaufen der Dateien im Quellordner
For Each file In sourceFile.Files
If fileSystem.GetExtensionName(file.Name) = "mp4" Then
' Modifizierten Namen ohne das letzte Wort (aus dem Quellordner)
modifiedName = Left(file.Name, Len(file.Name) - 4) ' Entfernen der .mp4 Erweiterung
lastSpace = InStrRev(modifiedName, " ")
If lastSpace > 0 Then
modifiedName = Left(modifiedName, lastSpace - 1) ' Entfernt das letzte Wort
End If

' Überprüfen, ob der modifizierte Name mit einem der Keywords übereinstimmt
matchesCriteria = False
For Each keyword In keywords
If InStr(modifiedName, keyword) > 0 Then
matchesCriteria = True
Exit For
End If
Next keyword

' Datei kopieren, wenn sie den Kriterien entspricht und noch nicht im Zielordner vorhanden ist
If matchesCriteria And Not IsFileExisting(modifiedName, existingFiles) Then
' Datei kopieren
fileSystem.CopyFile file.Path, destinationFolder & file.Name
End If
End If
Next file
End Sub

' Funktion zur Überprüfung, ob der modifizierte Name bereits im Zielordner vorhanden ist
Function IsFileExisting(modifiedName As String, existingFiles As Object) As Boolean
Dim key As Variant
For Each key In existingFiles.Keys
' Überprüfen, ob der modifizierte Name mit einem vorhandenen Dateinamen im Zielordner beginnt
If InStr(1, key, modifiedName) = 1 Then
IsFileExisting = True
Exit Function
End If
Next key
IsFileExisting = False
End Function
Anzeige
AW: scheine jetzt eine funktionierende Lösung zu haben
19.01.2025 04:57:17
emkaes
Hallo,

komme leider jetzt erst dazu, dir zu antworten.

du machst es dir mMn ein wenig zu umständlich, da du Methoden der FilesystemObjektes und des Dictionary nicht benutzt.

Das FileSystemobjekt stellt die die Methode file.BASENAME zur Verfügung, im Dictionary kannst du auf die Existens eines Keys prüfen ( dic.EXISTS (expression) ).

Darüber hinaus kannst du mit REPLACE Strings ( auch mehrfach ) manipulieren. Mit TRIM entfernst du Leerzeichen am Anfang/Ende einen strings.

Da ich wegen fehlendem Zugriff auf ein FileSystemObjekt mit deinen Beispieldaten über Arrays getestet habe ist das nachfolgende Makro in Analogie erstellt, aber nicht getestet.

Sub cpDateien()

Dim FSO As Object, FS_V As Object, FS_U As Object, fl As Object
Dim dic As Object

Set FSO = CreateObject("Scripting.FileSystemObject")
Set dic = CreateObject("Scripting.Dictionary")

' Daten einlesen
' dic: Dictionary mit Dateinamen aus "E:\U30" ohne Dateiendung, ohne "löschen" ohne "gesehen" ohne Leerzeichen am Ende

Set FS_U = FSO.getfolder("E:\U30")
For Each fl In FS_U.Files
dic (Trim(Replace(Replace(fl.BaseName, "löschen", ""), "gesehen", ""))), 0
Next

' Daten einlesen,vergleichen und kopieren
' arrNamen: Daten aus Tabelle Rechnung, H2:H32 ins Array arrNamen
' äußere Schleife iteriert über Dateinamen
' innere Schleife iteriert über Namen aus Rechnung -> bei Übereinstimmung
' prüfen ob Datei bereits in E:\U30 vorhanden, falls nein Datei kopieren und innere Schleife verlassen
'
Dim arrNamen As Variant, i As Long
With ThisWorkbook.Worksheets("Rechnung")
arrNamen = .Range("H2:H" & .Cells(Row.Count, 8).End(xlUp).Row).Value
End With
Set FS_V = FSO.getfolder("E:\Videos")
For Each fl In FS_V.Files
If FSO.getextensionname(fl.Name) = "mp4" Then
For i = LBound(arrNamen, 1) To UBound(arrNamen, 1)
If InStr(1, fl.BaseName, arrNamen(i, 1)) > 0 Then
If Not dic.exists(fl.BaseName) Then
FSO.CopyFile fl.Path, "E:\U30\" & fl.Name
Exit For
End If
End If
Next
End If
Next
End Sub

Anzeige
ein paar Dinge die mir beim ersten Überfliegen auffallen...
19.01.2025 09:33:07
Christian
Hallo,

vielen Dank für deine Mühe! Kein Problem, dass es etwas gedauert hat. Aktuell sind alle Dateien bereits kopiert, daher wird das Makro momentan keine weiteren Dateien zum Kopieren finden. Ich denke, dass ich am Dienstag neue Dateien für Tests bereit habe.

Ich habe inzwischen ein paar Anpassungen in deinem Makro vorgenommen:

Die Prüfung auf .mp4 habe ich entfernt, da ohnehin alle Dateien in beiden Ordnern .mp4-Dateien sind.
In Spalte H stehen jetzt die Namen aller Schauspieler und in Spalte I deren Geburtstage.
Da mehrere Schauspieler am selben Tag geboren sein können, habe ich den Code angepasst, sodass auch Personen in Zeilen 32, 33 usw. berücksichtigt werden, wenn sie denselben Geburtstag wie die Person in Zeile 31 haben.

Hier ist der aktualisierte Code:

Sub cpDateien()

Dim FSO As Object, FS_V As Object, FS_U As Object, fl As Object
Dim dic As Object
Dim arrNamen As Variant, i As Long, lastRow As Long
Dim ws As Worksheet, lastBirthday As Variant

' Objekte initialisieren
Set FSO = CreateObject("Scripting.FileSystemObject")
Set dic = CreateObject("Scripting.Dictionary")
Set ws = ThisWorkbook.Worksheets("Rechnung")

' Daten aus dem Ordner "E:\U30" in das Dictionary einlesen
' Entfernen von "löschen", "gesehen" und Leerzeichen am Ende
Set FS_U = FSO.GetFolder("E:\U30")
For Each fl In FS_U.Files
dic(Trim(Replace(Replace(fl.BaseName, "löschen", ""), "gesehen", ""))) = 0
Next

' Letzten Geburtstag in I31 auslesen
lastBirthday = ws.Range("I31").Value

' Dynamischen Bereich festlegen, um alle Personen mit demselben Geburtstag einzubeziehen
lastRow = 31
Do While ws.Cells(lastRow + 1, 9).Value = lastBirthday
lastRow = lastRow + 1
Loop

' Namen von H2 bis zum dynamisch bestimmten letzten Bereich einlesen
arrNamen = ws.Range("H2:H" & lastRow).Value

' Dateien aus "E:\Videos" vergleichen und kopieren
Set FS_V = FSO.GetFolder("E:\Videos")
For Each fl In FS_V.Files
For i = LBound(arrNamen, 1) To UBound(arrNamen, 1)
If InStr(1, fl.BaseName, arrNamen(i, 1)) > 0 Then
If Not dic.Exists(fl.BaseName) Then
FSO.CopyFile fl.Path, "E:\U30\" & fl.Name
Exit For
End If
End If
Next
Next
End Sub


Am Dienstag werde ich dir dann Feedback geben.

Viele Grüße
Christian
Anzeige
neuer Chatgpt Versuch
17.01.2025 09:47:32
Christian
Wie ihr seht ist da auch die Zeile drin
Debug.Print "Vergleich mit: " & targetBaseName & " und " & baseName


da stehen dann im Debug Fenster zwei völlig unterschiedliche Dateinamen, also liegt der Fehler vermutlich da.
Ich sitze schon wieder seit ner Stunde dran, Chatgpt das beheben zu lassen, aber es klappt einfach nicht.

Sub CopyFilteredFiles()

' Variablen für die Ordner und die Schlüsselwörter
Dim sourceFolder As String
Dim targetFolder As String
Dim keywords As Variant
Dim fileSystem As Object
Dim sourceFile As Object
Dim targetFile As Object
Dim fileName As String
Dim baseName As String
Dim targetBaseName As String
Dim keyword As Variant
Dim fileExists As Boolean

' Quell- und Zielordner definieren
sourceFolder = "E:\Videos\" ' Ordner, aus dem die Dateien kopiert werden
targetFolder = "E:\U30\" ' Ordner, in den die Dateien kopiert werden

' Schlüsselwörter aus dem Arbeitsblatt "Rechnung", Bereich H2:H31, laden
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Rechnung")
keywords = ws.Range("H2:H31").Value ' Alle Schlüsselwörter in einem Array speichern

' Zugriff auf das Dateisystem vorbereiten
Set fileSystem = CreateObject("Scripting.FileSystemObject")

' Berechnungen ausschalten, um die Leistung zu verbessern
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False ' Verhindert das Aktualisieren der Benutzeroberfläche

' Schleife: Alle Dateien im Quellordner durchlaufen
For Each sourceFile In fileSystem.GetFolder(sourceFolder).Files
fileName = sourceFile.Name ' Beispiel: "MRS 05716 New Year's Eve (08.12.2011) - Abigail Breslin (14.04.1996) 15-238 1832.mp4"
baseName = CleanFileName(fileName) ' Bereinigen des Dateinamens

Debug.Print "Prüfe Datei: " & fileName

' Überprüfen, ob der Dateiname eines der Schlüsselwörter enthält
For Each keyword In keywords
If InStr(1, fileName, keyword, vbTextCompare) > 0 Then ' Schlüsselwort gefunden?
fileExists = False ' Annahme: Datei existiert noch nicht im Zielordner

' Zielordner durchsuchen, um zu prüfen, ob die Datei (oder eine Variante) schon existiert
For Each targetFile In fileSystem.GetFolder(targetFolder).Files
targetBaseName = CleanFileName(targetFile.Name) ' Bereinigen des Ziel-Dateinamens

' Debug: Zieldatei prüfen
Debug.Print "Vergleiche mit Zieldatei: " & targetFile.Name
Debug.Print "Vergleich mit: " & targetBaseName & " und " & baseName

' Prüfen, ob die Basisnamen übereinstimmen oder Varianten existieren
If targetBaseName = baseName Or _
targetBaseName = baseName & " löschen" Or _
targetBaseName = baseName & " gesehen" Then
fileExists = True ' Datei oder Variante existiert schon
Debug.Print "Datei existiert bereits: " & targetFile.Name
Exit For
End If
Next targetFile

' Datei kopieren, wenn sie noch nicht im Zielordner vorhanden ist
If Not fileExists Then
Debug.Print "Kopiere Datei: " & fileName
fileSystem.CopyFile sourceFile.Path, targetFolder & sourceFile.Name ' Kopiervorgang
Exit Sub ' Beendet das Makro nach dem Kopieren der ersten Datei
Else
Debug.Print "Datei wird nicht kopiert, da sie bereits existiert."
End If

' Kurze Unterbrechung, um die Benutzeroberfläche reagieren zu lassen
DoEvents

Exit For ' Ein Schlüsselwort gefunden, keine weiteren prüfen
End If
Next keyword
Next sourceFile

' Berechnungen wieder einschalten
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True ' Benutzeroberfläche wieder aktivieren

' Fertigmeldung
MsgBox "Kopieren abgeschlossen!"
End Sub

' Funktion: Bereinigt den Dateinamen und entfernt alle Anhänge wie Zahlen oder "gesehen"/"löschen"
Function CleanFileName(fileName As String) As String
Dim parts As Variant
Dim ext As String
Dim cleanedName As String
Dim i As Long

' Dateiendung extrahieren (.mp4, .txt etc.)
ext = Mid(fileName, InStrRev(fileName, ".")) ' Beispiel: ".mp4"
fileName = Left(fileName, InStrRev(fileName, ".") - 1) ' Entfernt die Dateiendung

' Dateinamen in Teile (Wörter) aufteilen
parts = Split(fileName, " ")

' Nun alle Anhänge (Zahlen, "gesehen", "löschen") entfernen, falls sie am Ende stehen
i = UBound(parts)
Do While i >= 0
If IsNumeric(parts(i)) Or _
parts(i) = "löschen" Or _
parts(i) = "gesehen" Then
' Entferne das letzte Wort (Zahl oder "löschen" / "gesehen")
i = i - 1
Else
Exit Do ' Wenn wir auf das relevante Wort stoßen, brechen wir die Schleife ab
End If
Loop

' Teile wieder zusammenfügen und Dateiendung anhängen
cleanedName = Join(Split(fileName, " "), " ")

' Bereinigten Namen zurückgeben
CleanFileName = cleanedName & ext
End Function


Anzeige
AW: neuer Chatgpt Versuch
17.01.2025 12:18:42
emkaes
Hallo,

es ist immer einfacher eine aussagekräftige Beispiel-Datei zu haben als irgendeinen Code, der nicht richtig funktioniert.

Deine Beschreibung der Aufgabe und die Codes passen ja nicht zusammen und wir als Helfer sollen dann daraus die entsprechenden Folgerungen ziehen.

Dabei ist fraglich, ob die Beschreibung "richtig" und vollständig ist, oder ob der Hase im Code gepfeffert liegt.

Ergo, lade eine Beispieldatei hoch, die ein paar Namensvariationen sowohl in deiner Vergleichsliste, als auch in den beiden Verzeichnissen enthalten und wie dann das

Zielverzeichnis aussehen soll, wenn das Makro erfolgreich durchlaufen wurde

Anzeige
BspDatei
17.01.2025 14:44:23
Christian
Hier eine Datei, ich habe es zumindest versucht, zu erklären, ich hoffe es ist mir halbwegs gelungen.
Zur Info, das Blatt namens Dateien existiert in der Originaldatei nicht, ich habe es nur erstellt, um zu veranschaulichen, was ich vorhabe.
Diese Prüfungen , die ich im Blatt Dateien gemacht habe, sollen das Makro übernehmen.

In Spalte A habe ich alle Dateinamen aufgelistet, die im Ordner E:\Videos enthalten sind.
In Spalte G alle Dateinamen aus dem Ordner E:\U30.

In Spalte B habe ich die erste Bedingung aufgestellt, dass einer der Namen aus Rechnung H2:H31 im Dateinamen enthalten sein muss.
In Spalte C habe ich das letzte Wort der Dateinamen aus Spalte A abgeschnitten.
In Spalte D prüfe ich anhand des abgeschnittenen Dateinamens ob die Datei bereits im Ordner E:\U30 bereits vorhanden ist und gebe ein X aus wenn nicht.
In Spalte E entscheide ich dann kopieren ja/nein, in dem ich sage kopiere Dateien, wenn beide Bedigungen erfüllt sind (in beiden Spalten ein X steht).

Die Dateien aus den Zeilen, in denen in Spalte E "ja" steht sollen dann vom Ordner E:\Videos in den Ordner E:\U30 kopiert werden.

https://www.herber.de/bbs/user/174911.xlsm
Anzeige
AW: neuer Chatgpt Versuch
17.01.2025 14:00:04
Klexy
Warum gibst du dich mit Chatgpt ab, das dir 6-fingrigen Code schreibt, wenn ich dir eine funktionierende und getestete Lösung gegeben habe?
AW: neuer Chatgpt Versuch
17.01.2025 14:03:12
Christian
Weil ich dich so verstanden hatte, dass du nur den Teil mit dem Vergleich H2:H31 geändert hast, ich aber vorher schon durch meine Tests ausgeschlossen hatte dass es daran liegt. Deine zweite Nachricht in der du u.a. schreibst, dass es keine Prüfung auf Dateinamen mit einem Wort gibt, gab es zu dem Zeitpunkt noch nicht
Anzeige
AW: neuer Chatgpt Versuch
17.01.2025 14:40:11
Klexy
Meine zweite Antwort von allen hat den kompletten benötigten Code.

Forumthreads zu verwandten Themen

Anzeige