Having a server running in English (required), we set up its IIS instance with this global.asa sample
<script language="vbscript" runat="server">
Sub Session_OnStart
Session.LCID=1036 ' French (standard)
'Session.LCID=1033 ' English
End Sub
</script>
It seems that a DLL, especially using the object WinHttp.WinHttpRequest, returns messages in english. Below a sample showing when it occurs :
Public Function getHttpResponse(url As String)
Dim request As New WinHttpRequest
On Error GoTo errGetHttpResponse
request.Open "HEAD", url
request.Send
getHttpResponse = request.Status
Exit Function
errGetHttpResponse:
getHttpResponse = Err.Description ' <-- Right here
End Function
Does this mean that IIS doesn't "propagate" global.asa settings to the DLL ?
Related
As new coding maybe this question may be silly, but when I try to run this code, it keeps showing an Error 91 highlighting this line
'Get the number from the specified element on the page
number = html.getElementsByClassName("arial_14 redFont").Item(0).innerText
As I already identified number at the beginning, I have no idea why it keeps showing the variable wasn't defined.
Sub Get_Housing_Starts_From_Investing()
Dim request As Object
Dim response As String
Dim html As New HTMLDocument
Dim website As String
Dim number As Variant
' Source: https://www.youtube.com/watch?v=IOzHacoP-u4
' Remember to activate References: Microsoft Office 16.0 Object Library, Microsoft HTML Object Library, Microsoft XML, v6.0, Visual Basic For Applications, Microsoft Excel 16.0 Object Library, OLE Automation
' Website to go to
website = "https://www.investing.com/economic-calendar/housing-starts-151"
' Create the object that will make the website request
Set request = CreateObject("Msxml2.ServerXMLHTTP.6.0")
' Where to go and how to go there - donĀ“t need to change it
request.Open "GET", website, False
' Get fresh data
request.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
' Send the request for the webpage
request.send
' Get the webpage response data into a variable
response = StrConv(request.responseBody, vbUnicode)
' Put the webpage into an html object to make data references easier
html.body.innerHTML = response
'Get the number from the specified element on the page
number = html.getElementsByClassName("arial_14 redFont").Item(0).innerText
' Output the number into a message box
MsgBox number
End Sub
I have been using the following Excel VBA macro to bring back data from a website. It worked fine until a few days ago when the website stopped supporting IE. Of course the macro just fails now as there is no data on the webpage to bring back to Excel, Is there a way to have the "Get method" (MSXML2.XMLHTTP)
here is my Code
Public Sub GGGG()
Dim MSX As Object
Dim HTML As HTMLDocument
Dim URL As String
Dim UrlResponse As String
Dim N As Long
Dim sht1, sht2 As Worksheet
' On Error Resume Next
Set MSX = CreateObject("MSXML2.XMLHTTP")
Set HTML = New HTMLDocument
URL = "https://www.justdial.com/Agra/Yogi-General-Store-Opp-Eclave-Satiudum-Sadar-Bazaar/0562P5612-5612-120207212812-H5I2_BZDET"
With MSX
.Open "GET", URL, False
.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
.send
UrlResponse = StrConv(.responseBody, vbUnicode)
End With
ActiveCell.Offset(0, 1) = UrlResponse
End Sub
I get response like
Error
An error occurred while processing your request.
Reference #97.ec8a2c31.1621136928.281f3ca8
Please anyone can support me how to get data when IE dose not support
I am not an expert in coding
Okay, try this to get the title and votes from that site using vba in combination with selenium.
Sub FetchInfo()
Dim driver As Object, oTitle As Object
Dim oVotes As Object
Set driver = CreateObject("Selenium.ChromeDriver")
driver.get "https://www.justdial.com/Agra/Yogi-General-Store-Opp-Eclave-Satiudum-Sadar-Bazaar/0562P5612-5612-120207212812-H5I2_BZDET"
Set oTitle = driver.FindElementByCss("span.item > span", Raise:=False, timeout:=10000)
Set oVotes = driver.FindElementByCss("span.rtngsval > span.votes", Raise:=False, timeout:=10000)
Debug.Print oTitle.Text, oVotes.Text
End Sub
When the webpage no longer support IE in future, you can try out web scrape using Google Chrome with new add-in installed, please see following link for the add-in installation adn how to write in VBA. However, it is in my opinion the most simple way to perform your work is to use Uipath free community version, it work for all type of web-browser.
VBA guideline:
https://www.wiseowl.co.uk/vba-macros/videos/vba-scrape-websites/web-scraping-selenium-chrome/
VBA library installation for Selenium:
https://code.google.com/archive/p/selenium-vba/downloads
You probably need to set the Feature Browser Emulation to zero as detailed by Daniel here:
Everything You Never Wanted to Know About the Access WebBrowser Control
That said, your URL fails even when opened in Edge Chromium, so the site may suffer from a general failure.
I'm working on the following code, which will re-format a cell containing a link based on whether or not the link works when it is clicked:
Private Sub worksheet_followhyperlink(ByVal HL As HYPERLINK)
Dim linkReq As Object
Dim linkStatus As Integer
Application.ScreenUpdating = False
On Error GoTo linkError
Set linkReq = New MSXML2.XMLHTTP60
With linkReq
.Open "GET", HL.address, False
.Send
End With
linkStatus = linkReq.Status
If linkStatus = 404 Then HL.Parent.Interior.Color = rgbPink
If linkStatus <> 404 Then HL.Parent.Interior.Pattern = xlNone
If HL.Parent.Interior.Pattern = xlNone Then GoTo exitSub
Application.ScreenUpdating = True
MsgBox("Link is broken")
exitSub:
Application.ScreenUpdating = True
Exit Sub
linkError:
linkStatus = 404
Resume Next
End Sub
The code worked great yesterday! But now, it's returning everything as '404' and marking the cells pink, even if the links work. Debugging reveals that the value of HL.address is "folder/Document.pdf" instead of "https://website/folder/Document.pdf". This excel document is hosted on "https://website" through sharepoint.
The code not working because of the truncation.
Is there a way to extract a full url from an excel hyperlink, without truncation, regardless of the size of the url?
It seems that Excel is changing your hyperlinks adresses from absolute to relative.
You can try to force absolute adress by changing so called "Hyperlink Base". In order to do it go to: File > Info > Show All Properties > Hyperlink Base (on the right of screen) and change it to "x".
Reference from Microsoft Support site:
https://support.microsoft.com/en-us/help/903163/how-to-create-absolute-hyperlinks-and-relative-hyperlinks-in-word-docu
(Article presents solution for MS Word but it should work in MS Excel as well)
Hope that helps.
The range object in excel has a second property "Subaddress" .
Use the Subaddress functionality to get the rest of the address like below
range.Hyperlinks(1).Address + range.Hyperlinks(1).SubAddress
In my case I had to add additional characters in between Address and Subaddress. Please make sure to check how the full URL can be formed using both Address and Subaddress
I am new to VBA. I have written a VBA code in Microsoft Excel 2007 to send a SOAP Message and Handle the soap Response.
I am reading the Soap Response and writing values to Excel cells in a loop.
The sample soap response is :-
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:getMyResponse xmlns:ns2="http://my.samplenamesapce/">
<return>
<col1>col1Value</col1>
<col2>col2Value</col2>
<col3>3.283E7</col3>
</return>
<return>
<col1>col1Value</col1>
<col2>col2Value</col2>
</return>
</ns2:getMyResponse>
</soap:Body>
</soap:Envelope>
and the VBA code to write response in cells is:
Private Sub getReportBtn_Click()
Dim WS As Worksheet: Set WS = Worksheets("my_report")
Dim request As New MSXML2.XMLHTTP60
Dim url As String
Dim response As New MSXML2.DOMDocument60
Dim requestData As String
'Clear the Report Sheet
WS.Range("A2:C65536").ClearContents
url = Range("url").Value
'Construct SOAP REQUEST
request.Open "POST", url, False
request.setRequestHeader "Content-Type", "text/xml; charset=""UTF-8"""
request.setRequestHeader "SOAPAction", ""
'Create SOAP REQUEST BODY
requestData = xmlBody
request.setRequestHeader "Content-Length", Len(requestData)
On Error GoTo err_handler:
'Send SOAP REQUEST
request.send requestData
'Read SOAP RESPONSE
response.LoadXML request.responseText
Dim MyReport As MSXML2.IXMLDOMNode
Dim MyReportList As MSXML2.IXMLDOMNodeList
Set MyReportList = response.getElementsByTagName("return")
Dim i As Integer
i = 1
For Each MyReport In MyReportList
i = i + 1
WS.Range("col1Range").Cells(i).Value = MyReport.selectSingleNode("col1").Text
WS.Range("col2Range").Cells(i).Value = MyReport.selectSingleNode("col2").Text
If MyReport.SelectNodes("col3").Length > 0 Then
WS.Range("col3Range").Cells(i).Value = MyReport.selectSingleNode("col3").Text
End If
Next MyReport
If i = 1 Then
MsgBox "No data found for requested query!"
Sheets("query").Select
Exit Sub
End If
Sheets("my_report").Select
Exit Sub
err_handler:
MsgBox "Error occurred during submission, please check your settings."
Exit Sub
End Sub
When I run My excel sheet on Windows 7(64 Bit), it is taking double amount of time as compared to running it on Windows XP (32 Bit) to process same data.
The configuration and physical location of both the machines are identical except the Operating system.
You might need to declare the variables as 32-bit variables. To see if the variable declaration is the area of delay, set timers at the start and end of the code and a third timer before your WS.range clearContents. My hunch is that assigning memory space is taking twice the time on the 64-bit machine.
I would like to direct an excel VBA form to certain URLs, get the HTML source and store that resource in a string. Is this possible, and if so, how do I do it?
Yes. One way to do it is to use the MSXML DLL - and to do that you need to add a reference to the Microsoft XML library via Tools->References.
Here's some code that displays the content of a given URL:
Public Sub ShowHTML(ByVal strURL)
On Error GoTo ErrorHandler
Dim strError As String
strError = ""
Dim oXMLHTTP As MSXML2.XMLHTTP
Set oXMLHTTP = New MSXML2.XMLHTTP
Dim strResponse As String
strResponse = ""
With oXMLHTTP
.Open "GET", strURL, False
.send ""
If .Status <> 200 Then
strError = .statusText
GoTo CleanUpAndExit
Else
If .getResponseHeader("Content-type") <> "text/html" Then
strError = "Not an HTML file"
GoTo CleanUpAndExit
Else
strResponse = .responseText
End If
End If
End With
CleanUpAndExit:
On Error Resume Next ' Avoid recursive call to error handler
' Clean up code goes here
Set oXMLHTTP = Nothing
If Len(strError) > 0 Then ' Report any error
MsgBox strError
Else
MsgBox strResponse
End If
Exit Sub
ErrorHandler:
strError = Err.Description
Resume CleanUpAndExit
End Sub
Just an addition to the above response. The question was how to get the HTML source which the stated answer does not actually provide.
Compare the contents of oXMLHTTP.responseText with the source code in a browser for URL "http://finance.yahoo.com/q/op?s=T+Options". They do not match and even the returned values are different. (This should be executed after hours to avoid changes during the trading day.)
If I find a way to perform this task the basic code will be posted.
Compact getHTTP function
Below is a compact & generic function that will return HTTP response from a specified URL to, for example:
return the HTML Source of a web page,
JSON response from an API URL,
parse a text file at a URL, etc.
This does not require any VBA References since MSXML2 is used as a late-bound object.
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
Note that this basic function has no validation or error handling, as those are the parts that can vary considerably depending on which URL you're hitting.
If desired, check the value of .Status after the .Send) to check for success codes like 0 or 200, and also you can setup an error trap with On Error Goto... (never Resume Next!)
Example Usage:
This procedure scrapes this Stack Overflow page for the current score of this question.
Sub demo_getVoteCount()
Const answerID$ = 2522760
Const url_SO = "https://stackoverflow.com/a/" & answerID
Dim html As String, startPos As Long, voteCount As Variant
html = getHTTP(url_SO) 'get html from url
startPos = InStr(html, "answerid=""" & answerID) 'locate this answer
startPos = InStr(startPos, html, "vote-count-post") 'locate vote count
startPos = InStr(startPos, html, ">") + 1 'locate value
voteCount=Mid(html,startPos,InStr(startPos,html,"<")-startPos) 'extract score
MsgBox "Answer #" & answerID & " has a score of " & voteCount & "."
End Sub
Of course in reality there are far better ways to get the score of an answer than the example above, such as this way.)