Link to home
Create AccountLog in
Avatar of hbender
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
Avatar of xakem
xakem
Flag of Kazakhstan image

Hi!

http://www.xtremevbtalk.com/archive/index.php/t-108953.html
http://www.rebex.net/ftp.net/sample-ftp-list.aspx

' select the desired directory 
ftp.ChangeDirectory(path)
 
' retrieve and display the list of files and directories 
' 
Dim list As FtpList = ftp.GetList()
Dim item As FtpItem
For Each item In list
	'Add your code
	Console.Write(" {0}", item.Name)
	Console.WriteLine();
        ...
Next item

Open in new window

Avatar of hbender
hbender

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
Oh, sorry, then did you see the article below?

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

Open in new window

Avatar of hbender

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
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

Open in new window

You can pass it directly. Dont' think you need to set a reference to it. Give that a try

Sub DirectoryTest()

Call EnumFtpDirectory("pcdial.lehman.com", 21, "myusername", "mypassword", "/point/download/", frmOpenFTPform.lstDirectory)
frmOpenFTPform.Show

End Sub
Avatar of hbender

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.lehman.com", 21, "myusername", "mypassword", "/point/download/", frmOpenFTPform.lstDirectory)
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
Avatar of nffvrxqgrcfqvvc
nffvrxqgrcfqvvc

Link to home
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
See answer
Avatar of hbender

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!
Avatar of hbender

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.