Pages

Tuesday, May 30, 2017

Salesforce: List View Sharing

As per API 39.0, looking at ListView object, we can't retrieve who can access a list view with a simple SOQL query. But, looking at this metadata API documentation, we can retrieve who can access a list view using sharedTo field. We can use a SOQL query for this, as this is metadata API.

Here is the step by step to retrieve that info, you will need to use Workbench.
Let's say we would like to check who can access a list view called "Account start A".

1. Get the "fullName"
From Workbench:
- select Info | Metadata Types & Components
- select Listview from the dropdown
- Click Expand all and find the view name
- if the view is "Visible only to me", you will not find it here


2. Prepare XML file
Copy following XML and save it to a file called "package.xml"
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Account.Account_start_A</members>
        <name>ListView</name>
    </types>
    <version>39.0</version>
</Package>

3. Retrieve Package
Open workbench again:
- select migration | Retrieve
- select the XML file prepared in step 2
- tick "Single Package"
- Click the Next button
- Click Retrieve button
- when done click the Download ZIP File link
- extract the zip file
- look for the object folder
- in my case, this is Account object, so open the "Account.object" file with any text editor
- here is the result, you will easily see who has access to the view

<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
    <listViews>
        <fullName>Account_start_A</fullName>
        <columns>ACCOUNT.NAME</columns>
        <columns>ACCOUNT.SITE</columns>
        <columns>ACCOUNT.ADDRESS1_STATE</columns>
        <columns>ACCOUNT.PHONE1</columns>
        <columns>ACCOUNT.TYPE</columns>
        <columns>CORE.USERS.ALIAS</columns>
        <filterScope>Everything</filterScope>
        <filters>
            <field>ACCOUNT.NAME</field>
            <operation>startsWith</operation>
            <value>A</value>
        </filters>
        <label>Account start A</label>
        <language>en_US</language>
        <sharedTo>
            <group>Coba_Group</group>
            <role>CEO</role>
            <role>CFO</role>
            <role>COO</role>
        </sharedTo>
    </listViews>
</CustomObject>


Let's extend this to retrieve for many list views, modify the package XML file as below:

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Account.Account_start_A</members>
<members>Account.NewThisWeek</members>
<members>Account.RT_Ke2</members>
        <name>ListView</name>
    </types>
    <version>39.0</version>
</Package>

This is the sample result:
<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
    <listViews>
        <fullName>Account_start_A</fullName>
        <columns>ACCOUNT.NAME</columns>
        <columns>ACCOUNT.SITE</columns>
        <columns>ACCOUNT.ADDRESS1_STATE</columns>
        <columns>ACCOUNT.PHONE1</columns>
        <columns>ACCOUNT.TYPE</columns>
        <columns>CORE.USERS.ALIAS</columns>
        <filterScope>Everything</filterScope>
        <filters>
            <field>ACCOUNT.NAME</field>
            <operation>startsWith</operation>
            <value>A</value>
        </filters>
        <label>Account start A</label>
        <language>en_US</language>
        <sharedTo>
            <group>Coba_Group</group>
            <role>CEO</role>
            <role>CFO</role>
            <role>COO</role>
        </sharedTo>
    </listViews>
    <listViews>
        <fullName>NewThisWeek</fullName>
        <columns>ACCOUNT.NAME</columns>
        <columns>ACCOUNT.CREATED_DATE</columns>
        <columns>Record_Type_Name__c</columns>
        <filterScope>Everything</filterScope>
        <filters>
            <field>ACCOUNT.CREATED_DATE</field>
            <operation>equals</operation>
            <value>THIS_WEEK</value>
        </filters>
        <label>New This Week</label>
        <language>en_US</language>
    </listViews>
    <listViews>
        <fullName>RT_Ke2</fullName>
        <columns>ACCOUNT.NAME</columns>
        <columns>ACCOUNT.SITE</columns>
        <columns>ACCOUNT.ADDRESS1_STATE</columns>
        <columns>ACCOUNT.PHONE1</columns>
        <columns>ACCOUNT.TYPE</columns>
        <columns>CORE.USERS.ALIAS</columns>
        <filterScope>Everything</filterScope>
        <filters>
            <field>ACCOUNT.RECORDTYPE</field>
            <operation>equals</operation>
            <value>Account.AccRtKe2</value>
        </filters>
        <label>RT Ke 2 Manual</label>
        <language>en_US</language>
        <sharedTo>
            <group>All_Internal_User_Group</group>                               <roleAndSubordinates>ChannelSalesTeam</roleAndSubordinates>
        </sharedTo>
    </listViews>
</CustomObject>

From the XML returned:
- the 1st view "Account_start_A" is shared to 1 group and 3 roles
- the 2nd view "NewThisWeek" is visible to all users, therefore there is no sharedTo tag
- the 3rd view, "RT_Ke2" is shared to 1 group and 1 role with subordinates.

Let's randomly confirm if the return is correct:



Deploy change
So for this sample, you work on the Account.object, let's say you remove and add "group" or "role" from sharedTo. To deploy this back to Salesforce, you just need to zip the file back as the same structure as you originally downloaded the zip file.

Open Workbench, navigate to migration | Deploy, and select "Single Package".




Additional notes:
With REST explorer from Workbench, we can get data of list view, example:
- to get all list view in Account: /services/data/v39.0/sobjects/Account/listviews/

- to get list view data from a list view:
/services/data/v39.0/sobjects/Account/listviews/00B50000008DouiEAC/results

* 00B50000008DouiEAC is ListView ID


Last updated: 4-Mar-2019


Reference:
Metadata API Developer Guide - ListView
Force.com REST API Developer Guide - List Views




3 comments:

  1. Hello Johan,

    Downloaded the listview and updated the sharing settings. How do I deploy the changes using the workbench? What do I need to put in package.xml? Thanks for your help.

    Yogesh

    ReplyDelete
  2. can we access listView Metadata via Apex? i want access SharedTO field via Apex then check the access for logged in user? based on that i need to build list of lvNames, can i achieve my use case via APEX?

    ReplyDelete