Vba 上传文本文件

Vba Upload Text File

我正在尝试将纯文本文件上传到经典 asp 页面,但出现错误。

<p>Microsoft VBScript runtime </font> <font face="Arial" size=2>error '800a01a8'</font>
<p>
<font face="Arial" size=2>Object required: 'fields(...)'</font>

Html代码

<form action="upload.asp" method=post ENCTYPE="multipart/form-data">
      File :
<input type="file" class="form_field" name="File1" accept="image/jpeg">
<input type="submit" class="form_pb" Name="Action" value="Send File">
</form>

Vba 设置 post 变量并发送请求的代码。

    Const STR_BOUNDARY  As String = "a832972453175"
    Dim nFile           As Integer
    Dim baBuffer()      As Byte
    Dim sPostData       As String
....

'--- read file
nFile = FreeFile
Open sFileName For Binary Access Read As nFile
    If LOF(nFile) > 0 Then
        ReDim baBuffer(0 To LOF(nFile) - 1) As Byte
        Get nFile, , baBuffer
        sPostData = StrConv(baBuffer, vbUnicode)
    End If
Close nFile

sPostData = "--" & STR_BOUNDARY & vbCrLf & _
        "Content-Disposition: form-data; name=""File1""; filename=""" & Mid$(sFileName, InStrRev(sFileName, "\") + 1) & """" & vbCrLf & _
            "Content-Type: text/plain" & vbCrLf & vbCrLf & _
            sPostData & vbCrLf & vbCrLf & _
            STR_BOUNDARY & vbCrLf & _
            "Content-Disposition: form-data; name=""Action""" & vbCrLf & _
             vbCrLf & "Send File" & vbCrLf & _
            "--" & STR_BOUNDARY & "--"

With WinHttpReq

'UPLOAD REQUEST
.Open "POST", sUrl, False
.setRequestHeader "Content-Type", "multipart/form-data; boundary=" & STR_BOUNDARY
.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
.Send (sPostData)
end with

我可以访问经典 asp 页面的源代码,并且在服务器上使用 vbscript 运行 执行上传。

错误是 File1 参数 = "" 然后上传没有开始。

尽管 html 代码中的属性 accept 仅适用于 "image/jpeg" 我可以在使用浏览器导航时正常上传。

我认为 Vba 代码中的 sPostData 变量有问题。

带上传功能的文件在这里:https://www.royalholloway.ac.uk/resources/ASP/PStruh-CZ/1.3/upload.inc

谁能看出我做错了什么?

我创建了上传页面的副本并查找了错误。我发现页面重新识别的边界是 "myboundary" + ;Charset=UTF-8.

这种情况下的解决方案是在请求中添加字符集 header。

With WinHttpReq

'UPLOAD REQUEST
.Open "POST", sUrl, False
.setRequestHeader "Content-Type", "multipart/form-data; Charset=UTF-8;boundary=" & STR_BOUNDARY
.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
.Send (sPostData)
end with

.setRequestHeader "Content-Type", "multipart/form-data; Charset=UTF-8; boundary=" & STR_BOUNDARY

今天我发现我可以通过标准 POST 从 VBA Excel(也可以是 Word、MSAccess 或 Outlook)上传文件(文本或二进制)(至少它适用于小文件)。 首先,它打开一个字节数组中的文件。 其次,它将字节数组转换为 Base64 字符串。 第三,它使用 IE 对象填写表单并提交,没有直接的用户交互。

Public Function UploadFileTo(sourceFile As String, uURL As String, nameFieldID As String, dataFieldID As String, formID As String) As Boolean
    UploadFileTo = False
    ''---------------------------
    Dim nome As String, dados64
    Dim bs() As Byte
    nome = Dir(sourceFile)
    If (nome = "") Then Exit Function
    ''
    bs = ReadFile2("" & sourceFile) ' loads the file into a byte array
    dados64 = Base64Encode(bs) ' encodes it to base64 and returns as String
    ''
    Dim ie As InternetExplorerMedium
    'Dim ie 'As Object
    Dim docweb As Object
    Set ie = New InternetExplorerMedium
    'Set ie = CreateObject("InternetExplorerMedium")
    'Set ie = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}")
    ie.Navigate2 uURL
    ie.Visible = True
    While ie.Busy: DoEvents: Wend
    While ie.ReadyState <> 4: DoEvents: Wend
    ''
    Set docweb = ie.Document
    docweb.all(nameFieldID).Value = nome
    docweb.all(dataFieldID).Value = dados64
    docweb.all(formID).Submit
    While ie.Busy: DoEvents: Wend
    While ie.ReadyState <> READYSTATE_COMPLETE: DoEvents: Wend
    ''
    ie.Quit
    ''---------------------------
    UploadFileTo = True
End Function

例如:调用如下页面:

if UploadFileTo("C:\myPath\myFile.txt", "http://www.website.com/page.html", "myFileNameField", "myFileData", "myDistantForm") then
    MsgBox "File Uploaded successfully"
else
    MsgBox "Failed."
end if

它调用 URL http://www.website.com/page.html

<html>
 <head>
  <title>Sending files within POST with base64 encoding</title>
 </head>
 <body>
  <form id="myDistantForm" action="teste.cgi" method="POST">
   Name: <input type="text" id="finame" name="arq_nome" value="">    <br>
   Data: <textarea name="myFileNameField" id="fidata" rows="30" cols="120"></textarea> <br>
   <input type="submit" name="myFileData" value="Send the File"> <br>
  </form>
 </body>
</html>

重要提示:服务器必须能够解码 Base64 编码的字符串,然后使用给定的名称(或一些自动生成的唯一名称)将解码后的数据保存到所需服务器目录中的文件中,无论目标服务器是否运行 ASP、PHP、JSP、CGI/ISAPI 或其他。

将任何文件读取到字节数组:how can I read a binary file using VBA?

将该数组编码为 Base64 字符串:How do I base64 encode a string efficiently using Excel VBA?