Cannot perform auto search on a specific website - excel

Recently I am learning to use excel macro to search on a website. I've read several forum threads and I came up with the code below. However, error appears when I reach the row
SearchBox(0).Value = SearchString
I tried to remove the (0) but another error appears as well. The code works well on other websites. How should I change them to adapt to this site?
P.S. I would also like to know the way to click the search button.
Sub Searchstockcode()
Dim SearchString As String
SearchString = "700"
Set ie = CreateObject("InternetExplorer.Application")
With ie
ie.Visible = True
End With
ie.Navigate "http://www.hkexnews.hk/listedco/listconews/advancedsearch/search_active_main.aspx"
While ie.ReadyState <> 4
DoEvents
Wend
Dim SearchBox As Object
Set SearchBox = ie.Document.GetElementsByName("ct100$txt_stock_code")
SearchBox(0).Value = SearchString
Dim SearchButton As Object
Set SearchButton = ie.Document.GetElementsByName
End Sub

I don't know whether the problem with your name selection is due to the element having two name attributes but that seems possible.
You may use the following.
For the search box I use its id to target the element. This is normally unique on a document and the fastest selector method.
For the search button I use a CSS attribute + value selector of
[src*='/image/search.gif']
This targets the src attribute [] of the element by its value. * means contains. The selector looks for a src attribute containing /image/search.gif in its value.
You can observe the attribute here:
Option Explicit
Sub Searchstockcode()
Dim SearchString As String, SearchBox As Object, SearchButton As Object, ie As Object
SearchString = "700"
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
ie.navigate "http://www.hkexnews.hk/listedco/listconews/advancedsearch/search_active_main.aspx"
While ie.Busy Or ie.readyState < 4: DoEvents: Wend
Set SearchBox = ie.document.getElementById("ctl00_txt_stock_code")
SearchBox.Value = SearchString
Set SearchButton = ie.document.querySelector("[src*='/image/search.gif']")
SearchButton.Click
While ie.Busy Or ie.readyState < 4: DoEvents: Wend
Stop '<==Delete me
'other code
ie.Quit
End Sub

Related

VBA to click on a button on an IE form to submit it

I'm quite new to VBA so please bear with me. I've been trying to create an automation to fill in username and password and login to a site (to start with) but I've been having trouble trying to click on the submit button. Scoured the internet and learnt a whole bunch of things but I didnt find anything that seems to work. The page loads and fills in the details and nothing happens when I run the code below.
Would greatly appreciate some help with this. Thanks in advance as always!
Sub worldcheck()
Dim lastrow As Long
Dim IE As Object
Dim cel As Range
Dim post As Object
Dim ws As Worksheet
Dim element As Object
Set ws = Sheets("sheet1")
Set IE = CreateObject("internetexplorer.application")
lastrow = ws.Range("B" & ws.Rows.Count).End(xlUp).Row
IE.Visible = True
IE.Navigate "https://www.world-check.com/frontend/login/"
Do While IE.busy
DoEvents
Loop
Application.Wait (Now + TimeValue("0:00:2"))
IE.document.getElementbyID("username").Value = ws.Range("D2")
IE.document.getElementbyID("password").Value = ws.Range("D3")
IE.document.getElementbyClass("button").click
Do While IE.busy
DoEvents
Loop
End Sub
Nothing else happens? You should be getting an error message at the very least as you are trying to use a non existent method (VBA Run-time error 438 Object doesn't support this property or method) . The method is getElementsByClassName - note the s indicating it returns a collection and the ending is ClassName. You would then need to index into that collection before attempting to access the Click method
As there is only a single element with classname button you can use a faster css class selector (this is also faster than using a type selector of form; likewise, you can use the faster css equivalent of getElementById for the other two DOM elements). document.querySelector stops at the first match so is also more efficient.
Finally, rather than hard coded waits use proper page load waits as shown below:
Option Explicit
Public Sub WorldCheck()
Dim ie As Object
Set ie = CreateObject("InternetExplorer.Application")
With ie
.Visible = True
.Navigate2 "https://www.world-check.com/frontend/login/"
While .busy Or .readystate <> 4: DoEvents: Wend
With .document
.querySelector("#username").Value = "ABCDEF" ' equivalent to .getElementbyID("username").Value = "ABCDEF"
.querySelector("#password").Value = "GHIJKL" '.getElementbyID("password").Value = "GHIJKL"
.querySelector(".button").Click
End With
While .busy Or .readystate <> 4: DoEvents: Wend
Stop '<== delete me later
.Quit
End With
End Sub

IE click on a button that has no link associated to it (using Excel VBA)

I want to click on a "button" on a web page, but my problem is that this button doesn't seem to have link attach to it. By the way I'm phrasing this you can see I'm not familiar at all with the language of web browser.
Anyway I most use internet explorer and here's the code I have so far
Sub click_button_no_hlink()
Dim i As Long
Dim IE As Object
Dim Doc As Object
Dim objElement As Object
Dim objCollection As Object
Set IE = CreateObject("InternetExplorer.Application") 'create IE instance
IE.Visible = True
IE.Navigate "https://apex.xyz.qc.ca/apex/prd1/f?p=135:LOGIN_DESKTOP::::::" ' Adress of web page
Do While IE.Busy 'loading page
Application.Wait DateAdd("s", 1, Now)
Loop
'-------------Usually I would do something like that and it would works well.-----------------
Set link = IE.document.getElementsByTagName("a")
For Each l In link
a = l.innerText
If l.innerText = "Créer" Then '
l.Click
Exit For
End If
Next
'-------------That method works fine on other type of hlink to the page by the way------------
'-----------------------I also tried various methods around this with no luck------------------------------
Set objCollection = IE.document.getElementsByClassName("rc-content-buttons") 'recherche du bouton "Créer"
'---------------------------------
'--------------------or this also doesn't work-------------------------------
For Each btn In IE.document.getElementsByClassName("rc-content-buttons")
If btn.getAttribute("id") = "B91938241817236808" Then
btn.Click
Exit For
End If
Next btn
End Sub
For sake of clarity here's the code of the web page around the "button" I'm trying to interact with.
I've made many research but I'm in a dead end right now. Any help will be greatly appreciate.
Tx in advance.
SOLVED FINAL CODE: With help from DOMENIC and QHARR and Yu Zhou
Sub click_button_no_hlink()
Dim i As Long
Dim IE As Object
Dim Doc As Object
Dim objElement As Object
Dim objCollection As Object
Set IE = CreateObject("InternetExplorer.Application") 'create IE instance
IE.Visible = True
IE.Navigate "https://apex.xyz.qc.ca/apex/prd1/f?p=135:LOGIN_DESKTOP::::::" ' Adress of web page
While IE.Busy: DoEvents: Wend 'loading page
IE.document.querySelector("[value='Créer']").FireEvent "onclick" 'works like a charm
' IE.document.querySelector("div.rc-content-buttons input").Click
'also works but speaks less by itself when reading code
' IE.document.getElementById("B91938241817236808").Click
'also works
End Sub
It is within an input not a tag element so gathering a tags will not capture what you want. Using the id, as suggested in comments is one way to go. If you get element not found then check whether your element is within a parent frame or iframe which needs to be negotiated. General syntax for that is
ie.document.getElementsByTagName("frame")(appropriateIndexHere).contentDocument.getElementById("B91938241817236808")
ie.document.getElementsByTagName("iframe")(appropriateIndexHere).contentDocument.getElementById("B91938241817236808")
If the id is dynamic you can use the value attribute
ie.document.querySelector("[value='Créer']")
ie.document.getElementsByTagName("frame")(appropriateIndexHere).contentDocument.querySelector("[value='Créer']") 'etc
As there is an event, you may need to fire it.
ie.document.querySelector("[value='Créer']").FireEvent "onclick"
ie.document.getElementsByTagName("frame")(appropriateIndexHere).contentDocument.querySelector("[value='Créer']").FireEvent "onclick" 'etc
And use a proper page load wait. So this,
Do While IE.Busy 'loading page
Application.Wait DateAdd("s", 1, Now)
Loop
Should be
While ie.Busy Or ie.ReadyState <> 4: DoEvents:Wend
getElementsByClassName returns an array-like object of all child elements which have all of the given class names, so I think it should be IE.document.getElementsByClassName("rc-content-buttons")(0).Click if it is the first element with the classname.
You could also try: IE.document.querySelector("div.rc-content-buttons input").Click.
And I think IE.document.getElementById("B91938241817236808").Click is also right.

Automating a Report: Selecting from a drop down in IE using VBA

I'm trying to automate a report of mine using VBA. I was able to do the log in part and all but when it comes to navigating the next webpage with drop downs I can't seem to get a hold of it. I tried multiple ways to fill out the first drop down which is the report type and I can't find the correct code
All commented "'" are all the codes I've tried. I can't post the website since it's a client website.
html "inspect elemet" photo
Sub Get_RawFile()
Dim IE As New InternetExplorer
Dim HTMLDoc As HTMLDocument
Dim addressInput As HTMLInputElement
With IE
.Visible = True
.Navigate ("------------------------")
While IE.Busy Or IE.readyState <> 4: DoEvents: Wend
Set HTMLDoc = IE.document
HTMLDoc.all.UserName.Value = Sheets("Data Dump").Range("A1").Value
HTMLDoc.all.Password.Value = Sheets("Data Dump").Range("B1").Value
HTMLDoc.getElementById("login-btn").Click
While IE.Busy Or IE.readyState <> 4: DoEvents: Wend
'HTMLDoc.getElementByName("ddlReportType")(0).Value = "1"
'Set HTMLDoc = IE.document
'Set evtChange = HTMLDoc.createEvent("HTMLEvents")
'evtChange.initEvent "change", True, False
'Set selectElement = HTMLDoc.getElementById("ddlReportType")
'selectElement.Value = "1" 'Attendance
'selectElement.dispatchEvent evtChange
'Set htmlSelectElem = HTMLDoc.getElementsByTagName("ddlReportType")
'htmlSelectElem.selectedIndex = 1
'Set reporttype = IE.document.getElementById("ddlReportType")
'For i = 1 To reporttype.Options.Length
'If reporttype.Options(i).Text = "Attendance" Then
'reporttype.selectedIndex = i
'Exit For
'End If
'Next i
End With
Run-time error '438'
Object doesn't support this property or method
This method .getElementByName does not exist. It should be .getElementsByName("Something"), in which case the method returns a collection of elements whose Name attribute is Something.
The following would access the first element of the collection of elements whose Name attribute is ddlReportType and set its value to 1:
HTMLDoc.getElementsByName("ddlReportType")(0).Value = "1"
Having said that, you don't seem so sure as to what ddlReportType is.
If it's the id of an element then the element should look like so:
<tagName id="ddlReportType">Something</tagName>
In that case you should use the method .getElementByID()
If it's the Name of an element then the element should look like so:
<tagName Name="ddlReportType">Something</tagName>
In that case you should use the method .getElementsByName(), which returns a collection of elements.
If it's the Class of an element then the element should look like so:
<tagName Class="ddlReportType">Something</tagName>
In that case you should use the method .getElementsByClassName(), which returns a collection of elements.
Finally, I can tell you for sure that it's not a Tag Name so you definitely shouldn't use the .getElementsByTagName method.
EDIT
From the image you provided after editing your original post, it is clear that ddlReportType is the id of a <select></select> element. So you should do it this way:
Dim HTMLselect As HTMLSelectElement
Set HTMLselect = HTMLDoc.getElementById("ddlReportType")
HTMLselect.Value = "1"
References used: Microsoft HTML Object Library (VBE>Tools>References>...)
That's how to select one of the drop down options. To navigate further you would have to press some button I presume.

getElementById won't work in VBA, error 438

I am relatively new at VBA (I know the basics, but not much else) and I am trying to get some code set up that will fill out online forms for me, but when I run my code I get a 438 error:
object doesnt support this property or method
when it gets to
ie.document.getElementById ("q")
I have added the HTML object library and Microsoft internet controls to my references. I have looked at tons of online forums. I have even copied and pasted an entire script directly into VBA. Nothing will make it use getElementById(). Here is my code:
Sub internetstuff()
Dim ie As Object
Set ie = CreateObject("internetexplorer.application")
ie.Visible = True
ie.navigate ("https://www.google.com/")
Set searchbx = ie.document.getElementById("q")
searchbx.Value = "Howdy!"
End Sub
What should happen is that it should open InternetExplorer, go to Google, and populate the search bar with "Howdy!".
Instead, It only opens google, then I get the error message and it stops running.
Because "q" is not an ID, it's a Name.
You have to use GetElementsByName and select the 1st Element
try this:
Sub internetstuff()
Dim ie As Object
Set ie = CreateObject("internetexplorer.application")
ie.Visible = True
ie.Navigate ("https://www.google.com/")
Do Until ie.ReadyState >= 4
DoEvents
Loop
Set searchbx = ie.document.getElementsByName("q")(0)
searchbx.Value = "Howdy!"
End Sub
I have also added a waiting Event, in case it takes time to load Google.
Result:
A more concise and efficient way is to use querySelector to return first match for the name attribute
Option Explicit
Public Sub internetstuff()
Dim ie As Object
Set ie = CreateObject("InternetExplorer.Application")
With ie
.Visible = True
.Navigate2 "https://www.google.com/"
While .Busy Or .readyState < 4: DoEvents: Wend
.document.querySelector("[name=q]").Value = "Howdy"
Stop '<delete me later
.Quit
End With
End Sub

How to automate a dynamically changing web page url and autofill using Excel VBA?

How to automate a dynamically changing web page url and autofill using Excel VBA?
Your question is a light on the details, but from what I understand your code is working, but you are wanting to grab a new tab that opens up after your code completes.
You can do this with a function I have and use somewhat regularly. This will look at the URLs in your open browser (whether the browser is hidden or not) and allow you to set your object declaration to the tab containing your url.
Warning: Just as JohnRC stated in his comment, automatic manipulation of web pages handling financial transactions is ill-advised. An error in your coding can produce unexpected results. I do not personally recommend automation of financial transactions and any advice you take out of this you do so at your own risk.
Function:
Function GetIE(sLocation As String) As Object
Dim objShell As Object, objShellWindows As Object, o As Object
Dim sURL As String
Dim RetVal As Object
Set RetVal = Nothing
Set objShell = CreateObject("shell.application")
Set objShellWindows = objShell.Windows
For Each o In objShellWindows
sURL = ""
On Error Resume Next
'check the URL and if it's the one you want then
'assign it to the return value and exit the loop
sURL = o.document.Location
On Error GoTo 0
If sURL Like sLocation Then
Set RetVal = o
Exit For
End If
Next o
Set GetIE = RetVal
End Function
In your below code, you are now setting ie2 as the new webpage, with the URL string "*bildesk.com/id*". Once you accomplish this, you can manipulate ie2 just as you did with your first IE object.
Sub SearchBot()
'dimension (declare or set aside memory for) our variables
Dim IE As InternetExplorer 'special object variable representing the IE browser
Dim aEle As HTMLLinkElement 'special object variable for an <a> (link) element
Dim y As Integer 'integer variable we'll use as a counter
Dim result As String 'string variable that will hold our result link
'initiating a new instance of Internet Explorer and asigning it to objIE
Set IE = New InternetExplorer
Dim iedoc As Object
'navigate IE to this web page (a pretty neat search engine really)
IE.navigate "https://www.nbpdcl.co.in/(S(qq5avnlkl4xr2iqstldu0ehl))/frmQuickBillPaymentAll.aspx"
'wait here a few seconds while the browser is busy
Do Until IE.readyState = READYSTATE_COMPLETE: DoEvents: Loop
'in the search box put cell "A2" value
IE.document.getElementById("MainContent_txtCANO").Value = _
Sheets("Sheet1").Range("A2").Value
'click the 'go' button
IE.document.getElementById("MainContent_btnSubmit").Click
'wait here a few seconds while the browser is busy
Do While IE.Busy = True Or IE.readyState <> 4: DoEvents: Loop
'in the amount box put cell "B2" value
IE.document.getElementById("MainContent_txtAmountPayable").Value = _
Sheets("Sheet1").Range("B2").Value
'in the EMAIL box put cell "C2" value
IE.document.getElementById("txtEmailId").Value = _
Sheets("Sheet1").Range("C2").Value
'in the PHONE box put cell "D2" value
IE.document.getElementById("txtMobileNo").Value = _
Sheets("Sheet1").Range("D2").Value
'click the 'verify' button
IE.document.getElementById("MainContent_rbtnlstPaymode_0").Checked = True
'click the 'verify' button
IE.document.getElementById("MainContent_btnConfirmPay").Click
'wait here a few seconds while the browser is busy
Do While IE.Busy = True Or IE.readyState <> 4: DoEvents: Loop
'click the 'verify' button
IE.document.getElementById("MainContent_btnPayNow").Click
'<--------- Use the function here ---------->
Dim ie2 As InternetExplorer
Set ie2 = GetIE("*bildesk.com/id*")
End Sub
So just include the function provided with your module and you should be set.

Resources