Strings are converted to ids automatically, so you shouldn't need to do anything special. Here's an example from my dev org:
public class IdTest {
public static void testIdAsString()
{
String idsStr='0018000000pGTrn;0018000000tzbJr;0018000000tzbJw';
List<Contact> conts=new List<Contact>();
for (String idStr : idsStr.split(';'))
{
Contact cont=new Contact(FirstName='Unit', LastName='Test', AccountId=idStr);
conts.add(cont);
}
insert conts;
System.debug('### Contacts = ' + conts);
}
}
note how the AccountId field is populated directly from the idStr string. The debug output for this is:
09:02:10.351 (351115000)|USER_DEBUG|[15]|DEBUG|### Contacts =
(Contact:{AccountId=0018000000pGTrnAAG, FirstName=Unit,
Id=0038000001NuTAlAAN, LastName=Test},
Contact:{AccountId=0018000000tzbJrAAI, FirstName=Unit,
Id=0038000001NuTAmAAN, LastName=Test},
Contact:{AccountId=0018000000tzbJwAAI, FirstName=Unit,
Id=0038000001NuTAnAAN, LastName=Test})
If you are seeing an error from your code, I would think its likely to be one of the following:
- The Subsidiaries_On_Contract__c field doesn't contain ids
- The Subsidiaries_On_Contract__c doesn't contain the right type of id
(e.g. I have to use account ids for my contacts - which have to start with 001. If I used
an opportunity id that would fail)
- You aren't parsing the Subsidiaries_On_Contract__c field correctly.
Looking at your code, I think #3 is the most likely if Subsidiaries_On_Contract__c is a multi-select picklist, as this will contain a semi-colon separated list of values. Comma separated and square bracket delimited usually means a list converted to a string to me (much like my debug statement above). If it isn't a multi-select picklist, I'd output some debug to show the value of each "id string" that you are iterating - as you have replaced the opening and closing square brackets with commas, it may be that you are getting empty values for the first and last elements when the string is split.
Based on your updates to your original post, you have the sub account names rather than ids, but you'll need to use the ids to populate the lookup field.
You should therefore retrieve all of the sub account ids based on the names, stores them in a map and use them when creating the records. Something like the following (which assumes that your sub accounts are still modelled as accounts) - its not great, as there's some repetition, but hopefully you get the picture:
trigger AutoCreateSubs on Contract_Overview__c (after insert, after update)
{
List<Subs_Serviced_On_Contract__c> subs = new List<Subs_Serviced_On_Contract__c>();
// get the full list of sub account names for all records being processed by the trigger
List<String> subAccNames=new List<String>();
for (Contract_Overview__c newCont : Trigger.New)
{
if (newCont.Subsidiaries_On_Contract__c != '[]')
{
// split out the multi-select picklist using a comma delimiter
System.debug('Subsidiaries_On_Contract__c ' + newCont.Subsidiaries_On_Contract__c);
String temp = newCont.Subsidiaries_On_Contract__c;
temp = temp.replace(']','');
temp = temp.replace('[','');
String[] all = temp.split(',');
subAccNames.addAll(all);
}
}
// get the ids for all sub accounts and store in a map keyed by name
Map<String, Id> subAccIdsByName=new Map<String, Id>();
for (SubsidiariesAndBrands__c subAcc : [select id, Name from SubsidiariesAndBrands__c where Name in :subAccNames)
{
subAccIdsByName.put(subAcc.Name, subAcc.id);
}
//For each position processed by the trigger, add a new
//Subs_Serviced_On_Contract record for the specified Subsidiaries_On_Contract__c.
//Note that Trigger.New is a list of all the new positions
//that are being created.
for (Contract_Overview__c newContract : Trigger.New)
{
if (newContract.Subsidiaries_On_Contract__c != '[]')
{
// split out the multi-select picklist using a comma delimiter
System.debug('Subsidiaries_On_Contract__c ' + newContract.Subsidiaries_On_Contract__c);
String temp = newContract.Subsidiaries_On_Contract__c;
temp = temp.replace(']','');
temp = temp.replace('[','');
String[] all = temp.split(',');
for(String subsoncontract: all)
{
subsoncontract = subsoncontract.normalizeSpace();
//for(String subsoncontract: newContract.Subsidiaries_On_Contract__c.split(',')){
SubsidiariesAndBrands__c sac = new SubsidiariesAndBrands__c(Name = subsoncontract);
Subs_Serviced_On_Contract__c ssoc = new Subs_Serviced_On_Contract__c(
Name = subsoncontract,
Contract_Overview__c = newContract.Id,
Account__c = newContract.Account__c,
Subsidiaries_and_Brands__c = subAccIdsByName.get(subsoncontract), // GET THE SUB ACCOUNT ID BASED ON NAME
Contract_and_Sub__c = newContract.Name + '~' + subsoncontract,
Contract_Start_Date__c = newContract.Contract_Start_Date__c,
Contract_End_Date__c = newContract.Contract_End_Date__c,
Logo_Usage_Allowed__c = 'Yes');
subs.add(ssoc);
}
}
}
upsert subs;
}
I see that the code where you find actual accounts is not returned in wrapper format
public pagereference Search()
{
String finalSearchValue = '%' + fullname + '%';
Accounts = [Select Id, Name, Active__c FROM Account
where Name like :finalSearchValue];
wraplist = new list<wrapData>();
for(Account a: Accounts)
{
wrapList.add(new wrapData(a));
}
return null;
}
Same way apply for filter method as well.
Best Answer
Id
toString
conversion (and the reverse) is handled automatically when you do an assignment. If you get an invalid ID error it means that theString
value is not a valid 15 or 18 character Salesforce identifier.What are the values in the picklists? If they're account names then you can't assign the name to a lookup field. If the picklist is a list of IDs it should work ok in code (in formulae you need to call the
TEXT()
funciton).I suspect you're either not using IDs in the picklist, or an ID is not being selected, in which case you need to assign null, or do no assignment, rather than assigning an empty string.