I am using VBA to automate the pulling of reports from a structured web page.
I have the following code block which changes the dropdown element for each element in an array"
With IE
For Each itemName In itemNames()
i = i + 1
Module2.check_and_wait_for_item ("cboDistrict")
Set Dropdown = .document.getElementsByName("cboDistrict")(0)
Dropdown.Value = itemValues(i)
Dropdown.FireEvent ("onchange")
check_and_wait_for_item ("cmdRptPreview")
Set btnPreview = .document.getElementsByName("cmdRptPreview")(0)
btnPreview.Click
check_and_wait_for_item ("BtnExport")
Set HTMLDoc = .document
write_file_to_dir HTMLDoc, "C:\Users\user\Documents\____thing\", itemName & ".html"
.GoBack
Next itemName
End With
The problem arises with IE.GoBack. I have a function that checks if JavaScript has finished executing by looping while a particular element is not present on the page. "Going back" puts the element back on the page even though the JavaScript event has not finished running.
This is why I want to delete the old "cmdRptPreview" element before I have my function check if JavaScript event has finished running.
Is there a way to do so? Appreciate the help.
The solution was to remove the Node containing the element being checked by JavaScript waiter function.
After .GoBack:
check_and_wait_for_item ("cmdRptPreview")
.document.getElementsByName("cmdRptPreview")(0).ParentNode.RemoveChild .document.getElementsByName("cmdRptPreview")(0)
Related
Trying to achive downloading table from company website. I can download first page. However, cannot jump to second page.
HTML CODE for Page Number
1
HTML CODE
[![HTML CODE FOR TABLE][1]][1]
page numbers are inside table and increasing one by one. at the first time when page one is active link href is not visible and shows as
<span>1</span>
I use below code to click page however I cannot succeded.
Set doc = ie.document
i = 0
For Each link In doc.Links
'doing downloading stuff here
i = i + 1
link.innerText = "javascript:__doPostBack('ctl00$View$gv','Page$" & i
link.Click
Next
When I check the page also there is a javascript function.
Javasript CODE
//<![CDATA[
var theForm = document.forms['aspnetForm'];
if (!theForm) {
theForm = document.aspnetForm;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
after first page downloaded, macro click irrelevant page links even never click same page for each time.
Extra Question
also is there any way to get href values instead of innertext on below code
User Name
Thanks
Open any page by parameter of the url:
Look if you can open any page directly by a parameter of the url for the page number like this:
https://yourUrl.com?page=2
Then the walk through all pages is very easy. The only thing you must check at first is the number of the pages or a html code that only is in the page code when you try to open a page that is not available.
How to get href
You can't click innertext. That is only a string. You ask for a way to get the href and that is the right thought. If you want get the href of the first a-tag you can use this:
'Part of your code to open the page
'...
Dim nodeFirstLink as Object
Set nodeFirstLink = doc.getElementsByTagName("a")(0)
Debug.Print nodeFirstLink.href
'More of your code
'...
Here is an example how to change the href
But I don't know if this works also with JS links:
Sub ChangeHref()
Dim htmlDoc As Object
Dim nodeFirstLink As Object
'Set a short HTML Document for this example
Set htmlDoc = CreateObject("HtmlFile")
htmlDoc.body.innerHTML = "<a href='https://amazon.com'>Amazon</a>"
Set nodeFirstLink = htmlDoc.getElementsByTagName("a")(0) 'Get the first Link
Debug.Print nodeFirstLink.outerhtml 'The HTML of the first link in the html document
Debug.Print nodeFirstLink.href 'Only the href of the first link in the html document
nodeFirstLink.href = "https://ebay.com" 'Changing the href in the first link
Debug.Print nodeFirstLink.outerhtml 'The innertext is still Amazon
Debug.Print nodeFirstLink.href 'The href is the new one
End Sub
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"
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.
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.