1

I had a macro that used to go to a website pull a value from the A column, for example 517167000, from a particular part of the code and returning that value to a cell. The html source has changed now and i cant seem to get it to work.

My original code was

Public Function UnitPerBox(searchTerm As String) As String
Static request As Object
If request Is Nothing Then Set request = CreateObject("msxml2.xmlhttp")

With request
    .Open "GET", "https://larsonjuhl.co.uk/mouldings/larson-juhl-essentials/arq-essentials-moulding-" & searchTerm, False
    .send
    UnitPerBox = Trim(Split(Split(.responseText, "Units per box</td>")(1), "<tr")(0))
End With

End Function

So a working example of the website is

https://larsonjuhl.co.uk/mouldings/larson-juhl-essentials/arq-essentials-moulding-517167000

So that you can go to the website and view the source. The new html code looks like the below, but its been so long since i did the original macro, that i assumed that i could change

"Units per box</td>")(1), "<tr" 

to

"Units per pack</td> <td class="value">")(1), "<tr"

as the below new html code is what is now on the site, and i need the value 2.74 for example, but its not working.

<tr>
                <td class="name">Units per pack</td>
                <td class="value">2.74</td>
            </tr>

Any help would be much appreciated.

An example of Cheers

0

1 Answer 1

1

If you go and work with .responseText using Split() doing text manipulation you might as well use a regular expression without setting it's Global parameter:

Public Function UnitPerBox(searchTerm As String) As String
Static request As Object
If request Is Nothing Then Set request = CreateObject("msxml2.xmlhttp")

Dim RegEx As Object
Set RegEx = CreateObject("VBScript.RegExp")
RegEx.Pattern = "\d+(?:\.\d+)?"

With request
    .Open "GET", "https://larsonjuhl.co.uk/mouldings/larson-juhl-essentials/arq-essentials-moulding-" & searchTerm, False
    .send
    UnitPerBox = RegEx.Execute(Split(.responsetext, "Units per pack</td>")(1))(0)
End With

End Function

Neater (IMO) however is to avoid text manipulation on the .responseText alltogether and work through the HTML document, retrieve the appropriate data straigt from the HTML-table by element-ID and table indexes:

Public Function UnitPerBox(searchTerm As String) As String
Static request As Object
If request Is Nothing Then Set request = CreateObject("msxml2.xmlhttp")
Dim htmlResponse As Object: Set htmlResponse = CreateObject("htmlfile")

With request
    .Open "GET", "https://larsonjuhl.co.uk/mouldings/larson-juhl-essentials/arq-essentials-moulding-" & searchTerm, False
    .send
    htmlResponse.body.innerHTML = .responseText
    UnitPerBox = htmlResponse.body.document.getElementById("specifications").getElementsByTagName("tr")(10).getElementsByTagName("td")(1).innerText
End With

End Function

Note that the table is 0-indexed meaning we are actually retrieving our value from the 11th row, second column. In case you are not sure that the tablecontent is always found on the same indexes, you could also just loop the child nodes:

Public Function UnitPerBox(searchTerm As String) As String
Static request As Object
If request Is Nothing Then Set request = CreateObject("msxml2.xmlhttp")
Dim htmlResponse As Object: Set htmlResponse = CreateObject("htmlfile")
Dim Rws As Object

With request
    .Open "GET", "https://larsonjuhl.co.uk/mouldings/larson-juhl-essentials/arq-essentials-moulding-" & searchTerm, False
    .send
    htmlResponse.body.innerHTML = .responseText
    Set Rws = htmlResponse.body.document.getElementById("specifications").getElementsByTagName("tr")
    For Each Rw In Rws
        If Rw.getElementsByTagName("td")(0).InnerText = "Units per pack" Then
            UnitPerBox = Rw.getElementsByTagName("td")(1).InnerText
            Exit For
        End If
    Next
End With

End Function

Where I personally would prefer to use HTML document over text manipulation, all above options work to retrieve your value =)

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks a lot. Why do you use Static in this UDF? I mean what's the benefit?
@YasserKhalil, looking at that, I'm not sure how big the advantage would be of Static here, since I don't know what resources it takes to Set request = CreateObject("msxml2.xmlhttp"). If you plan on using the code a lot I guess it will have some advantage since it prevents creating this object over and over...
Hi JvdV, Thanks for the speedy response. I'm very new to this, but ive tried all three of your answers and im getting a Value error in the cell. My formula in the cell literally says =UnitPerBox(A1) as an example. Is this incorrect? It thought about it for a while, so it was definitely doing something, but im not getting a value returned. Thanks again for your help.
I tried all 3. Was still getting that error, obviously I’m doing something wrong. This is probably really cheeky, are you able to attach your working sheet. My sheet contains pricing and discounts etc. Thanks again
@JvdV Ill accept your answer, but it ended up that i didnt even need the help. Im using a macbook pro and apparently macOS just doesnt like it. I logged onto my windows remote desktop and my old one worked fine :) Thanks again

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.