Supportnet Computer
Planet of Tech

Supportnet / Forum / Datenbanken

Dateien animiert kopieren





Frage

Ich möchte mit Access Dateien mit dem in Windows üblichen Flying Windows Dialog kopieren. Ich habe dafür folgende Funktion: Option Compare Database Option Explicit Public Type SHFILEOPSTRUCT hwnd As Long wFunc As Long pFrom As String pTo As String fFlags As Integer fAborted As Long hNameMaps As Long sProgress As String End Type Public Declare Function GetDesktopWindow Lib "user32" () As Long Public Declare Function SHFileOperation Lib "shell32.dll" Alias _ "SHFileOperationA" _ (lpFileOp As SHFILEOPSTRUCT) As Long Public Function CopyFiles(asFiles() As String, _ sTarget As String) As Boolean // ----------------------------------------------------------------- // Methode: | Kopiert eine Anzahl Dateien; // | Aufruf des "flying windows"-Dialogs // | benötigt VBA6+ wegen Join-Funktion // ----------------------------------------------------------------- // Parameter: | asFiles = Datenfeld (Array) mit gültigen Pfaden // | sTarget = Zielordner // ----------------------------------------------------------------- // Rückgabe: | True bei Erfolg // ----------------------------------------------------------------- Const FO_COPY As Long = &H2 Const FOF_RENAMEONCOLLISION As Long = &H8 Dim sFiles As String Dim uSHFileOp As SHFILEOPSTRUCT On Error Resume Next sFiles = VBA.Join(asFiles, vbNullChar) sFiles = sFiles & vbNullChar With uSHFileOp .hwnd = GetDesktopWindow() .wFunc = FO_COPY .pFrom = sFiles .pTo = sTarget .fFlags = FOF_RENAMEONCOLLISION End With CopyFiles = (SHFileOperation(uSHFileOp) = 0) End Function Jetzt habe ich diese Funktion eingebaut und bekomme aber nur die Fehlermeldung: Funktionsaufruf auf der linken Seite der Zuweisung muß den Typ Variant oder Object zurückgeben. Was muß ich da korrigieren? Ich würde mich über eine Lösung sehr freuen!!

Antwort 1 von FrankieH

Mein Tipp:
CopyFiles = (SHFileOperation(uSHFileOp) = 0)

Weiss VBA, dass es sich hier um einen Vergleich handeln soll? Bin eigentlich in der C-Schiene zuhause, wo man das deutlich unterscheiden kann (Vergleiche lauten da: ==)

Ich nehme nämlich an, dass der Interpreter versucht den Funktionszeiger auf 0 (bzw. NULL) zu setzen, und da das ein Pointer ist, kommt die Meldung bzgl Variant.

Wie gesagt - ist nur ne Vermutung.
Wäre für uns einfacher, wenn Du bekannt gibtst, welche Zeile der Kompiliervorgang anzeigt.

Frankie

Antwort 2 von DixiDix

Anhand dieses Beispiels kann ich ja mal versuchen, das Problem deutlicher zu machen.
Die Meldung erscheint sobald man die Funktion StartCopy() ausführt.

Function StartCopy()
CopyFiles(Quelldateien, Zielordner) = True
End Function

Dabei hält der Debugger in der 1. Zeile an. Die Funktion wird gar nicht erst ausgeführt.

der Bereich

CopyFiles(Quelldateien, Zielordner) =

ist markiert.

Ich hoffe die Erklärung genügt!

Antwort 3 von FrankieH

Könnte meine Vermutung bestätigen.

Versuch es mal damit:

--------------------------------------------------------------
Function StartCopy()
dim Erg as Long

Erg = CopyFiles(Quelldateien,Zielordner)

End Function
--------------------------------------------------------------

Mit Erg kannst Du ja dann beliebiges anfangen. Der Datentyp von Erg kann auch was anderes sein.



Antwort 4 von _gau_

Erg sollte schon Boolean sein, denn die Funktion CopyFiles() gibt ja laut Definition Boolean zurück.

[gau]

Antwort 5 von DixiDix

Das hat auch nichts gebracht.
Hat jemand eine andere Idee, wie man zum kopieren von Dateien den animierten Windows-Dialog verwenden kann?

Danke für die bisherige Hilfe.

Antwort 6 von FrankieH

Hast Du es wirklich so wie in meinem Vorschlag eingegeben? Bei mir kommt diese Fehlermeldung nicht. Ich habe allerdings das VBA.Join auskommentiert.

Meine Idee:
Ich würde für Deinen Zweck den ganzen Vorgang in eine eigene DLL auslagern. Du brauchst dann auch nicht das VBA.Join. Nur die DLL muss im Suchpfad zu finden sein.


Antwort 7 von FrankieH

Vergessen zu posten:

Bei Deinem Beispiel muss zumindest ein call vor CopyFiles vorhanden sein, weil es eine Function und kein Sub ist.

also:
call CopyFiles(Quelldateien, Zielordner)


Antwort 8 von DixiDix

@FrankieH
Das haut nach wie vor nicht hin.
Was genau hast Du verändert?
Fehlt da möglicherweise ein Verweis?

Antwort 9 von FrankieH

Ich hab die Zeile mit VBA.join auskommentiert und ein call vor CopyFiles gesetzt. Dann lässt sich bei mir alles problemlos kompilieren.

Hab auch probiert zu kopieren - klappt. Allerdings habe ich nur eine Datei kopiert und dazu eine Zeile eingefügt: sFiles = asFiles(0) & vbNullchar

Geh doch mal Schritt-für-Schritt vor.

Erstelle ein Modul nur mit den Funktionsaufrufen (leeres Funktionsbody). Dann kompilieren und dann füllst Du diese nach und nach mit den einzelnen Code-Abschnitten.

Hier mein Modul - leider wie immer durch das posten etwas schlecht strukturiert.

-------------------------------------------------------------------
Option Compare Database
Option Explicit

Public Type SHFILEOPSTRUCT
hwnd As Long
wFunc As Long
pFrom As String
pTo As String
fFlags As Integer
fAborted As Long
hNameMaps As Long
sProgress As String
End Type

Public Declare Function GetDesktopWindow Lib "user32" () As Long
Declare Function SHFileOperation Lib "shell32.dll" Alias "SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) As Long

Public Function CopyFiles(asFiles() As String, sTarget As String) As Boolean
Const FO_COPY As Long = &H2
Const FOF_RENAMEONCOLLISION As Long = &H8
Dim sFiles As String
Dim uSHFileOp As SHFILEOPSTRUCT

On Error Resume Next

sFiles = VBA.Join(asFiles, vbNullChar)
sFiles = asFiles(0)
sFiles = sFiles & vbNullChar
With uSHFileOp
.hwnd = GetDesktopWindow()
.wFunc = FO_COPY
.pFrom = sFiles
.pTo = sTarget
.fFlags = FOF_RENAMEONCOLLISION
End With
CopyFiles = (SHFileOperation(uSHFileOp) = 0)

End Function

Function StartCopy()
Dim Quelldateien(5) As String
Dim Zielordner As String
Dim Antw As Variant

Quelldateien(0) = "c:\\tmp\\essen.dwg"
Zielordner = "c:\\tmp\\sms"
Antw = CopyFiles(Quelldateien, Zielordner)

End Function


Antwort 10 von DixiDix

Da mir geht glatt ein Licht auf.
So funktionierts tatsächlich. Zwar nur mit einer Datei, aber das müßte auch noch mit mehreren zu machen sein!

Danke erstmal!

Antwort 11 von FrankieH

Dann ist ja schon mal halb gewonnen...

Mit mehreren Dateien ist da so eine Crux. Man muß in ein SpeicherArray die Dateien jeweils durch ein Nullbyte getrennt einsetzen, hinter der letzten sind dann zwei Nullbytes. In C/C++ ist das kein Problem, aber in VB ... - Deswegen wohl dieser Join-Befehl.

Vielleicht kann ja da ein VB-Experte helfen...

Gruss
Frankie



Antwort 12 von PotzBlitz

Hallo Frankie,

der Join-Befehl macht genau das, was du vermutest: Die Elemente aus einem String entnehmen und zu einer Zeichenfolge zusammenzusetzen, jeweils getrennt durch das mitgelieferte Trennzeichen. Leider gibts diese Funktion nicht in Access, deswegen kommt hier die nachgebildete Join-Funktion für Access:

′-------------------------------------------------------
Private Function Join2(SourceArray As Variant, Optional Delimiter As Variant) As String
    Dim lngPos As Long
    Dim lngStart As Long
    Dim lngEnd As Long
    Dim strDelimiter As String
    Dim strString As String
    
    ′Trennzeichen-Übergabe prüfen, ggfs. Leerzeichen einsetzen
    If IsMissing(Delimiter) Then
        strDelimiter = " "
    Else
        strDelimiter = Delimiter
    End If
    
    ′Grenzwerte des Arrays festlegen
    lngStart = LBound(SourceArray)
    lngEnd = UBound(SourceArray) - 1
    
    ′String aufbauen und zurückgeben
    For lngPos = lngStart To lngEnd
        strString = strString & CStr(SourceArray(lngPos)) & strDelimiter
    Next
    
    Join2 = strString
End Function
′-------------------------------------------------------

Der Join2-Funktion muss dann nur noch das Array übergeben werden, sowie die Konstante vbNullChar als Null-Byte:

strErgebnis = Join2(arrFiles(), vbNullChar)

Die oben aufgeführten Codes zu SHFileOperation sind alle stark abgespeckt, da fehlen eine Menge sinnvoller Konstanten. Ich hoffe, dass die beim Kopieren ins Supportnet nur weggelassen wurden? Neben den weiteren Optionen fehlen noch Löschen, Verschieben und Umbenennen.

Gruss
PotzBlitz


Antwort 13 von PotzBlitz

So wie es aussieht, hat sich in den obigen Zeilen mal wieder ein Fehlerteufel eingeschlichen. Die Zeile

lngEnd = UBound(SourceArray) -1

sollte heissen

lngEnd = UBound(SourceArray)

Das war jetzt die schlechte Nachricht. Die gute ist, dass ich in der vergangenen Stunde das Thema SHFileOperation aufbereitet und eine recht einfach zu bedienende Funktion CopyFiles() auf die Beine gestellt habe. Sie erlaubt alle zulässigen Optionen inkl. Kopieren, Verschieben, Umbenennen und Löschen, ausserdem können sowohl Arrays als auch einzelne Dateien bei Quelle und Ziel angegeben werden. Das Anfügen des Null-Bytes geschieht automatisch.

Der Code ist zu lang, als dass er hier rein kopiert werden kann. Dafür kann er aber als Textdatei heruntergeladen werden. Details dazu sind in meiner Visitenkarte.

Gruss
PotzBlitz

Antwort 14 von DixiDix

Ist ja mehr als ich wollte. Vielen Dank für Eure Hilfe!

DixiDix

Ich möchte kostenlos eine Frage an die Mitglieder stellen:


Ähnliche Themen:


Suche in allen vorhandenen Beiträgen: