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
LearnSFDCLearnSFDC 

To get Users belonging to a praticular public Group

Hi,

 

    I seem to be missing something here.I am looking at the API for the group object and there is no method to get the Users belonging to that public group.Could anybody please let me know how to go about it.

 

 

Best Answer chosen by Admin (Salesforce Developers) 
bob_buzzardbob_buzzard

This isn't quite as straightforward as it sounds, as groups can contain other groups.

 

Here's an example that recursively extracts all users from the group and subgroups.  It will blow governor limits if the nesting goes too deep:

 

 

    public static Set<id> GetUserIdsFromGroup(Id groupId)
    {
        // store the results in a set so we don't get duplicates
        Set<Id> result=new Set<Id>();
        String userType = Schema.SObjectType.User.getKeyPrefix();
        String groupType = Schema.SObjectType.Group.getKeyPrefix();
        
        // Loop through all group members in a group
        for (GroupMember m : [Select Id, UserOrGroupId From GroupMember Where GroupId = :groupId])
        {
            // If the user or group id is a user
            if (((String)m.UserOrGroupId).startsWith(userType))
            {
                result.add(m.UserOrGroupId);
            }
            // If the user or group id is a group
            // Note: there may be a problem with governor limits if this is called too many times
            else if (((String)m.UserOrGroupId).startsWith(groupType))
            {
                // Call this function again but pass in the group found within this group
                result.addAll(GetUSerIdsFromGroup(m.UserOrGroupId));
            }
        }
        
        return result;  
    }
    

 

 

All Answers

bob_buzzardbob_buzzard

This isn't quite as straightforward as it sounds, as groups can contain other groups.

 

Here's an example that recursively extracts all users from the group and subgroups.  It will blow governor limits if the nesting goes too deep:

 

 

    public static Set<id> GetUserIdsFromGroup(Id groupId)
    {
        // store the results in a set so we don't get duplicates
        Set<Id> result=new Set<Id>();
        String userType = Schema.SObjectType.User.getKeyPrefix();
        String groupType = Schema.SObjectType.Group.getKeyPrefix();
        
        // Loop through all group members in a group
        for (GroupMember m : [Select Id, UserOrGroupId From GroupMember Where GroupId = :groupId])
        {
            // If the user or group id is a user
            if (((String)m.UserOrGroupId).startsWith(userType))
            {
                result.add(m.UserOrGroupId);
            }
            // If the user or group id is a group
            // Note: there may be a problem with governor limits if this is called too many times
            else if (((String)m.UserOrGroupId).startsWith(groupType))
            {
                // Call this function again but pass in the group found within this group
                result.addAll(GetUSerIdsFromGroup(m.UserOrGroupId));
            }
        }
        
        return result;  
    }
    

 

 

This was selected as the best answer
Pradeep_NavatarPradeep_Navatar

Try out the trigger code given below for creating a group and assigned user to them :


trigger sec_CreateGrp on User (after insert)
{
        try
        {            
            ID GrpId;
            String strGrpName;
            Integer sz = Trigger.new.size();
            for(integer i=0; i< sz;  i++ )
            {
            User usr = Trigger.new[i];
            Id prflId = usr.ProfileId;
            Id conId = usr.ContactId;
            Profile[] prfNm = [select Name from Profile where Id =: prflId];
            //system.debug('XXX   KKK   ' + prfNm[0].Name );
            if(prfNm[0].Name == 'Partner Staff')
            {
                Contact[] con = [select AccountId from contact where Id =: conId];
                strGrpName = 'Z_' + con[0].AccountId;
                Group[] grpRec = [Select g.Name, g.Id, g.Email From Group g where g.Name =: strGrpName limit 1];
                if(grpRec.size() == 0)
                {
                        Group grp= new Group();
                        grp.Name = strGrpName;                    
                        insert grp;
                        GrpId = grp.Id;
                }
                else
                {
                        GrpId = grpRec[0].Id;                   
                }  
                GroupMember grpMr = new GroupMember();
                grpMr.UserOrGroupId = usr.Id;
                grpMr.GroupId = GrpId;
                insert grpMr;  
            }
            }
        }
        catch (Exception e) {system.debug('Exeption ->  ' + e );}
}

 

Hope this helps.

LearnSFDCLearnSFDC

Thank you bob and Pradeep for the replies. My requirement was not so complex as all the members of the group were users and i wanted to fetch one of the user's belonging to that group.Bob's post gave me the solution i was looking for.I ended up with a simple query as below

 

Id userId=[Select g.UserOrGroupId From GroupMember g where g.Group.name = 'xyz' limit 1].UserOrGroupId

Matt ParlaneMatt Parlane
Hi all...

Just in case anyone stumbles on this page in future, I believe I've improved on @bob_buzzard's version:
 
public static Set<Id> getUsersFromGroupIds(Set<Id> groupIds) {
	String userType = Schema.SObjectType.User.getKeyPrefix();
	String groupType = Schema.SObjectType.Group.getKeyPrefix();
	Set<Id> userIds = new Set<Id>();
	Set<Id> innerGroupIds = new Set<Id>();
	for (GroupMember m : [Select UserOrGroupId From GroupMember Where GroupId In :groupIds]) {
		if (((String)m.UserOrGroupId).startsWith(userType))
			userIds.add(m.UserOrGroupId);
		else
			innerGroupIds.add(m.UserOrGroupId);
	}
	if (innerGroupIds.size() > 0)
		userIds.addAll(getUsersFromGroupIds(innerGroupIds));
	return userIds;
}

// A helper if you just want users from one group.
public static Set<Id> getUsersFromGroupIds(Id groupId) {
	return getUsersFromGroupIds(new Set<Id>{groupId});
}

System.debug(getUsersFromGroupIds('00G...'));

Basically, @bob_buzzard's version will result in a query for every group within the group, whereas the above version will only result in one query per nesting level.

Thanks to @bob_buzzard for breaking the back of it, and hope it helps someone!

Matt
Charles Onwuka 5Charles Onwuka 5
Hi Matt,

I can't seem to get the above (or Bob's original) to work. I keep getting this error: 
Error: Compile Error: Unexpected token 'Set'. at line 1 column 15

Any ideas?
Matt ParlaneMatt Parlane
Hi Charles... Very strange, almost 1 year to the day since my last reply.  :)

The code I (and Bob) posted is just a method, it needs to be part of a class. The class can be anything you want, I personally have the method in a class called Utils.

So the whole thing would go like this:

public class Utils {
    public static Set<Id> getUsersFromGroupIds(Set<Id> groupIds) {
        <rest of method>
    }
}

Hope that helps!