0

I am attempting to automate a certain process for my business by clicking on certain links on a webpage, inputting business data into a search box and compare it with existing data. I am however, unsuccessful at clicking a javascript based link which also the part of the table using VBA. The website's relevant HTML is as below,

<tr class="odd"> <td> <a onclick="viewCompanyDetails('B214273', '1529481460070');" href="javascript:;">Alinda Infrastructure Fund III (Euro) GP SARL</a></td> <td><a onclick="viewCompanyDetails('B214273', '1529481460070');" href="javascript:;">B214273</a></td> </tr>

Here is my poor attempt at doing the project,

        Private Sub CommandButton1_Click()
        Set IE = CreateObject("InternetExplorer.Application")
        my_url = "https://www.lbr.lu/mjrcs/jsp/DisplayConsultDocumentsActionNotSecured.action?FROM_MENU=true&time=1528967707649&currentMenuLabel=menu.item.companyconsultation"

    consoletext = consoletext & "Connection established to Luxembourg Business Registers on www.rcsl.lu via Internet Explorer..." & vbNewLine & vbNewLine
    txtConsole.Value = consoletext
    consoletext = consoletext & "Looking up Registre De Commerce et des Societes." & vbNewLine & vbNewLine
    txtConsole.Value = consoletext

        With IE
            .Visible = True
            .navigate my_url

        Do Until Not IE.Busy And IE.readyState = 4
            DoEvents
        Loop

        End With

    For Each objlink In IE.document.getElementsByTagName("href")
    If objlink.href = "/mjrcs/jsp/DisplayConsultDocumentsActionNotSecured.action?FROM_MENU=true&time=1528969484260&currentMenuLabel=menu.item.companyconsultation" Then
    objlink.Click
    Exit For
    End If
    Next objlink

    Do Until Not IE.Busy And IE.readyState = 4
            DoEvents
        Loop

    consoletext = consoletext & "Looking up " & Sheets("Results").Range("N1").Value & " in the registry." & vbNewLine & vbNewLine
    txtConsole.Value = consoletext

    Dim TradeName As String
    TradeName = ThisWorkbook.Sheets("Results").Range("Y1").Value

     IE.document.getElementById("companyName").Value = TradeName

    Set objSubmit = IE.document.getElementsByTagName("input")

    For Each btn In objSubmit
        If btn.Value Like "Search" Then
            btn.Click
        End If
    Next

        Do Until Not IE.Busy And IE.readyState = 4
            DoEvents
        Loop

    For Each entitylink In IE.document.getElementsByClassName("tr")
    If entitylink.getElementsByTagName = "a" And entitylink.textcontent = Sheets("Results").Range("N1").Value And entitylink.href = "javascript:;" Then
    entitylink.Click
    Exit For
    End If
    Next entitylink


    txtXMLpath.Value = ""

End Sub

This is what the webpage content looks like,

enter image description here

I have hidden the name of the entity to protect the identity of the client. I need to click the result on the first row per the image.

I will be much obliged if you could provide any help. Again, I'm a beginner in VBA and have no idea how to proceed here. Please let me know should you require further clarification

QHarr
  • 83,427
  • 12
  • 54
  • 101
  • The issue I face is with the code at the bottom - For Each entitylink In IE.document.getElementsByClassName("tr") If entitylink.getElementsByTagName = "a" And entitylink.textcontent = Sheets("Results").Range("N1").Value And entitylink.href = "javascript:;" Then entitylink.Click Exit For End If Next entitylink – Renin Mathew Jun 20 '18 at 09:05
  • Try to execute script directly instead of 'cliking'. https://stackoverflow.com/questions/3247391/click-button-or-execute-javascript-function-with-vba – Volod Jun 20 '18 at 09:14
  • Thanks for the response Volodymyr. I went through the link but to be honest, I have no clue what the post is referring to. Can you help me apply the same with my code here? – Renin Mathew Jun 20 '18 at 09:32
  • What exactly is the element I should be looking at here? – Renin Mathew Jun 20 '18 at 09:35
  • How come this line be valid `IE.document.getElementsByTagName("href")`? Don't you think `href` is an `attribute` instead of `tag` @Renin Mathew?. – SIM Jun 20 '18 at 14:30
  • @SIM Thank you for your response. Although, I'm quite unsure how it works, but it does provide the expected result. – Renin Mathew Jun 20 '18 at 14:38
  • Making it `("a")` instead of `("href")` is the right approach. Whether it is working or not is different issue. – SIM Jun 20 '18 at 14:42

1 Answers1

0

You can use .querySelector to get the element you want which is the first with

.document.querySelector("a[onclick='viewCompanyDetails('B214273', '1529481460070');']")

Then you may need to do either:

.document.querySelector("a[onclick='viewCompanyDetails('B214273', '1529481460070');']").Click

or

.document.querySelector("a[onclick='viewCompanyDetails('B214273', '1529481460070');']").fireEvent 'onclick'

CSS selector:

CSS query

The selector returns 2 items from your HTML but .querySelector will only return the first of these when applying the selector to the HTML. The first is the required "SARL".


More info on .fireEvent method:

fireEvent method: Fires a specified event on the object.

Syntax: object.fireEvent(bstrEventName, pvarEventObject,
pfCancelled)

It has a boolean return value which if TRUE tells you the event was successfully fired.


.querySelector method:

The Document method querySelector() returns the first Element within the document that matches the specified selector, or group of selectors. If no matches are found, null is returned.

Syntax: element = document.querySelector(selectors); <== note the ";" is not used in VBA


Edit:

If .querySelector method is not supported you could try looping the a tags and clicking when a particular string is found e.g.

Dim c As Object, n As Object
Set c = ie.document.getElementsByTagName("a")
For Each n In c
    If InStr(1, n.innerText, "Alinda Infrastructure Fund III (Euro) GP SARL") > 0 Then
        n.Click
        Exit For
    End If
Next n

Without more HTML to target the specific a tags of interest you can do a general write out of all a tags with:

Dim c As Object, n As Object, counter As Long
Set c = ie.document.getElementsByTagName("a")
With ActiveSheet
    For Each n In c
        counter = counter + 1
        .Cells(counter, 1) = n.innerText
    Next n
End With

More HTML is needed to target this better; perhaps there is a className or Id to identify the element housing these a tags?

For your link to write table to sheet:

Option Explicit
Public Sub GetInfo()
    Dim ie As Object
    Application.ScreenUpdating = False
    Set ie = CreateObject("InternetExplorer.Application")
    With ie
        .Visible = True
        .navigate "https://www.lbr.lu/mjrcs"

        While .Busy Or .readyState < 4: DoEvents: Wend '<== Loop until loaded

        Dim links As Object, link As Object
        Set links = .document.getElementsByTagName("a")

        For Each link In links
            If link.innerText = "View the person's file" Then
                link.Click
                Exit For
            End If
        Next link

        While .Busy Or .readyState < 4: DoEvents: Wend

        .document.getElementById("companyName").innerText = "Alinda"
        .document.getElementsByClassName("button")(0).Click

        While .Busy Or .readyState < 4: DoEvents: Wend

        Dim hTable As HTMLTable
        Set hTable = .document.getElementsByClassName("commonTable")(0)

        Dim n As Object, tRow As Object, tCell As Object, tr As Object, td As Object, r As Long, c As Long, hBody As Object

        r = 1
        With ActiveSheet
            Set hBody = hTable.getElementsByTagName("tbody")
            For Each n In hBody                 'HTMLTableSection
                Set tRow = n.getElementsByTagName("tr") 'HTMLTableRow
                For Each tr In tRow
                    Set tCell = tr.getElementsByTagName("td")
                    c = 1
                    For Each td In tCell         'DispHTMLElementCollection
                        .Cells(r, c).Value = td.innerText 'HTMLTableCell
                        c = c + 1
                    Next td
                    r = r + 1
                Next tr
            Next n
        End With
        .Quit '<== Remember to quit application
    End With
    Application.ScreenUpdating = True
End Sub
QHarr
  • 83,427
  • 12
  • 54
  • 101
  • Thank you for your response. Then again, I am quite lost - what is the intended purpose of the above? – Renin Mathew Jun 20 '18 at 14:41
  • Mostly yes but need not be the case. I need to click the closest match to the name provided in the search criteria. – Renin Mathew Jun 20 '18 at 19:04
  • Sheets("Results").Range("N1").Value is the name of the entity or the search criteria. I do not have a plan to get the closest match at the moment for now - like you may probably suggest, the topmost row is most likely the closest match and I think it should be fair to just go with the top row. – Renin Mathew Jun 20 '18 at 19:13
  • IE version 11.22 – Renin Mathew Jun 20 '18 at 19:14
  • Document mode = 11 (Default) – Renin Mathew Jun 20 '18 at 19:30
  • You're a champion, and I mean it. Thanks QHarr. I am much obliged. Please be around to answer a question or two I may face during the rest of this project. Thanks a lot again! – Renin Mathew Jun 20 '18 at 19:50
  • My most humble apologies, just to dig back into this again - is there anyway I can get the entire list of top 20 entities (as in the screenshot) onto an excel sheet? I could then perform some data validation to get the 'closest match' to the user entered search criteria – Renin Mathew Jun 20 '18 at 20:16
  • QHarr you're going to make heights. It was really kind of you to rewrite the entire code! On another note, I've been attempting to get the entity address text on the page above to an excel cell and all I get in the cell is "[OBJECT HTMLLIELEMENT]". I tried the same with debug.print and msgbox() but it works there and just not with the cell. Do you know why this happens? here is the code, Sheets("Results").Range("C27").Value = UCase(ie.document.getElementsByClassName("clearLeft")(1)) – Renin Mathew Jun 22 '18 at 10:04
  • ie.document.getElementsByClassName("clearLeft")(1).innerText – QHarr Jun 22 '18 at 10:09
  • This is embarrassing. Sometimes I can get stupid. :D Thanks again mate! – Renin Mathew Jun 22 '18 at 10:16
  • :-) we all do it! – QHarr Jun 22 '18 at 10:17