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
Eager-2-LearnEager-2-Learn 

Finding Opportunity Data even if the field has duplicates

Hi,

 

I have this process that uses a Map.  The key is a field that contains a value that comes from a legacy system.  This is kind of like a key, but not really.  What I mean 99% of the time for a year range of data it is unique but there are one-off situations that require two opportunities for the same company with the same key(remember kind of) data.

 

Up until this little know one-off situation the Map was working perfect; however, because Maps do not allow duplicates on the key I am dropping the duplicate from the process.  To give a more detailed understanding:

 

I get a map of all opportunities for a given date range which is the last year of opporutnities.  I have another object that has these possible matching keys which the process loops over and does a get on the Opp Map.  If I find a match I write the looped data record to an opportunity related object--easy enough and it works great.

 

The problem now are these few duplicates opportunities that are not getting the same record written to its related list.  So my question is this...

 

How can I keep governor limits low (this was why I went with the map approach to begin with) and read each import record (from legacy system), find the matching opportunity so that I can write the import data to the opportunity related object and if not found I would write the import data to an error object?

 

I know I cannot put a select inside of an outer loop because I would quickly hit limits and  a LIST allows duplicates but I don't think it has a quick search method like the map and if it even does--how would I know that I found the first one and search again excluding the first search.  That would seem like double searching for each opportunity!  I am at a loss!  Please help!

 

Best Answer chosen by Admin (Salesforce Developers) 
JohnSchultzJohnSchultz

You are correct that you aren't able to have duplicate keys. The best you can do is store a list of opportunities under a single key.

 

For example, let's use the field OwnerId, since it is not unique.

// code for creating the map where a key could relate to more than one opportunity:

Map<Id, List<Opportunity>> ownerOppMap = new Map<Id, List<Opportunity>>();

for (Opportunity o : [select Id, Name, OwnerId from Opportunity]) {
	if (!ownerOppMap.containsKey(o.OwnerId)) {
		ownerOppMap.put(o.OwnerId, new List<Opportunity>());
	}
	
	ownerOppMap.get(o.OwnerId).add(o);
}

// later when trying to access an opportunity:
Id specificOwnerId = '1234567890';
List<Opportunity> opps = ownerOppMap.get(specificOwnerId);

if (opps.size() == 1) {
	// do whatever you needed to do with the opportunity. for example:
	System.debug(opps[0]);
	
} else if (opps.size() > 1) {
	// since you have more than 1 opportunity, you need to loop through the opps
	// using some other value to get the one you want. for example:
	for (Opportunity o : opps) {
		if (o.Name == 'some name') {
			System.debug(o);
		}
	}
}

 The point is that no matter what solution you use, you'll always need a second identifier to narrow down which opportunity you actually want since the actual not-so-unique identifier is, well, not so unique.

All Answers

JohnSchultzJohnSchultz

I'm assuming you have your map defined something like: Map<String, Opportunity>.

 

Could you define it like Map<String, List<Opportunity>>?

 

Then you could store the opportunity record in the list in the map. That would allow you to have two (or more) opportunities under the same key. That would, of course, require you to process the map a little differently, both for adding values to it and for getting values out of it, but it may suit your needs without involving the altering of your SOQL queries.

Eager-2-LearnEager-2-Learn

Hi John,

 

Can you elaborate on your approach?  How would I use this approach in gathering a range of opportunities for example.  Then get the map to return the specific opportunity based on using the map's get method..  Remember this also has to allow for the key to be duplicated.  For example a custom field named MyLegacy may have a value  of 'abc' on two opportunities.  how will the map hold the key of both opportunities when I thought maps do not duplicate keys.

 

Thanks for your help in advance.

JohnSchultzJohnSchultz

You are correct that you aren't able to have duplicate keys. The best you can do is store a list of opportunities under a single key.

 

For example, let's use the field OwnerId, since it is not unique.

// code for creating the map where a key could relate to more than one opportunity:

Map<Id, List<Opportunity>> ownerOppMap = new Map<Id, List<Opportunity>>();

for (Opportunity o : [select Id, Name, OwnerId from Opportunity]) {
	if (!ownerOppMap.containsKey(o.OwnerId)) {
		ownerOppMap.put(o.OwnerId, new List<Opportunity>());
	}
	
	ownerOppMap.get(o.OwnerId).add(o);
}

// later when trying to access an opportunity:
Id specificOwnerId = '1234567890';
List<Opportunity> opps = ownerOppMap.get(specificOwnerId);

if (opps.size() == 1) {
	// do whatever you needed to do with the opportunity. for example:
	System.debug(opps[0]);
	
} else if (opps.size() > 1) {
	// since you have more than 1 opportunity, you need to loop through the opps
	// using some other value to get the one you want. for example:
	for (Opportunity o : opps) {
		if (o.Name == 'some name') {
			System.debug(o);
		}
	}
}

 The point is that no matter what solution you use, you'll always need a second identifier to narrow down which opportunity you actually want since the actual not-so-unique identifier is, well, not so unique.

This was selected as the best answer
Eager-2-LearnEager-2-Learn

SWEET!!!

This makes total sense!!! I will mark it as an accepted answer now as I believe it will resolve my issue.

 

Thank you so much.  I did not know that you could do that like that.  Man you saved my day!!!