فصل ۳۶ — استفاده از FTP در VBA
Applicationهای Access برای Manipulate و Present کردن داده ساخته میشوند و این داده اغلب روی Server دیگری است که اتصال مستقیم به آن ممکن نیست. نمونه میتواند فایل قیمت پایانی بورس یا ارزش ارزها باشد. دلایل میتواند مالکیت Third-party، Security یا نگرانی از Performance Database میزبان در اثر Connectionها و Queryهای سنگین باشد.
یک راه، انتقال داده با Text/CSV است؛ اما خود File باید به Application برسد. E-mail برای Automation چندان مناسب نیست. بسیاری از سازمانها از FTP (File Transfer Protocol) استفاده میکنند: با Internet Connection، User ID و Password میتوان Fileها را مانند Folderهای Local مشاهده و انتقال داد. نویسنده هشدار میدهد هنگام آزمایش روی Public FTP فقط از فایلهای متنی Sample خودتان استفاده کنید و Code ناشناس از منبع عمومی را اجرا نکنید.
انتقال File با VBA
برای انتقال در زمان درخواست User یا Job زمانبندیشده میتوان API Callهای wininet.dll را استفاده کرد:
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
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
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
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
Private Declare Function InternetCloseHandle Lib "wininet.dll" _
(ByVal hInet As Long) As Integer
Download
Sub GetFile()
Dim MyConn, MyINet, Chk As Boolean
Chk = False
MyINet = InternetOpen("MyFTP", 1, vbNullString, vbNullString, 0)
If MyINet > 0 Then
MyConn = InternetConnect(MyINet, "MyOrg.MyServer.net", 21, _
"MyUserID", "MyPassword", 1, 0, 0)
If MyConn > 0 Then
Chk = FTPGETFile(MyConn, "MyFolder/MyFileName.txt", _
CurrentProject.Path & "\MyFileName.txt", 0, 0, 1, 0)
InternetCloseHandle MyConn
End If
InternetCloseHandle MyINet
End If
If (Chk) Then
MsgBox "File downloaded"
Else
MsgBox "FTP Error"
End If
End Sub
InternetOpen Session اینترنتی را باز و Handle را در MyINet برمیگرداند. اگر Handle غیرصفر باشد InternetConnect با Server، Port پیشفرض FTP یعنی 21 و Credentialها اتصال ایجاد میکند. نام Server بدون ftp:// داده میشود. سپس FTPGETFile File راهدور را به مسیر Local میآورد؛ CurrentProject.Path مسیر Database Access را میدهد. نتیجهٔ True/False در Chk ذخیره و Message موفقیت/خطا نشان داده میشود. Handleها در پایان بسته میشوند.
Upload
Sub PutFile()
Dim MyConn, MyINet, Chk As Boolean
Chk = False
MyINet = InternetOpen("MyFTP", 1, vbNullString, vbNullString, 0)
If MyINet > 0 Then
MyConn = InternetConnect(MyINet, "MyOrg.MyServer.net", 21, _
"MyUserID", "MyPassword", 1, 0, 0)
If MyConn > 0 Then
Chk = FtpPutFile(MyConn, CurrentProject.Path & "\test.txt", _
"MyFolder/MyFileName.txt", 1, 0)
InternetCloseHandle MyConn
End If
InternetCloseHandle MyINet
End If
If (Chk) Then
MsgBox "File uploaded"
Else
MsgBox "FTP Error"
End If
End Sub
Upload تنها زمانی موفق است که User ID Permission لازم روی FTP Server داشته باشد.
استفاده از Semaphore File
Fileهای بزرگ ممکن است چند دقیقه Transfer شوند، در حالی که نام File خیلی زود در Folder دیده میشود و Size آن بهتدریج افزایش مییابد. اگر Process دیگری File نیمهکاره را باز کند Error رخ میدهد.
برای تشخیص پایان Transfer از Semaphore File استفاده میشود: Text File بسیار کوچکی، معمولاً همنام File اصلی و با پسوند SMP. Process تولیدکننده پس از کاملشدن File اصلی Semaphore را میسازد. Process دریافتکننده بهجای File اصلی، هر دقیقه وجود Semaphore را بررسی میکند؛ وقتی آن را یافت، میداند File اصلی کامل و آمادهٔ پردازش است.