As I tried to create a automation for my company I stumbled across difficulty I cannot surpass. I have read many articles on this and other sites however I did not found answer.
So basically I have a dropdown list triggered by click on internet application my company uses. User has to change value from "Read" to "All" for 10 positions. And then application acknowledges the change and allows for form to be saved.
As I managed to write a code which clicks on specific field to activate a dropdown, and choose correct option from this dropdown. However when I loop it through all of those 10 dropdowns, not effect is visible.
There is a funny part. Whenever I put a breakpoint on "debug.print objinputs.outerHTML" and then allow for macro to continue the changes takes places and everything is allright. But without breakpoint something is wrong and all the values goes back to "Read". Have anyone knows what might be the issue here?
If you need any more informations please let me know.
Set ifrm = Nothing
Do Until ifrm.Length > 0
Set ifrm = IE.Document.getElementsByTagName("iframe")(0).contentDocument.getElementsByTagName("iframe")(1).contentDocument.getElementsByTagName("iframe")(0).contentDocument.getElementsByTagName("iframe")(0).contentDocument.getElementsByTagName("tbody")(znacznik - 1).Document.getElementsByTagName("td")
Loop
Counter = 1
For Each ele In ifrm
Worksheets("Test").Cells(Counter, 1) = ele.outerHTML
Counter = Counter + 1
If InStr(ele.outerHTML, "<td title=" & Chr(34) & "Read") Then
ele.Click
Do Until Not ele.Busy And ele.readyState = READYSTATE_COMPLETE: Loop
Set objInputs = Nothing
Set objInputs = IE.Document.getElementsByTagName("iframe")(0).contentDocument.getElementsByTagName("iframe")(1).contentDocument.getElementsByTagName("iframe")(0).contentDocument.getElementsByTagName("iframe")(0).contentDocument.getElementsByTagName("tbody")(znacznik - 1).Document.getElementsByTagName("select")(3)
objInputs.Value = "All"
Debug.Print objInputs.Value
Do Until Not IE.Busy And IE.readyState = READYSTATE_COMPLETE: Loop
End If
Next
I found a solution.
It is not the most elegant one but it works and is correct enough for my needs.
I have added
CreateObject("WScript.Shell").Popup "Just Wait", 1, "Waiting"
after value change and it did the trick. I would love to know why does it happen, and why does this "trick" solves the issue.
Related
This is first time I am trying to extract an excel report from a webpage. Sequence of how my code should work is as under:
Initial URL - brings home page of the website (userid and password saved in browser to autologin) - image1
Click on "Reports"
New page appears (image2)
select from dropdown_module.
Select appropriate from dropdown_reports.
selection in dropdown_reports creates a new dropdown_project.
select from dropdown_project
click on drownload reports (image3)
give path for downloading.
image41
image12
image23
image34
I am able to reach upto point 3, but not able to proceed ahead.
On using inspect element on dropdown_module i get the code (image4)
My using so far is as under:
Set IE = CreateObject("InternetExplorer.Application")
URL = Range("hr_url").Value
IE.Visible = True
IE.navigate URL
Application.StatusBar = " is loading. Please wait..."
Do While IE.readyState = 4: DoEvents: Loop
Do Until IE.readyState = 4: DoEvents: Loop
Application.StatusBar = " Loaded"
Set doc = IE.document
For Each element In doc.all
If InStr(element.ID, "08191") > 0 Then
If InStr(element.ID, "AppPress:12") Then
element.Focus
element.Click
End If
End If
Next element
Application.Wait (5)
Do
DoEvents
Loop Until IE.readyState <> 4
Set doc = IE.document
For Each element In doc.all
If InStr(element.ID, "0261") > 0 Then
If InStr(element.ID, "AppPress:6") Then
MsgBox "element is found"
element.Options(0).Selected = True
End If
End If
Next element
The code isnt able to find the dropdown element and select the 0 index required. Can anyone suggest what is wrong here?
I was not aware that scraping was posible with VBA. (Scraping is the way the technique of extracting info from the web with software is called)
You should find this question useful:
Scraping data from website using vba
I am not aware of the posibilities off doing this with VBA that might be limited to internet explorer among other limitations. The little things I've done for that have been with python and a library called beautifulSoup, that is amazing!
https://www.crummy.com/software/BeautifulSoup/bs4/doc/
If you feel curious enough you might want to dive into it, as it is quite simple, and googling what you want to do might take you very far, also if you want to create an excel file with the info you extract.
Hope that helps
I want to enter data into a web page field.
There are 2 data entry fields on the web page.
I entered data in the first section.
However, I cannot enter data in the other field.
Information you need to review the site :
Site : http://splan.byethost7.com/mesaj_yaz.php?fno=1&kip=yeni
user :kurucu password :a11111
I entered the data in the "BAŞLIK" field.
However I am unable to write data to the field named "İÇERİK"
I want to enter data in this field using an Excel macro. But I can't enter data using the code:
Sub deneme()
Dim URL As String
On Error Resume Next
URL = "http://splan.byethost7.com/mesaj_yaz.php?fno=1&kip=yeni"
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = 1
For i = 1 To Range("A" & Rows.Count).End(3).row
If Cells(i, 1) <> Empty Then
ie.navigate URL
Call bekle
ie.Document.getElementById("mesaj_icerik").Value = "TEST"
ie.document.getElementsByName("mesaj_baslik").Item(0).Value = Cells(i, 1)
'IE.Document.getElementsByClassName("submitButton")(0).Click
Call bekle
End If
Next i
' IE.Quit
Set ie = Nothing
End Sub
Sub bekle()
With ie
Do Until .readyState = 4: DoEvents: Loop
Do While .Busy: DoEvents: Loop
End With
Application.Wait (Now + TimeValue("00:00:02"))
End Sub
As I said in my comments, there are several issues with your code, although the overall effort is good.
Firstly, this ie.document.getElementsid("mesaj_baslik") is not a valid method. If what you want is to access a single HTML element with a unique ID, then the method you need to use is ie.Document.getElementById("the element's ID").
Assuming that what I wrote above is what you were trying to achieve, you have to keep in mind that the .getElementById() method, returns only one single element.
So this ie.Document.getElementById("the element's ID").item(0) would give you an error saying:
Object doesn't support this property or method.
Even if all the aforementioned mistakes were corrected, I still don't see any elements with an ID equal to "mesaj_baslik", in the HTML snippet that you have provided. In fact this particular string is nowhere to be found in the HTML.
So even if the method was correct, this ie.Document.getElementById("mesaj_baslik"), would return Nothing.
Secondly, although your usage of the method ie.document.getElementsByName() is correct, there is no element with a Name attribute being equal to "formlar_mesajyaz", in the HTML snippet you have provided.
In fact this string seems to be a Class name rather than anything else. In this case you would have to use this method: ie.document.getElementsByClassName().
Now, from the info you have provided, the best I can do is assume that, what you want to do is enter some text in the textArea element. To do that, you can use the element's ID like so:
ie.Document.getElementById("mesaj_icerik").Value = "TEST"
I need a code that loops through options in a < select > object on a web page, selects each option and clicks "Show" button to show some data related to the selected option. I started with this code:
Set periodSelector = ie.document.getElementById("period")
For Each Period In periodSelector.Options
Period.Selected = True
Application.Wait (Now + TimeValue(waittime))
Next Period
It works well - the browser selects each option just fine. But when I add button.click to show the data related to the selected option, an error "Permission denied" occurs on the second selector loop (seems like it cannot use .select command anymore).
Set periodSelector = ie.document.getElementById("period")
For Each Period In periodSelector.Options
Period.Selected = True
Application.Wait (Now + TimeValue(waittime))
ie.document.getElementsByTagName("input")(17).Click
Application.Wait (Now + TimeValue(waittime))
Next Period
I guess it is due to same origin policy. Probably, when I click on the "Show" button, the page gets refreshed (although it is not really reloaded - the button uses scripts to retrieve some information and show it in a table below the button).
How can I avoid this same origin policy issue and loop through the dropdown options?
In cases like this I try a slightly different approach which is to work off the page and not a variable. You can get your number of options from an initial variable, but after that keep working off the current document which may have refreshed. Amongst other things, you want to avoid underlying stale element exceptions.
Dim periodSelector As Object, i As Long, optionsLength As Long
Set periodSelector = ie.document.querySelectorAll("#period option")
optionsLength = periodSelector.Length -1
For i = 0 to optionsLength
ie.document.querySelectorAll("#period option").item(i).Selected = True
Application.Wait Now + TimeValue(waittime)
ie.document.getElementsByTagName("input")(17).Click
Application.Wait Now + TimeValue(waittime) '<== this I would replace with proper page load wait While ie.Busy Or ie.readyState < 4: DoEvents: Wend
Next
Good Morning,
I’m hoping that some kind soul out there can help me with a roadblock I’ve encountered in my quest to manipulate a website with VBA. I am using MS Excel 2010 and Internet Explorer 11.0.56.
I’m somewhat comfortable with VBA but have never used it to navigate to a website, enter information and click on buttons. I’ve managed to muddle through as follows:
In Column A of my Excel spreadsheet, I have a list of 10 digit case numbers.
The code below will open IE, navigate to the desired website, pause while I log in, then navigate to the search screen, enter in the first case number and press the SEARCH button (yes, I have the case number in this example hard coded in with no looping, but that stuff I can handle so please ignore):
Sub Button_Click()
Dim objIE As Object
Set objIE = New InternetExplorerMedium
objIE.Top = 0
objIE.Left = 0
objIE.Width = 800
objIE.Height = 600
objIE.AddressBar = 0
objIE.StatusBar = 0
objIE.Toolbar = 0
objIE.Visible = True
objIE.Navigate ("https://somewebsite.com")
MsgBox ("Please log in and then press OK")
objIE.Navigate ("https://somewebsite.com/docs")
Do
DoEvents
Loop Until objIE.ReadyState = 4
objIE.Document.all("caseNumber").Value = "1234567890"
objIE.Document.getElementById("SearchButton").Click
Exit Sub
Do
DoEvents
Loop Until objIE.ReadyState = 4
MsgBox ("Done")
End Sub
That will bring me to this screen
The file number entered in the search field will return any number of files in a dynamic table with a checkbox to the left of each file.
For this example, let’s say I am ONLY concerned with the file called “CC8” under the “Type” column. There will only ever be one instance of “CC8” for a given file number.
What I need help with is, through VBA, how do I search through this table, find the “CC8” line, and then have the checkbox to the left automatically checked?
When I inspect the “CC8” element in IE, this is the HTML associated with it (highlighted in gray; the entire table is under class “listing list-view clearfix”)
see here
The HTML for the checkbox related to the “CC8” item is below:
HTML code here
The “id” for both has the same sequence of numbers, but one starts with “viewPages” and the other “doc”.
Can anyone help me out as to what I need to add to my code to get this checkbox checked? Thank you!
Note:
Please post the actual HTML using the snippet tool.
Generally:
Without HTML to properly test, I am assuming that the following 2 nodeLists are the same length, meaning that when the search text is found in aNodeList then the assumption is the same index can be used to target the corresponding checkbox in the bNodeList:
Dim aNodeList As Object, i As Long
With objIE.document
Set aNodeList = .querySelectorAll("a[target='_blank']")
Set bNodeList = .querySelectorAll("[title='Search Result: Checkbox']")
End With
For i = 0 To aNodeList.Length - 1
If aNodeList.item(i).innerText = "CC8" Then
bNodeList.item(i).Click
Exit For
End If
Next
You could also potentially use the following instead as you say the viewPages prefixes each item:
Set aNodeList = .querySelectorAll("a[id^='viewPages']")
Other observations:
Traditional checkboxes would have a checked attribute and syntax of
bNodeList.item(i).Checked = True, but as I can't see that attribute in your element I am assuming a .Click suffices.
I'm working making a loop to get data out of a combo form.
Analysis_1 is the first variable
Analysis_1_ComboB is the first ComboBox from the screen
Analysis_1 = Me.Analysis_1_ComboB.Column(0)
Analysis_2 = Me.Analysis_2_ComboB.Column(0)
Analysis_3 = Me.Analysis_3_ComboB.Column(0)
etc etc
as single lines, it is working I do want to work with a loop
for counter = 1 to 9
Analysis_&Counter = Me.Analysis_&Counter&_ComboB.Column(0)
next counter
unfortunately, this is not working, who can help me out here?
Unfortunately, you cannot dynamically specify variable names. (You can usually find a way to dynamically access various objects, especially if they are accessible be a "Name" index.)
The best way to achieve what you want to do is make your variables an array, e.g.:
Dim Analysis(1 To 9) As String
For counter = 1 To 9
Analysis(counter) = Me.Controls("Analysis_" & counter & "_ComboB").Column(0)
Next counter
MsgBox "Value from Analysis_5_ComboB is " & Analysis(5)
(This code assumes that your ComboBoxes are on a UserForm and therefore dynamically accessible via the form's Controls collection.)