Find form ID on a website and input value using VBA - vba

I would require a bit of help finding a form id on a public website (http://www.medicines.ie/). They updated the site and the previous id no longer works since now there is no Id to be found. What I am trying to do is open this site with VBA, input the value from a specific cell in excel to a form (textbox) on this website and press the search button. I am using the code below:
Sub Medicinesie()
Dim IE As Object
Set IE = CreateObject("INTERNETEXPLORER.APPLICATION")
IE.navigate "http://www.medicines.ie/"
IE.Visible = True
Do
DoEvents
Loop Until IE.ReadyState = READYSTATE_COMPLETE
IE.Document.getElementById("input").Value = Range("spc") '<---- spc is the name of the cell I am referencing
IE.Document.forms(0).submit
Do
DoEvents
Loop Until IE.ReadyState = READYSTATE_COMPLETE
End Sub

It looks like you could take advantage of the URL construction at this website. URL is constructed:
http://www.medicines.ie/medicines?page=1&per-page=25&query= + anything you would like to search in this database.
Sub MedicineS()
Dim IE As Object
Set IE = CreateObject("INTERNETEXPLORER.APPLICATION")
Dim URL As String
URL = "http://www.medicines.ie/medicines?page=1&per-page=25&query=" & _
Range("spc")
IE.Visible = True
IE.navigate URL
Do While IE.readyState <> READYSTATE_COMPLETE
Loop
End Sub
However if you still prefer to use your own way keep in mind that input you are looking for is 4th in the code so:
IE.Document.getElementByTagName("input")(3).Value
and the button is second so:
IE.Document.getElementByTagName("button")(1).Click

With selenium vba wrapper installed and adding tools > reference > selenium type library
Option Explicit
Public Sub test()
Dim d As WebDriver
Set d = New ChromeDriver '<== can change to internet explorer driver
With d
.Start "Chrome"
.Get "http://www.medicines.ie/"
.FindElementByCss("input.search__input").SendKeys "Aspirin" '<== Range("spc")
.FindElementByTag("form").Submit
Stop
'.Quit
End With
End Sub
Example run:

Related

Unable to switch to a new tab in an efficient manner

I've written a script in vba which is able to click on a certain link (Draw a map) of a webpage. When the clicking is done, a new tab opens up containing information I would like to grab from. My script can do all these errorlessly. Upon running the script it scrapes the title visible as Make a Google Map from a GPS file from the new tab.
My question: is there any alternative way to switch to new tab other than using hardcoded search like If IE.LocationURL Like "*" & "output_geocoder" Then?
This is my script:
Sub FetchInfo()
Const url As String = "http://www.gpsvisualizer.com/geocoder/"
Dim IE As New InternetExplorer, Html As HTMLDocument, R&
Dim winShell As New Shell
With IE
.Visible = True
.navigate url
While .Busy = True Or .readyState < 4: DoEvents: Wend
Set Html = .document
End With
Html.querySelector("input[value$='map']").Click
For Each IE In winShell.Windows
If IE.LocationURL Like "*" & "output_geocoder" Then
IE.Visible = True
While IE.Busy = True Or IE.readyState < 4: DoEvents: Wend
Set Html = IE.document
Exit For
End If
Next
Set post = Html.querySelector("h1")
MsgBox post.innerText
IE.Quit
End Sub
To execute the above script, add this reference to the library:
Microsoft Shell Controls And Automation
Microsoft Internet Controls
Microsoft HTML Object Library
Btw, there is nothing wrong with the above script. I only wish to know any better way to do the same.
This is the best I have so far with selenium
Option Explicit
Public Sub GetInfo()
Dim d As WebDriver
Set d = New ChromeDriver
Const url = "http://www.gpsvisualizer.com/geocoder/"
With d
.Start "Chrome"
.get url
.FindElementByCss("input[value$='map']").Click
.SwitchToNextWindow
.FindElementByCss("input.gpsv_submit").Click
MsgBox .Title
Stop
.Quit
End With
End Sub
The more fixed with title is:
.SwitchToWindowByTitle("GPS Visualizer: Draw a map from a GPS data file").Activate
.FindElementByCss("input.gpsv_submit").Click
tl;dr;
I will need to read up more on how robust .SwitchToNextWindow is.
FYI, you can get handles info with:
Dim hwnds As List
Set hwnds = driver.Send("GET", "/window_handles")

Clicking link within a HTML List

I'm trying use Excel's IE automation tools to click a website link within a users profile of this site. Using the following in VBA:
ie.Document.getElementsByClassName("website")(0).getElementsByTagName("a")(0).Click
But keep getting the Runtime error '438' when ran. Any advice on how to fix this or if clicking this link is even possible please? Thanks.
EDIT (Full Code):
Dim ie As InternetExplorer
Dim html As HTMLDocument
Set ie = New InternetExplorer
ie.Visible = True
ie.Navigate "site"
Do While ie.READYSTATE <> READYSTATE_COMPLETE
DoEvents
Loop
Set objA = ie.Document.getElementsByClassName("website")(0) 'GETTIN ERROR HERE
objA.getElementsByTagName("a")(0).Click
End Sub
It would appear that there were a few minor issues here.
One being that .Click doesn't always function properly, I would suggest using .getAttribute("href") combined with ie.Navigate()
Another being that you seem to define html then never use it again.
The following code works:
Sub test()
Dim ie As InternetExplorer
Dim html As HTMLDocument
Set ie = New InternetExplorer
ie.Visible = True
ie.Navigate "http://beverlyhills.yourkwoffice.com/mcj/user/AssociateSearchSubmitAction.do?orgId=5058&lastName=&firstName=&rows=100"
Do While ie.READYSTATE <> READYSTATE_COMPLETE
DoEvents
Loop
Set html = ie.Document
Set objA = html.getElementsByClassName("website")(0).getElementsByTagName("a")(0)
ie.Navigate (objA.getAttribute("href"))
End Sub

How to pause Excel VBA and wait for user interaction before loop

I have a VERY basic script I am using with an excel spreadsheet to populate a form. It inserts data into the fields then waits for me to click the submit button on each page. Then it waits for the page to load and fills in the next set of fields. I click submit, next page loads, etc. Finally, on the last two pages I have to do some manual input that I can't do with the spreadsheet. Code thus far is shown below.
My question is, at the end of what I have there now, how can I make the system wait for me to fill out that last page, then once I submit it realize that it has been submitted and loop back to the beginning, incrementing the row on the spreadsheet so that we can start over and do the whole thing again for the next student?
As you will probably be able to tell I am not a programmer, just a music teacher who does not savor the idea of filling out these forms manually for all 200 of my students and got the majority of the code you see from a tutorial.
Function FillInternetForm()
Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")
'create new instance of IE. use reference to return current open IE if
'you want to use open IE window. Easiest way I know of is via title bar.
IE.Navigate "https://account.makemusic.com/Account/Create/?ReturnUrl=/OpenId/VerifyGradebookRequest"
'go to web page listed inside quotes
IE.Visible = True
While IE.busy
DoEvents 'wait until IE is done loading page.
Wend
IE.Document.All("BirthMonth").Value = "1"
IE.Document.All("BirthYear").Value = "2000"
IE.Document.All("Email").Value = ThisWorkbook.Sheets("queryRNstudents").Range("f2")
IE.Document.All("Password").Value = ThisWorkbook.Sheets("queryRNstudents").Range("e2")
IE.Document.All("PasswordConfirm").Value = ThisWorkbook.Sheets("queryRNstudents").Range("e2")
IE.Document.All("Country").Value = "USA"
IE.Document.All("responseButtonsDiv").Click
newHour = Hour(Now())
newMinute = Minute(Now())
newSecond = Second(Now()) + 3
waitTime = TimeSerial(newHour, newMinute, newSecond)
Application.Wait waitTime
IE.Document.All("FirstName").Value = ThisWorkbook.Sheets("queryRNstudents").Range("a2")
IE.Document.All("LastName").Value = ThisWorkbook.Sheets("queryRNstudents").Range("b2")
IE.Document.All("Address1").Value = "123 Nowhere St"
IE.Document.All("City").Value = "Des Moines"
IE.Document.All("StateProvince").Value = "IA"
IE.Document.All("ZipPostalCode").Value = "50318"
End Function
I would use the events of the IE, more specifically the form, something like this, using MSHTML Controls library.
Private WithEvents IEForm As MSHTML.HTMLFormElement
Public Sub InternetExplorerTest()
Dim ie As SHDocVw.InternetExplorer
Dim doc As MSHTML.HTMLDocument
Set ie = New SHDocVw.InternetExplorer
ie.Visible = 1
ie.navigate "http://stackoverflow.com/questions/tagged/vba"
While ie.readyState <> READYSTATE_COMPLETE Or ie.Busy
DoEvents
Wend
Set doc = ie.document
Set IEForm = doc.forms(0)
End Sub
Private Function IEForm_onsubmit() As Boolean
MsgBox "Form Submitted"
End Function

Need to use VBA to select an option from a drop down list in Internet Explorer

I have successfully got my code to open IE, navigate to the webpage I need, and login. I now need to select an option from a drop down list - please see the following html code:
html code for the list
How do I select the "TPS Managed Conservative - Dec 11" option from the dropdown.
My code so far:
Sub Strategic_Alpha_Monthly_Pivots_1_MASTER()
' open IE, navigate to the desired page and loop until fully loaded
Dim ie As Object
Set ie = CreateObject("InternetExplorer.Application")
my_url = "http://analytics.financialexpress.net/login.aspx"
With ie
.Visible = True
.navigate my_url
Do Until Not ie.Busy And ie.readyState = 4
DoEvents
Loop
End With
' Input the userid and password
ie.document.getElementById("txtPassword").Value = "xxxxx"
' Click the "Search" button
ie.document.getElementById("btnAction").Click
Do Until Not ie.Busy And ie.readyState = 4
DoEvents
Loop
ie.document.getElementById("ListPortfolio").Select
End Sub
selectedIndex or Value could be used. According to the screenshot the value 983678630 can be used. HTH
If Not VBA.IsNull(ie.document.getElementById("ListPortfolio")) Then
Dim htmlSelect
Set htmlSelect = ie.document.getElementById("ListPortfolio")
' htmlSelect.selectedIndex = 6
htmlSelect.Value = 983678630
Else
MsgBox "Element 'ListPortfolio' was not found", vbExclamation
End If

VBA to open URL, wait for 5 seconds, then open another URL

I have a webpage I want to open (URL is generated out of cell values in Excel), but going to that URL directly requires logging in to open. But if I first open the mainpage of the server, I have automatic login, and then I'm able to open the first URL without the need for user/pass.
So far I have this code, which opens IE with both URLs at the same time, in the same window, but different tabs, exactly as I want it to do, except URL2 requires the login.
To get around the login, I would like to add a pause between the navigate and navigate2, so the first page can complete loading before the second URL opens.
Can anyone help me with this?
Edit:
I have tried the suggestions from below, but it still needs the login. I have tried another solution, which is not optional, but it works. It consists of two buttons, running different macros, where the first one opens the main page to get the login, and the second one opens the next URL.
I have written them as follows:
First one:
Sub login()
Dim IE As Object
Const navOpenInNewTab = &H800
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate "http://www.example.mainpage.com"
End Sub
Second one:
Sub search()
Dim IE As Object
Const navOpenInNewTab = &H800
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate2 "http://www.example.mainpage.com" & Range("w1").Cells.Value & Range("W2").Cells.Value, CLng(navOpenInNewTab)
End Sub
Is it possible to have a third macro running the other two with a delay between them?
Original code:
Sub open_url()
Dim IE As Object
Const navOpenInNewTab = &H800
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate "http://www.example.mainpage.com"
'here I would like to add a pause for 5 seconds
IE.Navigate2 "http://www.example.mainpage.com" & Range("w1").Cells.Value & Range("W2").Cells.Value, CLng(navOpenInNewTab)
End Sub
Maybe it would be better to wait until the first page is fully loaded:
IE.Navigate "http://www.example.mainpage.com"
Do While IE.Busy Or Not IE.readyState = IE_READYSTATE.complete: DoEvents: Loop
IE.Navigate2 "http://www.example.mainpage.com" & Range("w1").Cells.Value & Range("W2").Cells.Value, CLng(navOpenInNewTab)
Note that the ReadyState enum READYSTATE_COMPLETE has a numerical value of 4. This is what you should use in the case of late binding (always the case in VBScript).
Do you mean something like:
Application.Wait(Now + TimeValue("00:00:05"))