2

Looking for help on how to implement VBA code to check if an element exists or explicitly waiting for it in VBA. Here is a small sample code I am testing out. The below code gives an error while running since it says "Object Required"


Dim Driver As New ChromeDriver 

Driver.get "Test website"

If Driver.IsElementPresent(By.XPath("/html/body/div[2]/div/div[5]/h3"))) Then
   Debug.Print("Yes")
Else
   Debug.Print("No")

I even have tried changing the .IsElementPresent to this line of code so I can test the size of the element if it exists but receiving an error that "NoSuchElementError"

Debug.Print (browser.FindElementByXPath("/html/body/div[2]/div/div[5]/h3").Size())

2
  • Try If driver.FindElementsByPath("/html/body/div[2]/div/div[5]/h3").Count = 0 Then ..... What's the url? Does element get found with a delay added? Commented Apr 13, 2021 at 16:30
  • How do we add a delay? An implicit one? Like browser.Wait(5000) that will wait for the browser to wait 5 seconds before executing the next line of code? Commented Apr 13, 2021 at 19:03

2 Answers 2

4

Seem to work for me. The only issue I am seeing in your code is that you didn't declare By anywhere.

e.Start isn't a requirement, but I do it anyway.

enter image description here

So I would try declaring By and see what happen there. And you need to set it as a new instance, a simply type-declaration won't work, which means:

Just using Dim By As Selenium.By is NOT enough, but either of these lines:

Dim By As New Selenium.By

or

Dim By As Selenium.By
Set By = New Selenium.By

The Object Required error you are receiving is likely due to the missing declaration I stated above.

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

12 Comments

Thanks, I think that did it! Using this method .IsElementPresent more suitable for lets say waiting for a page to load fully and if the boolean is true then element is present then we can proceed or would there be a better way on doing this?
The issue with webpages in general is that there is no real standard on how data must load. Sure, IE had .ReadyState() (which itself was broken). Then you got iframes that load on its own (think of it like a webpage in a webpage). There is no fool-proof method using Selenium that I am aware of that will allow you to ensure that every element on a webpage has loaded.
Now, Selenium is a bit more forgiving than using HTML library, in that each time you attempt to work with an element there is a built-in grace timeout period that the code will wait before throwing an error. You can override the entire timeout period for all elements, or elements on a one-by-one basis. Take the method .FindElementById() or any of the other findelements... The 2nd argument is the timeout, which by default is set to -1 (which means it's using the global settings). You can set your own timeout here. You can play around with the .Timeouts properties for global settings.
You also stated that some occasions it did throw an error, which to me says that in those cases it DID take longer than 5 seconds. I am thinking that either your internet, the server, or your CPU is slow enough for you to have to wait close to that 5 second mark, which would be why sometimes it works and sometimes it doesn't - simply because it truly needs the full 5 seconds. Have you tried to increase it to around 20 seconds to see if it still takes only around 5 seconds? Because if it needs those 5 seconds to load the page there's not much you can do to fix that with optimizing your code.
Even a low amount of RAM can cause this issue as well. If your computer is having to move data from RAM to your pagefile to run the macro, open up the browser, and load the page, it can also slow down the loading/rendering of the page. Open up task manager and watch your RAM usage. If it is around 85% or above then I am sure it's moving data to your pagefile (which means it's moving it to your hard drive - which is much slower than RAM).
|
1

As text above, for me it worked like this...

Dim ch As Selenium.ChromeDriver
Set ch = New Selenium.ChromeDriver
'... all code ... 
    If ch.IsElementPresent(FindBy.XPath("//*[@id='div_footer']/table/tbody/tr/div")) Then
          ch.FindElement(FindBy.XPath("//*[@id='div_footer']/table/tbody/tr/div")).Click 
    ElseIf ch.IsElementPresent(FindBy.XPath("//*[@id='xlsbutton']")) Then
       ch.FindElement(FindBy.XPath("//*[@id='xlsbutton']")).Click
    Else
       'nohing here, only to understand stament
       boolean_check_Download_Click_XYZ = false
    End If

Comments

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.