Some background
1st solution: I have built an excel solution which imports the needed data using a from text data source.
I had chosen this method as the URL which send the data will be sending a csv file. Once the data is received many process and conditions have to be applied on this.
Cause of concern: This takes a lot of time to get the data more than 6 mins. Which causes the excel to hang.
In my 2nd similar solution :- i had chosen to call a vb script from excel to do the downloading of data. This works very well for this solution.
Now, i want to implement this method for 1st solution.
My main issue: The vb script used in the 2nd solution fails with the below error.
Error:- C:\Users-user id-\Desktop\script\download_moni.vbs(15, 1) msxml6.dll: The operation timed out
My code for VB Script:-
Set args = WScript.Arguments
Url = "url given here"
dim xHttp: Set xHttp = createobject("MSXML2.ServerXMLHTTP.6.0")
dim bStrm: Set bStrm = createobject("Adodb.Stream")
xHttp.Open "GET", Url, False 'Open socket to get the website
xHttp.Send 'send request
with bStrm
.type = 1 '//binary
.open
.write xHttp.responseBody
.savetofile "C:\Ticket\Monitoring.csv", 2 '//overwrite
end with
wscript.echo("Download complete")
Please let me know how to fix the timeout error.
You say that "[it] takes a lot of time to get the data more than 6 mins." Yet the default timeout of the library you are using seems to be 30 seconds for receiving data (source).
I am not familiar with the MSXML2.ServerXMLHTTP library you are using, but Google reveals that there is a setTimeouts method, which can be used to increase various timeouts of your library.
Related
I'm using this script I compiled to get details about the documentaries that I watch. Based on the filename, I get a documentary name, I then compile a google search string, I search google, get google's response, open the correct link from it, and get the data. This used to work until a few days ago. Today, I tried running my script, and I get an error right at the very beginning, while calling the function that does the google search. This is the function:
Public Function getHTTP(ByVal url As String) As String
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", url, False
.send
getHTTP = StrConv(.responseBody, vbUnicode)
End With
End Function
"url" is compiled based on different criteria. Right now it is:
https://www.google.com/search?hl=en&source=hp&q=site:docuwiki.net+++"secrets+in+our+dna+"
The error triggers on the ".send" line. The error is:
Run-time error '-2147024891 (80070005)': Access denied.
If I then click on debug and try to run the script again (from the current point), I get another error:
Run-time error '2147467259 (80004005)': Unspecified error.
I don't think I made any changes to the system between the last time it worked and now. Haven't installed anything, no updates, nothing. I should mention that I'm on a fairly old laptop, using MSOffice 2007 under Windows 7.
Here's a minimal reproducible example. This causes the aforementioned error (that it wouldn't have a couple of weeks ago).
Public Function getHTTP(ByVal url As String) As String
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", url, False
Debug.Print url
.send
getHTTP = StrConv(.responseBody, vbUnicode)
End With
End Function
Sub testing123()
Dim a, URL1
URL1 = "https://www.google.com/search?hl=en&source=hp&q=site:docuwiki.net+bbc+""beautiful+minds+"""
a = lcase(getHTTP(URL1))
End Sub
Apparently, the problem was caused by not having opened Internet Explorer in a long time. When I tested my URLs, I only did so in Chrome. When I tried to paste the same URL in IE and access it, I got one of those cookie confirmation pages. After agreeing to the cookies and closing IE, I tested the script again and it worked like it used to.
I have a code for my Excel application. It generates a product invoice and every time the invoice generated it will send the current billed amount along with thanks message. I have purchased a bulk SMS account and they have provided me the API.
I am using the "ActiveWorkbook.FollowHyperlink" method to send SMS, but it is sending SMS 2 times. Can anyone tell me why this method sends sms 2 times??
I have written the following program:
Sub Macro1()
Dim murl As String
murl = "<< SMS API HERE >>"
ActiveWorkbook.FollowHyperlink Address:=murl
End Sub
Consider using a raw GET request to your API, here is an example using late-binding to send a GET request to a google page - the MsgBox line is simply showing the response from google and you can replace the google.co.uk URL with your own API URL.
Public Sub Send_GET()
Dim con As Object ' MSXML2.ServerXMLHTTP60
Set con = CreateObject("MSXML2.ServerXMLHTTP") ' New MSXML2.ServerXMLHTTP60
con.Open "GET", "https://www.google.co.uk", False
con.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
con.send
MsgBox con.responsetext
End Sub
I've used late binding but if you want to explore the proper objects and properties then add a reference to "Microsoft XML v6.0" in your VBA project and you can get rid of the Object and CreateObject parts - sending requests like this is SO USEFUL.
Don't forget to mark an answer as correct if it helps solve your problem.
I am trying to perform a GET call with a where clause on an id. The back end is set up and the call works when you put the URL into a browser however it does take some time to load. However, when I try the GET call from Excel I get an HTTP Error: 500. "Reason: Illegal Character in query at position: 54"
My variable portion of the URL is /?q={"user_id":"abc12345"}
The VBA input is /?q={""user_id"":""" & vUser & """}"
The 54th position is the first bracket. Does vba require some other syntax?
I also tried putting in a wait function to see if it wasn't waiting for the execution. Didn't Help.
Any idea why it works in the browser but not in the VBA?
Below is the Object I am using:
Set http = CreateObject("WinHttp.WinHttpRequest.5.1")
http.SetAutoLogonPolicy 0
http.Open "GET", URL, False
http.send
I've successfully automated a VBA Excel macro to iterate through a loop and hit a series of URL's to trigger a server-side script - this is simply done with:
myIE.Navigate ("http://someURL.php?VARIABLE=" & var_string)
where var_string is assigned within the loop as it iterates through. Before this, I've cleared cache, cookies and history with:
Shell "RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess #
I've tried many #'s including 8,2, 16 etc to see if any of these had an effect (and combination of #'s).
The issue I am having, is that although the entire script SOMETIMES works, if I were to run it a second time the line where I navigate to the URL fails to call the URL even though the domain/URL is fully live and functional. Any other URL I manually type into the IE window works just fine - just not the one I am calling inside the loop. IE is locking me out of that domain temporarily. If I come back to the script a few hours from last running it, it generally works.
Again the domain is functional and script is fine - I verify it all the time with another machine.
It's as if I am setting something environmentally and breaking Internet Explorer within VBA even though the script is absurdly simple.
I've tried CreateObject(), GetObject as well as InternetExplorerMedium for myIE object.
If all you need is to "touch" that URL for its side effects, you can as well use a XMLHTTP object. In VBA, go to menu Tools, then References and choose Microsoft XML, v6.0. Then:
Dim Request As New XMLHTTP
Request.open "GET", Url & "?VARIABLE=" & var_string, False
Request.send
' Check Request.status, probably for 200
Some notes:
You may want to use POST instead of GET, if you're having problems with caching
You should pass the data in the POST body, if the server can handle it
The value of var_string should be escaped, in this case, URL encoded
If you don't want to block waiting for responses, you can make requests asynchronously (True third argument to open)
Following these notes, here's a more elaborate example:
Dim Request As New XMLHTTP
Request.open "POST", Url, True
Dim Handler As New CXMLHTTPHandler
Handler.Initialize Request
Set Request.onreadystatechange = Handler
Request.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
Request.send UrlEncode("VARIABLE") & "=" & UrlEncode(var_string)
' This returns immediately, the check must now be done in the Handler
For the missing pieces, here's the code for CXMLHTTPHandler, which I actually found through stackoverflow, and a definition of UrlEncode at stackoverflow.
You should specialize CXMLHTTPHandler for your needs, probably even make it accept an AddressOf a procedure and call it in the actual default procedure. The default procedure should set the m_xmlHttp to Nothing when m_xmlHttp.readyState is 4.
EDIT 1: If your request code is in a loop, you need to break the Dim ... New statements in two, to ensure you're using fresh objects:
Dim Request As XMLHTTP
Set Request = New XMLHTTP
Request.open "POST", Url, True
Dim Handler As CXMLHTTPHandler
Set Handler = New CXMLHTTPHandler
Handler.Initialize Request
Set Request.onreadystatechange = Handler
Request.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
Request.send UrlEncode("VARIABLE") & "=" & UrlEncode(var_string)
' This returns immediately, the check must now be done in the Handler
I have similar code in Excel VBA with WebBrowser control inserted in a form:
basePath = "http://www.amazon.co.uk/"
' Open main website (Home page)
WebBrowser.Navigate basePath
PauseTime = 30 ' Set duration to wait in seconds.
Start = Timer ' Set start time.
Do ' While Timer < Start + PauseTime
DoEvents ' allow other processes to work (the browser to have time to load the webpage)
Loop Until WebBrowser.ReadyState = READYSTATE_COMPLETE Or Timer > Start + PauseTime
This way I'm opening the specified URL.
Then I put bar-code value in the search field in the HTML and invoke .Click method on the "submit" button (HTML input element) for the same form.
I successfully open the search results page with what I'm searching for, but the browser control is already in WebBrowser.ReadyState = READYSTATE_COMPLETE status and I cannot track when actually the browser control finished the second load - the search page in this case.
Is there a way to RESET the ReadyState property in order to know when the second load has finished?
Because DocumentComplete it not reliable (thank you Alex for the suggestion!) - sometimes it fires before the page is fully loaded resulting in missing part I need for my job, I ended using this:
Set MyObj = Nothing
Do
DoEvents
Set MyObj = WebBrowser.Document.all("myobjID")
Loop Until Not MyObj is Nothing
But it's temporary solution - i'm not sure i'll always have this myobjID in the DOM!
Use the DocumentComplete event which is raised when a document is fully loaded so should fire for every call to .Navigate.
(This includes frames so if any are present you will need to filter them using the URL argument the event receives)