Jurgen Welz
jwelz at hotmail.com
Thu Jan 14 18:37:19 CST 2010
Sorry to say the example was not that detailed. I'd be happy to provide some real detail as needed. One point I need to reiterate is that my testing was in Access 2003 and the entire success of the drag and drop procedure is predicated on being able to rely on the VBA AddressOf procedure that didn't exist in Access 97, though it was available in VB 5 and up. I stated this in my original reply. My understanding was that AddressOf became available in VBA with version 6 (A2K). I've got an A2K file list form/subform example I built a few years ago to which I could add the d & d functionality to validate how it works in A2K. My personal machines are all currently A2K but I rarely use them for work given that everything we do is by VPN.
In order to make the file name and path returned by the example code at the link (as modified to work with an Access form by passing a form variable) do something useful, you need some additional code to do the grunt work. My subform gets a string with the destination path from the code and I already suggested how to get the file name from the string returned by the drop procedure. To do something useful like copy all the files or all files with a particular extension below a path and sub directories, you need to do a bit more work.
One example for shelling a Robocopy of everything below a path and writing a log file at the destination, and waiting for the copy to be done prior to processing anything moved follows:
Public Sub MovePath(strSource As String, strDest As String)
ShellWait "Robocopy.exe """ & strSource & """ " & strDest & " /E /V /log+:" & strDest & "\Robocopy.log"
End Sub
If the attributes of the dragged item in Explorer are returnedAttributes & vbDirectory = vbDirectory, you can call the above code to move files and create/append information about the files and success or failure to copy to a log file in response to a folder being dropped on a subform containing the drop code. You could lose the /log+ switch. The whole trick is getting the quotes right in order to call from VBA. There's lots of help on the switches and options for Robocopy.
The MovePath procedure depends on Robocopy.exe being found in a folder in the Path statement, otherwise you need to explicity provide the path to Robocopy.exe. The log file will show files that can't be copied because they are open or for any other reason.
If you want to run the Dos Dir command to set up a text file for parsing, you can generally use Environ$("comspec") and /C to run commands. On the server I'm working on Environ returns: C:\WINDOWS\system32\cmd.exe. For example, to write a file list of every file with the file extension '.pee' below a base path:
ShellWait Environ$("Comspec") & " /C dir " & """D:\GOM\Docs\Edmonton\2009\*.pee""" & " /S > " & """D:\GOM\Docs\Peefiles.txt"""
Once that is completed you can call something like the following procedure to add the names and paths of the .pee files to a table by parsing the Peefiles.txt file:
Sub FileParse()
Dim strTextLine As String
Dim strFilename As String
Dim intFileHandle As Integer
Dim strPath As String
Dim strfile As String
Dim lngStart As Long
Dim r As DAO.Recordset
Dim db As DAO.Database
strFilename = "D:\GOM\Docs\Peefiles.txt"
If Dir(strFilename) = "" Then Exit Sub
Set db = CurrentDb
Set r = db.OpenRecordset("tblPeeFiles")
intFileHandle = FreeFile
Open strFilename For Input As #intFileHandle
Do While Not EOF(intFileHandle)
Line Input #intFileHandle, strTextLine ' Read line into variable
lngStart = InStr(strTextLine, "Directory Of ")
If lngStart Then
'Folder path follows
strPath = Mid$(strTextLine, 15) & "\"
End If
If Right$(strTextLine, 4) = ".pee" Then
'File name follows
strfile = Mid$(strTextLine, 40)
If Len(Dir(strPath & strfile)) Then
r.AddNew
r(1) = strPath & strfile
r.Update
Else
Debug.Print "Invalid: " & strPath & strfile
End If
End If
Loop
Close #intFileHandle
End Sub
I'm using something very like the code above to populate a temporary table in order to migrate a few terabytes of files to a new server to various different paths based on some record attributes.
You need shellwait in order to pause the code until it has completed the shelled portion of work.
Variables & Declarations:
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal _
dwMilliseconds As Long) As Long
Private Declare Function CreateProcessA Lib "kernel32" (ByVal lpApplicationName As Long, ByVal _
lpCommandLine As String, ByVal lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, ByVal lpEnvironment As Long, _
ByVal lpCurrentDirectory As Long, lpStartupInfor As STARTUPINFO, lProcessInformation As _
PROCESS_INFORMATION) As Long
Private Const STARTF_USESHOWWINDOW& = &H1
Private Const NORMAL_PRIORITY_CLASS = &H20&
Private Const INFINITE = -1&
Private Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessID As Long
dwThreadID As Long
End Type
Private Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
The ShellWait procedure:
Public Sub ShellWait(pathname As String, Optional WindowStyle As Long)
Dim proc As PROCESS_INFORMATION
Dim start As STARTUPINFO
Dim ret As Long
With start
.cb = Len(start)
If Not IsMissing(WindowStyle) Then
.dwFlags = STARTF_USESHOWWINDOW
.wShowWindow = WindowStyle
End If
End With
ret& = CreateProcessA(0&, pathname, 0&, 0&, 1&, NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc)
ret& = WaitForSingleObject(proc.hProcess, INFINITE)
CloseHandle proc.hProcess
End Sub
Ciao Jürgen Welz
> From: darren at activebilling.com.au
> To: accessd at databaseadvisors.com
> Date: Fri, 15 Jan 2010 09:23:03 +1100
> Subject: Re: [AccessD] A2K:Get file name after drag and drop_SecondSend
>
> Hi Jürgen
>
> Wow this is great and very detailed - many thanks
> I will work on this again tonight - I'll let you know how it turns out
>
> Again - Many many thanks, you've put in a lot of effort on my behalf - I truly
> am most grateful.
>
> :-)
_________________________________________________________________