With the previous question's answer I stepped ahead however still stuck on one point where I wanted to click the element but it seems it has 2 frames and thats the reason when I am running code its giving error that element not found, please check attachment and below code and advise.
Sub activeBexIE_Final()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
'On Error Resume Next
Dim Perm_bot As New Selenium.IEDriver
Perm_bot.Get "official link"
Perm_bot.Wait 2000
Perm_bot.FindElementById("logonuidfield").SendKeys "XYZ"
Perm_bot.SendKeys Perm_bot.Keys.Tab
Perm_bot.SendKeys "PQR"
Perm_bot.SendKeys Perm_bot.Keys.Enter
Perm_bot.Wait 40000
Perm_bot.switchToFrame
Perm_bot.FindElementById("iframe_Roundtrip_9223372036563636042")
Perm_bot.FindElementById("BUTTON_OPEN_SAVE_btn1_acButton").SendKeys
Perm_bot.Keys.Enter
Perm_bot.Wait 30000' *till here I am sucessful- Opening Url-login-click on
"Open" option*
*'from here I am unable to move further, pls check attachment"select
layout" like how I wanted to select and also check the attachment "frame"
and "element" which is having the HTML details, not sure if this particular
element has 2 element, if yes then how I should write the script and after
this I wanted to do tab 7 times and then enter, kindly help for further
script, thanks in advance
'Perm_bot.switchToFrame Perm_bot.FindElementById("urPopupOuter0")
Perm_bot.switchToFrame Perm_bot.FindElementById("urPopupInner0")
Perm_bot.FindElementById("LOAD_state_tigen4_tlv1_list_unid6_tv").Click
SendKeys "{TAB}"
SendKeys "{TAB}"
SendKeys "{TAB}"
SendKeys "{TAB}"
SendKeys "{TAB}"
SendKeys "{TAB}"
SendKeys "{TAB}"
SendKeys "{ENTER}"
Perm_bot.Wait 10000
Application.DisplayAlerts = True
Application.ScreenUpdating = True
'perm_dot.Quit
'Set perm_dot = Nothing
End Sub
Select Layout
FrameElement
I believe your concern is your iframes are having similar attributes and you have to switch to each one of it before tabing 7 times.
Approach would be
Just like getting all windows handles and then loop you can use common xpath for iframe for e.g
findelements(By.Xpath("//iframes))
this will return iframe elements and then you can use loop and traverse and use
SwitchToFrame().
If your webpage is containing multiple frames and you need to perform an action on each frame too then I suggest trying to create an object for those frames and assign it to the 'document' object and then try to perform the action on each frame.
Sub demo()
Dim URL As String
Dim IE, doc1, doc2 As Object
Dim frame1 As HTMLFrameElement
Dim frame2 As HTMLFrameElement
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
URL = "D:\Tests\parent.html"
IE.Navigate URL
Do While IE.ReadyState = 4: DoEvents: Loop 'Do While
Do Until IE.ReadyState = 4: DoEvents: Loop 'Do Until
Set frame1 = IE.document.getElementByID("urpopupouter0")
Set frame2 = IE.document.getElementByID("urpopupinner0")
Set doc1 = frame1.contentWindow.document
Set doc2 = frame2.contentWindow.document
IE.document.getElementByID("btn1").Click
doc1.getElementByID("btn1").Click
doc2.getElementByID("btn1").Click
Set IE = Nothing
End Sub
I tested the above code on my side and it works fine with the multiple frames on a webpage.
Test result:
VBA code is clicking the button on each frame and on the parent web page which changes the forecolor of the button to red.
Further, you can try to modify the code as per your own requirements.
Related
My end goal is to dynamically get music playing. I figured that navigating to youtube, searching for the string, and playing the first video suggested is a good way of getting this done. Pandora and Spotify both have hoops that you need to jump through before playing.
Sub YouTube()
So we open up IE, and navigate to the website
Set objIE = CreateObject("InternetExplorer.Application")
WebSite = "www.youtube.com"
With objIE
.Visible = True
.navigate WebSite
Do While .Busy Or .readyState <> 4
DoEvents
Loop
So far, so good. Next we find the search box, and make a search. Dummy text entered for the sake of easy coding, it'll eventually be an argument passed to the function.
Set Element = .document.getelementsbyname("search_query")
Element.Item(0).Value = "portal 2 walkthrough video"
.document.forms(1).submit
Do While .Busy Or .readyState <> 4
DoEvents
Loop
Great, we made it! Now for the part I'm struggling on - clicking on the first video.
I've tried a few different things - I can't seem to find a name, and I keep getting a "Permission denied" when I try to do something like this, as suggested by other users. See: How do I click a link on a web page using Excel VBA?
I've decided not to programatically control the mouse and click, since the location I need to click on keeps dynamically changing.
I'm not very good at interfacing with IE while using VBA, so at this point I'm stumped.
Set Element2 = .document.getelementsbytagname("a")
For Each i In Element2
If i.classname = "yt-lockup-content" Then
i.Click
Exit For
Else
'do nothing
End If
Next i
End With
End Sub
I've also tried:
.document.getelementsbyclassname("yt-lockup-content").Click
But that's not a supported method
.document.querySelector("a[href=javascript:browserPrint();]").Click
Gets a permission denied
The following using a loop to wait until results are present. I try to keep much of the selectors used to target elements fairly loose to allow for changes in html
Option Explicit
Public Sub test()
Dim ie As InternetExplorer
Set ie = New InternetExplorer
With ie
.Visible = True
.Navigate2 "https://www.youtube.com/"
While .Busy Or .readyState <> 4: DoEvents: Wend
.document.querySelector("[title=Search]").Value = "portal 2 walkthrough video"
.document.querySelectorAll("form").item(1).submit
While .Busy Or .readyState <> 4: DoEvents: Wend
Do
Loop While .document.querySelectorAll("#results").Length = 0
.document.querySelector("#results h3 a").Click
While .Busy Or .readyState <> 4: DoEvents: Wend
Stop '<Delete me later
End With
End Sub
Another method is to use the querySelector() method. You know you want the element with the tag a, because the a tag means that it contains a link.
Then combine the above with the class name that you're looking for, yt-lockup-title, and you get this single line:
.querySelector("h3.yt-lockup-title").Click
Take note that this is a method of the document object. So objIE.Document.querySelector()
Don't want to use the .Click method? You can also grab the url from the href attribute and just perform a navigation:
Dim vidURL As String
vidURL = objIE.document.querySelector("h3.yt-lockup-title > a").getAttribute("href")
objIE.navigate "https://www.youtube.com" & vidURL
However, in the method you attempted with using
.document.getelementsbyclassname("yt-lockup-content").Click
the getElementsByClassName() function returns a collection of elements. Because of this, you would need to append the index number of the element you are wanting, which would very likely be the first element (since you want the first video).
One of the two lines would be what you're looking for:
.document.getelementsbyclassname("yt-lockup-content")(0).Click
' - OR -
.document.getelementsbyclassname("yt-lockup-content").Item(0).Click
They both do and mean the same thing.
I have changed a element to span element and it worked. Code below:
Sub YouTube()
Set objIE = CreateObject("InternetExplorer.Application")
WebSite = "www.youtube.com"
With objIE
.Visible = True
.navigate WebSite
Do While .Busy Or .ReadyState <> 4
DoEvents
Loop
Set Element = .document.getelementsbyname("search_query")
Element.Item(0).Value = "portal 2 walkthrough video"
.document.forms(1).submit
Do While .Busy Or .ReadyState <> 4
DoEvents
Loop
Set Element2 = .document.getelementsbytagname("span")
For Each i In Element2
Do While .Busy Or .ReadyState <> 4
DoEvents
Loop
If i.classname = "yt-thumb-simple" Then
i.Click
Exit For
Else
'do nothing
End If
Next i
End With
End Sub
I am trying to develop a macro that will be able to automatically check the format of tracking number in a sheet, decide which courier site to use, and then get the status of shipment. Until now it's going pretty well, since both tnt and dhl's results have tracking no in it's address, but I got kinda stuck with ups, where the submission of form seems to be done via javascript.
I managed to trick it by focusing on input box and making my macro send keys tab, tab and enter after inputting no, but it's not so elegant and the success rate seems to be about 70% from my testing.
I tried all different variations of getelementsby..., but nothing really seemed to submit the form successfully.
Is there a way to call the JavaScript to start query, or maybe another way of submitting the form itself?
Added an edited chunk of code for testing as well as html for both what seems to be code for the button and for the JavaScript :
sub ups()
Dim objIE
Dim Website
Dim Element
Dim cRng As Range
Set cRng = "1Z30RY119130505965"
Set objIE = "https://www.ups.com/tracking/tracking.html"
With objIE
.visible = True
.navigate Website
Do While objIE.Busy Or objIE.ReadyState <> 4
DoEvents
Loop
Set Element = .Document.GetElementsByName("trackNums")
'a part of code I found useful for when previous Do
'While fails and events start executing too early
Dim btimer As Integer
btimer = 0
Do While Element.Item(3).Value = 0
Application.Wait (Now + TimeValue("0:00:01"))
btimer = 4 Then
Exit Do
End If
Loop
Element.Item(3).Focus
Element.Item(3).Value = cRng.Value
SendKeys "{TAB}"
SendKeys "{TAB}"
SendKeys "{~}"
<div class="btnBar">
<input name="track.x" class="ups-cta ups-cta_primary" type="submit" value="Track"></input>
</div>
<script language="JavaScript1.2" type="text/javascript">
$(function)
{
Tracking.setLocaleString('en_KR');
Tracking.setLoadingText('Loading. Please wait a moment.');
Tracking.setErrorMessage3('The systen is unable to process your request at this time. Please try again later.');
Tracking.addInatructionTextForyinputPage("Enter up to 25 tracking or InfoNotice numbers, one per line.", 'y');
Thanks for any ideas in advance.
I'm currently experiencing a problem with VBA. I'm trying to tick checkbox on an external website. Here is a html snippet that I'm working with:Html code from external website
I have redacted any confidential information from the snippet.
Here is my VBA code:
Set elements = objIE.document.getElementsByTagName("input")
For Each ele In elements
ele.toString
If ele.Value = "xxx" Then ele.Click
Next
So in this code the elementsvariable is an object and the loop variable ele is not being populated at all. I need to compare that the value in the check box contains value xxx. I'm not too experienced in VBA.
Any help would be appreciated
Thanks
I really don't know if that works. But in VBA the
.Value
property of a Checkbox is eighter true or false. The property of the text that is shown is:
.Caption
This code is looping properly:
Sub test()
Set objIE = CreateObject("InternetExplorer.Application")
Dim elements, ele
objIE.Visible = True
For Each ip In Sheets("Sheet1").Range("A2:A13").Value
objIE.Navigate ip
Do Until Not objIE.Busy And objIE.ReadyState = 4
DoEvents
Loop
Set elements = objIE.document.getElementsByTagName("input")
For Each ele In elements
ele.toString
If ele.Value = "xxx" Then ele.Click
Next
Next
End Sub
I'm trying to write a short VBA code to click on a button on a website by searching first by its classname, and then by id:
Sub Autoclick[enter image description here][1]()
Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")
IE.Navigate "http://stackoverflow.com/"
IE.Visible = True
While IE.Busy
DoEvents
Wend
IE.Document.getElementsByClassname("nav mainnavs").getElementById("nav-jobs").Click
End Sub
However the code would not click on the Jobs button. I understand that I can just use getelementbyid directly, but I'd still like to know why using getelementsbyclassname and getelementbyid together would not work.
Attached image contains the html code of the website.
Thanks a lot for any help!
I'd still like to know why using getelementsbyclassname and
getelementbyid together would not work.
Because code IE.Document.getElementsByClassname("nav mainnavs").getElementById("nav-jobs") causes error 438: object doesn't support this property or method.
It doesn't work because getElementsByClassName("nav mainnavs") returns a div and divs doesn't have any getElementById method.
To search the div by element id it would probably be necessary to loop through all the elements of it and check their id:
Dim mainnavs
Set mainnavs = IE.document.getElementsByClassName("nav mainnavs")
If mainnavs.Length > 0 Then
Dim mainnavItem ' this is a div element and it doesn't have .getElementById() method
Set mainnavItem = mainnavs.Item(0)
Dim itm
For Each itm In mainnavItem.all
If itm.ID = "nav-jobs" Then
itm.Click
Exit For
End If
Next itm
Else
MsgBox "getElementsByClassName('nav mainnavs') didn't return any elements"
End If
when I apply the same method to my company's website it keeps on
showing the message box "didn't return any elements"
This means that element with such class name does not exist on the page.
Do you wait until the page is fully loaded?
While ie.Busy Or ie.readyState <> READYSTATE_COMPLETE: DoEvents: Wend
why would we do mainnavItem.all in the For loop
This is because there is no other possibility to search for element by its id. Therefore we go through all the children of the mainnavItem and check the id.
Sub Get_Data()
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
ie.Navigate "http://www.scramble.nl/military-database/usaf"
Do While ie.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
SendKeys "03-3114"
SendKeys "{ENTER}"
End Sub
The code below searches for keyboard typed value 03-3114 and gets a data in the table. If I 'd like to search for value which is already in cell A1 and scrape values from table for "Code, Type, CN, Unit" in cell range ("B1:E1") what should I do?
You are using SendKeys which are highly unreliable :) Why not find the name of the textbox and the search button and directly interact with it as shown below?
Sub Get_Data()
Dim ie As Object, objInputs As Object
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
ie.Navigate "http://www.scramble.nl/military-database/usaf"
Do While ie.readystate <> 4: DoEvents: Loop
'~~> Get the ID of the textbox where you want to output
ie.Document.getElementById("serial").Value = "03-3114"
'~~> Here we try to identify the search button and click it
Set objInputs = ie.Document.getElementsByTagName("input")
For Each ele In objInputs
If ele.Name Like "sbm" Then
ele.Click
Exit For
End If
Next
End Sub
Note: To understand how I got the names serial and sbm, refer to the explanation given just above the image below.
The code below searches for keyboard typed value 03-3114 and gets a data in the table. If I 'd like to search for value which is already in cell A1 and scrape values from table for "Code, Type, CN, Unit" in cell range ("B1:E1") what should I do?
Directly put the value from A1 in lieu of the hardcoded value
ie.Document.getElementById("serial").Value = Sheets("Sheet1").Range("A1").Value
To get the values from the table, identify the elements of the table by right clicking on it in the browser and clicking on "Inspect/Inspect Element(In Chrome it is just Inspect)" as shown below.
I can give you the code but I want you to do it yourself. If you are still stuck then update the question with the code that you tried and then we will take it from there.
Interesting read: html parsing of cricinfo scorecards