美文网首页
VBA实例—FTP批量上传模版

VBA实例—FTP批量上传模版

作者: Excel大咖 | 来源:发表于2019-12-04 09:34 被阅读0次

    在公司,经常使用FTP上传文件给不同部门的同事。

    用软件上传,虽然可以保存连接的站点在书签上,方便操作。但数据量一大,用鼠标点击十分麻烦。还无法判断文件是否上传成功。

    于是用VBA写了一个批量上传的模版,除了能批量上传文件,还可以检测文件是否上传成功。

    曾经试过使用系统自带的FTP命令,发现无法设置传输的模式为被动。所以借用了WinSCP这个软件,用 shell调用命令行来实现批理上传。

    代码如下,感兴趣的可以直接下载压缩包(里面包含WinSCP软件),直接使用模版

    Sub wsUpFile()
        Dim myWs As String, myDat As String, myLog As String, myPath As String
        Dim tmp As String
        Dim t, arr, brr, crr
        Dim lrow As Integer, n As Integer, i As Integer, j As Integer
        Dim Stm, dic, ddd, bjShell
        Application.ScreenUpdating = False
        
        myWs = ThisWorkbook.Path & "\WinSCP\WinSCP.exe" '软件位置
        myIni = Replace(myWs, ".exe", ".ini")
        myPath = Replace(myWs, "\WinSCP.exe", "")
        
        If Dir(myWs) = "" Then MsgBox "找不到软件,请在软件位置!": Exit Sub
        
        myWs = Chr(34) & myWs & Chr(34) '加双引号
        
        
        Range("I:XX").Clear
        
        myDat = myPath & "\example.txt"   '脚本
        myLog = myPath & "\log_file.txt"  '日志
        
        If Dir(myDat) <> "" Then Kill myDat    '删除脚本
        If Dir(myLog) <> "" Then Kill myLog     '删除日志
        
        lrow = Cells(Rows.Count, 1).End(3).Row
        
        If lrow <= 1 Then MsgBox "找不到上传文件,请在A列输入文件!": Exit Sub
        
        
        arr = Range("A1:A" & lrow)
        
        
        lrow = Cells(Rows.Count, 4).End(3).Row
        
        If lrow <= 1 Then MsgBox "找不到位置,请在D列输入文件!": Exit Sub
        
        brr = Range("D1").Resize(lrow, 4 + UBound(arr))
         
        n = 0
        For i = 2 To UBound(arr)
            t1 = InStrRev(arr(i, 1), "\")
            brr(1, 4 + i) = Right(arr(i, 1), Len(arr(i, 1)) - t1) '文件名
            If Dir(arr(i, 1)) = "" And Dir(arr(i, 1), vbDirectory) = "" Then n = n + 1  '文件存在,上传
            
        Next
        If n = UBound(arr) - 1 Then MsgBox "找不到上传文件,请在A列输入文件!": Exit Sub
        
        Set dic = CreateObject("scripting.dictionary")    '区分连接
        
        Set ddd = CreateObject("scripting.dictionary") '区分连接与目录位置
        
        
        For i = 2 To UBound(brr)
            
            tmp = "open ftp://" & brr(i, 1) & ":" & brr(i, 2) & "@" & brr(i, 3) & ":" & brr(i, 4) '区分连接
            dic(tmp) = dic(tmp) & "|" & i
            
            For j = 6 To UBound(brr, 2)
                tmp = "open ftp://" & brr(i, 1) & ":***@" & brr(i, 3) & ":" & brr(i, 4) & "||" & brr(i, 5) & "/" & brr(1, j)
                ddd(tmp) = i & "|" & j    '连续与目录文件位置
            Next
            
        Next
        
        Set Stm = CreateObject("Adodb.Stream")
        Stm.Open
        Stm.Charset = "utf-8"   '编码
        
        Stm.writetext "option batch continue" & vbCrLf '默认批处理
        Stm.writetext "option confirm off" & vbCrLf    '关闭提示信息
        Stm.writetext "option transfer binary" & vbCrLf    '使用二进制格式传送
        
        For Each ky In dic.keys
            
            Stm.writetext ky & vbCrLf  ' user:访问用户名 ,pwd:用户密码 ,ip:ip地址,port:端口号
            
            t = Split(dic(ky), "|")  '同连接下的各目录
            
            For j = 1 To UBound(t)
                
                For i = 2 To UBound(arr)
                    If Dir(arr(i, 1)) <> "" Or Dir(arr(i, 1), vbDirectory) <> "" Then   '文件或文件夹存在,上传
                        Stm.writetext "put " & arr(i, 1) & " " & brr(t(j), 5) & "/" & vbCrLf '上传文件,下载用get
                    End If
                Next
            Next
            Stm.writetext "Close" & vbCrLf   '关闭连接
        Next
        Stm.writetext "exit"   '退出
        Stm.SaveToFile myDat
        Stm.Close: Set Stm = Nothing
      
        pscode = myWs & " /script=" & myDat & " /log=" & myLog
        
        Set objShell = CreateObject("wscript.shell")
        iReturn = objShell.Run("cmd.exe /c " & pscode, 0, True) '执行代码并隐藏窗口并等代码执行完
         
        '检查是否上传成功
        For i = 2 To UBound(brr)
            For j = 6 To UBound(brr, 2)
                brr(i, j) = "Q"
            Next
        Next
        
        On Error Resume Next
        crr = Split(FileArr(myLog, "UTF-8", "gb2312"), vbNewLine)
           
        For i = 2 To UBound(crr)
            If InStr(crr(i), "Script: open") > 0 Then ftp = Split(crr(i), "Script: ")(1) '获取连接信息
            If InStr(crr(i), "上传成功") > 0 Then
                
                tmp = ftp & "||" & Split(crr(i - 1), "; ")(1)
                
                tp = Split(ddd(tmp), "|")
                brr(tp(0), tp(1)) = "R"      
            End If
        Next
        
        Range("D1").Resize(lrow, 4 + UBound(arr)) = brr
        Range("D1").Resize(lrow, 4 + UBound(arr)).Borders.LineStyle = xlContinuous
        Range("I2").Resize(lrow - 1, UBound(arr) - 1).Font.Name = "Wingdings 2"
        
        
        Application.ScreenUpdating = True
        
        MsgBox "已上传完成!请查看上传结果!"
    End Sub
    
    Function FileArr(sFile As String, sCode As String, dCode As String)
        '参数:源文件,源文件编码,目标文件,目标文件编码。编码举例----"gb2312"、"UTF-8"等
        Dim ObjStream As Object
        
        Set ObjStream = CreateObject("Adodb.Stream")
        With ObjStream
            .Mode = 3   'adModeReadWrite = 3 ' 指示读/写权限。
            .Type = 1   'adTypeBinary = 1
            .Open
            .LoadFromFile sFile '源文件
            .Position = 0
            .Type = 2   'adTypeText = 2
            .Charset = sCode
            FileArr = .ReadText '读取文本到sCode
            .Close
        End With
        Set ObjStream = Nothing
    End Function
    

    下面有个模版,直接解压就可以使用了
    https://pan.baidu.com/s/1fsIzin-riPK4MZ2Z3vb81A

    相关文章

      网友评论

          本文标题:VBA实例—FTP批量上传模版

          本文链接:https://www.haomeiwen.com/subject/deiwwctx.html