Javascript / Ajax selection and click

whose2know

Board Regular
Joined
May 1, 2002
Messages
59
I'm still stuck trying to pass a website click from VBA. I think I've inlcuded the portion of the code below that is related to selecting the account. Any help on how I pass the proper variables through to ie and then "click"?

PHP:
    function SelectAccount(id) {
        var params = JSON.stringify({ accountNumber: id });
 
        $.ajax({
            type: "POST",
            url: "SelectAccount2.aspx/SelectAccount",
            data: params,
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(response) {
                if (response.d) {
                    var returnURL = GetURLParameter("ReturnURL");
                    if (returnURL === "") {
                        var path = ****************.pathname.split('/');
                        path[path.length - 1] = "Billing.aspx";
                        var newPath = path.join('/');
                        var location = String.format("{0}//{1}{2}", ****************.protocol, ****************.host, newPath);
                        returnURL = location;
                    }
                    else {
                        returnURL = unescape(returnURL);
                    }
                    ****************.href = returnURL;
                }
            },
            error: function(XMLHttpRequest) {
                var response = JSON.parse(XMLHttpRequest.responseText);
                if (response.Message) {
                    DisplayMessage(response.Message);
                }
                else {
                    DisplayMessage("An unknown error occured when selecting the account.");
                }
            }
        }); 
    }
 

Excel Facts

Fastest way to copy a worksheet?
Hold down the Ctrl key while dragging tab for Sheet1 to the right. Excel will make a copy of the worksheet.
Can you post the HTML which calls SelectAccount(). If the HTML calls another function which calls SelectAccount() then post that as well.
 
Upvote 0
I think it is contained in this section:
PHP:
******** src="Scripts/Common.js" type="text/javascript">*********>
******** src="/ScriptResource.axd?d=2dijIrrWM1cb3HlCgkncdHFTjS6I_VKaizrw27nhcBsh6MADHcoPYneBG3_B3XjBpGNnj0tx-pAf8CeUFKNWgrNaA-01&t=634219993708532350" type="text/javascript">*********>
******** src="/ScriptResource.axd?d=2dijIrrWM1clywjXGi2TegGbq6loWyvFnuTPoZC_D2uVm6WYFUrsiGRpK2k2p5NVhhBGsiSfmVxEmoFWlEtutQyGuhwVkxg0vAT716CKKFo8ut_lbaGnhvJqRruIbEHjW_Lzqg2&t=634219994477912274" type="text/javascript">*********>
******** type="text/javascript"> 
//<![CDATA[
if (typeof(Sys) === 'undefined') throw new Error('ASP.NET Ajax client-side framework failed to load.');
//]]>
*********>
 
******** src="/ScriptResource.axd?d=2dijIrrWM1clywjXGi2TegGbq6loWyvFnuTPoZC_D2uVm6WYFUrsiGRpK2k2p5NVhhBGsiSfmVwPt_5LZ1l74JgKW0uuHDZg8K4zi-R5PA11RZAfFjIBKSMy6j4QZmpZPrc8uz17aYyoYmvU0&t=634219994477912274" type="text/javascript">*********>
******** type="text/javascript"> 
//<![CDATA[
var PageMethods = function() {
PageMethods.initializeBase(this);
this._timeout = 0;
this._userContext = null;
this._succeeded = null;
this._failed = null;
}
PageMethods.prototype = {
_get_path:function() {
 var p = this.get_path();
 if (p) return p;
 else return PageMethods._staticInstance.get_path();},
GetAccounts:function(sortExpression,filter,succeededCallback, failedCallback, userContext) {
/// <param name="sortExpression" type="String">System.String</param>
/// <param name="filter" type="String">System.String</param>
/// <param name="succeededCallback" type="Function" optional="true" mayBeNull="true"></param>
/// <param name="failedCallback" type="Function" optional="true" mayBeNull="true"></param>
/// <param name="userContext" optional="true" mayBeNull="true"></param>
return this._invoke(this._get_path(), 'GetAccounts',false,{sortExpression:sortExpression,filter:filter},succeededCallback,failedCallback,userContext); },
SelectAccount:function(accountNumber,succeededCallback, failedCallback, userContext) {
/// <param name="accountNumber" type="String">System.String</param>
/// <param name="succeededCallback" type="Function" optional="true" mayBeNull="true"></param>
/// <param name="failedCallback" type="Function" optional="true" mayBeNull="true"></param>
/// <param name="userContext" optional="true" mayBeNull="true"></param>
return this._invoke(this._get_path(), 'SelectAccount',false,{accountNumber:accountNumber},succeededCallback,failedCallback,userContext); }}
PageMethods.registerClass('PageMethods',Sys.Net.WebServiceProxy);
PageMethods._staticInstance = new PageMethods();
PageMethods.set_path = function(value) {
PageMethods._staticInstance.set_path(value); }
PageMethods.get_path = function() { 
/// <value type="String" mayBeNull="true">The service url.</value>
return PageMethods._staticInstance.get_path();}
PageMethods.set_timeout = function(value) {
PageMethods._staticInstance.set_timeout(value); }
PageMethods.get_timeout = function() { 
/// <value type="Number">The service timeout.</value>
return PageMethods._staticInstance.get_timeout(); }
PageMethods.set_defaultUserContext = function(value) { 
PageMethods._staticInstance.set_defaultUserContext(value); }
PageMethods.get_defaultUserContext = function() { 
/// <value mayBeNull="true">The service default user context.</value>
return PageMethods._staticInstance.get_defaultUserContext(); }
PageMethods.set_defaultSucceededCallback = function(value) { 
 PageMethods._staticInstance.set_defaultSucceededCallback(value); }
PageMethods.get_defaultSucceededCallback = function() { 
/// <value type="Function" mayBeNull="true">The service default succeeded callback.</value>
return PageMethods._staticInstance.get_defaultSucceededCallback(); }
PageMethods.set_defaultFailedCallback = function(value) { 
PageMethods._staticInstance.set_defaultFailedCallback(value); }
PageMethods.get_defaultFailedCallback = function() { 
/// <value type="Function" mayBeNull="true">The service default failed callback.</value>
return PageMethods._staticInstance.get_defaultFailedCallback(); }
PageMethods.set_path("/SelectAccount2.aspx");
PageMethods.GetAccounts= function(sortExpression,filter,onSuccess,onFailed,userContext) {
/// <param name="sortExpression" type="String">System.String</param>
/// <param name="filter" type="String">System.String</param>
/// <param name="succeededCallback" type="Function" optional="true" mayBeNull="true"></param>
/// <param name="failedCallback" type="Function" optional="true" mayBeNull="true"></param>
/// <param name="userContext" optional="true" mayBeNull="true"></param>
PageMethods._staticInstance.GetAccounts(sortExpression,filter,onSuccess,onFailed,userContext); }
PageMethods.SelectAccount= function(accountNumber,onSuccess,onFailed,userContext) {
/// <param name="accountNumber" type="String">System.String</param>
/// <param name="succeededCallback" type="Function" optional="true" mayBeNull="true"></param>
/// <param name="failedCallback" type="Function" optional="true" mayBeNull="true"></param>
/// <param name="userContext" optional="true" mayBeNull="true"></param>
PageMethods._staticInstance.SelectAccount(accountNumber,onSuccess,onFailed,userContext); }
 
Upvote 0
Sorry, I don't see much HTML there. Maybe use IE Developer Tools or Firebug to trace the calls.
 
Upvote 0
Scott

Which link do you actually want to click?
 
Upvote 0
Just had a look at one of the fragments of HTML that you posted earlier.

I noticed that in the table that lists the accounts each row has a click event associated with it via the ******* property.

That click event calls a _doPostback function with 2 parameters.

The first parameter is the id for the table listing the accounts - 'ctl00_MainContent_AccountsGrid'.

The other parameter is 'Select$<X>' where X is some sort of id or something that identifies the row/account.

That's actually sort of irrelavant because to trigger those events from code we don't actually need to know them.

What we do need to know/get is a reference to the correct click event.

Let's say we've already automate IE to the point where you've navigated to the page with the title 'EnergyDirect.com :: Select Account'.

That's the page with the table I mentioned above, the table looks something like this - which I salvaged from one of your earlier posts.

<TABLE style="BORDER-BOTTOM: gainsboro 1px solid; BORDER-LEFT: gainsboro 1px solid; WIDTH: 100%; BORDER-COLLAPSE: collapse; BORDER-TOP: gainsboro 1px solid; BORDER-RIGHT: gainsboro 1px solid" id=ctl00_MainContent_AccountsGrid border=0 cellSpacing=0><TBODY><TR style="COLOR: gray" class=chartHeader><TH style="WIDTH: 25%" scope=col align=left>CSS Account Number</TH><TH style="WIDTH: 25%" scope=col align=left>Meter ID</TH><TH style="WIDTH: 50%" scope=col align=left>Name</TH></TR><TR class=chartEvenRow ***********="" *******="__doPostBack('ctl00$MainContent$AccountsGrid','Select$0')"><TD style="WIDTH: 25%">1527485017</TD><TD style="WIDTH: 25%">7975101</TD><TD style="WIDTH: 50%">3Restraunts Llc</TD></TR><TR class=chartOddRow ***********="" *******="__doPostBack('ctl00$MainContent$AccountsGrid','Select$1')"><TD style="WIDTH: 25%">3419710010</TD><TD style="WIDTH: 25%">23354341</TD><TD style="WIDTH: 50%">Glendale </TD></TR><TR class=chartEvenRow ***********="" *******="__doPostBack('ctl00$MainContent$AccountsGrid','Select$2')"><TD style="WIDTH: 25%">4455216032</TD><TD style="WIDTH: 25%">85114354</TD><TD style="WIDTH: 50%">733G</TD></TR><TR class=chartOddRow ***********="" *******="__doPostBack('ctl00$MainContent$AccountsGrid','Select$3')"><TD style="WIDTH: 25%">4931324028</TD><TD style="WIDTH: 25%">83067463</TD><TD style="WIDTH: 50%">733G</TD></TR><TR class=chartEvenRow ***********="" *******="__doPostBack('ctl00$MainContent$AccountsGrid','Select$1060')"><TD style="WIDTH: 25%">7814007001</TD><TD style="WIDTH: 25%">19441510</TD><TD style="WIDTH: 50%">Feed Seed</TD></TR></TBODY></TABLE>

So we've got to this stage and have a reference to the page, doc.
Rich (BB code):
Rich (BB code):
Rich (BB code):
Rich (BB code):
Rich (BB code):
Rich (BB code):
Set doc = IE.Document

Now we get a reference to the table and to the rows collection of that table.
Rich (BB code):
Rich (BB code):
Set tbl = doc.GetElementByID("ctl00_MainContent_AccountsGrid")
 
Set rws = tbl.GetElementsByTagName("TR")

Now we can loop through the rows and fire the click event
Rich (BB code):
For Each rw In rws
 
        rw.click
Next rw

So if we pull all that code together we get this.
Rich (BB code):
Rich (BB code):
Option Explicit
 
Sub test()
Dim IE As Object
Dim doc As Object
Dim tbl As Object
Dim rws As Object
Dim rw As Object
Dim strBaseURL As String
Dim strFileURL As String
 
    strBaseURL = "C:\apache\Whose2Know\"
 
    strFileURL = "PageCode.html"
 
    Set IE = CreateObject("InternetExplorer.Application")
 
    IE.navigate strBaseURL & strFileURL
 
    Set doc = IE.Document
 
    Set tbl = doc.getElementById("ctl00_MainContent_AccountsGrid")
 
    Set rws = tbl.getElementsByTagName("TR")
 
    For Each rw In rws
 
        ' check row is actually row of data and not header
 
        If rw.className Like "*Row*" Then

            MsgBox rw.outerText

            rw.Click

        End If

    Next rw
 
    IE.Quit
 
End Sub
The above code works for me but obviously various things don't happen, for example the click event does nothing because the function it's calling isn't on the page.

The function being called is stored in an asp/x file somewhere on the server - if you look through the source you'll see plenty of references to the files but not the actual code.

This is what I've kind of been trying to emphasis all along.:)

Anyway you can try what I posted and perhaps it'll give you some ideas.

By the way I ran the code on a copy of the page stored locally, I suggest you try that too before trying it in real life/time.:)
 
Upvote 0
Norrie, A million thanks. Your posts are very thorough and clear...even for those like me who sometimes fumble with how to explain the problem.

The website code changed from several weeks ago, so what you helped me with then stopped functioning (I could no longer put the select$# into the EVENTARGUMENT value to get the click I wanted).

With your help, I've managed to get it back working again. I don't need to click on every row (only about 250 of 1100), so this does the trick nicely of checking each row and then clicking if it is the next in the list based on a variable. I've posted the code below that works now.

Code:
Sub Capture()

Sheets("Master").Select

Let fromcounter = Range("A2")
Let tocounter = Range("B2")

With CreateObject("InternetExplorer.Application")

For Counter = fromcounter To tocounter
Let SelectNum = Range("A" & Counter)
Let AcctNum = Range("B" & Counter)
Let MeterID = Range("C" & Counter)
Let AcctName = Range("D" & Counter)
Let RowNum = Range("E" & Counter)
Let Secure LO = Range("A5")
Let BillingDetail = "N"
Let EnergyInformation = "N"
Let DemandInformation = "N"
Let Acct2Pull = Range("F" & Counter)

        .Visible = True
        .navigate SecureLO
        Do Until .readyState = 4
            DoEvents
        Loop
        Do While .Busy: DoEvents: Loop
        
Set rws = vGet.GetElementsByTagName("TR")
For Each rw In rws
    Let vMat = rw.innerText
    If vMat = Acct2Pull Then '<--- checks to see if this is the next row to click
        rw.Click
        Exit For
    End If
Next rw

...REST OF CODE NOW THAT PROPER ROW HAS BEEN CLICKED ON

There's about 100 lines of code that follow, plus additional subroutines (including your table capture subroutine), so I saved mrexcel bytes by not posting that code above since they were not relevent to the issue.
 
Upvote 0

Forum statistics

Threads
1,215,020
Messages
6,122,709
Members
449,093
Latest member
Mnur

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top