function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Dakin_LabDakin_Lab 

Counting the number of Events, then populating field on custom object

Hello,

This is my first post. I have a custom object, and I need to count the number of events attached to the custom object and update the event count on the custom object. Is this possible using an s-control? I have limited programming experience, but can understand code. I appreciate your help in advance.

Gareth DaviesGareth Davies

Yes this is possible.

I would reccomend using the AJAX library from SFDC.


It will require that you can program in Javascript. You will need to perform a query looking for tasks and/or events with the "whatID" set to the "ID" of your custom object. Then count the results. If you are not yet a programmer this might be an opportunity to get into some code.


If you want to, please feel free to download the (free) Developer's Side Kick and have a look on the Schema Explorer - this will help you to see what fields relate the Task to your custom object (It'll probably be the WhatID). You can test this using the Datascope if you like, there is a free 14 day trial for that.


Good luck

Gareth.

Dakin_LabDakin_Lab
Below is my code so far...I am pretty bad at coding, as you probably can tell. But am unable to return any results below. I think the first step of the above mentioned process is to query the data, and at least be able to read the dynabean.

If I can get the right records in the dynabean, then do a dynabean.length(array) I can write the contents of an array to a custom field on the test object record. Am I completely off-base?



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>

<head>

<script language="javascript" src="https://www.salesforce.com/services/lib/ajax/beta3.3/sforceclient.js" type="text/javascript"></script>

<script>

<!--

function initPage() {

sforceClient.registerInitCallback(setup);

sforceClient.init("{!API_Session_ID}", "{!API_Partner_Server_URL_70}", true);

}

//Use this function as the entry point for your DHTML and JAVASCRIPT processing

function setup() {

var queryResult = sforceClient.query("Select Id FROM Event WHERE WhatId = '!Test_Object__c_Id', layoutResults);

}

function layoutResults(queryResult) {

if (queryResult.className == "Fault") {

alert("There was an error: " + queryResult.toString());

} else {

if (queryResult.size > 0) {

var output = "";

for (var i=0;i<queryResult.records.length;i++) {

var dynaBean = queryResult.records[i];

output += dynaBean.get("Id") + " " <br>";

}

var textNode = document.createTextNode(output);

document.getElementById("output").innerHTML = output;

} else {

var textNode = document.createTextNode("No records matched.");

}

}

}

//-->

</script>

</head>

<body onload="initPage()">

<div id="output"></div>

</body>

</html>
SteveBowerSteveBower
I didn't run your code or try to debug it, I just sucked it into Eclipse, eyeballed it, and started writing comments.  So, it's not debugged, etc. But perhaps this will help you get in the right direction and show a light at the end of the tunnel.  You were on the right track.  Good luck, Steve.
Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<script language="javascript" src="https://www.salesforce.com/services/lib/ajax/beta3.3/sforceclient.js" type="text/javascript"></script>
<script>

<!--
function initPage() 
{
 sforceClient.registerInitCallback(setup);
 sforceClient.init("{!API_Session_ID}", "{!API_Partner_Server_URL_70}", true);
}

//Use this function as the entry point for your DHTML and JAVASCRIPT processing
function setup() {

// Note that you don't *have* to use the callback mechanism to do the flow through your
// code.  In this case, I'd just put it all in setup().


 // If you are calling this s-control from a custom link set up on your custom
 // object (which is what I would expect), then the ID of the current custom
 // object is substituted into the s-control whereever "{!Label_ID}" appears.
 // (Where Label is the label you gave your object when you created it.)
 // In the case of your custom object called "Test Object", then it would be
 // "{!Test_Object_ID}".
 // (If you're not sure what to use, go to Setup->Build->Custom S-Control and
 // try to create a New one (just for a moment), then use the pulldown lists
 // at the top to show you the possible substitution values.
 var queryResult = sforceClient.query(
  "Select Id FROM Event WHERE WhatId = '{!Test_Object_Id}');
 // Is use their utility to get the type instead of just using classname. YMMV.
 if (Sforce.util.dltypeof(queryResult) == "Fault") {
  alert("There was an error: " + queryResult.toString());
 // I'm not adding it here, but you could also do testing to see if 
 // (Sforce.util.dltypeof(queryResult) != "QueryResult"), and
 // you could throw the whole thing into a Try/Catch block.
 
 } else {
 
 // Big digression.  By default, sforceClient.Batchsize is 200 (I believe)
 // If you think you will have more events than that, you could issue a
 // sforceClient.setBatchSize(2000);
 // I think 2000 is the largest they allow in one call.
 // If you think you have more than that, (then I'd argue that your application 
 // is poorly designed :-) ), you will have to investigate the queryMore
 // structure which allows you to go back and get more records than fit in
 // the first query.  There are samples on the boards if you search for
 // querymore.
 
 // The code below seems fine (I'm not running this, just looking at it
 // all by eyesight) to throw your results onto the screen.
  if (queryResult.size > 0) {
   var output = "";
   for (var i=0;i<queryResult.records.length;i++) {
    var dynaBean = queryResult.records[i];
    output += dynaBean.get("Id") + " " <br>";
   }
   var textNode = document.createTextNode(output);
   document.getElementById("output").innerHTML = output;
  } else {
   var textNode = document.createTextNode("No records matched.");
   // Note you're not doing anything with this text element.
  }
  
  // However, I was under the impression that you wanted to store the
  // record count back into some field in the custom object.
  // Presuming that you have a field called "Event Count", then you would
  // also have a current value for that field already loaded into
  // "{!Test_Object_Event_Count}".  So, rather than always do an update
  // of the current record, you might want to see if the value already stored
  // matches the current value, and only do the update if it's different.

  var nRec = queryResult.records.length;  // save typing.
  if ("{!Test_Object_Event_Count}" != nRec) {
   try {
    // Retrieve only fetches the ID's you ask for.  Faster than Query.
    var q = sforceClient.Retrieve("Id,Event_Count__c","Test_Object__c","{!Test_Object_Id}");
    rec = q[0]; 
    if (Sforce.Util.dltypeof(rec) != "Dynabean" ) {
     alert("Error retrieving Test Object information.\n" + rec);
    }
   } catch(e) {
    alert("Unable to retrieve and set values for Test Object record.\n" + e);
   }
   // Now set it.
   rec.set("Event_Count__c",nRec);
   rec.save();  // you could do this with sforceClient.Update if you prefer
   // and you should add error catching, etc. 
  }
 }
}

//-->
</script>
</head>
<body onload="initPage()">
<div id="output">
</div>
</body>
</html>

 

joe-kizayjoe-kizay

Just quickly looking at it I notice that you are missing the "{}" around !Test_Object__c_Id in the query.

 

wkuehlerwkuehler
One thing to keep in mind:  How is this code going to be executed?  Is there a way to call an scontrol everytime an activity is added?  If not you will have to run the code manually.

-wkuehler