I may be missing a very basic thing, but i just dont understand why this isnt working.
I am looking to fill out some web forms based on some user input.
I have already written this in vbscript where its working flawlessly. Now i want to import it to VB.
My 2 main issues atm.
Before, i would have a piece of code:
For Each wnd In CreateObject("Shell.Application").Windows
If InStr(1, wnd.FullName, "iexplore.exe", vbTextCompare) > 0 Then
Set IE = wnd
Exit For
End If
Next
For deciding what Internet Explore window to use. However, if i use this form in VB, i miss out on pretty much any type of event handling. I cant use IsBusy, i cant use DocumentCompleted or anything.
So instead i have to declare IE as a browser.
Dim IE As New WebBrowser
Which seems fine.. Except.. Now i cant navigate anywhere, no browsers are created, theres nothing happening. So when i run my code:
IE.Navigate("www.awebwithusernameandpasswordform.org")
IE.Visible = True
Helem = IE.Document.GetElementById("username")
Helem.Value = "xxxx"
Helem = IE.Document.GetElementById("password")
Helem.Value = "xxxx"
Helem = IE.Document.Forms("signupForm")
Helem.Submit()
It just fails at the element "Username" because it never gets to navigate to the website.
It like it just ignores the IE.Navigate. I have tryed running a new process with process.start() but that doesnt work either, it still isnt opening a webpage for me or anything.
Secondly, i am having major issues having vb checking when a document is completely loaded.
In VBS i used
Do while ie.readystate <> 4 or ie.busy or ie.document.readystate <> "complete"
wscript.sleep 500
Loop
Do until ie.document.readystate = "complete"
wscript.sleep 500
Loop
And that works like a charm.
In VB, ie.document.readystate is not recognised, and i cant seem to get DocumentCompleted event handling to work. I have attempted several thing from this website, but either they just make everything hang, or it just doesnt work for various reasons. I have attempted the 2 solutions from How to wait until WebBrowser is completely loaded in VB.NET? but they both just make the script hang.
Any tips would be greatly appreciated..
What is happening is that your code runs way faster than the browser can navigate, meaning that you try to get elements before it has loaded any, as Bjørn-Roger Kringsjå tried to say.
What you need to do is to wait between .Navigate and .GetElementById :
IE.Navigate("www.awebwithusernameandpasswordform.org")
'WAIT BEFORE COMPLETION
'Continue
Helem = IE.Document.GetElementById("username")
Helem.Value = "xxxx"
However, this is really tricky to do in-line and is not recommended. It is much better to use the DocumentCompleted event handler for the browser control to run code after a page is loaded. Hope this clears it up enough.
Related
Hoping someone might understand what might be going on. What I'm aiming for is using Excel VBA to open my PayPal Multi-Order Shipping page, then open the "Create Shipment" dialogue box and populate the basic name and address fields using data from a row in my excel spreadsheet. My current trouble is with clicking the "Create Shipment" button to open the dialogue box so I can populate the fields ... the code seems to ignore the GetElementByID("createNewOrder").click command and does absolutely nothing. Here's my code so far if anyone would care to take a look ... any help is much appreciated.
Sub PayPalMultiShip()
Dim IE As New SHDocVw.InternetExplorerMedium
IE.Visible = True
IE.Navigate ("https://www.paypal.com/shiplabel/createbulk")
Do While IE.ReadyState <> READYSTATE_COMPLETE
DoEvents
Loop
IE.Document.getElementById("createNewOrder").click
Debug.Print "All Done"
End Sub
Here is a screenshot of the html code for the button that I'm trying to access ...
This screenshot comes from the Event Listener tab in the DOM Explorer ...
Event Listener Screenshot
I apologize, but since I'm new to the forum it won't allow me to embed pictures unless someone else suggests the edit
Hi I am trying to write a scraper to get data from this website (www.coned.com/tcisng) and dump data into my Ms Access Backend. When I navigate to it and enter in my credentials (username and password), it does not activate the "Log In" button which I want to click next as it is the next step on my scraper. Also this "Log In" button has no name or ID. How to activate and make it click using VBA in Ms Access 2016.
Updated Code Snippet -
Dim ie As Object
Set ie = CreateObject("internetexplorer.application")
ie.Visible = True
ie.Navigate "www.coned.com/tcisng"
While ie.Busy
DoEvents
Wend
Do
DoEvents
Loop Until ie.ReadyState = READYSTATE_COMPLETE
ie.Document.all("LoginEmail").Value = "myemail"
ie.Document.all("LoginPassword").Value = "myPassword"
Do
DoEvents
Loop Until ie.ReadyState = READYSTATE_COMPLETE
While ie.Busy
DoEvents
Wend
'ie.Document.all(48).Click
'ie.Document.querySelector("[type=submit]").Click
ie.Document.querySelector("button[title*='Log in']").Click
In the last 3 line I am trying to select the "Log In" button but it is disabled, also it has no name or ID, can you also help what exact code to replace in order to activate the button and click it later.
Instead of trying to "click" the button, try submitting the form. The Javascript for that ConEdison page would be:
document.getElementById("form-login-email").form.submit()
In the "old days", with just a plain form, this would work fine.
But on that website there is a lot more going on. That email input element has nine events attached to it. By just filling in the value, you aren't triggering any of those events.
With forms built with ReactJS, for example, the user's interaction with the Input element is monitored, and the value is extracted and stored in a non-displaying object in the DOM tree. When the Submit button is clicked, the form's visible Input elements may not be used at all. In order to feed inputs into such forms, you need to understand ReactJS data structures, and manipulate them directly.
I recently built a scraper based on Chromedriver, which allows a Chrome browser window to be controlled from an external program, such as Access VBA. Once started, Chromedriver runs as a mini-webserver on localhost, and commands sent to it from Access VBA (through a ServerXMLHTTP60 object) cause it to launch Chrome, visit a URL, send keystrokes to input elements etc. Within the browser, the keystrokes fire all the events that human keystrokes would do. The target website was ReactJS-based, but I was able to ignore all of the internal complexity of ReactJS.
Since the website runs in a regular Chrome browser, I was able to use F12 Developer Tools in the development process.
The technology is Webdriver, and was developed for building website testing tools. There are Firefox and MS Edge Chromium versions as well.
I am trying to extract links from webpages, but it seems webbrowser does not navigate, so I get infinite loop at webbrowser1.readstate <> readystate_complete...
HOWEVER, if make a breakpoint at webbrowser1.readstate <> readystate_complete, the webbrowser navigates successfully in the userform, and code works....
Any ideas? Thanks
Do Until n = num
WebBrowser1.Navigate URL
Do While WebBrowser1.readyState <> READYSTATE_COMPLETE
Loop
If WebBrowser1.readyState = READYSTATE_COMPLETE Then
'code
end if
n = n +1
loop
The while loop you use in your question and in your answer is a busy waiting tight loop, consuming CPU cycles in vain while waiting for something to happen. It works (sort of) for InternetExplorer object, because the latter runs in its own separate process. It doesn't work for in-process WebBrowser control, because your loop doesn't pump Windows messages, which is required for navigation to work. If you want to stick with the loop approach, consider placing Sleep 250 and DoEvents calls inside your loop to mitigate busy waiting and pump messages. This is still not recommended, instead you should consider re-factoring your code to use WebBrowser_DocumentComplete event.
I have a WebBrowser control on my Vb.net winform. Now i need to find a way to detect if the page reloads or refreshed.
Similar to WebBrowser1_DocumentCompleted.
Example:
WebBrowser1_DocumentOnLoad, OR WebBrowser1_DocumentOnRefreshed
dim wb as new webbrowser
wb.navigate(url)
do while wb.ReadyState <> WebBrowserReadyState.Complete
application.doevents()
loop
wb.refresh()
do while wb.ReadyState <> WebBrowserReadyState.Complete
application.doevents()
loop
msgbox("refreshed")
You need to intercept the BeforeNavigate2 event, and if it is directed to the exact same URL that is currently loaded in the WB control (BN2 event provides a URL argument for you to read from and test, and your WB.LocationURL or WB.Document.URL can tell you the current URL of your WB control so you can compare it to.
So, when you intercept the BeforeNavigate2 event, you can do your comparison there, you can also do it during DocumentComplete, whatever you prefer. There is no OnRefresh event unfortunately (that I know of) so give my method a try and let me know how you get along with it, and if you need any further help.
Cheers.
I have a VB.Net app that needs to print a bunch of pages from a secure intranet site; the app was made and was working for a non-secure site but now the app needs to login before accessing the web pages necessary to print.
I get the error "Object Reference not set to an instance of an object" when I use my new Sub which follows:
Private Sub SiteLogin()
WebBrowser1.Navigate("http://url/login/")
WebBrowser1.Document.GetElementById("user").SetAttribute("value", "username")
WebBrowser1.Document.GetElementById("password").SetAttribute("value", "mypassword")
WebBrowser1.Document.GetElementById("submit").InvokeMember("click")
End Sub
I got the code from this VB tutorial, but I seem to be missing something in how I'm referencing the WebBrowser.Document object. I've never used VB.Net before so I don't know much about this problem, I have the following sub which DOES work from the original program however:
Private Sub WebPrint()
WebBrowser1.Navigate(strUrl)
WebDocLoaded = False
'lblMessage.Text = "Waiting for report page to load"
Do Until WebDocLoaded
System.Windows.Forms.Application.DoEvents()
Loop
End Sub
This Sub prints the given page in IE, so I figured I could use the same WebBrowser1 object for the login Sub, as I don't know how to or whether I should declare a separate object for the SiteLogin Sub. Both of these functions are called after the WebBrowser1 object is defined however.
I just need to be able to submit a simple login form to a set URL, and this info needs to all be hardcoded (there's no option to set the location or login info nor should there be). If there's another way to log into this site via VB.Net or if I need to give more information let me know.
.Navigate returns before the page load is complete so the DOM is not ready & .Document is not accessible.
See; How to wait until WebBrowser is completely loaded in VB.NET?