I would like to run my VBA macro on a specific internet explorer page that I have already opened and logged into .
This is because I have to login to my account and bypass the captcha code first.
I have to send this extremely repetitive message to over a couple hundred people over the course of the year.
Problem with the following is that I am opening up a brand new page and I wont be able to bypass the captcha.
Dim IE As InternetExplorer
Set IE = CreateObject("InternetExplorer.Application")
IE.navigate ("website")
IE.Visible = True
End Sub
Solution
Sub TestGetIE()
Dim IE As Object
'GetIE runs the Functoin we have created below
Set IE = GetIE("website opened in IE here ")
WaitFor IE
end sub
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
'Loop through all the opened internet explorer pages
sURL = ""
'Loops through all the pages opened on internet explorer
'Then we will tell our macro to work on that page
sURL = o.LocationURL
If sURL Like sLocation & "*" Then
Set retVal = o
Exit For
End If
Next o
Set GetIE = retVal
End Function
From your description, I understand that you want user interaction to fill the captcha and then want to continue to automate the same page.
I suggest you for both steps try to use 2 different modules and use the same IE object in both modules.
You can create a global IE object which you can use in both modules.
Then for the login part execute the first module.
After that user will fill the captcha manually.
Then execute the second module to automate the rest of the page.
Sample code:
Public ie As Object
Sub login()
Set ie = CreateObject("internetexplorer.application")
ie.Visible = True
ie.navigate "Your_web_site_URL_here..."
Do While ie.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
ie.document.getElementById("uname").Value = "user1"
ie.document.getElementById("pswd").Value = "12345"
End Sub
Sub second_part()
ie.document.getElementById("email").Value = "user1#abc.com"
ie.document.getElementById("age").Value = "30"
End Sub
UserForm1 code:
Private Sub CommandButton1_Click()
Call Module1.login
End Sub
Private Sub CommandButton2_Click()
Call Module1.second_part
End Sub
Output:
Calling upon this function helped me solve it.
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
'Loop through all the opened internet explorer pages
sURL = ""
'Loops through all the pages opened on internet explorer
'Then we will tell our macro to work on that page
sURL = o.LocationURL
If sURL Like sLocation & "*" Then
Set retVal = o
Exit For
End If
Next o
Set GetIE = retVal
End Function
One thing you could do is DoEvents until a certain Element is present on the page. Run your code to navigate to the website, then Do Until Element after captcha is present DoEvents. The code will loop until you are on logged into the website. I like using VBA SeleniumBasic ChromeDriver on GetHub. It makes web scraping way easier, and you do not need to use Internet Explorer.
Related
I want to open a url in chrome and supply the login ID and password.
My current code for IE looks like the below. From other posts I see Chrome can be opened via a basic shell command. Is there a way to pass the login id and password as part of the shell command? If no, what should the code look like to accomplish this? Thanks in advance!
Public Sub WeltokLogin()
'REFERENCES: MS Internet Controls, and MS HTML Object Library (No longer working in Windows 10)
On Error Resume Next
Const URL$ = "https://.../human.aspx"
Exit Sub
Dim UserName As String, Password As String
Dim htmlEle As IHTMLElement
Dim i As Integer
i = 1
UserName = "myloginID"
Password = "mypassword"
Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")
Dim AllLinks As Object
Dim Hyperlink As Object
With IE
.navigate URL
ieBusy IE
.Visible = True
Dim oLogin As Object, oPassword As Object
Set oLogin = .document.getElementsByName("Username")(0)
Set oPassword = .document.getElementsByName("Password")(0)
oLogin.Value = UserName
oPassword.Value = Password
.document.forms(0).submit
'Loop Until ie.ReadyState = 4
Exit Sub
Set AllLinks = IE.document.getElementsByTagName("div")(0)
For Each Hyperlink In AllLinks
If InStr(1, Hyperlink.innerText, "Folders") > 0 Then
Hyperlink.Click
Exit For
End If
Next Hyperlink
Stop
I found this VBA code online and it works on Facebook for example.
On https://www.solarmanpv.com/portal/LoginPage.aspx it does not work. It opens Internet Explorer, puts the credentials on the right places but won't press login.
Error '424' is shown on VBA when I try to run.
Sub LoginViaBrowser()
Dim Dc_Usuario As String
Dim Dc_Senha As String
Dim Dc_URL As String
Dim objIE As New InternetExplorer 'Referencie "Microsoft Internet Controls"
objIE.Visible = True
Dc_Usuario = "user#email.com"
Dc_Senha = "pass"
Dc_URL = "https://www.solarmanpv.com/portal/LoginPage.aspx"
objIE.Navigate2 Dc_URL
Do Until objIE.readyState = READYSTATE_COMPLETE
DoEvents
Loop
objIE.document.all("uNam").innertext = Dc_Usuario
objIE.document.all("uPwd").innertext = Dc_Senha
objIE.document.all("login").submit
End Sub
Please try to use F12 developer tools to check the html elements, then, you could find that the id of the login button is "Loginning", not "login".
Try to modify your code as below:
Sub LoginViaBrowser()
Dim IE As Object
Dim Dc_Usuario As String
Dim Dc_Senha As String
Dim Dc_URL As String
Dim txtNam As Object, txtPwd As Object
Dc_Usuario = "user#email.com"
Dc_Senha = "pass"
Set IE = CreateObject("InternetExplorer.Application")
With IE
.Visible = True
.Navigate "https://www.solarmanpv.com/portal/LoginPage.aspx"
While IE.ReadyState <> 4
DoEvents
Wend
IE.Document.getElementById("uNam").Value = Dc_Usuario
IE.Document.getElementById("uPwd").Value = Dc_Senha
IE.Document.getElementById("Loginning").Click
End With
Set IE = Nothing
End Sub
Have you tried calling a click on it by id?
IE.Document.getElementById("Loginning").Click
I have a code that works fine. The thing is it opens Internet Explorer for results. I want the results in Google Chrome. Modification would be helpful.
Option Explicit
Sub GetResults(r As Range)
Dim IE As Object
Dim frm As Object
Dim srch As Object
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate "http://www.google.com"
Do While IE.Busy: DoEvents: Loop
Do While IE.ReadyState <> 4: DoEvents: Loop
Set frm = IE.Document.forms("f")
Set srch = frm.Document.all("q")
srch.Value = r.Value
frm.submit
End Sub
This would be something similar written for selenium basic vba wrapper. After installing selenium you need to go tools > references > add reference to selenium type library.
This is literally written to follow what you have written. You may wish to consider targeting by id not name, also, whether you want a function to return something from the results specifically.
Option Explicit
Public Sub test()
Dim r As Range
Set r = [A1] '<== you really want a test that a single cell is passed or you will end up with an array later
GetResults r
End Sub
Public Sub GetResults(ByVal r As Range)
Dim d As WebDriver, frm As Object, srch As Object
Set d = New ChromeDriver
Const URL = "http://www.google.com"
With d
.Start "Chrome"
.get URL
Set frm = .FindElementByName("f")
Set srch = frm.FindElementByName("q")
srch.SendKeys r.Value
frm.submit
Stop '<=Delete me later
.Quit
End With
End Sub
Strangely enough I didn't find any information on the topic and I'm currently stuck at the point where I managed to open a new tab in an instance of IE by programmatically clicking a button, but I haven't the faintest clue of how to address the new tab in order to get information from there (the button basically brings up a new tab with the result of a search).
This is basically a straightforward question, but I'm including my code anyway:
Sub AddInfoFromIntranet()
Dim Ie As SHDocVw.InternetExplorer
Dim URL As String
Dim iFrames As MSHTML.IHTMLElementCollection
Dim iFrame As MSHTML.HTMLFrameElement
Dim Doc As MSHTML.HTMLDocument
Dim InputBox As MSHTML.IHTMLElementCollection, htmlButton, allTags, Tag
' Opens Intranet - yeah, sadly it's not a public web page
URL = "{My intranet website}"
Set Ie = New SHDocVw.InternetExplorer
With Ie
.navigate URL
.Visible = True
While .Busy Or .readyState <> READYSTATE_COMPLETE: DoEvents: Wend
Set Doc = .document
End With
' Gets top_window frame and navigates to it, then inserts the name to search
Set iFrames = Doc.getElementsByName("top_window")
If Not iFrames Is Nothing Then
Set iFrame = iFrames(0)
Ie.navigate URL & iFrame.src
While Ie.Busy Or Ie.readyState <> READYSTATE_COMPLETE: DoEvents: Wend
Set InputBox = Doc.getElementsByName("Nachnamevalue")
If Not InputBox Is Nothing Then InputBox(0).Value = "test"
' Clicks on "search"
Set allTags = Doc.getElementsByTagName("input")
For Each Tag In allTags
If Tag.Value = "suchen" Then
Tag.Click
Exit For
End If
Next
' Here a new tab is opened, must find info in this tab
While Ie.Busy Or Ie.readyState <> READYSTATE_COMPLETE: DoEvents: Wend
' HERE I HAVE NO CLUE WHAT TO WRITE. THE CODE ABOVE WORKS FLAWLESSLY
End If
Set Doc = Nothing
Set iFrames = Nothing
Set iFrame = Nothing
Set InputBox = Nothing
Set allTags = Nothing
Set Ie = Nothing
Ie.Quit
End Sub
Now, is there a way to address a tab by: 1) its name (and where do I find it) 2) its position in browser 3) the status (if it is "active") ?
Bonus questions: since I am new to VBA and Internet Explorer interaction, what exactly are the variables: htmlButton, allTags, Tag ? Also, could anyone explain if I need to set all the variables at the end to nothing, or I just need to set the Internet Explorer to nothing?
Thanks in advance!
See below for a function you can use to get an open IE document window - I don't think IE exposes any simple (VBA-accessible) API for working directly with tabs or determining whether a specific tab is active.
allTags is a collection of DOM elements with type "" , and Tag is a single memeber of that collection.
You do not have to set objects to Nothing before exiting a Sub (though some people still do that) - the VBA runtime will take care of that for you.
Sub TestGetIE()
Dim IE As Object
Set IE = GetIE("http://stackoverflow.com")
If Not IE Is Nothing Then
IE.document.execCommand "Print", False, 0
End If
End Sub
'Get a reference to an open IE window based on its URL
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
sURL = o.document.Location
On Error GoTo 0
'Debug.Print sURL
If sURL Like sLocation & "*" Then
Set retVal = o
Exit For
End If
Next o
Set GetIE = retVal
End Function
I have made a macro to read text from a saved html page/file. I now need to make it more advance by reading an already open webpage. would really appreciate the help
Need to replace the line
URL = "file:///C:/test.html"
with something that will read an open webpage. I can make sure that there is only one tab open. I'm using the latest IE
Dim URL As String
Dim Data As String
URL = "file:///C:/test.html"
Dim ie As Object
Dim ieDoc As Object
Set ie = CreateObject("InternetExplorer.Application")
ie.navigate URL
Do Until (ie.readyState = 4 And Not ie.Busy)
DoEvents
Loop
Set ieDoc = ie.Document
Data = ieDoc.body.innerText
If you know the title or url of the already open webpage you're looking for, then this code will let you control it
' Determine if a specific instance of IE is already open.
Set objShell = CreateObject("Shell.Application")
IE_count = objShell.Windows.Count
For x = 0 To (IE_count - 1)
On Error Resume Next ' sometimes more web pages are counted than are open
my_url = objShell.Windows(x).Document.Location
my_title = objShell.Windows(x).Document.Title
'You can use my_title of my_url, whichever you want
If my_title Like "Put your webpage title here" & "*" Then 'identify the existing web page
Set ie = objShell.Windows(x)
Exit For
Else
End If
Next
Use this code to get the currently running internet explorer (work atleast with IE9):
Dim ie As Object
Dim objShell As Object
Dim objWindow As Object
Dim objItem As Object
Set objShell = CreateObject("Shell.Application")
Set objWindow = objShell.Windows()
For Each objItem In objWindow
If LCase(objItem.FullName Like "*iexplore*") Then
Set ie = objItem
End If
Next objItem
MsgBox ie.Document.body.innertext
' Add reference to
' - Microsoft Internet Controls (SHDocVw)
' - Microsoft Shell Controls and Automation (Shell32)
' Find all running instances of IE and get web page Url
' Source: http://msdn.microsoft.com/en-us/library/windows/desktop/bb773974(v=vs.85).aspx
' Useful link: http://msdn.microsoft.com/en-us/library/windows/desktop/bb776890(v=vs.85).aspx
Sub main()
Dim browsers
Set browsers = GetBrowsers
Dim browser
Dim url
For Each browser In browsers
url = browser.document.Location.href
Debug.Print CStr(url)
Next browser
End Sub
Public Function GetBrowsers() As Collection
Dim browsers As New Collection
Dim shellApp As Shell32.Shell
Dim wnds As SHDocVw.ShellWindows
Set shellApp = New Shell
Set wnds = shellApp.Windows
Dim i As Integer
Dim ie As SHDocVw.WebBrowser
Dim name
For i = 1 To wnds.Count
Set ie = wnds(i)
If ie Is Nothing Then GoTo continue
If UCase(ie.FullName) Like "*IEXPLORE.EXE" Then
browsers.Add ie
End If
continue:
Next i
Set GetBrowsers = browsers
Set shellApp = Nothing
End Function