Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1776to1780
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Dateioperationen:

Dateioperationen:
13.08.2020 13:51:26
Gerald
Ich bastele an einen VBA Codeschnipsel, der folgende Dateioperationen durchführen soll.
A) C:\source\ (einschließlich Unterverzeichnisse)
B) C:\compare\ (einschließlich Unterverzeichnisse)
C) C:\destination
Alle Dateien aus A sollen mit B verglichen werden, um die Dateien,
- die noch nicht in B existieren sowie
- Dateien, die in A neuer sind als in B
nach C zu kopieren.
Um es richtig schwierig zu machen, können A und B beliebige Unterverzeichnisse haben, in denen die Files liegen.
Ich komme hier nicht weiter; hat jemand eine Idee?

9
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Dateioperationen:
13.08.2020 16:56:29
Nepumuk
Hallo Gerald,
im Prinzip so:
Option Explicit

Public Sub Gerald()
    
    Const FOLDER_PATH_1 As String = "C:\source\"
    Const FOLDER_PATH_2 As String = "C:\compare\"
    Const FOLDER_PATH_3 As String = "C:\destination\"
    
    Dim objDictionary_1 As Object, objDictionary_2 As Object
    Dim astrFolders() As String, strFilename As String
    Dim ialngFolders As Long
    Dim vntItem As Variant
    
    Set objDictionary_1 = CreateObject(Class:="Scripting.Dictionary")
    astrFolders = GetFolders(FOLDER_PATH_1)
    For ialngFolders = LBound(astrFolders) To UBound(astrFolders)
        strFilename = Dir$(PathName:=astrFolders(ialngFolders) & "*.*")
        Do Until strFilename = vbNullString
            Call objDictionary_1.Add(Key:=strFilename, Item:=astrFolders(ialngFolders) & strFilename)
            strFilename = Dir$
        Loop
    Next
    
    Set objDictionary_2 = CreateObject(Class:="Scripting.Dictionary")
    astrFolders = GetFolders(FOLDER_PATH_2)
    For ialngFolders = LBound(astrFolders) To UBound(astrFolders)
        strFilename = Dir$(PathName:=astrFolders(ialngFolders) & "*.*")
        Do Until strFilename = vbNullString
            Call objDictionary_2.Add(Key:=strFilename, Item:=astrFolders(ialngFolders) & strFilename)
            strFilename = Dir$
        Loop
    Next
    
    For Each vntItem In objDictionary_1.Keys
        If objDictionary_2.Exists(Key:=vntItem) Then
            If FileDateTime(PthName:=objDictionary_1.Item(Key:=vntItem)) > _
                FileDateTime(PthName:=objDictionary_2.Item(Key:=vntItem)) Then _
                Call FileCopy(Source:=objDictionary_1.Item(Key:=vntItem), Destination:=FOLDER_PATH_3 & vntItem)
        Else
            Call FileCopy(Source:=objDictionary_1.Item(Key:=vntItem), Destination:=FOLDER_PATH_3 & vntItem)
        End If
    Next
    
    Set objDictionary_1 = Nothing
    Set objDictionary_2 = Nothing
End Sub

Private Function GetFolders(ByVal pvstrPath As String) As String()
    Dim astrFolders() As String
    Dim strFolder As String, strPath As String
    Dim ialngIndex1 As Long, ialngIndex2 As Long
    Redim Preserve astrFolders(ialngIndex1)
    astrFolders(ialngIndex1) = pvstrPath
    ialngIndex1 = 1
    ialngIndex2 = 1
    strPath = pvstrPath
    Do
        strFolder = Dir$(PathName:=strPath & "*", Attributes:=vbDirectory)
        Do Until strFolder = vbNullString
            If strFolder <> "." And strFolder <> ".." Then
                If GetAttr(PathName:=strPath & strFolder) And vbDirectory Then
                    Redim Preserve astrFolders(0 To ialngIndex1)
                    astrFolders(ialngIndex1) = strPath & strFolder & "\"
                    ialngIndex1 = ialngIndex1 + 1
                End If
            End If
            strFolder = Dir$
        Loop
        If ialngIndex1 = ialngIndex2 Then Exit Do
        strPath = astrFolders(ialngIndex2)
        ialngIndex2 = ialngIndex2 + 1
    Loop
    GetFolders = astrFolders
End Function

Da ist jetzt aber noch keine Fehlerprüfung drin ob ein Dateiname in A oder B doppelt vorkommen und ob eine Datei die nach C kopiert werden soll nicht schon vorhanden ist.
Gruß
Nepumuk
Anzeige
AW: Dateioperationen:
13.08.2020 18:01:02
Nepumuk
Oops,
da ist noch ein Fehler drin. So passt es:
If FileDateTime(PathName:=objDictionary_1.Item(Key:=vntItem)) > _
    FileDateTime(PathName:=objDictionary_2.Item(Key:=vntItem)) Then _
    Call FileCopy(Source:=objDictionary_1.Item(Key:=vntItem), Destination:=FOLDER_PATH_3 & vntItem)

Gruß
Nepumuk
Anzeige
AW: Dateioperationen:
14.08.2020 11:40:32
Gerald
Vielen Dank für deine Mühe!
Genau verstanden habe den Code noch nicht (arbeite daran:-). Erste Tests sind schon vielversprechend.
Tatsächlich kommen Dateinamen in A und B mehrfach doppelt vor, sodass das Programm dann aussteigt.
Kann man die doppelten Einträge irgendwie aus „strFilename“ herauszufiltern?
AW: Dateioperationen:
14.08.2020 17:57:52
Nepumuk
Hallo Gerald,
sollen doppelte Dateinamen einfach ignoriert werden?
Gruß
Nepumuk
AW: Dateioperationen:
18.08.2020 10:09:39
Gerald
Hallo Nepumuk,
Habe etwas gebraucht um die Quelldateien zu analysieren.
Doppelte Dateinamen in A (Source) sind immer identische Files und müssen nur einmal berücksichtigt werden.
Doppelte Dateinamen in B (Compare) sind nicht zwangsläufig gleich.
Gruß
Gerald
Anzeige
AW: Dateioperationen:
18.08.2020 13:07:36
Nepumuk
Hallo Gerald,
ok, A ist kein Problem. Aber wie sollen zwei Dateien mit dem selben Namen in B behandelt werden? Z.B. ist eine älter als die Datei in A und eine jünger.
Gruß
Nepumuk
AW: Dateioperationen:
18.08.2020 15:15:08
Gerald
Hallo Nepumuk,
Eine Datei in A (Source) muss gegen die neueste gleichnamige Datei in B (compare) verglichen werden. Wenn A neuer als B dann in C kopieren, sonst nicht.
Gruß
Gerald
AW: Dateioperationen:
18.08.2020 16:08:01
Nepumuk
Hallo Gerald,
teste mal:
Option Explicit

Private Declare PtrSafe Function CopyFileA Lib "kernel32.dll" ( _
    ByVal lpExistingFileName As String, _
    ByVal lpNewFileName As String, _
    ByVal bFailIfExists As Long) As Long

Public Sub Gerald()
    
    Const FOLDER_PATH_1 As String = "C:\source\"
    Const FOLDER_PATH_2 As String = "C:\compare\"
    Const FOLDER_PATH_3 As String = "C:\destination\"
    
    Dim objDictionary_1 As Object, objDictionary_2 As Object
    Dim adtmFileDate() As Date
    Dim astrFolders() As String, strFilename As String
    Dim ialngFolders As Long, ialngFileDate As Long
    Dim vntItem As Variant
    
    Set objDictionary_1 = CreateObject(Class:="Scripting.Dictionary")
    astrFolders = GetFolders(FOLDER_PATH_1)
    For ialngFolders = LBound(astrFolders) To UBound(astrFolders)
        strFilename = Dir$(PathName:=astrFolders(ialngFolders) & "*.*")
        Do Until strFilename = vbNullString
            If Not objDictionary_1.Exists(Key:=strFilename) Then _
                Call objDictionary_1.Add(Key:=strFilename, Item:=astrFolders(ialngFolders) & strFilename)
            strFilename = Dir$
        Loop
    Next
    
    Set objDictionary_2 = CreateObject(Class:="Scripting.Dictionary")
    astrFolders = GetFolders(FOLDER_PATH_2)
    For ialngFolders = LBound(astrFolders) To UBound(astrFolders)
        strFilename = Dir$(PathName:=astrFolders(ialngFolders) & "*.*")
        Do Until strFilename = vbNullString
            If Not objDictionary_2.Exists(Key:=strFilename) Then
                Call objDictionary_2.Add(Key:=strFilename, Item:=ialngFileDate)
                Redim Preserve adtmFileDate(ialngFileDate)
                adtmFileDate(ialngFileDate) = FileDateTime(PathName:=astrFolders(ialngFolders) & strFilename)
                ialngFileDate = ialngFileDate + 1
            Else
                If FileDateTime(PathName:=astrFolders(ialngFolders) & strFilename) > _
                    adtmFileDate(objDictionary_2.Item(Key:=strFilename)) Then _
                    adtmFileDate(objDictionary_2.Item(Key:=strFilename)) = _
                    FileDateTime(PathName:=astrFolders(ialngFolders) & strFilename)
            End If
            strFilename = Dir$
        Loop
    Next
    
    For Each vntItem In objDictionary_1.Keys
        If objDictionary_2.Exists(Key:=vntItem) Then
            If FileDateTime(PathName:=objDictionary_1.Item(Key:=vntItem)) > _
                adtmFileDate(objDictionary_2.Item(Key:=vntItem)) Then _
                Call CopyFileA(objDictionary_1.Item(Key:=vntItem), FOLDER_PATH_3 & vntItem, 0)
        Else
            Call CopyFileA(objDictionary_1.Item(Key:=vntItem), FOLDER_PATH_3 & vntItem, 0)
        End If
    Next
    
    Set objDictionary_1 = Nothing
    Set objDictionary_2 = Nothing
End Sub

Private Function GetFolders(ByVal pvstrPath As String) As String()
    Dim astrFolders() As String
    Dim strFolder As String, strPath As String
    Dim ialngIndex1 As Long, ialngIndex2 As Long
    Redim Preserve astrFolders(ialngIndex1)
    astrFolders(ialngIndex1) = pvstrPath
    ialngIndex1 = 1
    ialngIndex2 = 1
    strPath = pvstrPath
    Do
        strFolder = Dir$(PathName:=strPath & "*", Attributes:=vbDirectory)
        Do Until strFolder = vbNullString
            If strFolder <> "." And strFolder <> ".." Then
                If GetAttr(PathName:=strPath & strFolder) And vbDirectory Then
                    Redim Preserve astrFolders(0 To ialngIndex1)
                    astrFolders(ialngIndex1) = strPath & strFolder & "\"
                    ialngIndex1 = ialngIndex1 + 1
                End If
            End If
            strFolder = Dir$
        Loop
        If ialngIndex1 = ialngIndex2 Then Exit Do
        strPath = astrFolders(ialngIndex2)
        ialngIndex2 = ialngIndex2 + 1
    Loop
    GetFolders = astrFolders
End Function

Gruß
Nepumuk
Anzeige
AW: Dateioperationen:
19.08.2020 11:44:53
Gerald
Ich werde ausfühlich testen und mich melden.
Vielen Dank!

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige