Pages

Sunday, June 2, 2013

Salesforce: Hyperlink in Excel file

Out-of-the-box, a lookup field in Salesforce report is click-able, such as: you can click Account Name in Opportunity report, it will bring user to Account page layout.

But, when the report export into Excel file, the link is gone. Can we make the link stay? Yes, here we go:

1. Create a Formula Field
  • Set the formula field return type = Text
  • Formula field: HYPERLINK("https://xxx.salesforce.com/"& Id , "Click me", "_self") - change xxx with your Salesforce instance, e.g.: ap1, na1, na6, etc
  • Do not need to show this formula field in any page layout
  • Make the field visible only to profile needed.

2. Add Formula Field into Report

3. Printable View
Instead of using 'Export Details' button, advise user to use 'Printable View' button. User can delete the header and footer is not needed in Ms Excel.

This may be not the best solution, but it works with simplest effort.

Salesforce report:


Microsoft Excel:



Salesforce: Using Permission Set to Query User Permission

Permission Set is a powerful feature in Salesforce. If you are using Enterprise and Unlimited editions (including Developer edition). Using the permission set, the admin can assign additional permissions to users on top of the permission given in the Profile assigned to that user. Permission Set is set per user basis and is only to ADD more permissions, not to reduce it from Profile. Permission Set also may be given to admin users when the permission cannot be enabled in the standard System Administrator profile.

Permission Sets include settings for:
- Assigned Apps
- Assigned Connected Apps
- Object Settings, which include objects, fields, and tab availability
- App Permissions
- Apex Class Access
- Visualforce Page Access
- External Data Source Access
- Named Credential Access
- Data Category Visibility
- Custom Permissions
- System Permissions
- Service Providers

In this blog, I am not going to explain how to set up the Permission Set; you can find the overview here.

As of now, we still cannot run a report on the Permission Set and Users assignment to Permission Set. But, since the Summer '11 release (API version 22), Salesforce has introduced 2 new objects related to this: PermissionSet and PermissionSetAssignment. To make this object more powerful, in the Spring '12 release (API version 24), FieldPermissions and ObjectPermissions objects are introduced with ParentId, which points to PermissionSet.

Once you understand the architecture, you can answer all sorts of questions about your users and permission. Here is the diagram (right-click the image to see it in full size) :



Here are a few samples using SOQL to query permission set:

List all Permission Set
SELECT Id, Name FROM PermissionSet 
WHERE IsOwnedByProfile = False 
ORDER BY Name

List all Permission Set that grant extra Permission, such as Create Dashboard
SELECT Id, Label FROM PermissionSet 
WHERE IsOwnedByProfile = False AND PermissionsCreateCustomizeDashboards = True 
ORDER BY Name



List all Permission Set does not from Managed Package
SELECT Id, Name FROM PermissionSet 
WHERE IsOwnedByProfile = False AND NamespacePrefix = '' 
ORDER BY Name


List all Users with ViewAllData Permission
SELECT Id, AssigneeId, Assignee.Name, PermissionSet.Name, PermissionSet.IsOwnedByProfile
FROM PermissionSetAssignment
WHERE PermissionSet.PermissionsViewAllData = True
ORDER BY PermissionSet.IsOwnedByProfile DESC, Assignee.Name

This query will return all Users with Permission to View All Data, either acquired from the Profile or from the Permission Set.



Compare this with the query below, where it just returns the permission from Profile only.
SELECT Id, Name FROM User
WHERE ProfileId IN (SELECT Id FROM Profile
                    WHERE PermissionsViewAllData = True)
ORDER BY Name


List all Active Users without ViewAllData Permission
SELECT Id, Name FROM User 
WHERE Id NOT IN (SELECT AssigneeId FROM PermissionSetAssignment 
                 WHERE PermissionSet.PermissionsViewAllData =  
                 True) 
      AND IsActive = True
ORDER BY Name 

So instead of pulling all users and all users with specific permission, then doing a vlookup() in Excel, we can combine the query using anti-joint query NOT IN.
Id in the main query is the same ID as AssigneeId in the sub-query, which is User Id.


List all Active Users with Transfer Record Permission
SELECT Id, AssigneeId, Assignee.Name, Assignee.Profile.Name, PermissionSet.IsOwnedByProfile FROM PermissionSetAssignment
WHERE PermissionSet.PermissionsTransferAnyEntity = True AND Assignee.IsActive = True
ORDER BY PermissionSet.IsOwnedByProfile DESC, Assignee.Name



List all Users by specific Profile and return the Permission Set assigned to that user
SELECT p.Id, p.Assignee.Name, p.Assignee.Profile.Name, p.PermissionSet.Label FROM PermissionSetAssignment p
WHERE p.PermissionSet.IsOwnedByProfile = False AND p.Assignee.Profile.Name = 'Sales Reps'
ORDER BY p.PermissionSet.Label, p.Assignee.Name

This query will return all Users with Permission Set assigned to users with Profile = Sales Reps and the additional Permission Set name assigned.



List Profile and Permission Set have read access to the Account for a User
SELECT Assignee.Name, PermissionSet.isOwnedByProfile, PermissionSet.Profile.Name, PermissionSet.Label FROM PermissionSetAssignment
WHERE PermissionSetId IN 
    (SELECT ParentId FROM ObjectPermissions 
     WHERE SObjectType = 'Account' AND PermissionsRead = True)
    AND Assignee.Name = 'Johan Yu'
ORDER BY PermissionSet.Profile.Name, PermissionSet.Label

This query will return Permission Set (and Profile if exists) that gives the user read access to the Account object.


List Profile and Permission Set that give Edit access to a Field for a User
SELECT Id, IsActive, ExpirationDate, AssigneeId, Assignee.Name, Assignee.IsActive, PermissionSetId, PermissionSet.Name,  PermissionSet.IsOwnedByProfile, PermissionSet.Profile.Name FROM PermissionSetAssignment 
WHERE PermissionSetId IN 
       (SELECT ParentId FROM FieldPermissions
        WHERE Field='A__c.Support_Staff__c' 
        AND PermissionsEdit = True)
AND Assignee.Name = 'Maria Ann'


List Permission a User has for Account and which permissions give that access
SELECT Id, SObjectType, Parent.Label, Parent.IsOwnedByProfile, PermissionsRead, PermissionsCreate, PermissionsEdit, PermissionsDelete, PermissionsViewAllRecords, PermissionsModifyAllRecords
FROM ObjectPermissions
WHERE (ParentId IN (SELECT PermissionSetId FROM PermissionSetAssignment WHERE Assignee.Name = 'Johan Yu'))
AND (SobjectType = 'Account')
ORDER BY Parent.IsOwnedByProfile DESC, Parent.Label

This query will return user permission for an object and also tell all Permission Sets (and profiles if they exist) that give the user that permission.


Show Object Settings added to all Permission Set
SELECT SobjectType, Parent.Name, PermissionsRead, PermissionsCreate, PermissionsEdit, PermissionsDelete, PermissionsViewAllRecords, PermissionsModifyAllRecords FROM ObjectPermissions WHERE SObjectType IN ('Account') AND Parent.IsOwnedByProfile = false

This query will return only Permission Set with additional permissions on a specific object.


Get all Non-Chatter users with Lightning Experience permission enabled
SELECT Id, Assignee.Username, Assignee.Profile.Name FROM PermissionSetAssignment WHERE Permissionset.PermissionsLightningExperienceUser = True AND Assignee.Isactive = True AND (NOT Assignee.Profile.Name LIKE '%chatter%') ORDER BY Assignee.Username


Mass Assign Permission Sets to Users
Based on PermissionSetAssignment attributes, we can use Data Loader to mass assign (and mass delete) users with a specific Permission Set. All you need to provide is AssigneeId (which is User Id) and PermissionSetId. But, you cannot update the record in PermissionSetAssignment.



Reference:


Last update: 9 Jul 2024


Tuesday, May 28, 2013

Salesforce Sandbox Refresh


Available in: Enterprise, Unlimited, and Database.com Editions only

Permission to view sandbox: “View Setup and Configuration”
Permission to create, refresh, activate, and delete sandbox: “Modify All Data”

From Spring '13 release, newly created sandboxes have the default email deliverability setting System email only. The System email only setting is especially useful for controlling email sent from sandboxes so that testing and development work doesn't send test emails to your users.

From Summer '13 release, you can create sandbox Template to choose data included only for Full sandbox.

You can refresh Full Sandbox every 29 days.
You can refresh Developer & Configuration Only Sandbox once a day.

Sandbox Status:
  • Copying, the initial creation stage. When you create (or refresh) a sandbox, Salesforce copies the configuration and data you specify to the sandbox. A sandbox in the “Copying” stage is not yet ready for use. Copy time depends on the size of the data, and can take several hours.
  • Ready for use, Salesforce finished copying data to the sandbox, and you can log into the sandbox or run application tests on the sandbox.
  • Replacement Ready, this status indicates Salesforce has a copy of your object data and is ready for you to activate the sandbox so you can use it.
  • In use, sandbox already activated and in use.

Login to Salesforce sandbox, from https://test.salesforce.com by appending .sandbox_name to their Salesforce usernames. For example, if a username for a production organization is user1@acme.com, and the sandbox is named “test”, then the modified username to log into the sandbox is user1@acme.com.test.

Once refresh, sandbox organization ID will be changed and may appear in different instance, e.g. cs6, cs3, cs12, etc.

Refresh link will be visible in a sandbox when it is eligible for refreshing.

Activate link to activate a refreshed sandbox. Activating a refreshed sandbox replaces the existing sandbox with the refreshed version. This permanently deletes the existing version and all data in it.

Few important date and time related to sandbox refresh
- Requested: date and time when admin click Refresh link
- Finished : date and time when Salesforce finish copying data to new sandbox
- Activated: date and time when admin click Activate link, old sandbox will be delete
- Copied On: date and time when Salesforce provision newly refresh sandbox and ready to use

For more information on sandbox, see this documentation.



Sunday, May 19, 2013

Disable user login to Salesforce temporary


From Salesforce Community, from time to time, I see people asking questions for best-practice to disable user login to Salesforce temporary for major/change release in Salesforce within an organization.

Back to the real need, do we need to block user to login to Salesforce? YES and NO, depend on the changes, but if it is a YES.
Do we need to inactive user? a BIG NO. Why? Inactivate user will:
- Remove user from all delegated groups and sharing privileges
- Remove user from opportunity team of closed & open opportunity (optional)
- Remove user from account team (optional)
- Remove user from case team of predefined & ad-hoc (optional)
So, how to block user to login to Salesforce if not inactivated them?
Play with the User Profile. Here we go:

1. Create a dummy Profile
After profile created, scroll to 'Login Hours' related list and set Start Time and End Time to 12:00AM













2. Export user list and their profile id to CSV file
Use Data loader to export all Active User
Here is the SOQL:
Select u.Id, u.ProfileId from User u where u.isActive = True

3. Update Profile Id in CSV file with newly created dummy Profile Id
Save CSV file into new file name
Make sure your (admin) user id is not included

4. Mass update User Profile in Salesforce
Use Data loader to update it to User object using CSV file modified

5. Deploy your Salesforce major / change release

6. Update back User Profile Id in Salesforce using original CSV file 

When you do the changes, any user will not able to login to Salesforce. You will be able to track who is trying to login from Login History




But, before all downtime planned in action, you should communicate it with all of your users few days in advance.

Tuesday, May 14, 2013

Salesforce: Roll-Up Summary field for running number


Few days ago, when following Salesforce Community conversation, a member asked for running number in  Opportunity based on Account Number.

Using trigger, this is not an issue at all. A trigger in Opportunity on create and update will work perfectly. But, not every salesforce.com admin is familiar with apex code which usually do by a Salesforce.com developer.

Is is possible just using configuration, point and click without coding?
YES, here we go:

1. Create roll-up summary field in Account 
Filter Criteria = All records should be included in the calculation
You can hide this field from page layout.
It will hold number of opportunity for that Account.
Example: Number of Opportunities













2. Create a text field in Opportunity
This field will show the Account Number + running number.
Let's say Account Number = SF-0100, the first Opportunity will have Tracking Number = SF-0100-1, the second will be SF-0100-2 and etc.
Example: Tracking Number


3. Create a workflow in Opportunity
Just make sure, Evaluation Criteria = created and Rule Criteria = true







4. Create a field update in Opportunity
The formula would be:
Account.AccountNumber +'-'+ TEXT(Account.Number_of_Opportunities__c+1)







Drawback:
Issue will arise if any opportunity created earlier get deleted. Running number in opportunity will keep running, except the opportunity deleted is the last opportunity.

Tuesday, May 7, 2013

Salesforce validation rule or workflow, use 15 or 18 characters Id?

Each Salesforce Id will have unique 15 or 18 characters. What is the different?
15 characters for case sensitive and 18 characters for case insensitive.
You also can use build-in function from Salesforce to convert 15 to 18 characters Id using CASESAFEID(Id) function.
See sample below:
00180000010shNA --> 00180000010shNAAAY
00180000010shNa --> 00180000010shNaAAI

There are few website provide tool to convert from 15 to 18 characters, example:

In this blog, I would like to share on using Salesforce Id on validation rule and workflow.

1. Only 15 characters Id will work in Validation Rule or Workflow
Test on 15 and 18 characters of Salesforce Id in validation rule and Workflow. Validation rule and Workflow only work with 15 characters Id, NOT in 18 characters Id.

2. Suggest to use $Profile.Name instead of using $Profile.Id or $User.ProfileId









See 2 validation rules below, which one is better (make our life easier) ?
AND (
NOT($User.ProfileId="00e800000017ey7"), 
NOT($User.ProfileId="00e800000018hwW"), 
ISPICKVAL(PRIORVALUE(StageName), "6 Close - Lost") 
)

AND (
NOT($Profile.Name="Regional Sales Ops"), 
NOT($Profile.Name="Global Sales Ops"), 
ISPICKVAL(PRIORVALUE(StageName), "6 Close - Lost") 
)

3. Use = instead of == 
Both == and = is working, but SFDC suggest to use = ; It's good idea to make it standard to use only =
 

Page-level ad