excel - 如何使用 ftp、http 或套接字从电子表格中使用 VBA for Microsoft Office 上传数据?

标签 excel http vba sockets sftp

我有一个 Excel 电子表格,我想在上面放一个按钮,这样用户就可以将他们的数据上传到 http/ftp 服务器,或者直接使用套接字将数据发送到服务器。我注意到有些人创建了一个 ftp 脚本来做。首先,我不确定每个人的 Windows 机器上是否都有 ftp,其次,我更愿意使用一种能让我更好地监控上传进度的方法。例如,我想知道用户 ID/密码是否失败,传输是否成功完成,接收服务器是否存在任何其他类型的错误。谢谢。

最佳答案

我编写了一个在 VBA 中使用的 FTP 类,它使用 Windows API 函数来传输文件:

Option Explicit

' die wichtigsten Funktionen und Typen aus dem WinInet-API

Private Const MAX_PATH = 260
Private Const INTERNET_OPEN_TYPE_PRECONFIG = 0
Private Const INTERNET_FLAG_ASYNC = &H10000000
Private Const INTERNET_DEFAULT_FTP_PORT = 21
Private Const INTERNET_SERVICE_FTP = 1
Private Const FTP_TRANSFER_TYPE_BINARY As Long = 2

Private Type WIN32_FIND_DATA
  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 As String * MAX_PATH
  cAlternate As String * 14
End Type

Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" (ByVal lpszAgent As String, ByVal dwAccessType As Long, ByVal lpszProxyName As String, ByVal lpszProxyBypass As String, ByVal dwFlags As Long) As Long
Private Declare Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" (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 InternetCloseHandle Lib "wininet.dll" (ByVal hInet As Long) As Long
Private Declare Function InternetGetLastResponseInfo Lib "wininet.dll" Alias "InternetGetLastResponseInfoA" (ByRef lpdwError As Long, ByVal lpszBuffer As String, ByRef lpdwBufferLength As Long) As Boolean
Private Declare Function FtpPutFile Lib "WinInet" Alias "FtpPutFileA" (ByVal hFtp As Long, ByVal lpszLocalFile As String, ByVal lpszNewRemoteFile As String, ByVal dwFlags As Long, ByVal dwContext As Long) As Long
Private Declare Function FtpGetFile Lib "WinInet" Alias "FtpGetFileA" (ByVal hFtp 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 Function FtpDeleteFile Lib "WinInet" Alias "FtpDeleteFileA" (ByVal hFtp As Long, ByVal lpszKillFile As String) As Long
Private Declare Function FtpCreateDirectory Lib "WinInet" Alias "FtpCreateDirectoryA" (ByVal hFtp As Long, ByVal lpszNewDir As String) As Long
Private Declare Function FtpGetCurrentDirectory Lib "WinInet" Alias "FtpGetCurrentDirectoryA" (ByVal hFtp As Long, lpszDirectory As String, ByVal BuffLength As Long) As Long
Private Declare Function FtpSetCurrentDirectory Lib "WinInet" Alias "FtpSetCurrentDirectoryA" (ByVal hFtp As Long, ByVal lpszDirectory As String) As Long
Private Declare Function FtpRemoveDirectory Lib "WinInet" Alias "FtpRemoveDirectoryA" (ByVal hFtp As Long, ByVal lpszKillDir As String) As Long
Private Declare Function FtpFindFirstFile Lib "WinInet" Alias "FtpFindFirstFileA" (ByVal hFtp As Long, ByVal lpszSearchFile As String, lpFindFileData As WIN32_FIND_DATA, ByVal dwFlags As Long, ByVal dwContext As Long) As Long
Private Declare Function FtpRenameFile Lib "WinInet" Alias "FtpRenameFileA" (ByVal hFtp As Long, ByVal lpszCurFile As String, ByVal lpszNewFile As String) As Long
Private Declare Function GetLastError Lib "kernel" () As Integer

' Member der Klasse
Private m_hConnect As Long
Private m_hFtp As Long

Private Sub Class_Initialize()
    m_hConnect = 0
    m_hFtp = 0
End Sub

Private Sub Class_Terminate()
    Disconnect
End Sub

Public Sub Connect(server As String, user As String, pwd As String)
    m_hConnect = InternetOpen("Microsoft Excel", INTERNET_OPEN_TYPE_PRECONFIG, vbNullString, vbNullString, 0) 'INTERNET_FLAG_ASYNC)

    If m_hConnect = 0 Then
        Err.Raise vbObjectError + 1, , "Verbindung konnte nicht hergestellt werden! Fehler " + CStr(GetLastError)
        Exit Sub
    End If

    m_hFtp = InternetConnect(m_hConnect, server, INTERNET_DEFAULT_FTP_PORT, user, pwd, INTERNET_SERVICE_FTP, 0, 0)

    If m_hFtp = 0 Then
        Err.Raise vbObjectError + 1, , "Verbindung konnte nicht hergestellt werden! Fehler " + CStr(GetLastError)
        Exit Sub
    End If
End Sub

Public Sub Disconnect()
    If m_hConnect <> 0 Then
        InternetCloseHandle m_hConnect
        m_hFtp = 0
        m_hConnect = 0
    End If
End Sub

Public Sub ChangeDir(RemoteDirectory As String)
    Dim ret As Long
    ret = FtpSetCurrentDirectory(m_hFtp, RemoteDirectory)
    If ret = 0 Then
        MsgBox CStr(Err.LastDllError)
        Err.Raise vbObjectError + 1, , LastError()

    End If
End Sub

Public Function CurrentDir() As String
    Dim ret As String
    ret = Space(1024)
    FtpGetCurrentDirectory m_hFtp, ret, 1023
    CurrentDir = ret
End Function

Public Sub PutFile(LocalFilename As String, RemoteFilename As String)
    If FtpPutFile(m_hFtp, LocalFilename, RemoteFilename, FTP_TRANSFER_TYPE_BINARY, 0) = 0 Then
        Err.Raise vbObjectError + 1, , LastError
    End If
End Sub

Private Function LastError() As String
    Dim ret As String
    Dim nErr As Long

    ret = Space(1024)
    InternetGetLastResponseInfo nErr, ret, 1024

    LastError = ret
End Function

像这样使用它:

Dim ftp As New CFtp
ftp.Connect GetVar("SERVER"), GetVar("USER"), GetVar("PASS")
ftp.PutFile FILENAME, "/httpdocs/ang.html"
ftp.Disconnect

关于excel - 如何使用 ftp、http 或套接字从电子表格中使用 VBA for Microsoft Office 上传数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3026308/

相关文章:

excel - 如何计算张数是一种数字方式,无论名称和操作如复制或移动

excel - 遍历已填充的行

java - 使用改造 :2. 0.0-beta1 发送带有文件的多部分

sql-server - Excel VBA 到 SQL Server ADODB 连接 - 提示输入用户 ID 和密码

python - 是否可以在 Excel 中使用 Python 动态更改公式引用的路径?

c++ - 将 tiff 图像转换为要作为二进制应用程序/八位字节流发布的字符串 (C++)

php - 合并两个 mp3 php

excel - 给定多个范围,如果满足多个条件,则隐藏行

excel - 编译错误: Argument not optional vba excel

excel - 退出/重新启动控制 excel 的 word 宏