Run-time error '9': Subscript out of range -Error - excel

I am running VBA in excel in order to do some web-scraping, but am coming up with this error when attempting to reach Google Chrome. How would one avoid this? I will click debug then a single line becomes highlighted...
This is where the error pops up
This is the highlighted line of code that must be giving the issue
Full Code in this picture
FULL CODE BELOW:
Private Sub time_sheet_filling()
Dim I As Long
Dim IE As Object
Dim doc As Object
Dim objElement As Object
Dim objCollection As Object
' Create InternetExplorer Object
Set IE = CreateObject("ChromeTab.ChromeFrame")
IE.Visible = True
' Send the form data To URL As POST binary request
IE.navigate "https://wistar.dispondo.net/#/login"
' Wait while IE loading...
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
'Load the logon page
Set objCollection = IE.Document.getElementsByTagName("input")
I = 0
While I < objCollection.Length
If objCollection(I).Name = "username" Then
' Set text to enter
objCollection(I).Value = "MyUsername"
End If
If objCollection(I).Name = "password" Then
' Set text for password
objCollection(I).Value = "MyPasword"
End If
If objCollection(I).Type = "submit" And objCollection(I).Name = "btnSubmit" Then ' submit button clicking
Set objElement = objCollection(I)
End If
I = I + 1
Wend
objElement.Click ' click button to load the form
' Wait while IE re-loading...
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
' Show IE
IE.Visible = True
Dim links, link
Dim n, j
Set links = IE.Document.getElementById("dgTime").getElementsByTagName("a")
n = links.Length
For j = 0 To n - 1 Step 2
links(j).Click
'I have some operations to be done will post another question for this
Next
End Sub

That error would occur if there is not a worksheet named "Website Data" in the active workbook at the time of the code running. Either the worksheet name does not match, or a different workbook is active when the code is running.
Make sure the worksheet name is correct and also explicitly reference the workbook it is located in (so that it doesn't matter which workbook is active when the code is running). If the "Website Data" sheet is in the workbook where the code is running, then refer to the value in the cell using:
ThisWorkbook.Sheets("Website Data").Cells(1,1).Value

You can't use Chrome instead of IE in this way. Chrome can only use via Selenium for web scraping via VBA. The IE is the only browser with a COM Interface which is needed to control an application via VBA:
For more information:
About the Component Object Model (COM)
About Selenium browser automation

Related

Automate IE via Excel to fill in a dropdown and continue

Admittedly still a newbie with automating IE via Excel but would appreciate whatever help anyone can offer with this. Basically, this opens up a webpage, selects a button, fills in 2 dropdowns, enters a value and then presses another button to display what I need.
I do have this working using SendKeys with a bunch of {Tabs}, {`}, {Down}, etc but it's rather clunky.
I'd rather do this the right way but I can only get to the 1st dropdown, select the value that I need and then it stops. What I'm missing, I guess, is telling IE to accept what I've entered and continue on.
Coding is below. Comments included to show what it's doing and where it stops.
Dim WebIDStr As String: WebIDStr = "CD00003630"
Dim IE As Object
WebNavStr = "https://a810-dobnow.nyc.gov/Publish/#!/"
On Error Resume Next
Set IE = Nothing
Set IE = CreateObject("InternetExplorer.Application")
With IE
.Visible = True
.navigate WebNavStr
Do Until .readyState = 4: DoEvents: Loop
End With
' Won't work without a delay??
Application.Wait (Now + TimeValue("00:00:03"))
IE.document.getElementsByClassName("white ng-scope")(3).Click
' the next command works and fills-in the dropdown with the value
' that I need but then locks up. Can't move on from here.
IE.document.getElementById("DeviceOptions").selectedIndex = 4
' GOOD to HERE. Tried the next 2 lines but they don't do anything, unfortunately
IE.document.getElementById("DeviceOptions").Focus
IE.document.getElementById("DeviceOptions").Click
' This is where I need to get to. Next Dropdown Value = 1
IE.document.getElementById("craneDeviceOption").selectedIndex = 1
' Once 2nd dropdown selected, fill in "DevCraneID" box
IE.document.getElementById("DevCraneID").Value = WebIDStr
' Press the "Select" button
IE.document.getElementById("Search4")(0).Click
' IE.Quit
' Set IE = Nothing
Ok, because you wrote you want to understand how it works I have commented the whole code by detail.
This is the working code:
Sub DeviceSearch()
'Define constants
Const url As String = "https://a810-dobnow.nyc.gov/Publish/#!/"
'Declare variables
Dim ie As Object
Dim htmlDoc As Object
Dim nodeDeviceTypeDropdown As Object
Dim nodeCraneDeviceDropdown As Object
Dim nodeCraneDeviceID As Object
Dim searchTerm As String
'Initialize variables
searchTerm = "CD00003630" 'craneID
'Initialize Internet Explorer, set visibility,
'call URL and wait until page is fully loaded
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
ie.navigate url
Do Until ie.readyState = 4: DoEvents: Loop
'Wait to load dynamic content after IE reports it's ready
Application.Wait (Now + TimeSerial(0, 0, 3))
'Shorten html document string for lazy coders ;-)
'Seriously: You can of course also use "With ie.document"
Set htmlDoc = ie.document
'Open the Device Search section
htmlDoc.getElementsByClassName("white ng-scope")(3).Click
'Try to get the first dropdown.
'Never use "On Error Resume Next" for the whole code.
'We use it here because if an html id can't be found
'a runtime error occours. But after the critical part
'we switch the error detection back on with "On Error GoTo 0"
'(I use this here only to show you what to do if not sure if
'you can get an element by id. In this case it's not realy
'requiered because we can assume the dropdown is present.)
On Error Resume Next
Set nodeDeviceTypeDropdown = htmlDoc.getElementById("DeviceOptions")
On Error GoTo 0
'Now we can check if the dropdown element was found
'If an object variable has no value it is "Nothing"
'To check if it has a value we must check if it's
'"Not" "Nothing"
'You can use this mechanism for every object variable
'in VBA
If Not nodeDeviceTypeDropdown Is Nothing Then
'Select the wanted dropdown entry
nodeDeviceTypeDropdown.selectedIndex = 4
'To make the selection work you must trigger the
'html change event of the dropdown
Call TriggerEvent(htmlDoc, nodeDeviceTypeDropdown, "change")
'Give time to generate the code for the second dropdown
Application.Wait (Now + TimeSerial(0, 0, 1))
Else
'Dropdown not found
MsgBox "The Dropdown for Device Search was not found"
'Stop makro
Exit Sub
End If
'Here we can use the second dropdown "Search Crane Device"
'We do it from here without error handling
Set nodeCraneDeviceDropdown = htmlDoc.getElementById("craneDeviceOption")
'Select the wanted dropdown entry
nodeCraneDeviceDropdown.selectedIndex = 1
'Trigger the change event of this dropdown
Call TriggerEvent(htmlDoc, nodeCraneDeviceDropdown, "change")
'Give time to generate the code for the text field
Application.Wait (Now + TimeSerial(0, 0, 1))
'Now we have the text field present and can enter the search term (craneID)
'Get the html input element
Set nodeCraneDeviceID = htmlDoc.getElementById("DevCraneDeviceID")
'
'It is not enough to enter the ID. The input field also has html events
'that must be triggered so that the entered value is not only displayed
'but also taken over to submit.
'We have to embed the entering of the crane id in the both events
'"compositionstart" and "compositionend"
Call TriggerEvent(htmlDoc, nodeCraneDeviceID, "compositionstart")
nodeCraneDeviceID.Value = searchTerm
Call TriggerEvent(htmlDoc, nodeCraneDeviceID, "compositionend")
'Click the submit button
htmlDoc.getElementById("search4").Click
'Give time to load the result page
Application.Wait (Now + TimeSerial(0, 0, 5))
'Do here what you want with the result
'...
End Sub
This is the procedure to trigger html events
Private Sub TriggerEvent(htmlDocument As Object, htmlElementWithEvent As Object, eventType As String)
Dim theEvent As Object
htmlElementWithEvent.Focus
Set theEvent = htmlDocument.createEvent("HTMLEvents")
theEvent.initEvent eventType, True, False
htmlElementWithEvent.dispatchEvent theEvent
End Sub
Here are two screenshots from FireFox html inspector with the events of the elements
If you don't know which event(s) are needed you must try till it works ;-)
All events for the used dropdowns on the page
The events for the used input field on the page

Excel web automation: invalid inputs

I am trying to write code to upload data into web form at work. If I copy and paste the details the form accepts the values, but If the VBA code enters the same exact values then I get input error.
Screen script of form is below
This Excel Vba code taken from StackOverflow searches and youtube "https://www.youtube.com/watch?v=T6HRjiAdW38&list=PLBGMKJfLuhqa3q0RWyiN40NV24rxTJ0Yt&index=1"
Sub Ihub_upload()
Dim appIE As InternetExplorerMedium
Dim objElement As Object
Dim objCollection As Object
Dim sURL As String
Set appIE = New InternetExplorerMedium
sURL = "company web site "
With appIE
.navigate sURL
.Visible = True
End With
Do While appIE.Busy
Application.Wait DateAdd("s", 2, Now)
Loop
':::: Enter data collection ::::'
' I will put code below into a loop to enter multiple values if it works'
'Data collecton'
appIE.document.getElementById("CPH_MasterBody_CPH_EtlMasterBody_DDL_DataCollection").Value = 120
'File location tab 16'
appIE.document.getElementById("CPH_MasterBody_CPH_EtlMasterBody_TXT_SourceConnectionString").Value = "Y:\Databases\2019-Kv9xQ.xls"
'start date tab 18 '
appIE.document.getElementById("CPH_MasterBody_CPH_EtlMasterBody_TXT_PeriodStartDateTime").Value = "01/09/2019"
'End date tab 19'
appIE.document.getElementById("CPH_MasterBody_CPH_EtlMasterBody_TXT_PeriodEndDateTime").Value = "30/09/2019"
'publication date tab 20 '
If ThisWorkbook.Sheets("Data").Range("I3").Value <> "" Then
appIE.document.getElementById("CPH_MasterBody_CPH_EtlMasterBody_TXT_PublicationDateTime").Value = "14/11/2019"
End If
'Source URL tab 21 '
If ThisWorkbook.Sheets("Data").Range("I3").Value <> "" Then
appIE.document.getElementById("CPH_MasterBody_CPH_EtlMasterBody_TXT_SourceUrl").Value = "https://www.england.nhs.uk"
End If
':::: Save record? click ok button ::::'
Application.Wait DateAdd("s", 3, Now)
appIE.document.getElementById("CPH_MasterBody_CPH_EtlMasterBody_BTN_Save").Click

DOM VBA IE11 Automate Placing Orders on a Website - Trouble With OnChange and Picture Upload

We have a Virtual Assistant placing hundreds of orders for ball markers on this site:
https://www.golfballs.com/Golf-Misc/Tools/Classic-Photo-Poker-Chips-3-Pack.htm
I had used VBA before to get data from a website but I would like to use it to automate the placing of orders. I can get close but there are a few things tripping me up.
First of all, when you select a color with your mouse, the "Upload a Photo" box appears. I cannot get the box to show up using my VBA code.
Using VBA, I cannot make the onchange event fire for the life of me. I have tried the following four combinations:
doc.getElementById("2").selectedIndex = 2
doc.getElementById("2").FireEvent ("onchange")
doc.getElementById("2").Focus
doc.getElementById("2").selectedIndex = 2
doc.getElementById("2").FireEvent ("onchange")
doc.getElementById("2").selectedIndex = 2
doc.getElementById("2").FireEvent ("onclick")
doc.getElementById("2").Focus
doc.getElementById("2").selectedIndex = 2
doc.getElementById("2").FireEvent ("onclick")
Second, even if I can get the boxes to show and I click on "Upload a Photo", the popup box is there and I am having trouble putting the focus on it and I am unsure on how to tell the ID "fileField" what picture from my browse I want to upload. There is also a second Confirmation pop up.
If I can get the picture upload to work, I can successfully complete the automated order. Here is my code through clicking the Add to Cart button. The entirety of my "Upload Picture" section does not work and the last line under "Select the Color" does not make the "Upload a Photo" box show.
Dim IE As InternetExplorer
Dim doc As HTMLDocument
Set IE = New InternetExplorer
IE.Visible = True
'Go to the Ball Marker Page
ballMarkerURL = "https://www.golfballs.com/Golf-Misc/Tools/Classic-Photo-Poker-Chips-3-Pack.htm"
IE.navigate ballMarkerURL
'Wait for page to load
Do While IE.readyState <> READYSTATE_COMPLETE Or IE.Busy: DoEvents: Loop
Set doc = IE.document
'Select the Color
doc.getElementById("2").Focus
doc.getElementById("2").selectedIndex = 2
doc.getElementById("2").FireEvent ("onchange")
'Upload Picture
markerFilePath = "M:\Cuddle Clones Share (Team Folder)\Operations\Vendors\Pet Prints\0 - Ready to Order - Golfballs.com\"
markerFileName = "380844 - Ball Marker - 200604-Red-1-of-1-qty-1.png"
fullString = markerFilePath & markerFileName
doc.getElementById("copyright_check").Checked
doc.getElementById("fileField").Value = fullString
doc.getElementById("upload").Click
doc.getElementById("saveBtn").Click
'Update Quantity
doc.getElementById("formQty").Value = 2
'Add to Cart
doc.getElementsByClassName("buttonStatic r addCart")(0).Click
In my original posting I explained how to trigger an event. Now I explain too how to click the "Upload a photo" button and focus the popup window.
The problem now is, the needed html document is in an iframe I can't access. I know there can be different reasons but none of them solve the problem.
This is, what I have now:
Sub SelectColorForGolfballs()
Dim objShell As Object
Dim objWindow As Object
Dim browser As Object
Dim url As String
Dim nodeColorDropDown As Object
Dim nodeThreeButtons As Object
Dim browserPopUp As Object
Dim nodeFrames As Object
Dim nodeIframeDoc As Object
Set objShell = CreateObject("Shell.Application")
url = "https://www.golfballs.com/Golf-Misc/Tools/Classic-Photo-Poker-Chips-3-Pack.htm"
'Initialize Internet Explorer, set visibility,
'call URL and wait until page is fully loaded
Set browser = CreateObject("internetexplorer.application")
browser.Visible = True
browser.navigate url
Do Until browser.ReadyState = 4: DoEvents: Loop
'Select color from dropdown
Set nodeColorDropDown = browser.document.getElementByID("2")
nodeColorDropDown.selectedIndex = 6 'Pink for testing
Call TriggerEvent(browser.document, nodeColorDropDown, "change")
'Manual break for loading the page complitly
'Application.Wait (Now + TimeSerial(pause_hours, pause_minutes, pause_seconds))
Application.Wait (Now + TimeSerial(0, 0, 2))
'Open Picture Upload
'The document changed, so you can't work with the old document here
'In a first step you need the div element with the three buttons
'we get in the last step by trigger dropdown event
'
'<div class="options-gallery">
' <a href="javascript:productSelection(1, 'P');">
' <img src="https://d1tp32r8b76g0z.cloudfront.net/images/property/button/Half/Condition_P.jpg" title="Personalized" border="0">
' </a>
' <a href="javascript:productSelection(1, 'S');">
' <img src="https://d1tp32r8b76g0z.cloudfront.net/images/property/button/Half/Condition_S.jpg" title="Photo" border="0">
' </a>
' <a href="javascript:productSelection(1, 'L');">
' <img src="https://d1tp32r8b76g0z.cloudfront.net/images/property/button/Half/Condition_L.jpg" title="Novelty" border="0">
' </a>
'</div>
Set nodeThreeButtons = browser.document.getElementsByClassName("options-gallery")(0)
'The second button must be clicked
nodeThreeButtons.FirstChild.NextSibling.Click
Application.Wait (Now + TimeSerial(0, 0, 2))
'Focus popup by runnig throuhg all open windows
For Each objWindow In objShell.Windows
'Check if it's an IE
If InStr(1, UCase(objWindow.FullName), "IEXPLORE") > 0 Then
'Check if it's the right IE
If InStr(1, objWindow.document.getElementsByTagName("title")(0).innertext, "iCusomize Image Selection") Then
Set browserPopUp = objWindow
Exit For
End If
End If
Next objWindow
'Now we can work with the popup
'It has only short code over all and a very short body
'You have to access the content of an iFrame
'
'Problem: I don't know why the following don't work
'I know it can't be in the same line
'You must split the access to the iFrame
'Get a node collection of all frames/ iframes of the document
Set nodeFrames = browserPopUp.document.frames
'The following line couses the error "Access denied"
'Select the first (and only) frame from the node collection
Set nodeIframeDoc = nodeFrames(0).document
'Check the copyright checkbox
nodeIframeDoc.getElementByID("copyright_check").Click
'If you are at this point we can look ahead
End Sub
And this procedure to trigger the event you need:
Private Sub TriggerEvent(htmlDocument As Object, htmlElementWithEvent As Object, eventType As String)
Dim theEvent As Object
htmlElementWithEvent.Focus
Set theEvent = htmlDocument.createEvent("HTMLEvents")
theEvent.initEvent eventType, True, False
htmlElementWithEvent.dispatchEvent theEvent
End Sub

Run-Time error '91': Object variable or With block variable not set - works once then won't work again

I get the error mentioned in the title every time I try to run my VBA code. Error is appearing on this line:
Set Button_Top_Result = IE.document.getElementById_
("javascript:gx.evt.execEvt('EUSRACNAM.CLICK.0001',this);").href
Also did some research online and find this alternative code and tried it as well.
For Each ele In IE.document.getElementsByTagName("a")
If InStr(ele.href, "javascript:gx.evt.execEvt('EUSRACNAM.CLICK.0001',this);") > 0 Then IE.navigate_
ele.href: Exit For
Next
This line worked once, and now no longer works.
VBA Novice here, so this might be a simple solution but I am stumped - working on navigating through the company website and wrote line to click on hyperlink to navigate me to this next page. It worked the first time, and then won't work and spits out the above error. Really stumped here, already did some digging online and can't figure out where my error is.
Here is the html part of the web page
https://i.stack.imgur.com/kgJOo.png
'''Option Explicit
Sub GetMasterDetailKeyedDataTest2()
'The goal of this macro is to quickly and conveniently update BNA Depreciation by automating the steps necessary to complete the process.
'Dimensions identfy things I will define later to use.
Dim name As String
Dim IE As InternetExplorerMedium
Dim store As String
Dim client As String
Dim URL As String
Dim username
Dim Password
Dim Button_Next
Dim Button_Login
Dim Button_OnDemandReporting
Dim Search_Bar
Dim Button_Mag_Glass
Dim Button_Top_Result As Action
'Line below bypasses login if user is already logged in
'On Error Resume Next
store = Workbooks("Learning").Sheets("Sheet1").Range("A2")
client = Workbooks("Learning").Sheets("Sheet1").Range("B2")
'Abbreviates Internet Explorer. Note I need the correct references enabled in tools in order to run a web query using this name.
Set IE = New InternetExplorerMedium
'Define URL
URL = "Company website"
'make IE browser visible (False would allow IE to run in the background)
'Once program is working I will want to turn this off so that the user doesn't see the webbrowser.
IE.Visible = True
'Navigate to Login page
IE.navigate URL
'This loop prevents Excel from continuing the code
Do While IE.Busy Or IE.readyState <> 4
DoEvents
Loop
'These next four steps navigate through the login
Set username = IE.document.getElementById("username") 'id of the username control (HTML Control)
username.Value = "username"
Set Button_Next = IE.document.getElementById("next") 'id of the button control (HTML Control)
Button_Next.Click
Set Password = IE.document.getElementById("password") 'id of the password control (HTML Control)
Password.Value = "password"
Set Button_Login = IE.document.getElementById("submit") 'id of the button control (HTML Control)
Button_Login.Click
Do While IE.Busy Or IE.readyState <> 4
DoEvents
Loop
'Connects to OnDemand Reporting
Set Button_OnDemandReporting = IE.document.getElementById("IMAGE1_0004")
Button_OnDemandReporting.Click
Do While IE.Busy Or IE.readyState <> 4
DoEvents
Loop
Set Search_Bar = IE.document.getElementById("vNAME")
Search_Bar.Value = Workbooks("Learning").Sheets("Sheet1").Range("B2")
Set Button_Mag_Glass = IE.document.getElementById("IMAGE1")
Button_Mag_Glass.Click
Set Button_Top_Result = IE.document.getElementById("javascript:gx.evt.execEvt('EUSRACNAM.CLICK.0001',this);").href
Button_Top_Result.Click
End Sub
'''
I expect the last step to navigate me to the next part of the web page, but instead I keep getting the above error.

Excel VBA: Check all check boxes on Web Page

I'm trying to check all the checkboxes available on a webpage via VBA since the name convention doesnt appear to be one in which I can be selective. However I cannot seem to get anything to work. I can login to the website and navigate to the section of the website I want but cannot cross this hurdle. Any help would be greatly appreciate. Below is the source code from the webpage.
<li data-product-family="30yr"
data-product-amortizationTerm="30"
data-product-type="Conventional"
data-product-amortizationType="Fixed"
>
<label>
<input type="checkbox"
value="154232"
class="product-Conventional product-item"
data-authorized-remittance-types="ActualActual "
/>30-Year Fixed Rate - 110k Max Loan Amount</label>
</li>
VBA I attempted to write (edited)... code I'm using presently:
Public Sub TestIE()
Dim IE As Object
Dim aNodeList As Object, i As Long
' Create InternetExplorer Object
Set IE = CreateObject("InternetExplorer.Application")
' You can uncoment Next line To see form results
IE.Visible = False
' Send the form data To URL As POST binary request
IE.Navigate "https://"
' Statusbar
Application.StatusBar = "Page is loading. Please wait..."
' Wait while IE loading...
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
IE.Visible = True
Set aNodeList = IE.document.querySelectorAll("input[type=checkbox]")
If aNodeList Is Nothing Then Exit Sub
For i = 0 To aNodeList.Length
aNodeList.Item(i).Checked = True
Next i
End Sub
You can try to get a nodeList of the checkboxes with:
IE.document.querySelectorAll("input[type=checkbox]")
You can traverse the nodeList along its .Length property.
E.g.
Dim aNodeList As Object, i As Long
Set aNodeList = IE.document.querySelectorAll("input[type=checkbox]")
If aNodeList Is Nothing Then Exit Sub
For i = 0 To aNodeList.Length -1
On Error Resume Next
aNodeList.item(i).Checked = True
On Error GoTo 0
Next i

Resources