We keep attendees list(Initials) under Event/Activity people who attended meetings. Now I want to create duplicate records for these attendees, so they would get credit for attending the meeting. So, I have started this code, but I am stuck where I am checking to see if UserId's initial matches Attendees' Initial. I could create two for loops but I think this is not efficient. Also, I am fetching all the active users and checking against Attendee's initial. FYI, We store initial under User page. Thank you in advance!

    public class cloneEvents {
@InvocableMethod(label='Clone Events' description='Clone Events')
    public static void getClonedInovakable(List<Id> activityId) {

        //fetch all fields related to activity id
        System.debug('Print the list' + activityId);
        List<Event> queryEvent = [
            SELECT Attendees__c,    Assigned_Initial__c  From Event WHERE id=:activityId

        //Fetch all users and their initials 
        Map <id,User> userMap = new map<id, User>([SELECT id, Initials__c FROM user WHERE IsActive = True]);

        //I am not sure how to check Attendees Initial inside userMap
        for(Event e:queryEvent){
            String[] tempString=  e.Attendees__c.split(';');
            for(String t:tempString){
                 system.debug('str: ' + userMap.contains(t));
        // Check if t is inside userMap and get their ID. Then create new Event records to this users. 
}//end of cloneEvents

List<Event> updateAllEvent = new List<Event>();
for(Event record: queryEvent) {
    for(String initial: record.Attendees__c.split(';')) {
        Id attendeeId = initialsToUserId.get(initial);
        if(attendeeId != null && record.OwnerId != attendeeId) {
         Event e = new Event();
         e.Subject = record.Subject;
         e.OwnerId = attendeeId;
         e.StartDateTime = record.StartDateTime;
         e.EndDateTime = record.EndDateTime;
         e.Description = record.Description;

         System.debug('updateALLEvent' + updateAllEvent);
  }// end of query

    Insert updateAllEvent;

You'll need a map to identify users quickly, and you'll want to start by gathering the Initials first, then getting the users. I call this the "Aggregate Query Update" programming pattern.

Event[] queryEvent = [
  SELECT Attendees__c FROM Event WHERE Id = :activityId AND Attendees__c != NULL];
Map<String, Id> initialToUserId = new Map<String, Id>();
Set<String> initials = new Set<String>();
for(Event record: queryEvent) {
for(User record: [SELECT Initials__c FROM User WHERE Initials__c = :initials AND IsActive = TRUE]) {
  initialsToUserId.put(record.Initials__c, record.Id);
for(Event record: queryEvent) {
    for(String initial: record.Attendees__c.split(';')) {
        Id attendeeId = initialsToUserId.get(initial);
        if(attendeeId != null) {
           // Do something for this user
  • Thank you so much. This will help immensely. Also, thank you for the site. I will bookmark it.
    – mike
    Feb 11 '20 at 20:07
  • @sfdcfox using soql in for loop is best practice or not?
    – Rahul
    Feb 11 '20 at 20:32
  • 1
    @Rahul There's often confusion about what the "do not SOQL in a loop" advice means. The syntax here is the SOQL For Loop, which is preferred when possible (better CPU time, less heap usage). The anti-pattern is when you put a query inside the loop (for(...) { doQuery(); }), which is definitely a no-no.
    – sfdcfox
    Feb 11 '20 at 20:35
  • fox, I tried inserting/creating record but it is not creating the record at all after Insert updateAllEvent. I see everything in the debug being printed fine. I have updated the code above.
    – mike
    Feb 11 '20 at 21:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.