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

Set of All Activities for use in Visualforce controller

I have a visualforce page where the user enters a start date and end date to return a table that returns aggregate results over various groupings.


The object that is at the core of my data set is Trade__c. I've been able to return most of my aggregates without too much work, but I've run across a major issue when trying to retrieve what we call "Contacted Reps". Contacted Reps are Contacts that have an Activity tied to them.Trade__c is related to Contact through a field named Contact__c.


I need to be able to create an aggregate result like this:


for(AggregateResult ar : [SELECT Count(Id) repCount, Account.Name branchName, AccountId branchId FROM Contact WHERE Account.ParentId =: firm AND Account.Territory__c =: territory AND Id IN : contactSet GROUP BY Account.Name, AccountId ORDER BY Account.Name, AccountId]){
Contacted objContacted = new Contacted((String)ar.get('branchName'),(Integer)ar.get('repCount'));



where contactSet is a list/set of all Contacts with an Activity. I've been creating this contactSet like this:



Set<Id> contactSet = new Set<Id>();
for (SObject cReps : [SELECT Id, (SELECT Id FROM Events WHERE ActivityDate >=: startDate AND ActivityDate <=: endDate AND Who.Type = 'Contact'), (SELECT Id FROM Tasks WHERE ActivityDate >=: startDate AND ActivityDate <=: endDate AND Who.Type = 'Contact') FROM Contact WHERE Active__c = True AND Account.RecordTypeId = '01230000000Q9p4AAC' AND Account.Parent.Broker_Number__c =:dist174]) {
	SObject[] cEvents = cReps.getSObjects('Events');
	SObject[] cTasks = cReps.getSObjects('Tasks');
	if(cEvents != null || cTasks != null) {


The issue is that this list will always create a 'Too Many Rows' failure in our environment (lots of contacts).


This could be avoided in some part by creating the list through:


for(Contact c : [SELECT Id FROM Contact WHERE Id IN (SELECT WhoId FROM Task WHERE ActivityDate >=: startDate AND ActivityDate <=: endDate AND Who.Type = 'Contact') OR Id IN (SELECT WhoId FROM Event WHERE ActivityDate >=: startDate AND ActivityDate <=: endDate AND Who.Type = 'Contact')]) {  


but Task and Event or not supported for semi join inner selects. Ultimately this wouldn't help all that much, considering my user could put a date range that could retrieve all Contacts.


With that said, is there a way for me to create this set at all?  I feel like I'm missing something very basic hear. I've seen 'batch apex' thrown around a lot, but all the examples I've seen are for making updates to existing data, not creating a list to be used in controllers.


Maybe I'm just thinking about this all wrong, but I can't help but think there's a workaround for this. Thanks for any help.