בעיה בקוד vba להורדת קובץ משרת ftp
-
זו כנראה בעיה של גרסת 64 של אקסס, אצלי יש גרסת 32 ועובד.
בכל מקרה יש פתרון אחר בלי שימוש בספרייה הנ"ל, על ידי שימוש בקריאות לAPI של Windows.
יש לך כאן קוד VBA שמתאים גם ל64. תעתיק ותדביק במודול חדש:Private Const FTP_TRANSFER_TYPE_UNKNOWN As Long = 0 Private Const INTERNET_FLAG_RELOAD As Long = &H80000000 Private Declare PtrSafe 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 PtrSafe 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 PtrSafe Function FtpGetFileA Lib "wininet.dll" ( _ ByVal hConnect As Long, _ ByVal lpszRemoteFile As String, _ ByVal lpszNewFile As String, _ ByVal fFailIfExists As Long, _ ByVal dwFlagsAndAttributes As Long, _ ByVal dwFlags As Long, _ ByVal dwContext As Long) As Long Private Declare PtrSafe Function FtpPutFileA _ Lib "wininet.dll" _ _ (ByVal hFtpSession As Long, _ ByVal lpszLocalFile As String, _ ByVal lpszRemoteFile As String, _ ByVal dwFlags As Long, _ ByVal dwContext As Long) As Boolean Private Declare PtrSafe Function InternetCloseHandle Lib "wininet" ( _ ByVal hInet As Long) As Long Sub FtpDownload(ByVal strRemoteFile As String, ByVal strLocalFile As String, ByVal strHost As String, ByVal lngPort As Long, ByVal strUser As String, ByVal strPass As String) Dim hOpen As Long Dim hConn As Long hOpen = InternetOpenA("FTPGET", 1, vbNullString, vbNullString, 1) hConn = InternetConnectA(hOpen, strHost, lngPort, strUser, strPass, 1, 0, 2) If FtpGetFileA(hConn, strRemoteFile, strLocalFile, 1, 0, FTP_TRANSFER_TYPE_UNKNOWN Or INTERNET_FLAG_RELOAD, 0) Then Debug.Print "Success" Else Debug.Print "Fail" End If 'Close connections InternetCloseHandle hConn InternetCloseHandle hOpen End Sub Sub FtpUpload(ByVal strLocalFile As String, ByVal strRemoteFile As String, ByVal strHost As String, ByVal lngPort As Long, ByVal strUser As String, ByVal strPass As String) Dim hOpen As Long Dim hConn As Long hOpen = InternetOpenA("FTPGET", 1, vbNullString, vbNullString, 1) hConn = InternetConnectA(hOpen, strHost, lngPort, strUser, strPass, 1, 0, 2) If FtpPutFileA(hConn, strLocalFile, strRemoteFile, FTP_TRANSFER_TYPE_UNKNOWN Or INTERNET_FLAG_RELOAD, 0) Then Debug.Print "Success" Else Debug.Print "Fail" End If 'Close connections InternetCloseHandle hConn InternetCloseHandle hOpen End Sub
יש שם גם דוגמאות
כדי להוריד קובץ:FtpDownload "//Download/text file.txt", "C:\text file.txt", _ "192.168.0.100", 21, "username", "password"
כדי לשלוח קובץ:
FtpUpload "C:\text file.txt", "//Download/text file.txt", _ "192.168.0.100", 21, "username", "password"
-
טוב, אחרי שקצת חיפשתי מידע בנושא, נראה שאין פתרון פשוט לבעיה על ידי VBA בלבד הגעתי לכמה מסקנות:
- הגישה לשרת FTP כיום שונה מהגישה שהיתה בתקופת כתיבת הקוד הנ"ל. כיום משתמשים במצב שנקרא Passive Mode (כנראה מטעמי אבטחה)
- ל-Windows אין מנגנון מובנה לכך.
כדי לגשת בצורה מאובטחת לשרת FTP יש צורך בתוכנה חיצונית.
פתרון אפשרי (טלאי) אולי הוא ליצור Script טקסט עבור התוכנה החיצונית, ולהריץ אותו מתוך VBA...אשמח אם יש למבינים בנושא משהו להוסיף.