I have this code in Visual Basic .net and I would like to make the same thing in Visual Basic 6. The code upload an image to a given URL. I have to use Rest protocol because the server I upload the image request it.
Dim res As New RestSharp.RestRequest("URL_OF_SERVER", RestSharp.Method.POST)
res.AddFile("file", "File_location_on_PC")
Dim restClient As New RestSharp.RestClient()
Dim r As New RestSharp.RestResponse
r = restClient.Execute(res)
Is it posible to do the same Rest Protocol in Visual Basic 6?
EDIT 1: I HAVE TRIED THIS BUT AN ERROR HAPPENS
Dim xmlhttp As MSXML2.XMLHTTP30
Const STR_BOUNDARY As String = "3fbd04f5-b1ed-4060-99b9-fca7ff59c113"
Dim nFile As Integer
Dim baBuffer() As Byte
Dim sPostData As String
'--- read file
nFile = FreeFile
Open NombreArchivo 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
'--- prepare body
sPostData = "--" & STR_BOUNDARY & vbCrLf & _
" Content-Disposition: form-data; name=""image002""; filename=""C:\image002.jpg" & _
"--" & STR_BOUNDARY & "--"
'--- post
Set xmlhttp = New MSXML2.XMLHTTP30
With xmlhttp
.Open "POST", Url, False
.setRequestHeader "Content-Type", "multipart/form-data; boundary=" & STR_BOUNDARY
.send pvToByteArray(sPostData)
End With
Private Function pvToByteArray(sText As String) As Byte()
pvToByteArray = StrConv(sText, vbFromUnicode)
End Function
ERROR :
responseText
{"message":"file.not_found","error":"There is no file in request.","status":400,"cause":[]}
Thanks!
If you need just to post a file here is a simple function
Private Sub pvPostFile(sUrl As String, sFileName As String, Optional ByVal bAsync As Boolean)
Const STR_BOUNDARY As String = "3fbd04f5-b1ed-4060-99b9-fca7ff59c113"
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
'--- prepare body
sPostData = "--" & STR_BOUNDARY & vbCrLf & _
"Content-Disposition: form-data; name=""uploadfile""; filename=""" & Mid$(sFileName, InStrRev(sFileName, "\") + 1) & """" & vbCrLf & _
"Content-Type: application/octet-stream" & vbCrLf & vbCrLf & _
sPostData & vbCrLf & _
"--" & STR_BOUNDARY & "--"
'--- post
With CreateObject("Microsoft.XMLHTTP")
.Open "POST", sUrl, bAsync
.SetRequestHeader "Content-Type", "multipart/form-data; boundary=" & STR_BOUNDARY
.Send pvToByteArray(sPostData)
End With
End Sub
Private Function pvToByteArray(sText As String) As Byte()
pvToByteArray = StrConv(sText, vbFromUnicode)
End Function
You can switch to MSXML2.ServerXMLHTTP to be able to use its SetTimeouts method if your file is large enough and timeouts in 30 sec.
You can create a COM callable wrapper (CCW) for the RestSharp assembly - see this URL for details of how to do this:
http://msdn.microsoft.com/en-us/library/ms973802.aspx
Once it is registered, you can use RestSharp from VB6.
Related
I am trying to use vba/XMLHTTP in an Access 2010 database to upload a file. While it is going through the process and I'm not receiving any errors, nothing ends up on my web site.
Here's the code which is called using:
response = HTTP_FileUpload(ShowName, "www.website_name","POST")
Public Function HTTP_FileUpload(FileName As String, ByVal pUrl As String, _
Optional ByVal pMethod As String = "GET") As String
Dim strResponse As String
On Error GoTo ErrorHandler
Dim xmlStream As Object
Set xmlStream = CreateObject("ADODB.Stream")
xmlStream.Mode = 3 ' //read write
xmlStream.Type = adTypeBinary
xmlStream.Open
xmlStream.LoadFromFile FileName
Dim objHttp As Object
Set objHttp = CreateObject("MSXML2.XMLHTTP")
objHttp.Open pMethod, pUrl, False
Debug.Print "file Name is " & FileName & " Size of file is " & xmlStream.Size
objHttp.setRequestHeader "Content-Type", "text/generic"
objHttp.setRequestHeader "Content-Length", xmlStream.Size
objHttp.send
strResponse = objHttp.responseText
HTTP_FileUpload = strResponse
Set objHttp = Nothing
Exit Function
ErrorHandler:
MsgBox "Error - code is " & Err.Number & " - " & Err.Description
End Function
I need to be able to send a file to another website from server-side Classic ASP code. The other website has a form with a file upload control, and I need to simulate posting to this form.
I found some sample code which seemed perfect for the job here, and it uploads the file without error, but the received file is not valid and when I inspect it on the other server the beginning of the file before the binary data has part of the posted data in it that shouldn't be there, eg:
ntent-Type: image/jpeg
Content-Disposition: form-data; name="file"; filename="archivebox.jpg"
ÿØÿà...
The receiving website code works fine when I upload data via a form, so it definately looks like the problem is with the above code.
If this code is not going to work, can anyone else point me in the direction of another sample for submitting files in this way?
Using the code sample in the link in my question, I modified it to build the request manually and it worked. I also converted to a single function that takes a binary file and one parameter and POSTs the request.
Function PostDocument(intDocumentID, binFile, strFilename, strContentType)
Dim objHttp, strBoundary, strRequestStart, strRequestEnd, binPost
Dim objStream
strBoundary = "---------------------------9849436581144108930470211272"
Set objHttp = Server.CreateObject("MSXML2.ServerXMLHTTP.6.0")
strRequestStart = "--" & strBoundary & vbCrlf &_
"Content-Disposition: form-data; name=""id""" & vbCrlf &_
vbCrlf &_
intDocumentID & vbCrlf &_
vbCrlf &_
"--" & strBoundary & vbCrlf &_
"Content-Disposition: form-data; name=""file""; filename=""" & strFilename & """" & vbCrlf &_
"Content-Type: " & strContentType & vbCrlf &_
vbCrlf
strRequestEnd = vbCrLf & "--" & strBoundary & "--"
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Type = adTypeBinary '1
objStream.Mode = adModeReadWrite '3
objStream.Open
objStream.Write StringToBinary(strRequestStart)
objStream.Write binFile
objStream.Write StringToBinary(strRequestEnd)
objStream.Position = 0
binPost = objStream.Read
Response.Write binPost
objStream.Close
Set objStream = Nothing
objHttp.Open "POST", "(url removed)", False, "(username removed)", "(password removed)"
objHttp.setRequestHeader "Content-Type", "multipart/form-data; boundary=""" & strBoundary & """"
objHttp.Send binPost
PostDocument = objHttp.ResponseText
Set objHttp = Nothing
End Function
Function StringToBinary(toConvert)
Dim objStream, data
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Charset = "ISO-8859-1"
objStream.Type = adTypeText '2
objStream.Mode = adModeReadWrite '3
objStream.Open
objStream.WriteText toConvert
objStream.Position = 0
objStream.Type = adTypeBinary '1
StringToBinary = objStream.Read
objStream.Close
Set objStream = Nothing
End Function
Is there any way to create an excel spreadsheets using VBScript? I can create a text file using a FileSystemObject and use any extension I want, but when I try and download this and it gives me the open in excel option a message then appears stating that it is in a different format, and that is what I want to avoid:
set fs=Server.CreateObject("Scripting.FileSystemObject")
set tfile=fs.CreateTextFile(Server.MapPath("xls/streamtest.xls"),true,false)
I know this is pushing text into the file in ASCII format.
Is there 'something' character sequence, specific formatting that I can use to get around all of this?
Thanks
The best and fastest way, without using Excel.application on the server, which is really not recommended, is to generate an Excel Xml file. The only feature you won't be able to do is insert a picture.
Unlike using html table, you'll be able to support native data in excel (like date), and you'll be able to format, insert formula, ...
Save your excel as Excel XML and see the generate XML file. This is little bit tricky, but works very well.
Microsoft .xlsx files are just a Zipped collection of xml files
That means that we can write out the xml files and folder structure as text files, the zip the folder and rename that zip file to .xlsx. Now we have a new, empty excel file. Here is my code to do just that without having to have MS Excel installed.
The ZipAFolder function has been modified from another stackoverflow question here
'
' Dependencies: ZipAFolder, moveFile, writeToFile, Environ, OpenWithExplorer, FileExists, FolderExists, ScriptEngine, MkDir
' Version: 1.0.0
' by jeremy.gerdes#navy.mil
' CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
' [TODO] reset the file attributes of date - Created, Modified, and Accessed to 12/31/1979 11:00 PM (for eastern time zone) to all files
' Usage example
' BuildEmptyExcelFile GetCurrentFileFolder() & "\" & "anEmptyExcelFile.xlsx"
Public Sub BuildEmptyExcelFile(strNewExcelFile)
Dim strLocalAppTmp
strLocalAppTmp = Environ("LocalAppData") & "\" & "tmp"
MkDir strLocalAppTmp
Dim strTmpZipPath
strTmpZipPath = strLocalAppTmp & "\" & "buildEmptyExcelFile"
MkDir strTmpZipPath
WriteToFile strTmpZipPath & "\" & "[Content_Types].xml" , _
"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>" & _
"<Types xmlns=""http://schemas.openxmlformats.org/package/2006/content-types""><Default Extension=""rels"" ContentType=""application/vnd.openxmlformats-package.relationships+xml""/><Default Extension=""xml"" ContentType=""application/xml""/><Override PartName=""/xl/workbook.xml"" ContentType=""application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml""/><Override PartName=""/xl/worksheets/sheet1.xml"" ContentType=""application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml""/><Override PartName=""/xl/theme/theme1.xml"" ContentType=""application/vnd.openxmlformats-officedocument.theme+xml""/><Override PartName=""/xl/styles.xml"" ContentType=""application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml""/><Override PartName=""/docProps/core.xml"" ContentType=""application/vnd.openxmlformats-package.core-properties+xml""/><Override PartName=""/docProps/app.xml"" ContentType=""application/vnd.openxmlformats-officedocument.extended-properties+xml""/></Types>", _
False, True
MkDir strTmpZipPath & "\" & "_rels"
WriteToFile _
strTmpZipPath & "\" & "_rels" & "\" & ".rels" , _
"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><Relationships xmlns=""http://schemas.openxmlformats.org/package/2006/relationships""><Relationship Id=""rId3"" Type=""http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties"" Target=""docProps/app.xml""/><Relationship Id=""rId2"" Type=""http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"" Target=""docProps/core.xml""/><Relationship Id=""rId1"" Type=""http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"" Target=""xl/workbook.xml""/></Relationships>", _
False, True
MkDir strTmpZipPath & "\" & "docProps"
WriteToFile _
strTmpZipPath & "\" & "docProps" & "\" & "app.xml" , _
"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><Properties xmlns=""http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"" xmlns:vt=""http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes""><Application>Microsoft Excel</Application><DocSecurity>0</DocSecurity><ScaleCrop>false</ScaleCrop><HeadingPairs><vt:vector size=""2"" baseType=""variant""><vt:variant><vt:lpstr>Worksheets</vt:lpstr></vt:variant><vt:variant><vt:i4>1</vt:i4></vt:variant></vt:vector></HeadingPairs><TitlesOfParts><vt:vector size=""1"" baseType=""lpstr""><vt:lpstr>Sheet1</vt:lpstr></vt:vector></TitlesOfParts><Company>HPES NMCI NGEN</Company><LinksUpToDate>false</LinksUpToDate><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged><AppVersion>16.0300</AppVersion></Properties>", _
False, True
WriteToFile _
strTmpZipPath & "\" & "docProps" & "\" & "core.xml" , _
"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><cp:coreProperties xmlns:cp=""http://schemas.openxmlformats.org/package/2006/metadata/core-properties"" xmlns:dc=""http://purl.org/dc/elements/1.1/"" xmlns:dcterms=""http://purl.org/dc/terms/"" xmlns:dcmitype=""http://purl.org/dc/dcmitype/"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""><dc:creator>jeremy.gerdes</dc:creator><cp:lastModifiedBy>jeremy.gerdes</cp:lastModifiedBy><dcterms:created xsi:type=""dcterms:W3CDTF"">2021-04-09T02:10:55Z</dcterms:created><dcterms:modified xsi:type=""dcterms:W3CDTF"">2021-04-09T02:11:30Z</dcterms:modified></cp:coreProperties>", _
False, True
MkDir strTmpZipPath & "\" & "xl"
MkDir strTmpZipPath & "\" & "xl" & "\" & "theme"
WriteToFile _
strTmpZipPath & "\" & "xl" & "\" & "styles.xml", _
"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>" & _
"<styleSheet xmlns=""http://schemas.openxmlformats.org/spreadsheetml/2006/main"" xmlns:mc=""http://schemas.openxmlformats.org/markup-compatibility/2006"" mc:Ignorable=""x14ac x16r2"" xmlns:x14ac=""http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"" xmlns:x16r2=""http://schemas.microsoft.com/office/spreadsheetml/2015/02/main""><fonts count=""1"" x14ac:knownFonts=""1""><font><sz val=""11""/><color theme=""1""/><name val=""Calibri""/><family val=""2""/><scheme val=""minor""/></font></fonts><fills count=""2""><fill><patternFill patternType=""none""/></fill><fill><patternFill patternType=""gray125""/></fill></fills><borders count=""1""><border><left/><right/><top/><bottom/><diagonal/></border></borders><cellStyleXfs count=""1""><xf numFmtId=""0"" fontId=""0"" fillId=""0"" borderId=""0""/></cellStyleXfs><cellXfs count=""1""><xf numFmtId=""0"" fontId=""0"" fillId=""0"" borderId=""0"" xfId=""0""/></cellXfs><cellStyles count=""1""><cellStyle name=""Normal"" xfId=""0"" builtinId=""0""/></cellStyles>" & _
"<dxfs count=""0""/><tableStyles count=""0"" defaultTableStyle=""TableStyleMedium2"" defaultPivotStyle=""PivotStyleLight16""/><extLst><ext uri=""{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}"" xmlns:x14=""http://schemas.microsoft.com/office/spreadsheetml/2009/9/main""><x14:slicerStyles defaultSlicerStyle=""SlicerStyleLight1""/></ext><ext uri=""{9260A510-F301-46a8-8635-F512D64BE5F5}"" xmlns:x15=""http://schemas.microsoft.com/office/spreadsheetml/2010/11/main""><x15:timelineStyles defaultTimelineStyle=""TimeSlicerStyleLight1""/></ext></extLst></styleSheet>", _
False, True
WriteToFile _
strTmpZipPath & "\" & "xl" & "\" & "workbook.xml", _
"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>" & _
"<workbook xmlns=""http://schemas.openxmlformats.org/spreadsheetml/2006/main"" xmlns:r=""http://schemas.openxmlformats.org/officeDocument/2006/relationships"" xmlns:mc=""http://schemas.openxmlformats.org/markup-compatibility/2006"" mc:Ignorable=""x15"" xmlns:x15=""http://schemas.microsoft.com/office/spreadsheetml/2010/11/main""><fileVersion appName=""xl"" lastEdited=""6"" lowestEdited=""6"" rupBuild=""14420""/><workbookPr defaultThemeVersion=""164011""/><mc:AlternateContent xmlns:mc=""http://schemas.openxmlformats.org/markup-compatibility/2006""><mc:Choice Requires=""x15""><x15ac:absPath url=""\\snnsvr045\NNSY Perm\T&I Lab\NNSY IT Assistant\Documentation\"" xmlns:x15ac=""http://schemas.microsoft.com/office/spreadsheetml/2010/11/ac""/></mc:Choice></mc:AlternateContent><bookViews><workbookView xWindow=""0"" yWindow=""210"" windowWidth=""15495"" windowHeight=""6435""/></bookViews><sheets><sheet name=""Sheet1"" sheetId=""1"" r:id=""rId1""/></sheets><calcPr calcId=""162913""/><extLst>" & _
"<ext uri=""{140A7094-0E35-4892-8432-C4D2E57EDEB5}"" xmlns:x15=""http://schemas.microsoft.com/office/spreadsheetml/2010/11/main""><x15:workbookPr chartTrackingRefBase=""1""/></ext></extLst></workbook>", _
False, True
MkDir strTmpZipPath & "\" & "xl" & "\" & "_rels"
WriteToFile _
strTmpZipPath & "\" & "xl" & "\" & "_rels" & "\" & "workbook.xml.rels", _
"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><Relationships xmlns=""http://schemas.openxmlformats.org/package/2006/relationships""><Relationship Id=""rId3"" Type=""http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"" Target=""styles.xml""/><Relationship Id=""rId2"" Type=""http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"" Target=""theme/theme1.xml""/><Relationship Id=""rId1"" Type=""http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"" Target=""worksheets/sheet1.xml""/></Relationships>", _
False, True
MkDir strTmpZipPath & "\" & "xl" & "\" & "theme"
WriteToFile _
strTmpZipPath & "\" & "xl" & "\" & "theme" & "\" & "theme1.xml", _
"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>" & _
"<a:theme xmlns:a=""http://schemas.openxmlformats.org/drawingml/2006/main"" name=""Office Theme""><a:themeElements><a:clrScheme name=""Office""><a:dk1><a:sysClr val=""windowText"" lastClr=""000000""/></a:dk1><a:lt1><a:sysClr val=""window"" lastClr=""FFFFFF""/></a:lt1><a:dk2><a:srgbClr val=""44546A""/></a:dk2><a:lt2><a:srgbClr val=""E7E6E6""/></a:lt2><a:accent1><a:srgbClr val=""5B9BD5""/></a:accent1><a:accent2><a:srgbClr val=""ED7D31""/></a:accent2><a:accent3><a:srgbClr val=""A5A5A5""/></a:accent3><a:accent4><a:srgbClr val=""FFC000""/></a:accent4><a:accent5><a:srgbClr val=""4472C4""/></a:accent5><a:accent6><a:srgbClr val=""70AD47""/></a:accent6><a:hlink><a:srgbClr val=""0563C1""/></a:hlink><a:folHlink><a:srgbClr val=""954F72""/></a:folHlink></a:clrScheme><a:fontScheme name=""Office""><a:majorFont><a:latin typeface=""Calibri Light"" panose=""020F0302020204030204""/><a:ea typeface=""""/><a:cs typeface=""""/><a:font script=""Jpan"" typeface=""??????å? Light""/>" & _
"<a:font script=""Hang"" typeface=""?? ??""/><a:font script=""Hans"" typeface=""???? Light""/><a:font script=""Hant"" typeface=""?¼????w""/><a:font script=""Arab"" typeface=""Times New Roman""/><a:font script=""Hebr"" typeface=""Times New Roman""/><a:font script=""Thai"" typeface=""Tahoma""/><a:font script=""Ethi"" typeface=""Nyala""/><a:font script=""Beng"" typeface=""Vrinda""/><a:font script=""Gujr"" typeface=""Shruti""/><a:font script=""Khmr"" typeface=""MoolBoran""/><a:font script=""Knda"" typeface=""Tunga""/><a:font script=""Guru"" typeface=""Raavi""/><a:font script=""Cans"" typeface=""Euphemia""/><a:font script=""Cher"" typeface=""Plantagenet Cherokee""/><a:font script=""Yiii"" typeface=""Microsoft Yi Baiti""/><a:font script=""Tibt"" typeface=""Microsoft Himalaya""/><a:font script=""Thaa"" typeface=""MV Boli""/><a:font script=""Deva"" typeface=""Mangal""/><a:font script=""Telu"" typeface=""Gautami""/><a:font script=""Taml"" typeface=""Latha""/><a:font script=""Syrc"" typeface=""Estrangelo Edessa""/>" & _
"<a:font script=""Orya"" typeface=""Kalinga""/><a:font script=""Mlym"" typeface=""Kartika""/><a:font script=""Laoo"" typeface=""DokChampa""/><a:font script=""Sinh"" typeface=""Iskoola Pota""/><a:font script=""Mong"" typeface=""Mongolian Baiti""/><a:font script=""Viet"" typeface=""Times New Roman""/><a:font script=""Uigh"" typeface=""Microsoft Uighur""/><a:font script=""Geor"" typeface=""Sylfaen""/></a:majorFont><a:minorFont><a:latin typeface=""Calibri"" panose=""020F0502020204030204""/><a:ea typeface=""""/><a:cs typeface=""""/><a:font script=""Jpan"" typeface=""??????å?""/><a:font script=""Hang"" typeface=""?? ??""/><a:font script=""Hans"" typeface=""????""/><a:font script=""Hant"" typeface=""?¼????w""/><a:font script=""Arab"" typeface=""Arial""/><a:font script=""Hebr"" typeface=""Arial""/><a:font script=""Thai"" typeface=""Tahoma""/><a:font script=""Ethi"" typeface=""Nyala""/><a:font script=""Beng"" typeface=""Vrinda""/><a:font script=""Gujr"" typeface=""Shruti""/><a:font script=""Khmr"" typeface=""DaunPenh""/>" & _
"<a:font script=""Knda"" typeface=""Tunga""/><a:font script=""Guru"" typeface=""Raavi""/><a:font script=""Cans"" typeface=""Euphemia""/><a:font script=""Cher"" typeface=""Plantagenet Cherokee""/><a:font script=""Yiii"" typeface=""Microsoft Yi Baiti""/><a:font script=""Tibt"" typeface=""Microsoft Himalaya""/><a:font script=""Thaa"" typeface=""MV Boli""/><a:font script=""Deva"" typeface=""Mangal""/><a:font script=""Telu"" typeface=""Gautami""/><a:font script=""Taml"" typeface=""Latha""/><a:font script=""Syrc"" typeface=""Estrangelo Edessa""/><a:font script=""Orya"" typeface=""Kalinga""/><a:font script=""Mlym"" typeface=""Kartika""/><a:font script=""Laoo"" typeface=""DokChampa""/><a:font script=""Sinh"" typeface=""Iskoola Pota""/><a:font script=""Mong"" typeface=""Mongolian Baiti""/><a:font script=""Viet"" typeface=""Arial""/><a:font script=""Uigh"" typeface=""Microsoft Uighur""/><a:font script=""Geor"" typeface=""Sylfaen""/></a:minorFont></a:fontScheme>" & _
"<a:fmtScheme name=""Office""><a:fillStyleLst><a:solidFill><a:schemeClr val=""phClr""/></a:solidFill><a:gradFill rotWithShape=""1""><a:gsLst><a:gs pos=""0""><a:schemeClr val=""phClr""><a:lumMod val=""110000""/><a:satMod val=""105000""/><a:tint val=""67000""/></a:schemeClr></a:gs><a:gs pos=""50000""><a:schemeClr val=""phClr""><a:lumMod val=""105000""/><a:satMod val=""103000""/><a:tint val=""73000""/></a:schemeClr></a:gs><a:gs pos=""100000""><a:schemeClr val=""phClr""><a:lumMod val=""105000""/><a:satMod val=""109000""/><a:tint val=""81000""/></a:schemeClr></a:gs></a:gsLst><a:lin ang=""5400000"" scaled=""0""/></a:gradFill><a:gradFill rotWithShape=""1""><a:gsLst><a:gs pos=""0""><a:schemeClr val=""phClr""><a:satMod val=""103000""/><a:lumMod val=""102000""/><a:tint val=""94000""/></a:schemeClr></a:gs><a:gs pos=""50000""><a:schemeClr val=""phClr""><a:satMod val=""110000""/><a:lumMod val=""100000""/><a:shade val=""100000""/></a:schemeClr></a:gs>" & _
"<a:gs pos=""100000""><a:schemeClr val=""phClr""><a:lumMod val=""99000""/><a:satMod val=""120000""/><a:shade val=""78000""/></a:schemeClr></a:gs></a:gsLst><a:lin ang=""5400000"" scaled=""0""/></a:gradFill></a:fillStyleLst><a:lnStyleLst><a:ln w=""6350"" cap=""flat"" cmpd=""sng"" algn=""ctr""><a:solidFill><a:schemeClr val=""phClr""/></a:solidFill><a:prstDash val=""solid""/><a:miter lim=""800000""/></a:ln><a:ln w=""12700"" cap=""flat"" cmpd=""sng"" algn=""ctr""><a:solidFill><a:schemeClr val=""phClr""/></a:solidFill><a:prstDash val=""solid""/><a:miter lim=""800000""/></a:ln><a:ln w=""19050"" cap=""flat"" cmpd=""sng"" algn=""ctr""><a:solidFill><a:schemeClr val=""phClr""/></a:solidFill><a:prstDash val=""solid""/><a:miter lim=""800000""/></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst>" & _
"<a:outerShdw blurRad=""57150"" dist=""19050"" dir=""5400000"" algn=""ctr"" rotWithShape=""0""><a:srgbClr val=""000000""><a:alpha val=""63000""/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val=""phClr""/></a:solidFill><a:solidFill><a:schemeClr val=""phClr""><a:tint val=""95000""/><a:satMod val=""170000""/></a:schemeClr></a:solidFill><a:gradFill rotWithShape=""1""><a:gsLst><a:gs pos=""0""><a:schemeClr val=""phClr""><a:tint val=""93000""/><a:satMod val=""150000""/><a:shade val=""98000""/><a:lumMod val=""102000""/></a:schemeClr></a:gs><a:gs pos=""50000""><a:schemeClr val=""phClr""><a:tint val=""98000""/><a:satMod val=""130000""/><a:shade val=""90000""/><a:lumMod val=""103000""/></a:schemeClr></a:gs><a:gs pos=""100000""><a:schemeClr val=""phClr""><a:shade val=""63000""/><a:satMod val=""120000""/></a:schemeClr></a:gs></a:gsLst>" & _
"<a:lin ang=""5400000"" scaled=""0""/></a:gradFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/><a:extraClrSchemeLst/><a:extLst><a:ext uri=""{05A4C25C-085E-4340-85A3-A5531E510DB2}""><thm15:themeFamily xmlns:thm15=""http://schemas.microsoft.com/office/thememl/2012/main"" name=""Office Theme"" id=""{62F939B6-93AF-4DB8-9C6B-D6C7DFDC589F}"" vid=""{4A3C46E8-61CC-4603-A589-7422A47A8E4A}""/></a:ext></a:extLst></a:theme>", _
False, True
MkDir strTmpZipPath & "\" & "xl" & "\" & "worksheets"
WriteToFile _
strTmpZipPath & "\" & "xl" & "\" & "worksheets" & "\" & "sheet1.xml", _
"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>" & _
"<worksheet xmlns=""http://schemas.openxmlformats.org/spreadsheetml/2006/main"" xmlns:r=""http://schemas.openxmlformats.org/officeDocument/2006/relationships"" xmlns:mc=""http://schemas.openxmlformats.org/markup-compatibility/2006"" mc:Ignorable=""x14ac"" xmlns:x14ac=""http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac""><dimension ref=""A1""/><sheetViews><sheetView tabSelected=""1"" workbookViewId=""0""/></sheetViews><sheetFormatPr defaultRowHeight=""15"" x14ac:dyDescent=""0.25""/><sheetData/><pageMargins left=""0.7"" right=""0.7"" top=""0.75"" bottom=""0.75"" header=""0.3"" footer=""0.3""/></worksheet>", _
False, True
ZipAFolder strTmpZipPath, _
strLocalAppTmp & "\" & "EmptyExcelFile.zip"
moveFile strLocalAppTmp & "\" & "EmptyExcelFile.zip", strNewExcelFile
End Sub
'Dependancies NONE
'Version 1.0.0
'By jeremy.gerdes#navy.mil
Public Sub moveFile(strSourcePath, strDestinationPath)
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
'Does the source file exist?
If FileExists(strSourcePath) Then
'If the destination is a folder then move the file into the folder preserving the source name
If FolderExists(strDestinationPath) Then
strDestinationPath = strDestinationPath & "\" & fso.GetFileName(strSourcePath)
End If
'If the destination allready exists, attempt to delete it... this move method allways over writes
If FileExists(strDestinationPath) Then
fso.DeleteFile strDestinationPath, True
End If
'If the destination path doesn't exist attempt to make it
If Not FolderExists(fso.GetParentFolderName(strDestinationPath)) Then
MkDir (fso.GetParentFolderName(strDestinationPath))
End If
'Move the file
fso.moveFile strSourcePath, strDestinationPath
End If
End Sub
Public Sub WriteToFile(ByRef strFileName, ByRef strContent, ByRef fOpenFile, ByRef fOverwrite)
Dim tf ' As Object
Dim FSO ' As Object
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FileExists(strFileName) Then
If fOverwrite Then
FSO.DeleteFile strFileName
End If
End If
Set tf = FSO.OpenTextFile(strFileName, 8, True)
tf.WriteLine strContent
tf.Close
If fOpenFile Then
OpenWithExplorer strFileName
End If
'Clean up
Set tf = Nothing
Set FSO = Nothing
End Sub
Sub ZipAFolder (sFolder, zipFile)
'From /a/15143587/1146659
With CreateObject("Scripting.FileSystemObject")
zipFile = .GetAbsolutePathName(zipFile)
sFolder = .GetAbsolutePathName(sFolder)
With .CreateTextFile(zipFile, True)
.Write Chr(80) & Chr(75) & Chr(5) & Chr(6) & String(18, chr(0))
End With
End With
With CreateObject("Shell.Application")
.NameSpace(zipFile).CopyHere .NameSpace(sFolder).Items
Do Until .NameSpace(zipFile).Items.Count = _
.NameSpace(sFolder).Items.Count
WScript.Sleep 200
Loop
End With
End Sub
Public Sub OpenWithExplorer(ByRef strFilePath)
Dim wshShell
Set wshShell = CreateObject("WScript.Shell")
wshShell.Exec ("Explorer.exe " & strFilePath)
Set wshShell = Nothing
End Sub
Public Function Environ(ByRef strName)
'Replaces VBA.Envrion Public Function with wscript version for use in all VB engines
Dim wshShell: Set wshShell = CreateObject("WScript.Shell")
Dim strResult: strResult = wshShell.ExpandEnvironmentStrings("%" & strName & "%")
'wshShell.ExpandEnvironmentStrings behaves differently than VBA.Environ when no environment variable is found,
' conforming all results to return nothing if no result was found, like VBA.Environ
If strResult = "%" & strName & "%" Then
Environ = vbNullString
Else
Environ = strResult
End If
'cleanup
Set wshShell = Nothing
End Function
' Return true if file exists and false if file does not exist
Public Function FileExists(ByVal strPath) ' As String) As Boolean
Dim FSO 'As Object
Set FSO = CreateObject("Scripting.FileSystemObject")
FileExists = FSO.FileExists(strPath)
' Clean up
Set FSO = Nothing
End Function
Public Function FolderExists(ByVal strPath) 'As String) As Boolean
Dim FSO ' As Object
' Note I used to use the vba.Dir Public Function but using that Public Function
' will lock the folder and prevent it from being deleted.
Set FSO = CreateObject("Scripting.FileSystemObject")
FolderExists = FSO.FolderExists(strPath)
' Clean up
Set FSO = Nothing
End Function
Function MkDir(strPath)
' Version: 1.0.3
' Dependancies: NONE
' Returns: True if no errors, i.e. folder path allready existed, or was able to be created without errors
' Usage Example: MkDir Environ("temp") & "\" & "opsRunner"
' Emulates linux 'MkDir -p' command: creates folders without complaining if it allready exists
' Superceeds the the VBA.MkDir function, but requires that drive be included in strPath
' By jeremy.gerdes#navy.mil
Dim fso ' As Scripting.FileSystemObject
Set fso = CreateObject("Scripting.FileSystemObject") ' New Scripting.FileSystemObject
If Not fso.FolderExists(strPath) Then
On Error Resume Next
Dim fRestore ' As Boolean
fRestore = False
'Handle Network Paths
If Left(strPath, 2) = "\\" Then
strPath = Right(strPath, Len(strPath) - 2)
fRestore = True
End If
Dim arryPaths 'As Variant
arryPaths = Split(strPath, "\")
'Restore Server file path prefix
If fRestore Then
arryPaths(0) = "\\" & arryPaths(0)
End If
Dim intDir ' As Integer
Dim strBuiltPath ' As String
For intDir = LBound(arryPaths) To UBound(arryPaths)
strBuiltPath = strBuiltPath & arryPaths(intDir) & "\"
If Not fso.FolderExists(strBuiltPath) Then
fso.CreateFolder strBuiltPath
End If
Next
End If
MkDir = (Err.Number = 0)
'cleanup
Set fso = Nothing
End Function
'Dependencies: NONE
'--- This function modified from: https://www.reddit.com/r/vba/comments/aom8xs/how_to_tell_if_script_is_running_in_vba_vbscript/ei0z2ll?utm_source=share&utm_medium=web2x&context=3
'--- Returns a string containing which script engine this is running in. Modified to test that wscript has a property 'Version' to allow for wscript emulation in the VBIDE
'--- Will return either "VBS","VBA", or "HTA".
Function ScriptEngine()
On Error Resume Next
ScriptEngine = "VBA"
Dim tmp
tmp = wscript.Version
If Err.Number = 0 Then
ScriptEngine = "VBS"
End If
Err.Clear
ReDim window(0)
If Err.Number = 501 Then
ScriptEngine = "HTA"
End If
On Error GoTo 0
End Function
'Dependencies: ScriptEngine
Function GetCurrentFileFolder()
Select Case ScriptEngine()
Case "VBS"
GetCurrentFileFolder = Left(wscript.ScriptFullName, Len(wscript.ScriptFullName) - Len(wscript.ScriptName) - 1)
Case "VBA"
Select Case Application.Name
Case "Microsoft Word"
GetCurrentFileFolder = ThisDocument.Path
Case "Microsoft Access"
GetCurrentFileFolder = CurrentProject.Path
Case "Microsoft Excel"
GetCurrentFileFolder = ThisWorkbook.Path
End Select
'Not going to bother checking for other VBA contexts like powerpoint, visio, ms project or autocad.
Case "HTA"
'----------------------------------------------------------------------
' - There are several methods to get the current directory of the HTA -
'----------------------------------------------------------------------
'From testing don't use the following
'This method drops the server path for network paths
'strPath = Left(Document.Location.pathname, InStrRev(Document.Location.pathname, "\") - 1) & "\Main.hta"
'This method works fine if the HTA directly executed,
'but if explorer.exe or cscript.exe executes the hta this method returns the %windir% dictory
'Dim objScripShell
'Set objScripShell = CreateObject("WScript.Shell")
'strPath = objScripShell.CurrentDirectory & "\Main.hta"
Dim strPath
strPath = jsUrlDecode(Document.Location.href)
strPath = Replace(strPath, "/", "\")
strPath = Left(strPath, InStrRev(strPath, "\") - 1)
'URLs that begin with a drive letter will begin with 'file:\\\' Check this first
If Left(strPath, 8) = "file:\\\" Then
strPath = Right(strPath, Len(strPath) - 8)
End If
'URLs that begin with a server name will begin with 'file:'
If Left(strPath, 5) = "file:" Then
strPath = Right(strPath, Len(strPath) - 5)
End If
GetCurrentFileFolder = strPath
End Select
End Function
'BuildEmptyExcelFile GetCurrentFileFolder & "\" & "anEmptyExcelFile.xlsx"
I agree with the comments above. I have always done this using Response.ContentType and Response.AppendHeader
Response.ContentType = "application/vnd.ms-excel"
Response.AppendHeader "content-disposition", "filename=MySpreadsheet.xls"
If Excel is installed and accessible on the server and sFSpec is the full (server mapped, accessible) file spec of the (empty) .xls you want to create, then
Dim oExcel : Set oExcel = [Server.]CreateObject( "Excel.Application" )
oExcel.Workbooks.Add.SaveAs sFSpec
oExcel.Quit
should work. If you can't use "Excel.Application", you may use ADO by opening a Excel connection and execute a suitable CREATE TABLE statement.
ADDED
The low tech approach would be to use an empty .xls stolen from some workstation as a template; but you can create an .xls on the fly:
Dim sFSpec : sFSpec = resolvePath("..\data\byado.xls")
If goFS.FileExists(sFSpec) Then goFS.DeleteFile sFSpec
Dim oXDb : Set oXDb = CreateObject("ADODB.Connection")
Dim sCS : sCS = Join(Array(_
"Provider=Microsoft.Jet.OLEDB.4.0" _
, "Data Source=" & sFSpec _
, "Extended Properties=""" _
& Join(Array( _
"Excel 8.0" _
, "HDR=Yes" _
, "IMEX=0" _
), ";" ) _
& """" _
), ";")
oXDb.Open sCS
oXDb.Execute "CREATE TABLE [WhatEver] (DontCare INTEGER)"
oXDb.Close
If goFS.FileExists(sFSpec) Then WScript.Echo "qed"
(You may have to tinker with the "Excel !Version!"; the "IMEX=0" is important)
I answered this on a another question.
correct formatting for excel spreadsheet
You should be able to use CreateObject("Excel.Application") on your server if office (at least Excel) is installed.
Xls (and the other types of Excel 2007/2010 are binary fiels that you can not easily create like that, you need to use Com objects to create and manipulate them. Here an example from the scripting guys http://blogs.technet.com/b/heyscriptingguy/archive/2005/01/31/how-can-i-make-changes-to-and-then-re-save-an-existing-excel-spreadsheet.aspx
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
objExcel.DisplayAlerts = FALSE
Set objWorkbook = objExcel.Workbooks.Add
Set objWorksheet = objWorkbook.Worksheets(1)
objWorksheet.Cells(1, 1).Value = Now
objWorkbook.SaveAs("C:\Scripts\Test.xls")
objExcel.Quit
see http://msdn.microsoft.com/en-us/library/aa223697(v=office.11).aspx for a list of vba functions you can use
I want to send Corel Draw .CDR drawing binary files and XML SVG files from the application to a server via HTTP POST.
I have done some research and this existing post seems closest but doesn't work for my situation:
How can I send an HTTP POST request to a server from Excel using VBA?
I've added a user-custom button to the Corel Draw tool pane and created a macro to run when this button is pressed. The macro contains the following code.
Sub OpenLabelPrintExport()
'
' Recorded 24/06/2008
'
' Description:
'
'
' Add a reference to Microsoft WinHTTP Services
Const HTTPREQUEST_SETCREDENTIALS_FOR_SERVER = 0
'MsgBox "hello"
Dim expflt As ExportFilter
Dim expopt As StructExportOptions
Dim responseText As String
Set expopt = New StructExportOptions
expopt.UseColorProfile = False
' expopt.DontExportFonts
Set expflt = ActiveDocument.ExportEx("C:\afile.svg", cdrSVG, cdrAllPages, expopt)
expflt.Finish
file = "C:\afile.svg"
Dim oS As ADODB.STREAM
Set oS = New STREAM
oS.Type = 2
oS.Open
oS.LoadFromFile file
Dim contentlength As Integer
contentlength = oS.Size
sEntityBody = "-----boundary" & vbCrLf
sEntityBody = sEntityBody & "Content-Dispostion: form-data; name=fileInputElementName; filename=""" + sFileName + """" & vbCrLf
sEntityBody = sEntityBody & "Content-Transfer-Encoding: 7bit" & vbCrLf
sEntityBody = sEntityBody & "Content-Type: text/xml" & vbCrLf & vbCrLf
' did use oS
sEntityBody = sEntityBody & "text" & vbCrLf
sEntityBody = sEntityBody & "-----boundary--" & vbCrLf & vbCrLf
' Set xhr = New MSXML2.XMLHTTP30
Dim xhr As WinHttp.WinHttpRequest
Set xhr = New WinHttpRequest
xhr.Open "POST", sUrl, False
xhr.SetRequestHeader "Content-Type", "multipart/form-data; boundary=""-----boundary"""
xhr.Send sEntityBody
End Sub
On my server, I have the following Perl CGI script to accept the file:
#!/usr/bin/perl -wT
use strict;
use CGI;
use CGI::Carp qw ( fatalsToBrowser );
use File::Basename;
$CGI::POST_MAX = 1024 * 5000;
my $safe_filename_characters = "a-zA-Z0-9_.-";
my $upload_dir = "/usr/lib/cgi-bin/";
my $query = new CGI;
my $filename = $query->param("file");
my $email_address = $query->param("email_address");
if ( !$filename )
{
print $query->header ( );
print "There was a problem uploading your file (try a smaller file).";
exit;
}
my ( $name, $path, $extension ) = fileparse ( $filename, '\..*' );
$filename = $name . $extension;
$filename =~ tr/ /_/;
$filename =~ s/[^$safe_filename_characters]//g;
if ( $filename =~ /^([$safe_filename_characters]+)$/ )
{
$filename = $1;
}
else
{
die "Filename contains invalid characters";
}
my $upload_filehandle = $query->upload("file");
open ( UPLOADFILE, ">$upload_dir/$filename" ) or die "$!";
binmode UPLOADFILE;
while ( )
{
print UPLOADFILE;
}
close UPLOADFILE;
print STDOUT "success";
I have tested the server-side script with a HTML form on a brower.
I would like advise on getting the VBA script that runs in Corel Draw to work correctly. I have searched and searched and can't seem to find a definitive answer to sending binary and text files from a VBA enabled application to a server via HTTP POST. I have bought some books on the subject too but am no wiser.
I need this to work with Corel Draw 12 and Corel Draw X4.
Thanks in advance.
Here is a working solution for Corel Draw 12. This is for exporting SVG - it could be extended to export .CDR and .PDF at the same time using the exporter object provided by Corel for the Visual Basic Application environment. For these two binary formats, base64 may be required to encode them before sending.
Credits:
credit http://www.vbforums.com/showthread.php?t=337424 extended this function to actually do the sending originally the function used Winsock - but this is unavailable in the Visual Basic Application environment of Corel Draw 12/XIV So I replaced this with a WinHttpRequest
credit: http://bytes.com/topic/asp-classic/answers/659406-winhttprequest-posting-byte-string-multipart-message-howto#post2618801 - for adding the req.setRequestHeader "Content-Type", "multipart/form-data; boundary=" & boundary line which is required in WinHttpRequest so that the server-side code on receiving the post can retrieve the actual file data and other params
credit: http://word.mvps.org/faqs/macrosvba/DeleteFiles.htm to delete the temporary file
Four parts to the solution provided below:
Instructions for installing the Corel Draw Visual Basic Application code (part 2 below)
The Corel Draw Visual Basic Application code
the server-side Perl CGI script to accept the file sent as a standard HTTP POST CGI message
test html form web page just to test the server-side Perl cgi script
1) Instructions
Corel Draw: Tools->Visual Basic->Visual Basic Editor
Back to Microsoft Visual Basic: View->Project Explorer
Open FileConverter->Modules->Recorded Macros
Paste in code. NOTE: May need to add-in objects required by script, such as WinHttpRequest, via the Object Browser: View->Object Browser
Close, back to...
Back to Corel Draw: Tools->Customization
In Option pop-up dialog: Options->Customization->Command Bars
Click New
Export To Server for tool bar name
click OK
Drag newly created toolbar onto top pane it should be 'absorbed' into it.
Right click on it
Customize->Export to server toolbar->Add new command
From drop down in 'Options' dialog, select Macros
Find FileConverter.RecordedMacros.DrawingExportToServer
Drag and drop this onto the newly created blank Export to server toolbar to create the button
To export a drawing to the server: create a drawing as usual and click the button
2) The Corel Draw Visual Basic Application code
Type URL
Scheme As String
Host As String
Port As Long
URI As String
Query As String
End Type
Sub DrawingExportToServer()
Dim expflt As ExportFilter
Dim expopt As StructExportOptions
Dim responseText As String
Set expopt = New StructExportOptions
expopt.UseColorProfile = False
' moved from BuildFileUploadRequest to here
' want to re-use this for generating a temporary file name that has minimal risk of clashing/overwriting an other temporary files
Dim strBoundary As String
strBoundary = RandomAlphaNumString(32)
Dim tempExportFile As String
tempExportFile = "C:\WINDOWS\Temp\tempExportFileCorelDraw_" & strBoundary & ".svg"
Set expflt = ActiveDocument.ExportEx(tempExportFile, cdrSVG, cdrAllPages, expopt)
expflt.Finish
Dim realFilenameOfDrawing As String
realFilenameOfDrawing = ActiveDocument.FileName
realFilenameOfDrawing = realFilenameOfDrawing & ".svg"
Dim strFile As String
strFile = GetFileContents(tempExportFile)
Dim strHttp As String
sUrl = "http://myserver.com/cgi-bin/server_side_perl_script.cgi"
Dim DestUrl As URL
DestUrl = ExtractUrl(sUrl)
strHttp = BuildFileUploadRequest(strFile, DestUrl, "file", realFilenameOfDrawing, "text/xml", strBoundary, sUrl)
KillProperly (tempExportFile)
End Sub
' credit http://www.vbforums.com/showthread.php?t=337424
' extended this function to actually do the sending
' originally the function used Winsock - but this is unavailable in the Visual Basic Application environment of Corel Draw 12/XIV
' So I replaced this with a WinHttpRequest
' credit: http://bytes.com/topic/asp-classic/answers/659406-winhttprequest-posting-byte-string-multipart-message-howto#post2618801
' - for adding the req.setRequestHeader "Content-Type", "multipart/form-data; boundary=" & boundary
' line which is required in WinHttpRequest so that the server-side code on receiving the post can retrieve the actual file data and other params
Private Function BuildFileUploadRequest(ByRef strData As String, _
ByRef DestUrl As URL, _
ByVal UploadName As String, _
ByVal FileName As String, _
ByVal MimeType As String, _
ByVal aStrBoundary As String, _
ByVal aUrlString As String) As String
Dim strHttp As String ' holds the entire HTTP request
Dim strBoundary As String 'the boundary between each entity
Dim strBody As String ' holds the body of the HTTP request
Dim lngLength As Long ' the length of the HTTP request
' create a boundary consisting of a random string
'strBoundary = RandomAlphaNumString(32)
strBoundary = aStrBoundary
' create the body of the http request in the form
'
' --boundary
' Content-Disposition: form-data; name="UploadName"; filename="FileName"
' Content-Type: MimeType
'
' file data here
'--boundary--
strBody = "--" & strBoundary & vbCrLf
strBody = strBody & "Content-Disposition: form-data; name=""" & UploadName & """; filename=""" & _
FileName & """" & vbCrLf
strBody = strBody & "Content-Type: " & MimeType & vbCrLf
strBody = strBody & vbCrLf & strData
strBody = strBody & vbCrLf & "--" & strBoundary & "--"
' find the length of the request body - this is required for the
' Content-Length header
lngLength = Len(strBody)
' construct the HTTP request in the form:
'
' POST /path/to/reosurce HTTP/1.0
' Host: host
' Content-Type: multipart-form-data, boundary=boundary
' Content-Length: len(strbody)
'
' HTTP request body
strHttp = "POST " & DestUrl.URI & "?" & DestUrl.Query & " HTTP/1.0" & vbCrLf
strHttp = strHttp & "Host: " & DestUrl.Host & vbCrLf
strHttp = strHttp & "Content-Type: multipart/form-data, boundary=" & strBoundary & vbCrLf
strHttp = strHttp & "Content-Length: " & lngLength & vbCrLf & vbCrLf
strHttp = strHttp & strBody
Dim ContentType As String
Dim xhr As New WinHttp.WinHttpRequest
Dim anUploadName As String
anUploadName = "file"
Dim aFileName As String
aFileName = "file"
Dim aContentType As String
aMimeType = "text/xml"
ContentType = "multipart/form-data, boundary=" & strBoundary & vbCrLf
xhr.Open "POST", aUrlString, False
xhr.SetRequestHeader "Content-Type", ContentType
xhr.Send strHttp
BuildFileUploadRequest = strHttp
End Function
' this function retireves the contents of a file and returns it as a string
' this is also ture for binary files
Private Function GetFileContents(ByVal strPath As String) As String
Dim StrReturn As String
Dim lngLength As Long
lngLength = FileLen(strPath)
StrReturn = String(lngLength, Chr(0))
On Error GoTo ERR_HANDLER
Open strPath For Binary As #1
Get #1, , StrReturn
GetFileContents = StrReturn
Close #1
Exit Function
ERR_HANDLER:
MsgBox Err.Description, vbCritical, "ERROR"
Err.Clear
End Function
' generates a random alphanumeirc string of a given length
Private Function RandomAlphaNumString(ByVal intLen As Integer)
Dim StrReturn As String
Dim X As Integer
Dim c As Byte
Randomize
For X = 1 To intLen
c = Int(Rnd() * 127)
If (c >= Asc("0") And c <= Asc("9")) Or _
(c >= Asc("A") And c <= Asc("Z")) Or _
(c >= Asc("a") And c <= Asc("z")) Then
StrReturn = StrReturn & Chr(c)
Else
X = X - 1
End If
Next X
RandomAlphaNumString = StrReturn
End Function
' returns as type URL from a string
Function ExtractUrl(ByVal strUrl As String) As URL
Dim intPos1 As Integer
Dim intPos2 As Integer
Dim retURL As URL
'1 look for a scheme it ends with ://
intPos1 = InStr(strUrl, "://")
If intPos1 > 0 Then
retURL.Scheme = Mid(strUrl, 1, intPos1 - 1)
strUrl = Mid(strUrl, intPos1 + 3)
End If
'2 look for a port
intPos1 = InStr(strUrl, ":")
intPos2 = InStr(strUrl, "/")
If intPos1 > 0 And intPos1 < intPos2 Then
' a port is specified
retURL.Host = Mid(strUrl, 1, intPos1 - 1)
If (IsNumeric(Mid(strUrl, intPos1 + 1, intPos2 - intPos1 - 1))) Then
retURL.Port = CInt(Mid(strUrl, intPos1 + 1, intPos2 - intPos1 - 1))
End If
ElseIf intPos2 > 0 Then
retURL.Host = Mid(strUrl, 1, intPos2 - 1)
Else
retURL.Host = strUrl
retURL.URI = "/"
ExtractUrl = retURL
Exit Function
End If
strUrl = Mid(strUrl, intPos2)
' find a question mark ?
intPos1 = InStr(strUrl, "?")
If intPos1 > 0 Then
retURL.URI = Mid(strUrl, 1, intPos1 - 1)
retURL.Query = Mid(strUrl, intPos1 + 1)
Else
retURL.URI = strUrl
End If
ExtractUrl = retURL
End Function
' url encodes a string
Function URLEncode(ByVal str As String) As String
Dim intLen As Integer
Dim X As Integer
Dim curChar As Long
Dim newStr As String
intLen = Len(str)
newStr = ""
' encode anything which is not a letter or number
For X = 1 To intLen
curChar = Asc(Mid$(str, X, 1))
If curChar = 32 Then
' we can use a + sign for a space
newStr = newStr & "+"
ElseIf (curChar < 48 Or curChar > 57) And _
(curChar < 65 Or curChar > 90) And _
(curChar < 97 Or curChar > 122) Then
newStr = newStr & "%" & Hex(curChar)
Else
newStr = newStr & Chr(curChar)
End If
Next X
URLEncode = newStr
End Function
' decodes a url encoded string
Function UrlDecode(ByVal str As String) As String
Dim intLen As Integer
Dim X As Integer
Dim curChar As String * 1
Dim strCode As String * 2
Dim newStr As String
intLen = Len(str)
newStr = ""
For X = 1 To intLen
curChar = Mid$(str, X, 1)
If curChar = "%" Then
strCode = "&h" & Mid$(str, X + 1, 2)
If IsNumeric(strCode) Then
curChar = Chr(Int(strCode))
Else
curChar = ""
End If
X = X + 2
End If
newStr = newStr & curChar
Next X
UrlDecode = newStr
End Function
' credit: http://word.mvps.org/faqs/macrosvba/DeleteFiles.htm
Public Sub KillProperly(Killfile As String)
If Len(Dir$(Killfile)) > 0 Then
SetAttr Killfile, vbNormal
Kill Killfile
End If
End Sub
3) the server-side Perl CGI script to accept the file sent as a standard HTTP POST CGI message
#!/usr/bin/perl -w
use strict;
use warnings;
use CGI;
use CGI::Carp qw ( fatalsToBrowser );
use File::Basename;
sub main
{
my $rc = 0;
my $errorMsg = "";
$CGI::POST_MAX = 1024 * 5000;
my $safe_filename_characters = "a-zA-Z0-9_.-";
# NOTE: make sure that appropriate chmod permissions are set so that the script can create and write files to this directory
my $upload_top_level = "/usr/lib/cgi-bin/drawings";
# NOTE: make sure that appropriate chmod permissions are set in this file's parent holding directory and the file itself if already exists
# so that the script can create and write the file
my $upload_log = "/usr/lib/cgi-bin/uploadlog.txt";
my $query = new CGI;
my $filename = $query->param("file");
my $machineid = $query->param("machineid");
my %allParams = $query->Vars;
my $allParamsAsString = "";
my $paramName = "";
foreach $paramName ( keys ( %allParams ) )
{
$allParamsAsString .= "$paramName=".$allParams{$paramName};
}
if ( !$filename )
{
$rc = 1;
$errorMsg = "Filename not specified.";
}
if ( $rc == 0 )
{
my ( $name, $path, $extension ) = fileparse ( $filename, '\..*' );
$filename = $name . $extension;
$filename =~ tr/ /_/;
$filename =~ s/[^$safe_filename_characters]//g;
if ( $filename =~ /^([$safe_filename_characters]+)$/ )
{
$filename = $1;
}
else
{
$rc = 1;
$errorMsg = "Filename contains invalid characters.";
}
}
if ( $rc == 0)
{
my $upload_filehandle = $query->upload("file"); # file is the file field in the form
my $upload_path = "";
# if a machine id is provided
# then we make a subdirectory off of the main top level uploads directory
if ( $machineid )
{
$upload_path = $upload_top_level."/".$machineid."/";
if (!( -e $upload_path ))
{
mkdir $upload_path;
}
}
else
{
$upload_path = $upload_top_level."/";
}
unless( open ( UPLOADFILE, ">$upload_path/$filename" ) )
{
$rc = 1;
$errorMsg = "Cannot open $upload_path/$filename";
}
if ( $rc == 0 )
{
binmode UPLOADFILE;
while ( <$upload_filehandle> )
{
print UPLOADFILE;
}
close UPLOADFILE;
print STDOUT $query->header();
$errorMsg = "Success.";
print STDOUT responseToClient( "Success." );
}
}
else
{
print STDOUT $query->header();
print STDOUT responseToClient( $errorMsg );
}
# needs (f)locking
open ( LOG, ">>$upload_log" );
print LOG $filename.", ".$machineid.", ".$errorMsg.", ".$query->all_parameters.", ".$allParamsAsString."\n";
close ( LOG );
}
sub responseToClient
{
my ( $message ) = #_;
my $response =
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n"
."<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"
."<head>\n"
."<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n"
."<title>".$message."</title>\n"
."</head>\n"
."<body>\n"
."<p>".$message."</p>\n"
."</body>\n"
."</html>\n\n";
return $response;
}
main ();
4) test html form web page just to test the server-side Perl cgi script
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>File Upload</title>
</head>
<body>
<form action="/cgi-bin/nsr_store_label.cgi" method="post"
enctype="multipart/form-data">
<p>File to Upload: <input type="file" name="file" /></p>
<p>Machine id: <input type="text" name="machineid" /></p>
<p><input type="submit" name="Submit" value="Submit Form" /></p>
</form>
</body>
</html>
You can save the file locally, and then use cURL to post the data to your server (using the Shell command in VBA).
The code below works. But if I comment out the line Dim objRequest As MSXML2.XMLHTTP and uncomment the line Dim objRequest As Object it fails with the error message :
The parameter is incorrect
Why, and what (if anything) can I do about it?
Public Function GetSessionId(strApiId, strUserName, strPassword) As String
Dim strPostData As String
Dim objRequest As MSXML2.XMLHTTP
'Dim objRequest As Object '
strPostData = "api_id=" & strApiId & "&user=" & strUserName & "&password=" & strPassword
Set objRequest = New MSXML2.XMLHTTP
With objRequest
.Open "POST", "https://api.clickatell.com/http/auth", False
.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
.send strPostData
GetSessionId = .responseText
End With
End Function
Corey, yes, I know I would have to do that in order for my code to work without a reference to the MSXML type library. That's not the issue here. The code fails when using Dim objRequest As Object regardless of whether I use
Set objRequest = NEW MSXML2.XMLHTTP with the reference, or
Set objRequest = CreateObject("MSXML2.XMLHTTP") without the reference.
For some reason, this works:
Dim strPostData As String
Dim objRequest As Object
strPostData = "api_id=" & strApiId & "&user=" & strUserName & "&password=" & strPassword
Set objRequest = New MSXML2.XMLHTTP
With objRequest
.Open "POST", "https://api.clickatell.com/http/auth", False
.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
.send (strPostData)
GetSessionId = .responseText
End With
Instead of building the URL-encoded strPostData via string concatenation, it's strongly advisable to use a URL encoding function:
strPostData = "api_id=" & URLEncode(strApiId) & _
"&user=" & URLEncode(strUserName) & _
"&password=" & URLEncode(strPassword)
A couple of choices for a URLEncode() function in VBA are in this thread: How can I URL encode a string in Excel VBA?
If you use the Dim objRequest As Object then you would need to code:
Set objRequest = CreateObject("MSXML2.XMLHTTP")
I realise this is nearly identical to the code from Tomalek above (all credit due to you!), but this question helped me towards a full solution to a problem I had (Excel submitting to PHP server, then dealing with response)...so in case this is of any help to anyone else:
Sub Button1_Click2()
Dim objXMLSendDoc As Object
Set objXMLSendDoc = New MSXML2.DOMDocument
objXMLSendDoc.async = False
Dim myxml As String
myxml = "<?xml version='1.0'?><Request>Do Something</Request>"
If Not objXMLSendDoc.LoadXML(myxml) Then
Err.Raise objXMLSendDoc.parseError.ErrorCode, , objXMLSendDoc.parseError.reason
End If
Dim objRequest As MSXML2.XMLHTTP
Set objRequest = New MSXML2.XMLHTTP
With objRequest
.Open "POST", "http://localhost/SISADraftCalcs/Test2.php", False
.setRequestHeader "Content-Type", "application/xml;charset=UTF-16"
.setRequestHeader "Cache-Control", "no-cache"
.send objXMLSendDoc
End With
Dim objXMLDoc As MSXML2.DOMDocument
Set objXMLDoc = objRequest.responseXML
If objXMLDoc.XML = "" Then
objXMLDoc.LoadXML objRequest.responseText
If objXMLDoc.parseError.ErrorCode <> 0 Then
MsgBox objXMLDoc.parseError.reason
End If
End If
Dim rootNode As IXMLDOMElement
Set rootNode = objXMLDoc.DocumentElement
MsgBox rootNode.SelectNodes("text").Item(0).text
End Sub