I'm one step away from success on a huge automation project. I've got a dynamic download automated all the way up to the IE11 Save As dialogue box. This is where I'm stuck. I need to 1) enter in a dynamic file name and save to a dynamic folder (all based on a cell value). 2) click Save while overriding any update dialogue boxes
Limitations; I cant download based on the URL if you were going to suggest that. I'm dealing with a secure site and a funky URL that can only be accessed via the For Next loop I have below. I'm limited to dealing with this SaveAs box as far as I'm aware.
Here's what I have so far;
Sub savedownload()
Dim objIE As InternetExplorer
Set objIE = New InternetExplorer
objIE.Visible = True
objIE.navigate Sheet3.Range("A1").Value ' this is where the dynamic URL is updated
Do While objIE.Busy = True Or objIE.readyState <> 4: DoEvents: Loop
objIE.document.getElementById("PrintFormat").Value = "Pdf"
Do While objIE.Busy = True Or objIE.readyState <> 4: DoEvents: Loop
Dim list As Object, item As Object
Set list = objIE.document.getElementsByTagName("a")
For Each item In list
If item.innerText = "Export" Then
item.Click
Exit For
End If
Next
Application.Wait (Now + TimeValue("0:00:05"))
Application.SendKeys "{TAB}", True
Application.SendKeys "{TAB}", True
Application.SendKeys "{DOWN}", True
Application.SendKeys "{DOWN}", True
Application.SendKeys "{RETURN}", True
'this is where the dialoge box comes up, but I cant seem to send a dynamic string of text to the file name/path field
End Sub
I have attached a screenshot as well. Would send keys work? Is there a way to call the SaveAs window and drop in a dynamic file name? I can throw a file name at it and get it to save with SendKeys, but I'm thinking there's a better way where I can send an entire dynamic String to the FileName field in the dialogue box.
Thanks for any suggestions.
Screenshot of IE11 SaveAs dialogue box
Related
I thought I was well on my way to success. What I'm attempting to do is Load a URL in IE, input some data, then run a report.
To accomplish this, I've created an InternetExplorer object, used that object to turn on visibility, and navigate to my URL.
Upon getting to the page, I have to supply some data to let the report generator do what it needs to do, then press enter. Once I'm to this point I need to do some navigation to different URLs until I arrive at the report page. To accomplish this, I'm attempting to return to using my InternetExplore object (IE) to navigate, but any time I use IE.anything the 462 error pops.
My question is two fold:
The object was good to begin with, I have to assume it was the use of Application.Send or Application.Wait that has somehow broke my object, why?
What did I do wrong?
Suggestions on how to resolve this?
Dim text As String
Dim IE
Set IE = CreateObject("InternetExplorer.Application")
'
IE.Visible = True
IE.Navigate "http://~~~~~~~~~.net/reports/views/result/reportResult.faces"
'
text = "somedata"
.
Application.Wait (Now + TimeValue("00:00:02"))
Application.SendKeys (text), True
'
Application.Wait (Now + TimeValue("00:00:02"))
Application.SendKeys vbCrLf, True
'
Application.Wait (Now + TimeValue("00:00:02"))
IE.Navigate "http://~~~~~~~~~.net/reports/views/myMrs/myFavorites.faces"
The end product was completely different than where I was headed. Thanks to those who provided input, especially Sorceri who turned me on to focusing on the elements.
Below is the finished code segment (I have more things I do after this but this gets me where I needed to go).
Private Sub OpenReport()
Dim text As String
Dim x As Integer
Dim IE
Set IE = New InternetExplorerMedium
text = "somecode"
'Load link
IE.Visible = True
IE.Navigate "http://~~~~~~~~~/reports/views/result/reportResult.faces"
'Wait for page to load
Do While IE.Busy Or IE.ReadyState <> 4
DoEvents
Loop
'fill in the pcode
IE.Document.getelementbyid("code").Value = text
'Click Submit
IE.Document.getElementsByClassName("btn btn-lg btn-primary btn-block")(0).Click
'Wait for page to load
Do While IE.Busy Or IE.ReadyState <> 4
DoEvents
Loop
'Click on Favorites
IE.Document.getElementsByClassName("myMRSFavoritesLink")(0).Click
'Wait for page to load
Do While IE.Busy Or IE.ReadyState <> 4
DoEvents
Loop
'Click on report
IE.Document.getElementsByName("myFavoritesForm:treeTable_tableId:1:infoButton101644806j_id__v_19")(0).Click
'Wait for page to load
Do While IE.Busy Or IE.ReadyState <> 4
DoEvents
Loop
Click on execute report
IE.Document.getElementsByName("setParametersForm:startReportButton")(0).Click
End Sub
I have issues with a code I am writing on VBA. I am basically using vba to open a website, input information and then click a download button, which downloads a csv that I can then copy and put onto my excel file. I do manage to get everything done up to the clicking download button. When I do that a Dialogue window shows up for IE11 asking me whether I want to save or open the file. I have no idea how solve this issue and how to click open or save. I have tryed everything mentioned in a solution for the same problem in Controlling IE11 "Do you want to Open/Save" dialogue window buttons in VBA , but even though I use this solution, the code runs but just does not do anything.
I have tried using the UIAutomation but I have been unsuccessful . I used the solution provided in Controlling IE11 "Do you want to Open/Save" dialogue window buttons in VBA. I have also tried using Sendkeys but I am not entirely sure how to set the focus on Internet explorer so that the sendkeys do what they are supposed to.
Code is actually very simple
Sub GetHTMLDocument()
Dim ie As New SHDocVw.InternetExplorer
Dim HTMLDoc As HTMLDocument
Dim HTMLInput As MSHTML.IHTMLElement
Dim HTMLButtons As MSHTML.IHTMLElementCollection
Dim HTMLButton As MSHTML.IHTMLElement
ie.Visible = True
ie.Navigate "this is where i put the website"
Do While ie.ReadyState <> READYSTATE_COMPLETE
Loop
Set HTMLDoc = ie.Document
Set HTMLInput = HTMLDoc.getElementById("Search")
HTMLInput.Value = "Hello"
Set HTMLInput = HTMLDoc.getElementById("downloadCSV")
HTMLInput.Click
End Sub
Unfortunately I cannot give the website and I cannot use a public one, after that I get the message whether to open or save it on internet explorer
Possible duplicate of VBA interaction with internet explorer
Though this answer may be more clear for this specific question.
1) add this to top of your module - It creates a function that will allow you to give any window focus. I have no idea on the details.
Public Declare Function SetForegroundWindow Lib "user32" (ByVal HWND As Long) As Long
2) Modify this code to taste in order to use SendKeys
'give IE focus to prepare for SendKeys
' IE.HWND = the handle of the Windows Internet Explorer main window.
Dim HWNDSrc As Long
HWNDSrc = IE.HWND
SetForegroundWindow HWNDSrc
'Make sure IE is not busy
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
'send Alt-S to save
Application.SendKeys "%{S}"
'Make sure IE is not busy
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
I've written a script in vba in combination with IE to click on some dots available on a map in a web page. When a dot is clicked, a small box containing relevant information pops up.
Link to that website
I would like to parse the content of each box. The content of that box can be found using class name contentPane. However, the main concern here is to generate each box by clicking on those dots. When a box shows up, it looks how you can see in the below image.
This is the script I've tried so far:
Sub HitDotOnAMap()
Const Url As String = "https://www.arcgis.com/apps/Embed/index.html?webmap=4712740e6d6747d18cffc6a5fa5988f8&extent=-141.1354,10.7295,-49.7292,57.6712&zoom=true&scale=true&search=true&searchextent=true&details=true&legend=true&active_panel=details&basemap_gallery=true&disable_scroll=true&theme=light"
Dim IE As New InternetExplorer, HTML As HTMLDocument
Dim post As Object, I&
With IE
.Visible = True
.navigate Url
While .Busy = True Or .readyState < 4: DoEvents: Wend
Set HTML = .document
End With
Application.Wait Now + TimeValue("00:0:07") ''the following line zooms in the slider
HTML.querySelector("#mapDiv_zoom_slider .esriSimpleSliderIncrementButton").Click
Application.Wait Now + TimeValue("00:0:04")
With HTML.querySelectorAll("[id^='NWQMC_VM_directory_'] circle")
For I = 0 To .Length - 1
.item(I).Focus
.item(I).Click
Application.Wait Now + TimeValue("00:0:03")
Set post = HTML.querySelector(".contentPane")
Debug.Print post.innerText
HTML.querySelector("[class$='close']").Click
Next I
End With
End Sub
when I execute the above script, it looks like it is running smoothly but nothing happens (I meant, no clicking) and it doesn't throw any error either. Finally it quits the browser gracefully.
This is how a box with information looks like when a dot gets clicked.
Although I've used hardcoded delay within my script, they can be fixed later as soon as the macro starts working.
Question: How can I click each of the dots on that map and collect the relevant information from the popped-up box? I only expect to have any solution using Internet Explorer
The data are not the main concern here. I would like to know how IE work in such cases so that I can deal with them in future cases. Any solution other than IE is not I'm looking for.
No need to click on each dots. Json file has all the details and you can extract as per your requirement.
Installation of JsonConverter
Download the latest release
Import JsonConverter.bas into your project (Open VBA Editor, Alt + F11; File > Import File)
Add Dictionary reference/class
For Windows-only, include a reference to "Microsoft Scripting Runtime"
For Windows and Mac, include VBA-Dictionary
References to be added
Download the sample file here.
Code:
Sub HitDotOnAMap()
Const Url As String = "https://www.arcgis.com/sharing/rest/content/items/4712740e6d6747d18cffc6a5fa5988f8/data?f=json"
Dim IE As New InternetExplorer, HTML As HTMLDocument
Dim post As Object, I&
Dim data As String, colObj As Object
With IE
.Visible = True
.navigate Url
While .Busy = True Or .readyState < 4: DoEvents: Wend
data = .document.body.innerHTML
data = Replace(Replace(data, "<pre>", ""), "</pre>", "")
End With
Dim JSON As Object
Set JSON = JsonConverter.ParseJson(data)
Set colObj = JSON("operationalLayers")(1)("featureCollection")("layers")(1)("featureSet")
For Each Item In colObj("features")
For j = 1 To Item("attributes").Count - 1
Debug.Print Item("attributes").Keys()(j), Item("attributes").Items()(j)
Next
Next
End Sub
Output
I'm currently using the following code to open an IE instance and navigate a complete-with-answers google form link. By accessing this link, the google form is immediately answered by the "entry.1102259784=XXXX" strings.
Private Sub Workbook_Open()
Application.ScreenUpdating = False
Dim IE As Object
Call Usernames
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = False
IE.Silent = True
IE.Navigate Cells(7, 1)
While IE.Busy
DoEvents
Wend
IE.Quit
Set IE = Nothing
End Sub
Its quite simple and works well (hidden and fast) except for this particular instance (google forms), as the IE opens and just stands there with the "Your form has been submitted" webpage on display.
The idea is to submit information about who is opening the file and when to a google spreadsheet.
I would appreciate any help on this matter.
Thank you very much!
I have been trying to automate a web page since two weeks but I could not proceed further after 3rd page.
First I'm logging into login page by giving credentials and then I would click a link from 2nd page. Until this point I'm fine; but after that again I need to click another link from the 3rd page that I'm not able to, Even I was not able to read the proper innerhtml of that particular page. The innerhtmal varies from the source code of that page. Using the source code I have taken the id/name to get the element but no use. The problem I'm seeing is the DOCUMENT object is not taking the inner details of 3rd page. When I tried to print the links of that page it printed me some common links in that page which would be available in all the pages instead of printing all the links in that particular page. I guess this might happen because the page frame varies with respect to the FromDate & ToDate. Pardon me if I'm wrong. Do we need to change every time the "ie.document" object with respect to the navigation of web page? Because I think it sticks with the same when the page loaded 1st time.
Below is my code:
Public Sub Test ()
Dim shellWins As ShellWindows
Dim ie As InternetExplorer
Dim doc As HTMLDocument
Dim frm As HTMLFrameElement
Dim frms As HTMLElementCollection
Dim strSQL As String
Dim Login As Boolean
strSQL = "https://website.com"
Set ie = CreateObject("InternetExplorer.Application")
With ie
.Visible = True
.Navigate strSQL
Do Until .ReadyState = 4: DoEvents: Loop
Set doc = ie.document
Dim link As Object
For Each link In doc.Links
'Debug.Print link.innerText
If link.innerText = "Click Here" Then
link.Click
Exit For
End If
Next link
Do While ie.Busy: DoEvents: Loop
Login_Pane:
For Each link In doc.Links
If link.innerText = "Leave & Attendance" Then
'Debug.Print doc.body.innerHTML
link.Click
Login = True
Exit For
End If
Next link
If Login <> True Then
Application.Wait (Now + TimeValue("00:00:02"))
Application.SendKeys "<USERNAME>", True
Application.SendKeys "{TAB}"
Application.Wait (Now + TimeValue("00:00:02"))
Application.SendKeys "<PASSWORD>", True
Application.SendKeys "{ENTER}"
GoTo Login_Pane
End If
Do While ie.Busy: DoEvents: Loop
Dim link As Object
For Each link In doc.Links
Debug.Print link.innerText
' Above line code should print all the links in that page_
_but unfortunatly it is not displaying as it is in the source code.
' instead printing half of the links which are commonly_ _available in all pages.
' This page has three frames
Next link
End With
'IE.Quit
End Sub
i'm unable to post the image of that page to make you understand more, Anyways i'll try my best.
when i use this below code i can only able to get the links from the upper portion of the page.
Set doc = ie.document
Dim text As Object
For Each text In doc.Links
Debug.Print text.innerText
Next text
Below to that portion of the page i have option to enter FromDate & ToDate, by giving dates to this textboxes i'll be able to see the details according to the dates (by default page displayes the details from 1st of the curent month to the current date of the month).
So, here i'm not getting the links/or other details. And i think the details of this sections are not stored in the ie.document object.
And this particular section alone has different URL from the main page.
Thanks.
A couple of thoughts:
For a page that dynamically loads you need to use Application.Wait (5 seconds or so) instead of Do Until .ReadyState = 4: DoEvents: Loop. The latter does not work if you have javascript being executed.
Using SendKeys should always be avoided as it is not robust.Inspect the element with a DOM explorer to get the ID or name.