PDA

View Full Version : Solved: Download a file viw FTP using VBA code?



GreenTree
12-23-2007, 11:10 AM
I'd like to download the .txt file located at

ftp://tgftp.nws.noaa.gov/data/observations/metar/stations/KORD.TXT

to my computer, using VBA to do it, so that later parts of my code can do things with the resulting file. Can someone please point me to a discussion of how to do that download?

Many thanks!

G.T.

:xmas:

Carl A
12-23-2007, 02:41 PM
Here is one source.
http://www.dailydoseofexcel.com/archives/2006/01/29/ftp-via-vba/

GreenTree
12-23-2007, 10:41 PM
Many thanks!

With a bit of tinkering around, I was able to get exactly the result I wanted. Here is the code I used, in case anyone else would like the "Cliff Notes" version. References are listed in the comments; most of the hard work was done in the first two articles.


Option Explicit

' Code and ideas came mostly from the following:
' The posting by Billkamm at http://www.dailydoseofexcel.com/archives/2006/01/29/ftp-via-vba/
' http://www.access-programmers.co.uk/forums/attachment.php?attachmentid=13389&d=1145948437
' http://msdn2.microsoft.com/en-us/library/aa383996.aspx
' http://msdn2.microsoft.com/en-us/library/aa384363(VS.85).aspx
' http://msdn2.microsoft.com/en-us/library/aa384180(VS.85).aspx
' http://msdn2.microsoft.com/en-us/library/aa384157(VS.85).aspx
' http://msdn2.microsoft.com/en-us/library/aa384166(VS.85).aspx
' http://www.devx.com/getHelpOn/10MinuteSolution/20373/1763


' Open the Internet object
Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" _
(ByVal sAgent As String, ByVal lAccessType As Long, ByVal sProxyName As String, _
ByVal sProxyBypass As String, ByVal lFlags As Long) As Long

' Connect to the network
Private Declare Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" _
(ByVal hInternetSession As Long, ByVal sServerName As String, _
ByVal nServerPort As Integer, ByVal sUsername As String, _
ByVal sPassword As String, ByVal lService As Long, _
ByVal lFlags As Long, ByVal lContext As Long) As Long

' Get a file using FTP
Private Declare Function FtpGetFile Lib "wininet.dll" Alias "FtpGetFileA" _
(ByVal hFtpSession As Long, ByVal lpszRemoteFile As String, _
ByVal lpszNewFile As String, ByVal fFailIfExists As Boolean, _
ByVal dwFlagsAndAttributes As Long, ByVal dwFlags As Long, _
ByVal dwContext As Long) As Boolean

' Send a file using FTP
Private Declare Function FtpPutFile Lib "wininet.dll" Alias "FtpPutFileA" _
(ByVal hFtpSession As Long, ByVal lpszLocalFile As String, _
ByVal lpszRemoteFile As String, ByVal dwFlags As Long, _
ByVal dwContext As Long) As Boolean

' Close the Internet object
Private Declare Function InternetCloseHandle Lib "wininet.dll" _
(ByVal hInet As Long) As Integer

Sub GetORD_TXT()

' This sub uses the above functions to get a particular text file stored on the NOAA servers. (It is the aviation
' weather report for Chicago O'Hare.) This is very basic "proof of concept" code to demonstrate to myself that
' the above functions work (they do!) and what I need to be doing when I call them.
'
' This routine will get the KORD.TXT file from the NOAA server and place it in the C:\ directory on my computer.
'
' I've commented out the uninteresting MsgBox lines; they show long (and meaningless) numbers.
'

Dim AgentStr As String
Dim AccessTypeLong As Long
Dim ProxyNameStr As String
Dim ProxyBypassStr As String
Dim FlagsLong As Long

Dim InternetSessionLong As Long
Dim ServerNameStr As String
Dim ServerPortInt As Integer
Dim UserNameStr As String
Dim PasswordStr As String
Dim ServiceLong As Long
Dim ContextLong As Long

Dim FTPSessionLong As Long
Dim RemoteFileStr As String
Dim NewFileStr As String
Dim FailIfExistsBool As Boolean
Dim FlagsAndAttributesLong As Long

Dim SomeThingLong As Long
Dim MyInternetHandleLong As Long
Dim MyFTPHandleLong As Long
Dim SomeInteger As Integer
Dim FTPSuccessBool As Boolean ' Did the FTP download work?

' ********************************
' ** **
' ** Call INTERNET OPEN first **
' ** **
' ********************************

AgentStr = "GreenTreeTest" ' can be whatever
AccessTypeLong = 0 ' zero appears to work fine
ProxyNameStr = "" ' nul works fine here
ProxyBypassStr = "" ' nul works fine here
FlagsLong = 0 ' zero appears to work fine

MyInternetHandleLong = InternetOpen(AgentStr, AccessTypeLong, ProxyNameStr, ProxyBypassStr, FlagsLong)

' MsgBox MyInternetHandleLong


' *********************************
' ** **
' ** Call Internet CONNECT next **
' ** **
' *********************************

' The file I want to get is at ftp://tgftp.nws.noaa.gov/data/observations/metar/stations/KORD.TXT

'MyInternetHandleLong is obtained above
ServerNameStr = "tgftp.nws.noaa.gov" ' address of the FTP server, WITHOUT the "ftp://" part
ServerPortInt = 21 ' default FTP port
UserNameStr = "anonymous" ' "anonymous" is the is the default
PasswordStr = "" ' nul is the default
ServiceLong = 1 ' this for the FTP service (2 = gopher, 3 = http)
FlagsLong = 0 ' 0 appears to work fine here
ContextLong = 0 ' 0 appears to work fine here

MyFTPHandleLong = InternetConnect(MyInternetHandleLong, ServerNameStr, ServerPortInt, UserNameStr, PasswordStr, ServiceLong, FlagsLong, ContextLong)

' MsgBox "My FTP handle = " & MyFTPHandleLong
' (this is NOT the same value as MyInternetHandle, above)


' *****************************
' ** **
' ** Call FTP Get File next **
' ** **
' *****************************

' MyFTPHandleLong is obtained above
RemoteFileStr = "/data/observations/metar/stations/KORD.TXT" ' file name on server, including directories
NewFileStr = "C:\KORD.txt" ' file name on MY system
FailIfExistsBool = False ' should NOT fail if file already exists on MY computer.... HOWEVER,
' if the file does exist, the FTP DOES fail. Don't know about this. Short answer:
' the target file should NOT exist on my computer before calling this routine!
FlagsAndAttributesLong = 128 ' Normal file, no special flags set.
FlagsLong = 2 ' FTP Transfer Type Binary (the default)
ContextLong = 0 ' apparently not required.


FTPSuccessBool = FtpGetFile(MyFTPHandleLong, RemoteFileStr, NewFileStr, FailIfExistsBool, FlagsAndAttributesLong, FlagsLong, ContextLong)

MsgBox "FTP Success = " & FTPSuccessBool

' ************************************
' ** **
' ** Finally, close the connection **
' ** **
' ************************************


SomeInteger = InternetCloseHandle(MyInternetHandleLong)

' MsgBox SomeInteger
' Seems to return "1"


End Sub


Merry Christmas! :xmas::xmas:

unmarkedhelicopter
12-24-2007, 02:46 AM
Thanks for posting back with your solution.
... and a happy new year !!!