Use VBA to navigate a website and modify drop down box - html

Good Morning,
I am working a VBA project where I would like to access an internal company, login required, web site and extract data from a table. I have successfully written code that will navigate to the correct website, and then modify a drop down box value from "All Transactions" to "Running Record". The problem I have is that I cannot not get the data in the table to refresh once the drop down box is updated. On the website, next to the drop down field, is a "Go" hyperlink. Whenever I try to activate the link, using vba, it resets the drop down and I don't get the data displayed that I want.
I was able to find a similar post where a user explained that the issue was related to the site being secured and that a .FireEvent would need to be used. Although the concept made sense to me implementation was another story. The biggest difference between my situation and the other's was that when his drop down box was changed it would activate the event. In my case there is a seperate ID, the "Go" hyperlink I mentioned above, that needs to be activated once the drop down value is entered.
Below is a portion of the HTML code where drop down box options are located as well as the "GO" hyperlink.
<select name="classList" onchange="selectClass(this);"><option class=tblrow2 value="All" selected=selected>All Schedules</option>
<option value="A" >
Transactions-Financial
</option>
<option value="N" >
Transactions-Non-Financial
</option>
<option value="RB" >
Running Balance
</option></select>
<input type="hidden" name="classindx" id = "classindx" value="" />
Go
This is a portion of my code that modifies the dropdown box value.
'try to get form by ID
Set frm = ie.Document.getElementByID("myFormID")
'try to get form by name
If frm Is Nothing Then Set frm = ie.Document.getElementsByName("facilityFeeRepayForm").Item(0)
'Set ieButton = ie.Document.getElementById("classindx") Here I tried to treat the Go hyperlink like a button but that didn't work either.
If frm Is Nothing Then
Else
ie.Visible = True
For Each element In frm.elements
On Error Resume Next
Select Case element.Name
Case "classList": element.Value = "RB"
ie.getElementByID("classindx").FireEvent("onClick") 'nothing happens with this code
While ie.ReadyState <> 4: DoEvents: Wend
End Select
Next
End If
I would appreciate any help you can offer.
Thank you,
John

Instead of clicking the link, try this:
ie.Document.parentWindow.execScript "submitTransForm()", "JavaScript"

Related

How to add elements revealed by click action to elements list in Excel VBA for an html web form

I'm trying to set up an Excel form that auto-fills an HTML web form. I've figured out how to use VBA to get the elements and cycle through them to add values. My issue is with a text field that is revealed with the click of a check box. I can't have Excel check the box until after I've obtained the elements for the form.
I've looked at the html, and it looks like the field is hidden to some degree when the form is first loaded, as the id and everything can only be found in the tree once the box is checked. The problem is, this field won't show up in the VBA elements list no matter what I try. I've tried re-doing the Set command, and gotten an error when I do that. I'm not sure how to refresh the elements list in VBA to include the new input box.
I used the Set command to get all the elements
Set frm = ie.document.getElementByID("form1")
This is fine, but I can't use that same command to try to re-Set the element list. I get the run-time error 438 (Object doesn't support this property or method)
I tried making a Variant titled frm2, but I get the same error
Sub formFill()
Dim ie As Object
Dim frm As Variant
Dim element As Variant
Set ie = CreateObject("InternetExplorer.Application")
ie.navigate "THIS IS THE URL"
While ie.readyState <> 4: DoEvents: Wend
'Get form by ID
Set frm = ie.document.getElementByID("form1")
ie.Visible = True
For Each element In frm.elements
Select Case element.Name
Case "fv_RRFC$chkOtherModel"
element.Checked = True
element.FireEvent ("OnClick")
frm.getElementByID("fv_RRFC_txtOtherModel")(0).Value = "test model" 'I tried using the command here, but it didn't work
Case "fv_RRFC$txtRRFC_PROGRAM"
element.Value = "test"
Case "fv_RRFC$txtOtherModel"
element.Value = "test model"
'My attempt to add it to the Select Case. Not surprised this didn't work, as the for Each loop uses the list it had before
End Select
Next
End Sub
I expected to be able to re-load the elements list to interact and fill the newly revealed box, but I've had no luck finding a way to do that.

Pass value to textbox in website using Excel VBA

I am trying to navigate a website and perform activities based on input from Excel.
I am stuck in passing values to input element which auto populates value in next text box based on value we have passed (eg: if I pass a zip code in target box then city name is auto populated in next box). I can pass values but it is not triggering the JS which auto populates value.
Target box code in webpage
<input name="zipcode" class="inputBoxRequired" id="zipcode" onkeypress="return isNumberKey(event)" onblur="getZipCity(this.value,'/ProviderPortal')" type="text" size="46" maxlength="5">
Code tried
Set Zip = ie_Doc.getElementById("zipcode")
Zip.Value = Zip_Code 'Here value gets updated but associated js is not triggered
ie_Doc.getElementById("zipcode").Focus
even tried fire event
Zip.FireEvent ("onchange")
In webpage it is mentioned as Onkeypress event. I googled to find solution but I can't get exact one.
Zip.FireEvent ("onkeypress")
Zip.FireEvent ("onblur") '<== Apparently this did the trick
Those are the shown events.
I have come across the same scenario for solution verified this post whereas in my case I do not have "onblur" tag, so I did some search and come up with an solution.
Dim event_onChange As Object
Set event_onChange = ie_Doc.createEvent("HTMLEvents")
event_onChange.initEvent "keypress", True, False
Zip.dispatchEvent event_onChange
It will help others who are facing same problem.

Referencing the value of a hyperlinked text box

So I'm having some difficulties with this code. I know it's obnoxiously wordy, but every attempt I made to turn some of these form references into variables to save space ended with me having even less functionality than before.
Basically what I've done so far is create a navigation form with several tabs, one to create a ticket, one to resolve/edit a ticket, and one to search the tickets. The search tab is basically a continuous form that updates based on the search criteria I enter. My goal is that when I click on the ticketID for each record, it will take me to the selected record on the Resolve/Edit Ticket page (on that page I have a combo box [called cboGoToRecord] where you can select the record you want).
I have a hyperlink in place that takes the user to the Resolve/Edit page and code that works ONLY when the line I've denoted with four asterisks (for clarity) is replaced with
rst.FindFirst "ticketID =" & [some number].
When I do that, the results are as expected. If I leave it as it is below, every record looks up the first record (A Debug.print check shows that the value of this field is apparently always 1...) So I guess what I need to figure out is how do I access the ticketID hyperlink's value so that I can put it on that line and make my code function effectively? I apologize if this is overly detailed but figured too much was better than not enough.
Private Sub ticketID_Click()
'Takes user from Search Tickets to Resolve/Edit Issues tab
DoCmd.BrowseTo acBrowseToForm, "frmResolveIssues", "frmBrowseTickets.NavigationSubform"
On Error Resume Next
Dim rst As Object
Set rst = Forms!frmBrowseTickets!NavigationSubform.Form.RecordsetClone
[Forms]![frmBrowseTickets]![NavigationSubform].Form![cboGoToRecord].Value = [Forms]![frmBrowseTickets]![NavigationSubform].Form![ticketID].Value
****rst.FindFirst "ticketID =" & [Forms]![frmBrowseTickets]![NavigationSubform].Form![cboGoToRecord].Value
Forms!frmBrowseTickets!NavigationSubform.Form.Bookmark = rst.Bookmark
Debug.Print [Forms]![frmBrowseTickets]![NavigationSubform].Form![ticketID].Value
End Sub
Edit:
After altering my form to add a separate hyperlink and referencing the static ticketID, I have concluded that everything I thought was true was not. Finding the value of a hyperlink was NOT the problem. The problem is that my ticketID value truly does insist on being one, and I have no clue how to fix that.
When this works:
Debug.Print [Forms]![frmBrowseTickets]![NavigationSubform].Form![ticketID].Value
then also check out:
Debug.Print [Forms]![frmBrowseTickets]![NavigationSubform].Form![cboGoToRecord].Value
As June7, I never use the Navigation form. It complicates everything too much.

vbscript capture text in the html select option tag

I've looked through all other questions, plus many searches over the internet, and cannot find anything that works with my situation.
I have a macro that was developed in VBScript for IBM Personal Communications (PCOMM). My bosses want me to convert it so it can be used in Macro Express Pro (ME). ME is a WYSIWYG (what you see is what you get) editor that has preset functions and allows for external scripting of JScript, VBScript, and HTA.
The PCOMM macro is about 1000 lines of pure VBScript, so it only makes sense to keep it that way, however ME doesn't allow some things that PCOMM does, so some modifications need to be made.
One modification is there already is one global instance of Internet Explorer (IE), so the macro has been designed to use that instance. I'm trying to get the selected option of a drop down box, but everything I've tried has been unsuccessful.
Here's the HTML code:
<select name="ctl00$cphContent$ddlWorkQueue" onchange="javascript:setTimeout('__doPostBack(\'ctl00$cphContent$ddlWorkQueue\',\'\')', 0)" id="ctl00_cphContent_ddlWorkQueue" class="ddlbox">
<option selected="selected" value="5422">605</option>
<option value="5419">ACCUM</option>
<option value="5418">CORRESPONDENCE</option>
<option value="5415">FEKEY</option>
<option value="5416">NKPORTAL</option>
<option value="5420">PROVIDER</option>
<option value="5423">EDITS</option>
<option value="5421">TRACR</option>
<option value="5417">WAND</option>
</select>
As you can see, "605" is selected. I want to be able to display "605" in a message box. Here's the VBScript for this:
'This subroutine checks to see if the selected queue matches the ini value if it does not it updates the ini value
Sub SetQueue
Dim Selection
'Commented out by previous developer. We do not want to create a new instance of Internet Explorer. We want to use the existing instance...
'Set objIE = CreateObject("InternetExplorer.Application")
Selection = Document.getElementById("ctl00_cphContent_ddlWorkQueue").selectedIndex
MsgBox "Selection: " & Selection
End Sub
Hopefully someone can offer me some assistance and point me in the right direction. All I get when I run the macro is "Selection: ".
Any of these methods should work:
' Method 1 - Get the current HTML displayed within the <select> element:
MsgBox Document.getElementById("ctl00_cphContent_ddlWorkQueue").innerHTML
' Method 2 - Get the current text displayed within the <select> element:
MsgBox Document.getElementById("ctl00_cphContent_ddlWorkQueue").innerText
' Method 3 - Use the selected index to look up the selected option:
Set e = Document.getElementById("ctl00_cphContent_ddlWorkQueue")
MsgBox e.Options(e.selectedIndex).Text
' Method 4 - Loop through all options looking for the selected one:
For Each o In Document.getElementById("ctl00_cphContent_ddlWorkQueue").Options
If o.Selected Then MsgBox o.Text
Next

Saving checkbox state on form post problem

I'm having problems setting the unchecked state of checkboxes upon form post. I have over 1000 checkboxes and so far i am able to check each checkbox n save there checked state. My problem however is unchecking the checkboxes.
I'm not having problems saving the checked state of each checkbox after form is posted. My problem is unchecking values then having that unchecked state saved after form post.
I'm also using paging on the page as shown in the code below (Values of submit buttons are parameters of a stored procedure)-
<center><input id="buttonStyle" type="submit" name="Page" value="#">
<% for i = 97 to 122 %>
<input id="buttonStyle" type="submit" name="Page" value="<%=CHR(i) %>">
<% next %></center>
<input id="buttonStyle" type="submit" name="Page" value="View All">
I need to save my checked state as I view each letter. So far thanks to the help of shadowwizard I am able to save checked and unchecked states of checkboxes if I click view all button. However the problem now is that when i click another letter (e.g - a, b, c) any checked state is removed when clicking view all.
<%
Dim tempArray
Dim checkArray
Dim temphiddenArray
Dim hiddenArray
'CheckBox Selection Array
if len(Request.Form("selectedRecord")) > 0 then tempArray = split(Request.Form("selectedRecord"), ",")
if isarray(tempArray) then
redim checkArray(ubound(tempArray))
'Create CheckArray ARRAY
for i = lbound(tempArray) to ubound(tempArray)
checkArray(i) = trim(tempArray(i))
next
'Hidden Array check
if len(request.Form("hiddenArray")) > 0 then temphiddenArray = split(request.Form("hiddenArray"), ",")
if isarray(temphiddenArray) then
redim hiddenArray(ubound(temphiddenArray))
for i = lbound(hiddenArray) to ubound(hiddenArray)
hiddenArray(i) = trim(temphiddenArray(i))
Session("LastCheck_"&i) = hiddenArray(i)
next
if ubound(hiddenArray) >= ubound(checkArray) then
for i = lbound(hiddenArray) to ubound(hiddenArray)
Session("CheckBox_"&(Session("LastCheck_"&i))) = ""
next
end if
end if
for i = lbound(checkArray) to ubound(checkArray)
Session("CheckBox_"&checkArray(i)) = "Checked"
%>
<input type="hidden" name="hiddenArray" value="<%=checkArray(i) %>">
<%
next
else
Session("CheckBox_"&request.Form("hiddenArray")) = ""
end if
%>
<% while not objRS.EOF %>
<input type="checkbox" name="selectedRecord" value="<%=objRS("Id") %>" <%=Session("CheckBox_"&objRS("Id")) %>>
objRS.MoveNext
wend
You're going through whole forest instead of climbing a short tree, or in other words making something simple terribly complicated.
What you need is this function:
<%
Function WasCheckedByUser(id)
Dim x
WasCheckedByUser = "checked=""checked"""
For x=1 To Request.Form("selectedRecord").Count
If Trim(Request.Form("selectedRecord").Item(x))=Trim(id) Then
Exit Function
End If
Next
WasCheckedByUser = ""
End Function
%>
Then use it like this:
<input type="checkbox" name="selectedRecord" value="<%=objRS("Id") %>" <%=WasCheckedByUser(objRS("Id")) %>/>
No need in arrays, no need in Session variables. Just simple iteration over the posted values (which are the values of the checked checkboxes) and if certain value is there, it means the corresponding checkbox should be checked, otherwise leave it unchecked.
Edit: you lose the "state" because when you click specific letter, you send to the browser only part of the checkboxes - so the previous value is indeed "lost" for good.
The most simple way to fix that is to send all checkboxes to the browser - always - and using simple style hide those that you currently don't send at all.
So, you'll have to change the SQL used to populate objRS to always select all, and change the loop to this:
<%
Do Until objRS.EOF
Response.Write("<input type=""checkbox"" name=""selectedRecord"" value=""" & objRS("Id") & """ " & WasCheckedByUser(objRS("Id")))
If Len(Request.Form("Page"))=1 And Trim(Left(objRS("Id"), 1))<>Trim(Request.Form("Page")) Then
Response.Write(" style=""display: none;""")
End If
Response.Write(" />")
objRS.MoveNext
Loop
%>
As far as I can see it should work and now preserve the state even for the hidden checkboxes.
check the resulting source code to see what it generated.
From what I can see, one problem would be that only checked checkboxes are posted when you submit a form, so if you originally have 10 checkboxes and check 3 of them and post, only those 3 will post back (and from the code, I guess only those 3 checkboxes would display after you submit, all of them checked).
You'd need to save all the checkboxes in the first run (say, with a default empty value like space), and then just change their session values when they're checked
The checkboxes are they actual items such as a category or option?
The reason i ask is that if you're setting checkboxes, how are these checkboxes defined? are they static fields or are they dynamic. I hope dynamic.
Here's how you can get things going.
Create a table called news (newsid, newstxt)
Create a table called categories (catid, catxt)
Create a table called NewscatSelected (ncsid, newsid, catid)to store check boxes of selected categories with the related newsid
Checkbox page form (cb1.asp)
Send the newsid as a query string to page (cb1.asp?newsid=34)
Dynamically list all categories as checkboxes, and get all records from NewscatSelected and pair them up. Any items that exist in the table NewscatSelected will be checked. They will have the same name but with an underscore and the numeric value of the category (cbt_34) to distinguish them easily
3.
Update Page Form (cb2.asp)
Upon getting querystring delete any existing values for the newsid sent to avoid duplicates
Insert the new checked values into the table called "NewscatSelected"
Redirect back to (cb1.asp?newsid=34) and new values will be checked.
See image below
I just posed an answer to this problem here:
how to implement a check box in classic asp
It's specifically designed for non-sequentially numbered, dynamically created checkboxes which require passing both a unique ID value and either checked or unchecked.
The solution does require a hidden field for each check box, but it does not use Javascript or any client side programming.
As the previous answer states, checkboxes do not get posted back when they are unchecked, so you have nothing in the request object that represents unchecked ones, which is fine if you know everything you are expecting to be posted back, but if it's all dynamic then it's not much use.
One workaround i've used before is to use hidden fields for the actual data, and use the checkboxes to control (via JS) the value's of the associated hidden fields, however I don't know how that solution would perform if you have 1000's of them on a page!