2

I have two objects: Object A has Sales Rep and Revenue. Object B has Sales Rep and Goals. I have queried both the objects separately, but now I have to map them on Sales Rep to display it in a single chart where against each Sales Rep, their Revenue and Goals will be plotted. I also want to plot ratio of Revenue / Goal. How can I do this in the controller code?? Please help..

3 Answers 3

4

You can use wrapper/inner class to achieve this. Use Sales Rep as the identifier.

For an intro go through this. http://wiki.developerforce.com/page/Wrapper_Class

Add this class in your controller.

public class SalesWrapper{  
    public string salesRep;  
    public Object1 obj1;  
    public Object2 obj2;  
}

Include necessary constructors, getters, setters etc...

Iterate over the two lists you get for both objects (SOQL) and then populate the list of SalesWrapper object. SalesRep unique identifier will be helpful in populating the wrapper list.

2
  • Yeah I figured that I would have to do something like that.. but can you give me an example? probably a sample code?
    – Robin
    Feb 9, 2014 at 11:26
  • Any particular reason for using string data type rather than type of Sales Rep? Same aplies for obj1/obj2 in regards to object types they should store (i.e. Revenue and Goals)?
    – dino ursic
    Feb 10, 2014 at 13:27
4

As zuke had already mentioned, you should use wrapper class to store data from both queries. However, in the wrapper class I'd go with the data types which fully describe the objects that they store.

In your case the class would look something like (note two constructors accepting different types of object as parameters):

public class SalesRepWrapper {
    public Sales_Rep__c salesRep { get; set; }
    public Revenue__c revenue { get; set; }
    public Goals__c goals { get; set; }

    public SalesRepWrapper(Object_A__c objA) {
        this.salesRep = objA.Sales_Rep__c;
        this.revenue = objA.Revenue__c;
    }

    public SalesRepWrapper(Object_B__c objB) {
        this.salesRep = objB.Sales_Rep__c;
        this.goals = objB.Goals__c;
    }
}


With your wrapper class defined, you could create a Map with salesRep's id as map key and SalesRepWrapper as map value. When iteratating over the collection of objects A and objects B, you should check whether an instance of SalesRepWrapper for the currently examined sales rep exists - if not, you should create a new instance of SalesRepWrapper and store it in the map; if it exists, you should only update the non-existant value (goals in iteration over objectA's; revenue in iteration over objectB's).

Let's assume your initial two queris are performed in the controller of your VF page:

public with sharing class YourVFPageController {

    public Map<Id, SalesRepWrapper> salesRepWrappersMap { get; set; }

    public YourVFPageController() {

        salesRepWrappersMap = new Map<Id, SalesRepWrapper>();

        List<Object_A__c> objAs = [SELECT Id, Name, Sales_Rep__c, Revenue__c FROM Object_A__c];
        List<Object_B__c> objBs = [SELECT Id, Name, Sales_Rep__c, Goals__c FROM Object_B__c];

        for(Object_A__c objA : objAs) {
            if (salesRepWrappersMap.containsKey(objA.Sales_Rep__c)) {
                salesRepWrappersMap.get(objA.Sales_Rep__c).revenue = objA.Revenue__c;
            } else {
                salesRepWrappersMap.put(objA.Sales_Rep__c, new SalesRepWrapper(objA));
            }
        }

        for(Object_B__c objB : objBs) {
            if (salesRepWrappersMap.containsKey(objB.Sales_Rep__c)) {
                salesRepWrappersMap.get(objB.Sales_Rep__c).goals = objB.Goals__c;
            } else {
                salesRepWrappersMap.put(objB.Sales_Rep__c, new SalesRepWrapper(objB));
            }
        }
    }

    public class SalesRepWrapper {
        // ...
        // As described above
        // ...
    }
}


Then, wherever you require only the list of SalesRepWrapper, you can access it by invoking salesRepWrappersMap.values().

0

If Sales_Rep__c is a parent relationship (either lookup or master detail) for both objects you could do everything with a single query instead of worrying about maps and inner classes.

Your query would look like the following, again assuming that Sales Rep is a parent object of both Goals and Revenue.

List<Sales_Rep__c> salesReps = [Select (Select Id From Goals__r),(Select Id From Revenue__r) From Sales_Rep__c Where ...];

From this you could iterate over both Goals and Revenue from the same Sales_Rep__c record like below:

for(Sales_Rep__c current : salesReps){
    for(Goal__c : goal){

    }

    for(Revenue__c : revenue){

    }
}

If your data model isn't defined this way, then the Map and wrapper approach is the way to go.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .