You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Excel VBA宏向SFTP服务器传输文件失败求助

问题排查与解决建议

一、先修复现有代码的致命错误

你的代码存在几个明显的语法和逻辑问题,导致文件根本没上传成功,却弹出了成功提示:

  1. HostKey变量未赋值
    你把主机密钥内容写到了sftpPass变量里,但代码中实际用于验证的hostKey是空的,这会直接导致SFTP连接时主机密钥验证失败,终止上传流程。把sftpPass的内容移到hostKey,同时清空sftpPass(因为你用私钥登录,不需要密码)。

  2. Shell命令语法错误
    你直接把sftpRemotePath塞进命令序列,这是无效的WinSCP命令,需要用cd命令切换到远程目标路径。

  3. 未检查命令执行结果
    不管WinSCP命令是否真的执行成功,你的代码都会弹出成功提示,这会误导你判断实际执行状态。应该捕获Shell的执行返回值,或者生成日志来排查问题。

  4. 命令拼接的引号嵌套问题
    原命令里的引号嵌套逻辑有问题,容易导致路径被截断,引发执行错误。

修正后的代码

Sub SFTPUpload()
    Dim winscpExePath As String
    Dim sftpHost As String
    Dim sftpUser As String
    Dim hostKey As String
    Dim sftpKeyPath As String
    Dim sftpRemotePath As String
    Dim sftpLocalPath As String
    Dim winSCPCommand As String
    Dim shellResult As Integer
    
    ' 配置参数
    winscpExePath = "C:\Program Files (x86)\WinSCP\WinSCP.com"
    sftpHost = "eu-sftp.apps.airliquide.com"
    sftpUser = "al-ald-prod"
    hostKey = "ssh-rsa 2048 91:cd:88:de:53:93:f7:6d:2f:47:c2:8f:e9:a1:e5:ce"
    sftpKeyPath = "C:\Users\brice.tikiabane\Desktop\SFTP keys - Copie\al-ald-prod-2023-03-01-private_key.ppk"
    sftpRemotePath = "/al-gio-sftp-giocentralbatchprod-s-8ab50e07929c4a698/al-ald-prod/"
    sftpLocalPath = "C:\Users\brice.tikiabane\Documents\ALDE file.txt"
    
    ' 拼接正确的WinSCP命令
    winSCPCommand = """" & winscpExePath & """ /command " & _
        """open sftp://" & sftpUser & "@" & sftpHost & " -privatekey=""" & sftpKeyPath & """ -hostkey=""" & hostKey & """ " & _
        "cd """ & sftpRemotePath & """ " & _
        "put """ & sftpLocalPath & """ " & _
        "exit"""
    
    ' 执行命令并获取返回值(0表示成功,非0表示失败)
    shellResult = Shell(winSCPCommand, vbNormalFocus)
    
    ' 等待WinSCP执行完成(避免弹窗过早)
    Do While Shell("tasklist /FI ""IMAGENAME eq WinSCP.com""", vbHide) <> ""
        DoEvents
    Loop
    
    ' 根据结果给出提示
    If shellResult <> 0 Then
        MsgBox "上传失败,请检查日志或配置"
    Else
        MsgBox "上传成功"
    End If
End Sub

二、进一步排查步骤

  1. 启用WinSCP日志
    在open命令后添加/log="C:\temp\WinSCP.log",生成详细执行日志,查看连接、上传过程中是否有权限不足、路径不存在、私钥密码错误等问题。
    示例:"""open sftp://... -hostkey=... /log=""C:\temp\WinSCP.log"""" "

  2. 手动验证WinSCP命令
    把拼接好的winSCPCommand内容复制到CMD中执行,确认命令本身是否能成功上传,排除VBA代码的问题。

  3. 检查远程路径权限
    确认你的SFTP账号对目标路径有写入权限,部分服务器会在权限不足时静默失败,文件不会上传到指定路径。

三、替代方案

如果WinSCP.com的方式不好调试,推荐使用WinSCP .NET Assembly,它可以直接在VBA中调用,支持更详细的错误捕获和日志:

  1. 先在VBA编辑器中引用WinSCPnet.dll(通常位于WinSCP安装目录下)
  2. 示例代码片段:
Sub SFTPUpload_UsingDotNet()
    Dim session As New WinSCP.Session
    Dim sessionOptions As New WinSCP.SessionOptions
    
    With sessionOptions
        .Protocol = Protocol.Sftp
        .HostName = "eu-sftp.apps.airliquide.com"
        .UserName = "al-ald-prod"
        .SshPrivateKeyPath = "C:\Users\brice.tikiabane\Desktop\SFTP keys - Copie\al-ald-prod-2023-03-01-private_key.ppk"
        .SshHostKeyFingerprint = "ssh-rsa 2048 91:cd:88:de:53:93:f7:6d:2f:47:c2:8f:e9:a1:e5:ce"
    End With
    
    On Error GoTo ErrorHandler
    session.Open(sessionOptions)
    ' 上传文件并检查是否成功
    session.PutFiles("C:\Users\brice.tikiabane\Documents\ALDE file.txt", "/al-gio-sftp-giocentralbatchprod-s-8ab50e07929c4a698/al-ald-prod/").Check()
    MsgBox "上传成功"
    session.Close()
    Exit Sub
    
ErrorHandler:
    MsgBox "上传失败:" & Err.Description
    session.Close()
End Sub

另外,也可以使用Chilkat SFTP等第三方组件,但需要额外安装,WinSCP的方案相对更轻量,适合已有WinSCP安装环境的场景。

内容的提问来源于stack exchange,提问作者Brice Tiki Abane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 04:15:03