Apex共有で所有者と同じロールへレコードを共有する方法
Salesforceでは、組織の共有設定が「非公開」に設定されている場合、
同じロールに属するユーザが所有するレコードは参照できません。
(営業部ロールにAさんとBさんが属していた場合、Aさんが所有するレコードをBさんは参照できない)
一方で、「同じロールに属するユーザが所有するレコードは参照できるようにしたい
(営業部の誰かが所有するレコードは、営業部全員で参照できるようにしたい)」
という要望を頂くことは結構多いような気がします。
この要望は、↓の共有ルールを作成すれば実現できます。
所有者の所属:「営業部ロール」
共有先:「営業部ロール」
アクセス権:「参照のみ」
但し、この方法だと、このルールを適用するロールの数だけ共有ルールを作成しなければなりません。また、ロールの追加や変更の度に、共有ルールを追加・変更しなければなりません。
大規模な組織などで、ロールの数が多い場合や、ロールの追加・変更が多い場合は、
下記で紹介する方法で、トリガからApex共有を使って、自動的に対応するロールにレコードを共有すると良いでしょう。
トリガでApex共有を使って、レコード共有する方法
1. トリガを作成するオブジェクトに、Apex共有の理由を作成
理由表示ラベルと理由名を設定(どちらも任意の名称でOK)して、Apex共有の理由を作成します。
ここでは、
理由表示ラベル:所有者のロールへの共有
理由名:OwnerRoleSharingReason
と設定します。
2. トリガ作成
オブジェクトに所有者のロールへレコードを共有するトリガを作成します。
ここでは、Item__cというカスタムオブジェクトに作成する場合のソースコードを記載します。
Trigger ShareItemTrigger on Item__c (after insert, after update) {
// レコードIDリストの作成
// 所有者IDリストの作成
List<ID> recordIdList = new List<ID>();
List<ID> ownerIdList = new List<ID>();
for(Item__c item : Trigger.new){
recordIdList.add(item.Id);
ownerIdList.add(item.OwnerId);
}
// 共有レコード追加リストの作成の
// 共有先ユーザ/グループの設定のところで、
// 所有者IDに対応するグループIDを取得したいので、
// 「所有者ID-ロールID マップ」と
// 「ロールID-グループID マップ」を作成する
//
// 所有者ID-ロールID マップの作成
Map<Id, Id> ownerIdMap = new Map<Id, Id>();
for(User u : [Select Id, UserRoleId From User
Where Id = :ownerIdList]) {
ownerIdMap.put(u.Id, u.UserRoleId);
}
// ロールID-グループID マップの作成
Map<Id, Id> roleIdMap = new Map<Id, Id>();
for(Group grp :
[Select Id, RelatedId From Group
Where RelatedId = :ownerIdMap.values()
and Type = 'Role']) {
roleIdMap.put(grp.RelatedId, grp.Id);
}
// 共有レコード追加リストの作成
// (共有オブジェクトに追加するレコードを作成する)
List<Item__Share> addShareList
= new List<Item__Share>();
for(Item__c item : Trigger.new) {
Item__Share shareObj = new Item__Share();
// 共有レコードID
shareObj.ParentId = item.Id;
// 共有先ユーザ/グループ
// (所有者のロールに対応するグループIDを設定)
shareObj.UserOrGroupId =
roleIdMap.get(ownerIdMap.get(item.OwnerId));
// アクセス権限
// 参照のみ : read
// 参照・更新 : edit
shareObj.AccessLevel = 'read';
// 共有の理由
shareObj.RowCause =
Schema.Item__Share.RowCause.OwnerRoleSharingReason__c;
addShareList.add(shareObj);
}
// 共有レコード削除リストの作成
List<Item__Share> delShareList =
[Select Id From Item__Share
Where ParentId = :recordIdList
and RowCause =
:Schema.Item__Share.RowCause.OwnerRoleSharingReason__c];
try {
// 共有の理由が「所有者のロールへの共有」である
// 共有レコードを削除してから、追加する
delete delShareList;
insert addShareList;
}
catch(System.DmlException e) {
}
}
トリガ作成後に、レコードを追加・更新すると、所有者のロールにレコードが共有されるようになります。
レコードの詳細画面で「共有」を押下すると、↓のように、所有者のロールへ共有されていることが分かります。

の
コメント