VBA IE 11 Runtime - excel

I have coded VBA in IE 11 before, and have been able to work around problems, but on this I keep getting an Error 91 or Error 424. While sometimes it works perfectly.
Unfortunately I cannot share the exact site since its password protected, but I am including the source code that's relevant.
I do option explicit, so there should be no problem with my variables.
These are all the different ways I have tried to fill the box with yesterday's date, and none of them work.
html.getElementById("begin")(1).Value = Format(Date - 1, "mm/dd/yyyy") '<-error 91
Set StartDate = html.getElementById("begin") ‘<- Error 424 or Erorr 80010108
Set EndDate = html.getElementById("end")
Set CampaignID = html.getElementById("campaign_id")
These are the 4 different things I am trying, but they all work periodically.
StartDate.Item(0).Value = Format(Date - 1, "mm/dd/yyyy") ‘<-Error 91
StartDate.Value = Format(Date - 1, "mm/dd/yyyy")
StartDate.Value(0) = Format(Date - 1, "mm/dd/yyyy")
Set StartDate(0).Value = Format(Date - 1, "mm/dd/yyyy
Source Code:
<div class="row form-group">
<div class="col-xs-12">
<div class="row">
<div class="pull-left text-left" style="width:115px;margin-left:20px">
<label for="">From :</label>
</div>
div class="col-xs-3">
<input type="text" name="begin" value="" class="form-control input-sm datepicker" id="begin" />
</div>
<div class="col-xs-1 text-right">
<label for="">To :</label>
</div>
<div class="col-xs-3">
<input type="text" name="end" value="" class="form-control input-sm datepicker" id="end" />
</div>
</div>
</div>
</div>

I figured it out.
I was refreshing the page after I signed in. This reset the permissions and was blocking me from changing any of the text boxes. Not sure why, but it was half of the problem.
Then, I changed the variable editing to run through the whole list of "input"s on the page, as seen below:
Dim CampaignId, StartDate, EndDate, RunReport As Object
Set StartDate = appIE.Document.getelementbyid("begin")
Set EndDate = appIE.Document.getelementbyid("end")
Set CampaignId = appIE.Document.getelementbyid("campaign_id")
Set RunReport = appIE.Document.getElementsByName("_action_report")
ButtonNum = 0
Set objCollection = appIE.Document.getElementsByTagName("input")
While ButtonNum < objCollection.Length
If objCollection(ButtonNum).Name = "begin" Or _
objCollection(ButtonNum).Name = "end" Then
Set objElement = objCollection(ButtonNum)
objCollection(ButtonNum).Value = Format(Date - 1, "mm/dd/yyyy")
End If
ButtonNum = ButtonNum + 1
Wend
This way found the buttons on the page where the getElementById failed.
Thanks for looking!

Related

Unable to extract Text using VBA, when there are multiple Classname , tagname and attributes with same name

I am trying to extract the innertext under the 'span' class from a IE browser, but facing an issue. Below is the HTML code
1st html snippet
<div class="SectionStart" style="display: block;" oraload="oraDisplayNone(item,'newDev','Y','=')" oraInitDisplayStyle="block">
<label oramdlabel="CM_SN">Serial Number</label>
<!--style tag has been added-->
<span class="oraDefault" style="left: -5px; top: 4.5px; position: relative;" orafield="MSerialNumber" oraType="string;precision:20" oraErrorElement="mSerialNumber">G4A001</span>
</div>
2nd html snippet
<div class="SectionStart">
<label oramdlabel="CM_SN">Serial Number:</label>
<!--style tag has been added-->
<span class="oraDefault" style="left: -5px; top: 4.5px; position: relative;" orafield="MSerialNumber" oraType="string;precision:20" oraErrorElement="mSerialNumber">E5W807</span>
</div>
Here the issue is as per below code ,while trying to fetch the 2nd value "E5W807", I am only fetching the not required value "G4A001".
Please guide how can I tackle the problem of ONLY extracting the text "E5W807".
Set objSubCollec = objCollection(0).contentWindow.document.getElementById("Page")
Set objElement = objSubCollec.contentWindow.document.getElementById("Frame_4")
objElement.Focus
Set objElement1 = objElement.contentWindow.document
Set elm2 = objElement1.getElementsByTagName("span")
For Each e1 In elm2
If e1.getAttribute("orafield") = "MSerialNumber" Then
temp = e1.innerText
'MsgBox temp
Worksheets("Sheet1").Range("B6") = temp
Exit For
End If
Next
Maybe Try this:
It will print all the found numbers in succession from B6.
Set objSubCollec = objCollection(0).contentWindow.document.getElementById("Page")
Set objElement = objSubCollec.contentWindow.document.getElementById("Frame_4")
objElement.Focus
Set objElement1 = objElement.contentWindow.document
Set elm2 = objElement1.getElementsByTagName("span")
i = 6
For Each e1 In elm2
If e1.getAttribute("orafield") = "MSerialNumber" Then
temp = e1.innerText
Worksheets("Sheet1").Range("B & i") = temp
i = i + 1
End If
Next

Select Radio Button / input value in Open box on website using vba

I am trying to punch the radio button question and want to input the value in an open text box as well (using VBA). Below is the script I am using.
I tried multiple things, looked at other websites as well but it is not working.
It would be great if someone can guide me.
Dim IE As Object
Dim Region, VOCSentDate As String
Sheets("Sheet1").Select
Region = ThisWorkbook.Worksheets("Sheet1").Range("A1").Value
VOCSentDate = ThisWorkbook.Worksheets("Sheet1").Range("B1").Value
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate "website link....."
Application.StatusBar = "Submitting"
While IE.Busy
DoEvents
Wend
I'm not sure how to punch the radio button question. I tried the 3 types for Open textbox below but none of them are not working, throwing object required error
IE.Document.getElementById("ctl00_body_7F22FA6E-5D77-426A-AA84-68D833FA05C1_3").Value = VOCSentDate
IE.Document.getElementById("ctl00_body_7F22FA6E-5D77-426A-AA84-68D833FA05C1_3").innerText = VOCSentDate
IE.Document.all("ctl00_body_7F22FA6E-5D77-426A-AA84-68D833FA05C1_3").Value = VOCSentDate
Application.StatusBar = "Form Submitted"
IE.Quit
Set IE = Nothing
-------------- HTML of the Radio button --------------
<div class="SurveyItem RadioButtonList Item1">
<div class="ItemText">
<span class="NoItemNumber"></span><span class="QuestionText">Please select your region:</span>
</div>
<div class="Validators">
<span id="ctl00_body_ctl12" style="color:Red;display:none;">A response to this question is required</span>
</div>
<div id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1" class="Response">
<div class="ResponseOption">
<input id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_1" type="radio" name="ctl00$body$ctl00_body_ctl00_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1" value="01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_1" /><label for="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_1">Americas</label>
</div>
<div class="ResponseOption AlternatingRow">
<input id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_2" type="radio" name="ctl00$body$ctl00_body_ctl00_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1" value="01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_2" /><label for="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_2">ANZ</label>
</div>
<div class="ResponseOption">
<input id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_3" type="radio" name="ctl00$body$ctl00_body_ctl00_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1" value="01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_3" /><label for="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_3">APAC</label>
</div>
<div class="ResponseOption AlternatingRow">
<input id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_4" type="radio" name="ctl00$body$ctl00_body_ctl00_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1" value="01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_4" /><label for="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_4">APME</label>
</div>
<div class="ResponseOption">
<input id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_5" type="radio" name="ctl00$body$ctl00_body_ctl00_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1" value="01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_5" /><label for="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_5">Europe</label>
</div>
<div class="ResponseOption AlternatingRow">
<input id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_6" type="radio" name="ctl00$body$ctl00_body_ctl00_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1" value="01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_6" /><label for="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_6">India</label>
</div>
<div class="ResponseOption">
<input id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_7" type="radio" name="ctl00$body$ctl00_body_ctl00_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1" value="01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_7" /><label for="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_7">North America</label>
</div>
------------------- HTML of Open End -------------------------
<div class="SurveyItem Item3">
<div class="ItemText">
<span class="NoItemNumber"></span><span class="QuestionText">EOPR First Sent Date (dd/mm/yyyy)</span>
</div>
<div class="Validators">
<span id="ctl00_body_ctl52" style="color:Red;display:none;">A response to this question is required</span><span id="ctl00_body_ctl53" style="color:Red;display:none;">Incorrect Date Format</span>
</div>
<div class="Response">
<input name="ctl00$body$01EE9560-B1F9-4BA3-A922-9D53A1120FC2_3" type="text" id="ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_3" class="TextBox" />
</div>
</div>
tl;dr;
The following are based on the HTML as shown. If there are parent form/frame/iframe tags involved they will also need to be negotiated before making the selections below.
Radio buttons:
For the radio buttons you can use a CSS selector combination to target the page styling and return a nodeList of all of the radio button elements. You can then select by index the appropriate button
Dim aNodeList As Object
Set aNodeList = ie.document.querySelectorAll(".ResponseOption [type=radio]")
aNodeList.item(0).Click '<==Select first option
I think click may be likely method here as I can't see a checked attribute, else the syntax would be aNodeList.item(0).checked = True
The returned nodeList is as follows by index
Textbox:
There is an ID for the input box so you can use an ID selector, #, to target
ie.document.querySelector("#ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_3").Value = "myText"
To choose a radio button style input, make the checked property true.
IE.Document.getElementById("ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_1_6").checked = true
An input textbox gets its value set.
IE.Document.getElementById("ctl00_body_01EE9560-B1F9-4BA3-A922-9D53A1120FC2_3").value = format(VOCSentDate, "d/m/yy")

Trying to select an item in kendogrid kendoDropDownList using Excel VBA

I'm trying to select an item on a dropdown list on an internal company web page. I am able to set text entry items and get the dropdownlist to open, but I' having a hard time figuring out how to make a selection
In other area I'm able to make a selection using the ID and td/tr tags, but this routine doesn't have any tr/td tags with entry names.
Here'a couple of things I've tried so far:
These two items perform the same function and work fine for opening the first dropdown
ie.Document.getElementById("FromDistrict").Click
ie.Document.parentWindow.execScript "$('#FromDistrict').kendoDropDownList('open');"
I've tried several variations of these:
ie.Document.parentWindow.execScript "$('#FromDistrict').data('kendoGrid').dataItem($('transport').data('kendoDropDownList').select('KILGORE'));"
ie.Document.parentWindow.execScript "$('#FromDistrict').data('kendoGrid').data('kendoDropDownList').select('KILGORE'));"
ie.Document.parentWindow.execScript "$('#FromDistrict').data('kendoGrid').data('kendoDropDownList').select('eq:0'));"
ie.Document.parentWindow.execScript "$('#FromDistrict').data('kendoDropDownList').select('KILGORE'));"
ie.Document.parentWindow.execScript "$('#FromDistrict').select('KILGORE'));"
Viewing the source code for this particular segment is:
</div>
<form action="/TransferLoad/Add" method="post"><input name="__RequestVerificationToken" _
type="hidden" value="IP80d5XM-Qi0XQ1-IgGKGmhLVNGdtDAyM-r7lJ6yQCI1RIdJJph0uPnz-DzEHx12_booO4xwvcWg6EUWPiLnHv7ww6PD-aqfhiVxPcy-VYm6mnBRHsba3H7Hembliybo0" /> _
<div class="k-block k-info-colored">
<div class="k-header">
<span>Add Transfer Load Details</span>
</div>
<div class="k-content">
<div class="infocontainer">
<table>
<tr>
<td class="columnLabel">
<label for="From_District:">From District:</label>
</td>
<td class="columnData">
<input id="FromDistrict" name="FromDistrict" style="width: 200px" type="text" />
<script>
jQuery(function(){jQuery("#FromDistrict").kendoDropDownList({"dataSource" _
:{"transport":{"read": {"url":"/DistrictProfiles/GetUserDistricts","data": _
function() { return kendo.ui.DropDownList.requestData(jQuery("#FromDistrict")); }}, _
"prefix":""}, "serverFiltering":true,"filter":[],"error":OnError, _
"schema": {"errors":"Errors"}}, "dataTextField":"DistrictName","autoBind":true, _
"dataValueField":"DistrictCode", "optionLabel":"Select District..."});});
</script>
</td>
<td class="columnLabel"> 'Next dropdown section starts here
<label for="To_District:">To District:</label>
</td>
When the dropdown opens, it has 2 items to choose from, but nowhere in the code can I find those 2 items listed, so I'm assuming they're pulled from this line: return kendo.ui.DropDownList.requestData(jQuery("#FromDistrict")) , but I'm not sure. Can someone point out what I'm missing here ?
I did not post the "view element" because of the difficulty in copying it. All selections dynamically change other selection options.
IN the browser DOM explorer (which shows the markup 'computed/sanitized' by the rendering engine) you should see that
<input id="FromDistrict" name="FromDistrict" style="width: 200px" type="text" />
has been changed to include the datalist attribute. eg.
<input id="FromDistrict" name="FromDistrict" style="width: 200px" type="text" datalist="DistrictName" />
..... and further down the DOM, you should see the datalist element that has been injected into the DOM by the Kendo code.
<datalist id="DistrictName">
<option value="Kent">Kent</option>
<option value="Surry">Surry</option>
</datalist>
You should be able to automate the field, by just assigning a valid comma-separated list to the FromDistrict.
eg. FromDistrict.value='Kent, Surry';
I was able to accomplish what I wanted in a crude sort of way by using the following, but I'm working on a better more efficient way.
'Choose the FROM district
ie.Document.parentWindow.execScript "$('#FromDistrict').kendoDropDownList('open');"
Dim FrDist, li
Set FrDist = ie.Document.getElementById("FromDistrict-list").getElementsByTagName("li")
Dim fd
fd = 0
For Each li In FrDist
'MsgBox ("li.innertext is - " & li.innerText & " fd value is: " & fd)
If li.innerText Like "*KILGORE*" Then
FrDist(fd).Click
Else
'Do Nothing
End If
fd = fd + 1
'Application.Wait (Now + TimeValue("0:00:02"))
Next
Application.Wait (Now + TimeValue("0:00:02"))
'Choose the TO district
ie.Document.parentWindow.execScript "$('#ToDistrict').kendoDropDownList('open');"
Dim ToDist
Set ToDist = ie.Document.getElementById("ToDistrict-list").getElementsByTagName("li")
Dim tod
tod = 0
For Each li In ToDist
'MsgBox ("li.innertext is - " & li.innerText & " tod value is: " & tod)
If li.innerText Like "*KILGORE*" Then
ToDist(tod).Click
Else
'Do Nothing
End If
tod = tod + 1
Next

How to set the value of the input name "PickupDate" using VBA?

I have tried the following code but obtain an Object error:
Dim g As IHTMLElement
Set g = appIE.getElementsByName("PickupDate")
g.Value = b
<div class="date date-time-field" id="pickup-date">
<div class="date-icon icon"></div>
<input name="PickupDate" class="short picker__input" id="P666421526" aria-expanded="false" aria-haspopup="true" aria-readonly="false" aria-owns="P666421526_root" type="text" readonly="" placeholder="Date">
</div>
Give this a shot:
For a particular value:
Set post = html.getElementsByName("PickupDate")
MsgBox post(0).ID
Looping through multiple values:
For Each post In html.getElementsByName("PickupDate")
MsgBox post.ID
Next post

Upload a file to a site using VBA

I am using VBA to automate IE to upload a file to a site.
I found the button with the "file" type, but then seem to draw a blank when setting the path.
My current VBA:
Dim btnInput As Object ' MSHTML.HTMLInputElement
Dim ElementCol As Object ' MSHTML.IHTMLElementCollection
.
.
.
Set ElementCol = appIE.Document.getElementsByTagName("input")
For Each btnInput In ElementCol
If btnInput.Type = "file" Then
btnInput.Value = "C:\temp\text.csv"
Exit For
End If
Next btnInput
The HTML it is reading:
<div id="upload-assignments-modal" class="modal hide fade in" tabindex="-1" role="dialog" aria-hidden="false" style="display: block;">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">Upload order changes</h3>
</div>
<form id="upload-form" enctype="multipart/form-data" action="" method="post" accept-charset="utf-8">
<div class="modal-body">
<div style="display:none"><input type="hidden" name="csrfmiddlewaretoken" value="abcde"></div>
<input type="hidden" name="partner" value="488" id="id_partner">
<p><label for="id_feed_file">Feed file</label><input type="file" name="feed_file" id="id_feed_file"></p>
<input type="hidden" name="feed_type" value="390" id="id_feed_type">
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal">Cancel</button>
<button name="action" value="upload" type="submit" class="btn btn-primary">Upload</button>
</div>
</form>
</div>
It finds the Type when stepping through and does go to set the value, but then there is no change on screen (I have the IE instance shown as visible for testing) and the file is not added.
Would I be right to assume that the "file" input type requires something other than .Value for it's input?
Give it a try
Set ElementCol = appIE.Document.getElementsByTagName("input")
For Each btnInput In ElementCol
If btnInput.Type = "file" Then
btnInput.Value = "C:\temp\text.csv"
btnInput.FireEvent ("onclick")
Exit For
End If
Next btnInput

Resources