hbender
asked on
Load list of ftp files from directory into a userform?
Hello experts, I am creating a tool so that a user can load a file from an ftp server into excel by choosing from userform control (listbox). My question, is there a way to display the contents of the ftp directory in a listbox? (similar to using DIR in command line ftp)? Thanks, Henry
ASKER
Thanks, but I'm not really following either of those suggestions. [ I asked this question as a 'related question' to my previous post that egl1044 helped me with.] I am using wininet functions to get files from a remote ftp server.
Is there a wininet function that can get the file names in the directory? Thanks
Is there a wininet function that can get the file names in the directory? Thanks
Oh, sorry, then did you see the article below?
http://articles.techrepublic.com.com/5100-10878_11-1044939.html
http://articles.techrepublic.com.com/5100-10878_11-1044939.html
You need to use (FtpFindFirstFile) (InternetFindNextFile) API. The following example I wrote should help you. Place the name of the listbox control your using where ( ctrList ) is defined.
' Form1.frm
Option Explicit
Private Type WIN32_FIND_DATA_W
dwFileAttributes As Long
ftCreationTime As Currency
ftLastAccessTime As Currency
ftLastWriteTime As Currency
nFileSizeHigh As Long
nFileSizeLow As Long
dwReserved0 As Long
dwReserved1 As Long
cFileName(520) As Byte
cAlternateFileName(28) As Byte
End Type
Private Declare Function InternetOpenA Lib "wininet.dll" ( _
ByVal sAgent As String, _
ByVal lAccessType As Long, _
ByVal sProxyName As String, _
ByVal sProxyBypass As String, _
ByVal lFlags As Long) As Long
Private Declare Function InternetConnectA Lib "wininet.dll" ( _
ByVal hInternetSession As Long, _
ByVal sServerName As String, _
ByVal nServerPort As Long, _
ByVal sUsername As String, _
ByVal sPassword As String, _
ByVal lService As Long, _
ByVal lFlags As Long, _
ByVal lcontext As Long) As Long
Private Declare Function FtpFindFirstFileW Lib "wininet.dll" ( _
ByVal hConnect As Long, _
ByVal lpszSearchFile As Long, _
ByVal lpFindFileData As Long, _
ByVal dwFlags As Long, _
ByVal dwContext As Long) As Long
Private Declare Function InternetFindNextFileW Lib "wininet.dll" ( _
ByVal hConnect As Long, _
ByVal lpvFindData As Long) As Long
Private Declare Function InternetCloseHandle Lib "wininet.dll" ( _
ByVal hInet As Long) As Long
Private Declare Sub RtlZeroMemory Lib "kernel32" ( _
dst As Any, _
ByVal nBytes As Long)
Private Function remove_bittynull(ByVal strData As String) As String
' helper function remove leading null chars
remove_bittynull = Left$(strData, InStr(1, strData, vbNullChar) - 1)
End Function
Public Sub EnumFtpDirectory(ByVal strHost As String, ByVal lngPort As Long, ByVal strUser As String, ByVal strPass As String, ByVal strSetDir As String, ctrList As ListBox)
' Returns: List of files from a ftp directory(Wide Version)
' Usage: Call EnumFtpDirectory("ftp.server.com", 21, "user", "pass", "/TEST/", List1)
Dim hOpen As Long
Dim hConn As Long
Dim hFind As Long
Dim w32 As WIN32_FIND_DATA_W
' // initialize struct (zero byte)
RtlZeroMemory w32, Len(w32)
' // initialize ftp sessions
hOpen = InternetOpenA("ftpdir", 1, vbNullString, vbNullString, 1)
' // initialize credentials
hConn = InternetConnectA(hOpen, strHost, lngPort, strUser, strPass, 1, 0, 2)
' // initialize enumeration
hFind = FtpFindFirstFileW(hConn, StrPtr(strSetDir), VarPtr(w32), 0, 0)
' // find all files and add to listbox (ctrList)
Do
ctrList.AddItem (remove_bittynull(w32.cFileName))
Loop Until InternetFindNextFileW(hFind, VarPtr(w32)) = 0
' // clean up handles
InternetCloseHandle hConn
InternetCloseHandle hOpen
InternetCloseHandle hFind
End Sub
ASKER
Thanks egl1044,
I'm having trouble passing the listbox to the function. The ListBox is a control (lstDirectory) on a userform (frmOpenFTPform). See any problems here? Thanks for your help. HB
I'm having trouble passing the listbox to the function. The ListBox is a control (lstDirectory) on a userform (frmOpenFTPform). See any problems here? Thanks for your help. HB
Sub DirectoryTest()
Dim lstList As ListBox
Set lstList = frmOpenFTPform.lstDirectory
Call EnumFtpDirectory("pcdial.lehman.com", 21, "myusername", "mypassword", "/point/download/", lstList)
frmOpenFTPform.Show
End Sub
You can pass it directly. Dont' think you need to set a reference to it. Give that a try
Sub DirectoryTest()
Call EnumFtpDirectory("pcdial.l ehman.com" , 21, "myusername", "mypassword", "/point/download/", frmOpenFTPform.lstDirector y)
frmOpenFTPform.Show
End Sub
Sub DirectoryTest()
Call EnumFtpDirectory("pcdial.l
frmOpenFTPform.Show
End Sub
ASKER
I tried that initially, but I get 'Type mismatch' (runtime error 13) for some reason . . .
I have setup a project that is identical to what it looks like you are trying to do and it works fine.
1) I created two forms(renamed Form2 to :frmOpenFTPform)
2) I put a listbox on frmOpenFTPform (named: lstDirectory)
3) I put a command button on Form1 with the following code:
Call EnumFtpDirectory("pcdial.l ehman.com" , 21, "myusername", "mypassword", "/point/download/", frmOpenFTPform.lstDirector y)
frmOpenFTPform.Show
If you could post what you have in your project perhaps I can overlook it and see what is causing the problem. Remember to remove any personal information before posting.
1) I created two forms(renamed Form2 to :frmOpenFTPform)
2) I put a listbox on frmOpenFTPform (named: lstDirectory)
3) I put a command button on Form1 with the following code:
Call EnumFtpDirectory("pcdial.l
frmOpenFTPform.Show
If you could post what you have in your project perhaps I can overlook it and see what is causing the problem. Remember to remove any personal information before posting.
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
ASKER
Thanks egl1044. I got it to work also by using 'As Object'
I suspected it was application related problem.
Do you think it is better to use 'As MSForms.ListBox' ?
I will make the change and see if there is any performance impact.
Thanks for all of your help on this. This is really helpful, and I really appreciate it!
I suspected it was application related problem.
Do you think it is better to use 'As MSForms.ListBox' ?
I will make the change and see if there is any performance impact.
Thanks for all of your help on this. This is really helpful, and I really appreciate it!
ASKER
Thanks again, you rock.
If you use the direct MSForms.ListBox then VBA knows you are referencing the Listbox user control. I am pretty certain that there is two types of ListBox objects for excel. Although I don't do much coding in excel itself you could probrably get away with either but to be on the safe side I would use the direct reference in this case.
http://www.xtremevbtalk.com/archive/index.php/t-108953.html
http://www.rebex.net/ftp.net/sample-ftp-list.aspx
Open in new window