I have the following VBA code:
Sub OpenWebPage()
Dim oIE As Object
Dim sURL As String
Dim HTML As HTMLDocument, hDataManager As IHTMLElementCollection, hDropSelect
Dim HWNDSrc As Long
Dim itm As Variant
'objects
Set oIE = CreateObject("InternetExplorer.Application")
'//---Open the browser and log in, then navigate to the data manager
oIE.silent = True 'No pop-ups
oIE.Visible = True
sURL = "https://publicisuk.lumina.mediaocean.com/Admin/DataManager.aspx"
oIE.navigate sURL
'wait for process to complete before executing the next task
Do While oIE.Busy: DoEvents: Loop
Do Until oIE.ReadyState = 4: DoEvents: Loop
'get window ID for IE so we can set it as active window
HWNDSrc = oIE.HWND
'set IE as active window
SetForegroundWindow HWNDSrc
'loop through elements/ items to find username field
For Each itm In oIE.document.All
If itm = "[object HTMLInputElement]" Then
If itm.Name = "username" Then
Debug.Print "Username field found!"
itm.Value = "johnsmith#gmail.com"
Debug.Print "Username: " & itm.Value
Exit For
End If
End If
Next itm
'now loop through to find password element
For Each itm In oIE.document.All
If itm = "[object HTMLInputElement]" Then
If itm.Name = "password" Then
Debug.Print "Password field found!"
itm.Value = "IAmAMonkey"
Debug.Print "Password: " & itm.Value
Application.SendKeys "~", True
Exit For
End If
End If
Next itm
What it does is loads Internet Explorer to an object, and then navigates to a URL where I want to log in. I loop through the elements on the web-page checking for InputElements. When the Username input box is found it sets the .Value to the username, and when the Password input box is found it sets the .Value to the password, after which I send the Enter key, presumably to log in.
Now, the interesting problem. When I run this it prints out that it finds the respective fields, and also prints out their newly set values, however, no text appears in the boxes at all.
I have also tried the following syntax:
oIE.Document.getElementById("username").Value = "johnsmith#gmail.com"
oIE.Document.getElementsByName("username").Value = "johnsmith#gmail.com"
With the same result - there is no error, but the values aren't showing up in the boxes.
Does anyone know why this would be the case or what is wrong with my approach?
Below is the HTML code.
<div id="login-panel">
<input name="username" class="form-required-field" id="username" accesskey="u" type="text" placeholder="Username" value="" data-bind="value: form().username, placeholder: bundle['user.label.html']" htmlescape="true" autocomplete="off" cssclass="form-required-field"><!-- organization select goes here if multiple organizations use the same domain --><div class="inline-organization-panel" id="inline-organization-panel" style="display: none;" data-bind="moSlideVisible: isOrganisationSelectPanelVisible()">
<span id="inline-organization-label" data-bind="text: bundle['organization.panel.label']">Choose organization.</span>
<div data-bind="foreach: organisationInfoArray"></div>
</div>
<input name="password" class="form-required-field" id="password" accesskey="p" type="password" placeholder="Password" value="" data-bind="value: form().password, placeholder: bundle['password.label.html']" htmlescape="true" autocomplete="off" cssclass="form-required-field" csserrorclass="error"><!-- Continent selection goes here if mf-style username and don't have continent cookie -->
I would focus on each element before assigning value then you simply need to remove the disabled attribute from the submit button
Option Explicit
Public Sub LogIn()
Dim ie As SHDocVw.InternetExplorer
Set ie = New SHDocVw.InternetExplorer
With ie
.Visible = True
.Navigate2 "https://publicisuk.lumina.mediaocean.com/mo-cas/login"
While .Busy Or .readyState <> 4: DoEvents: Wend
With .document
With .querySelector("#username")
.Focus
.Value = "johnsmith#gmail.com"
End With
With .querySelector("#password")
.Focus
.Value = "IAMaMonkey"
End With
With .querySelector("#buttonSignin")
.removeAttribute "disabled"
.Click
End With
End With
Stop
End With
End Sub
Here is where I got to, i'll try again a little later, but may help in the meantime.
Dim ie As InternetExplorer
Dim d As HTMLDocument
Dim f As HTMLFormElement
Set ie = New InternetExplorer
ie.Visible = 1
ie.navigate "https://publicisuk.lumina.mediaocean.com/Admin/DataManager.aspx"
Do While ie.Busy Or ie.readyState <> READYSTATE_COMPLETE
DoEvents
Loop
Set d = ie.document
Set f = d.forms(0)
'Putting a break point here and waiting a moment allows access
f.elements("username").Value = "username"
I tested and found that the code would run when setting breakpoints before setting value but wouldn't run without breakpoints.
I think it could be that debug mode adds more delay so I tried to add a separate delay in the code and it works. You could check my sample below:
Sub LOADIE()
Set ieA = CreateObject("InternetExplorer.Application")
ieA.Visible = True
ieA.navigate "https://publicisuk.lumina.mediaocean.com/mo-cas/login"
Do Until ieA.readyState = 4
DoEvents
Loop
delay 4
Set doc = ieA.Document
Set UserName = doc.getElementById("username")
UserName.Value = "johnsmith#gmail.com"
Set Password = doc.getElementById("password")
Password.Value = "IAmAMonkey"
Set btn = doc.getElementById("buttonSignin")
btn.Disabled = False
btn.Click
End Sub
Private Sub delay(seconds As Long)
Dim endTime As Date
endTime = DateAdd("s", seconds, Now())
Do While Now() < endTime
DoEvents
Loop
End Sub
Related
I am trying to login Web page and fetch data however my login details are not getting update, i have tried all possibilities code from your forum, nothing is working for me
Below is my code, am getting attached error
Sub test()
Dim ie As Object
Dim objCollection As Object
Dim i As Integer
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
ie.navigate "https://portal.expeditors.com/expo/login"
Do While ie.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
'Get all the elements with input tag name
Set objCollection = ie.document.getElementsByTagName("input")
i = 0
'Loop through all elements and find login form and fill it
While i < objCollection.Length
'Login name
If objCollection(i).Name = "username" Then
objCollection(i).Value = "bom-sumand"
End If
'Store login button in object
If objCollection(i).Type = "submit" Then
Set objElement = objCollection(i)
End If
i = i + 1
Wend
'Click login
objElement.Click
'Clean up
Set ie = Nothing
End Sub
I would use the available ids rather than looping to find the input boxes and sign in. These are much faster selector methods. You can add a .Focus. Also, swop InternetExplorer for InternetExplorerMeduim in some cases.
If problem continues check your internet settings in case site is blocked.
Open the URL via creating an IE instance direct.
Option Explicit
Public Sub Login()
Dim ie As New InternetExplorer 'InternetExplorerMedium
Const MAX_WAIT_SEC As Long = 5
Dim t As Date, ele As Object
With ie
.Visible = True
.navigate "https://portal.expeditors.com/expo/login"
While .Busy Or .readyState < 4: DoEvents: Wend
With .document
Do
DoEvents
On Error Resume Next
Set ele = .getElementById("j_username")
On Error GoTo 0
If Timer - t > MAX_WAIT_SEC Then Exit Do
Loop While ele Is Nothing
If ele Is Nothing Then Exit Sub
With ele
.Focus
.Value = "bob"
End With
With .getElementById("j_password")
.Focus
.Value = "penny"
End With
.getElementById("signInBtn").Click
End With
While .Busy Or .readyState < 4: DoEvents: Wend
Stop '<== Delete me later
.Quit
End With
End Sub
Macro trying and failing to open a second instance of IE try this.
Sub test()
Dim ie As Object
Dim redURL As String
Dim objCollection As Object
Dim i As Integer
redURL = "https://portal.expeditors.com/expo/login"
On Error Resume Next
Set ie = GetObject(, "InternetExplorer.Application")
If Err Then
Set ie = CreateObject("InternetExplorer.Application")
End If
On Error GoTo 0
ie.Visible = True
ie.Navigate redURL
Do While ie.Busy
Loop
End Sub
Need help how to create excel vba code for this
I'll be needing the codes so I can complete my macro.
Thanks in advance
First, you will need to create a reference to:
Microsoft Internet Controls
Microsoft HTML Object Library
In VBE, click Tools > References
Sub clickLink()
Dim ie As New InternetExplorer, Url$, doc As HTMLDocument
Url = "http://UrlToYourLink.com"
With ie
.navigate Url
Do While .Busy Or .readyState < READYSTATE_COMPLETE
DoEvents
Loop
doc = .document
.Visible = True
End With
Dim myBtn As Object
Set myBtn = doc.getElementsByClassName("button rounded")(0)
myBtn.Click
End Sub
The Internet control is used to browse the webpage and the HTML Objects are used to identify the username and password textboxes and submit the text using the control button.
Dim HTMLDoc As HTMLDocument
Dim oBrowser As InternetExplorer
Sub Login_2_Website()
Dim oHTML_Element As IHTMLElement
Dim sURL As String
On Error GoTo Err_Clear
sURL = "https://www.google.com/accounts/Login"
Set oBrowser = New InternetExplorer
oBrowser.Silent = True
oBrowser.timeout = 60
oBrowser.navigate sURL
oBrowser.Visible = True
Do
' Wait till the Browser is loaded
Loop Until oBrowser.readyState = READYSTATE_COMPLETE
Set HTMLDoc = oBrowser.Document
HTMLDoc.all.Email.Value = "sample#vbadud.com"
HTMLDoc.all.passwd.Value = "*****"
For Each oHTML_Element In HTMLDoc.getElementsByTagName("input")
If oHTML_Element.Type = "submit" Then oHTML_Element.Click: Exit For
Next
' oBrowser.Refresh ' Refresh If Needed
Err_Clear:
If Err <> 0 Then
Debug.Assert Err = 0
Err.Clear
Resume Next
End If
End Sub
The program requires references to the following:
1 Microsoft Internet Controls
2. Microsoft HTML Object Library
Microsoft internet controls are a great way to do this, but if you aren't allowed to add new references, here is another way to go about web scraping.
This methode ain't as 'clean' as Microsoft internet controls and HTML object but it gets the job done.
Sub GoogleSearch()
Dim ie As Object
Dim objSearchBnt As Object
Dim objCollection As Object
Dim i As Integer
'initialize counter
i = 0
'Create InternetExplorer Object
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
'navigate to the url
ie.navigate "Www.google.com"
'Statusbar shows in the buttom corner of excel
Application.StatusBar = "Loading, please wait..."
'Wait until page is ready
Do While ie.busy
Application.Wait DateAdd("s", 1, Now)
Loop
'Store all the elements with input tag
Set objCollection = ie.Document.getElementsByTagName("input")
'Go through all input elements
While i < objCollection.Length
'input search field
If objCollection(i).Name = "q" Then
objCollection(i).Value = "Hello World"
End If
'search button
If objCollection(i).Type = "submit" Then
Set objSearchBnt = objCollection(i)
End If
i = i + 1
Wend
objSearchBnt.Click
'Clean up
Set objSearchBnt = Nothing
Set objCollection = Nothing
Set ie = Nothing
'Give excel control over the status bar agian
Application.StatusBar = ""
End Sub
as title says i am having an error at htdoc.all.verificationcode.Value = otp
it says Run-time error '438':
Object doesn't support this property or method
i have spent an afternoon trying to find what is wrong with it and i really hope that you guys could help me out.
Dim HTMLDoc As HTMLDocument
Dim htdoc As HTMLDocument
Dim MyBrowser As InternetExplorer
Sub login()
Dim username As Range
Dim password As Range
Dim otp As Range
Dim myValue As Variant
Dim MyHTML_Element As IHTMLElement
Dim MyURL As String
MyURL = "XXXXXXXXXXXXXXXXXXXXXX"
Set MyBrowser = New InternetExplorer
MyBrowser.silent = True
MyBrowser.navigate MyURL
MyBrowser.Visible = True
Set username = Range("B1")
Set password = Range("B2")
Set otp = Range("B3")
Do
Loop Until MyBrowser.readyState = READYSTATE_COMPLETE
Set HTMLDoc = MyBrowser.document
HTMLDoc.all.UserId.Value = username
HTMLDoc.all.password.Value = password
For Each MyHTML_Element In HTMLDoc.getElementsByTagName("input")
If MyHTML_Element.Type = "submit" Then MyHTML_Element.Click: Exit For
Next
MyURL2 = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
MyBrowser.silent = True
MyBrowser.navigate MyURL2
MyBrowser.Visible = True
myValue = InputBox("Enter OTP")
Range("B3").Value = myValue
Application.Wait (Now + TimeValue("0:00:10"))
Do
Loop Until MyBrowser.readyState = READYSTATE_COMPLETE
Set htdoc = MyBrowser.document
htdoc.all.verificationcode.Value = otp
For Each MyHTML_Element In htdoc.getElementsByTagName("input")
If MyHTML_Element.Type = "btnobj" Then MyHTML_Element.Click: Exit For
Next
Err_Clear:
If Err <> 0 Then
Err.Clear
Resume Next
End If
End Sub
HTML in the webpage for the form is
<input name="verficationcode" id="verficationcode" type="password" size="18" maxlength="16" autocomplete="off">
<input name="btnobj" class="inputbutton" id="submitButton" onclick="checkSubmit(this);" type="button" value="Submit">
OK. That looks like a good start. You are going to a page, inputting some values and clicking Submit>. You have not set MyBrowser.visible to False so I'm assuming that you can see this going on.
The first thing you need is to wait while MyBrowser loads the page after you .click submit>. You will need to wait every time you go to a new page; My favorite is to put all of the waiting into a single line like this.
MyHTML_Element.Click
Do While (MyBrowser.Busy Or MyBrowser.readyState <> READYSTATE_COMPLETE): DoEvents: Loop
When you have that new page, you need to locate your OTP and store it in a variable. Look at the HTML behind the new page. You might see something like this:
<div id='One_Time_Password'>
47665489_29751678
</div>
You can put this into a variable you have previously declared like this.
dim myOTP as string
myOTP = MyBrowser.getElementsById("One_Time_Password").innerText
Now you have the password stored and you can do something with it.
I continue to get the above error when running this code. I have tried dozens of web searches and adjustments to fix but unsuccessful. The code is below and any help if very much appreciated.
Public Sub Tagg()
Dim URL As String
Dim ie As SHDocVw.InternetExplorer 'MICROSOFT Internet Controls (shdocvw.dll)
Dim HTMLdoc As MSHTML.HTMLDocument 'Microsoft HTML Object Library
Dim loginFrame As HTMLIFrame
Dim usernameInput As HTMLInputElement, passwordInput As HTMLInputElement
Dim username As String, password As String
username = "MTorres" 'CHANGE THIS
password = "melissa1" 'CHANGE THIS
URL = "https://webaccess.tagglogistics.com/cadence/webaccess.net?action=203&Full=Y&args=415878"
Set ie = New SHDocVw.InternetExplorer
With ie
.Visible = True
.navigate URL
Do While .readyState <> READYSTATE_COMPLETE Or .Busy
DoEvents
Loop
Set loginFrame = .document.getElementById("loginframe") ' ****ERROR HERE****
Set HTMLdoc = loginFrame.contentWindow.document
'<input name="username" id="uname" class="ti" maxlength="32" onchange="setUserValue();"
'onkeydown="setupUserValue(event);" onmouseup="return false;" onclick="SelectAll();" onfocus="SelectAll();"
'aria-describedby="cof_username errormsg" type="text">
Set usernameInput = HTMLdoc.getElementsByName("username")(0)
usernameInput.Focus
DoEvents
usernameInput.Value = username
usernameInput.FireEvent "onkeydown"
usernameInput.FireEvent "onchange"
usernameInput.FireEvent "onmouseup"
'<input id="cofisso_ti_passw" name="password" class="ti" maxlength="32" aria-describedby="pass" type="password">
Set passwordInput = HTMLdoc.getElementsByName("password")(0)
passwordInput.Focus
passwordInput.Value = password
'HTMLdoc.forms(0).submit
'<input src="/resources/images/btn_login.gif" alt="Login" title="Login" name="cofisso_btn_login" id="cofisso_btn_login" type="image">
HTMLdoc.getElementById("cofisso_btn_login").Click
Do While .readyState <> READYSTATE_COMPLETE Or .Busy
DoEvents
Loop
'----------- NEW CODE --------------
'Might need this wait loop
While .document.readyState <> "complete"
DoEvents
Wend
'Either reload HTMLdoc from current IE.document:
Set HTMLdoc = .document
'Or if LNKLOGOUT is inside an iframe:
' Dim iframe As HTMLIFrame
' Set iframe = .document.getElementsByTagName("IFRAME")(0) '0 = 1st iframe
' Set HTMLdoc = iframe.contentWindow.document
'HTMLdoc should now be available here - display webpage TEXT TO verify
MsgBox HTMLdoc.body.innerText
'---------- END OF NEW CODE ----------
'Click "Sign Out" link
'<a id="LNKLOGOUT" class="logout" href="https://servicing.capitalone.com/C1/SelfService/CMLogoutIntercept.aspx">Sign Out</a>
HTMLdoc.getElementById("LNKLOGOUT").Click
Do While .readyState <> READYSTATE_COMPLETE Or .Busy
DoEvents
Loop
End With
End Sub
CSS selectors:
You could have shortened most of that by using CSS selectors to target the elements of interest.
The selectors are:
input[name='LoginID']
input[name='Password']
input[type='image']
These says select elements with input tag having attribute name or type, with value of 'Login' or 'Password' or 'image' respectively. "[]" is the selector for attribute.
VBA:
You apply CSS selectors with .querySelector method of document:
.document.querySelector("input[name='LoginID']").Value = USERNAME
.document.querySelector("input[name='Password']").Value = PASSWORD
.document.querySelector("input[type='image']").Click
Code:
Option Explicit
Public Sub Tagg()
Dim URL As String, ie As SHDocVw.InternetExplorer, HTMLdoc As MSHTML.HTMLDocument
Const USERNAME As String = "MTorres"
Const PASSWORD As String = "melissa1"
URL = "https://webaccess.tagglogistics.com/cadence/webaccess.net?action=203&Full=Y&args=415878"
Set ie = New SHDocVw.InternetExplorer
With ie
.Visible = True
.navigate URL
Do While .readyState <> READYSTATE_COMPLETE Or .Busy
DoEvents
Loop
.document.querySelector("input[name='LoginID']").Value = USERNAME
.document.querySelector("input[name='Password']").Value = PASSWORD
.document.querySelector("input[type='image']").Click
Do While .readyState <> READYSTATE_COMPLETE Or .Busy
DoEvents
Loop
Set HTMLdoc = .document
'Other code
.Quit
End With
End Sub
You aren't setting the document and loginframe correctly.
Replace these lines:
Set loginFrame = .document.getElementById("loginframe") ' ****ERROR HERE****
Set HTMLdoc = loginFrame.contentWindow.document
With these:
Set HTMLdoc = ie.Document
Set loginFrame = HTMLdoc.getElementById("loginframe") ' ****ERROR FIXED****
You'll get another error a few lines down when you try to find an element with the name "username" because there is no such element on that page, but hopefully this will get you on the right track.
I am able to pass the excel values to the website and click it through vba. But it opens up another page with title "Results - Research Randomizer" and I dont know how I retrieve those values inside "Set#1". Can anyone give me some idea to retrieve those values into a variable. My code is
Sub OpenPage()
Const myPageTitle As String = "Research Randomizer Form v4.0"
Const myPageURL As String = "http://www.randomizer.org/form.htm"
Dim NoofSet, NoPSet, RangeBeg, RangeEnd As String
NoofSet = Range("b3").Value
NoPSet = Range("c3").Value
RangeBeg = Range("d3").Value
RangeEnd = Range("e3").Value
Dim myIE As SHDocVw.InternetExplorer
Dim doc As HTMLDocument
Dim PageForm As HTMLFormElement
Dim UserIdBox As HTMLInputElement
Dim PasswordBox As HTMLInputElement
Dim HrangeBeg, HrangeEnd As HTMLInputElement
Dim FormButton As HTMLInputButtonElement
Dim Elem As IHTMLElement
'check if page is already open
Set myIE = GetOpenIEByTitle(myPageTitle, False)
If myIE Is Nothing Then
'page isn't open yet
'create new IE instance
Set myIE = GetNewIE
'make IE window visible
myIE.Visible = True
'load page
If LoadWebPage(myIE, myPageURL) = False Then
'page wasn't loaded
MsgBox "Couldn't open page"
Exit Sub
End If
End If
Do
DoEvents
Loop Until myIE.readyState = READYSTATE_COMPLETE
Set doc = myIE.document
Set PageForm = doc.forms(0)
'Get the User Id textbox
'< input class="TextBox" maxlength="15" name="UserName" size="12">
Set UserIdBox = PageForm.elements("numofsets")
'Set the User Id
UserIdBox.Value = NoofSet
'Get the password textbox
'< input class="TextBox" type="password" maxlength="10" name="Password" size="12">
Set PasswordBox = PageForm.elements("numperset")
'Set the password
PasswordBox.Value = NoPSet
Set HrangeBeg = PageForm.elements("rangebeg")
HrangeBeg.Value = RangeBeg
Set HrangeEnd = PageForm.elements("rangeend")
HrangeEnd.Value = RangeEnd
'Submit the form (like clicking the 'Submit' button) to navigate to next page
PageForm.Button.Click
'Wait for the new page to load
Do
DoEvents
Loop Until myIE.readyState = READYSTATE_COMPLETE
myIE.Visible = True
'Working fine till here
'Need to pull the data from the 2nd webisite
End Sub
'returns new instance of Internet Explorer
Function GetNewIE() As SHDocVw.InternetExplorer
'create new IE instance
Set GetNewIE = New SHDocVw.InternetExplorer
'start with a blank page
GetNewIE.Navigate2 "about:Blank"
End Function
'loads a web page and returns True or False depending on
'whether the page could be loaded or not
Function LoadWebPage(i_IE As SHDocVw.InternetExplorer, _
i_URL As String) As Boolean
With i_IE
'open page
.navigate i_URL
'wait until IE finished loading the page
Do While .readyState <> READYSTATE_COMPLETE
Application.Wait Now + TimeValue("0:00:01")
Loop
'check if page could be loaded
If .document.URL = i_URL Then
LoadWebPage = True
End If
End With
End Function
'finds an open IE site by checking the URL
Function GetOpenIEByURL(ByVal i_URL As String) As SHDocVw.InternetExplorer
Dim objShellWindows As New SHDocVw.ShellWindows
'ignore errors when accessing the document property
On Error Resume Next
'loop over all Shell-Windows
For Each GetOpenIEByURL In objShellWindows
'if the document is of type HTMLDocument, it is an IE window
If TypeName(GetOpenIEByURL.document) = "HTMLDocument" Then
'check the URL
If GetOpenIEByURL.document.URL = i_URL Then
'leave, we found the right window
Exit Function
End If
End If
Next
End Function
'finds an open IE site by checking the title
Function GetOpenIEByTitle(i_Title As String, _
Optional ByVal i_ExactMatch As Boolean = True) As SHDocVw.InternetExplorer
Dim objShellWindows As New SHDocVw.ShellWindows
If i_ExactMatch = False Then i_Title = "*" & i_Title & "*"
'ignore errors when accessing the document property
On Error Resume Next
'loop over all Shell-Windows
For Each GetOpenIEByTitle In objShellWindows
'if the document is of type HTMLDocument, it is an IE window
If TypeName(GetOpenIEByTitle.document) = "HTMLDocument" Then
'check the title
If GetOpenIEByTitle.document.Title Like i_Title Then
'leave, we found the right window
Exit Function
End If
End If
Next
End Function
This code will find and identify the open "Results" window and then assign the source code behind it to a variable (my_var). You can then extract what you want from the variable.
' Find the open instance of IE that contains the "Results"
Set objShell = CreateObject("Shell.Application")
IE_count = objShell.Windows.Count
For x = 0 To (IE_count - 1)
On Error Resume Next
my_url = objShell.Windows(x).document.Location
my_title = objShell.Windows(x).document.Title
If my_title Like "Results - Research Randomizer" Then
Set ie = objShell.Windows(x)
Exit For
Else
End If
Next
my_var = ie.document.body.innerhtml