Pages

Tuesday, May 30, 2017

Salesforce: List View SharedTo

As per API 39.0, looking at ListView object, we can't retrieve who can access a list view with 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 Next button
- click Retrieve button
- when done click Download ZIP File link
- extract the zip file
- look for object folder
- in my case, this is account object, so open "Account.object" file with any text editor
- here is the result, you will easily see who have 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:



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



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




Sunday, May 28, 2017

How to turn off Salesforce1?

Salesforce1 app is nice, it gives you access to your Salesforce data and application with no cost and lower effort to configure. But in some organization, it has to be off due to compliance guidelines or security protocols, administrators may be asked to prevent all User from accessing the Salesforce1 platform.



To completely eliminate your Users' ability to access the Salesforce1 interface, you will need to make the following changes:

1. Connected Apps
Navigate to Setup | Apps | Connected Apps | Manage Connected Apps, click Edit link on Salesforce1 for AndroidSalesforce1 for iOS, and Salesforce1 for Windows.

Ensure that the 'Permitted Users' value under 'OAuth policies' is set to 'Admin approved Users are pre-authorized', and click Save.



2. Deactivate from User Profile
Navigate to User Profile and ensure that the 'Salesforce1 for Android', 'Salesforce1 for iOS', and 'Salesforce1 for Windows' permissions are all disabled under the "Connected App Access" section. Once all of these have been disabled, save the changes for the Profile and repeat these steps for all Profiles in your organization.


3. Salesforce1 mobile browser app
To ensure that your Users are not able to access the browser-based version of Salesforce1, navigate to Setup | Apps | Mobile Apps | Salesforce1 Settings. From here, ensure that the 'Enable the Salesforce1 mobile browser app' option is unchecked, and click Save.



Now, let's see what happened when user login to Salesforce1


Next, we need to enable Salesforce1 for a few users to test if Salesforce1 can be approved as the corporate-wide app. There are 2 options:

1. Profile
If all the users are located under the same profile, open the profile and look for Salesforce1 under 'Connected App Access'.

2. Permission Set
This would be more flexible as you can enable it user by users across profiles. Ideally, you should create new Permission Set, click 'Assigned Connected Apps', click Edit button and look for Salesforce1 for... and lastly assign the permission set to the users.



Reference: Salesforce1 - How to Prevent all Users from Accessing the App



Sunday, May 21, 2017

Salesforce: Report use in Dashboard

When you are doing reports clean-up, you may not be able to delete reports that are used as the data source for the dashboard.



So, we need to find out the report is used by which dashboard:
1. Create a new custom report type with primary object "Reports"
2. Report type label: "Reports with Dashboard information"
3. Store in Category "Administrative Reports"
4. Click relate to another object
5. Select "Dashboard Components"


6. Save

Now create a new report using above report type created, I would like to add following fields in the report:
- Report Name
- Report Unique Name
- Report ID
- Dashboard: Title
- Dashboard Column
- Dashboard Component ID




ReferenceHow to identify reports attached to dashboards?




Sunday, May 14, 2017

Salesforce Lightning: News in Lightning Components

I thought News component is standard and available to use in Lightning App Builder, but when I see following screenshot taken from "Home" page in an org., the same for Account page too.


As of this document The News Component, News component is available from Group to Unlimited Editions, but why it is not available?

Root cause: this is because News have not enabled for that org. Follow this steps to enable it:
- Navigate to Setup | Feature SettingsAccount Settings
- Tick Enable News
- Click Save



Now, back to Lightning App Builder for Home page, and notice the News component now available to use.



Let's see what is News component offered and where it exist:
This component will get instant access to relevant, timely news about customers, partners, and competitors. The News component includes articles and Twitter posts, and is available on accounts, contacts, leads, opportunities, and the Home page. It provides relevant, timely news items that help you stay up-to-date with the companies, people, and industries you work with. News is available from US news sources in English.


Reference:



Sunday, March 26, 2017

Salesforce Lightning: Customize Fields on Recently Viewed List


When you click a tab in Salesforce, you will see default columns / fields from records recently viewed. For most list views, your users can select which fields to display and how to order the view columns. However, they can’t edit the recent records quick list on object home pages. Only Salesforce admins can select and order the fields to display for the recent records view.

In Classic, to modify fields displayed in the Recently Viewed List on Object home pages, navigate to Setup | Customizeobject name | Search Layouts, click the object name Tab, you can select fields would like to show in the Recently Viewed List. You can order columns by selecting one or more fields from Selected Fields and clicking Up or Down.

If you are familiar with the step in Classic, this is different in Lightning Experience. If you follow above steps, the Recently Viewed List on Object home pages will not change. So, follow this steps:
  1. From Setup, enter Object Manager in the Quick Find box, then select Object Manager.
  2. Click the label name of the object for the Recently Viewed list you want to modify.
  3. From the menu of links at the top of the page, click Search Layouts.
  4. In the far right of the Search Results column, click arrow icon and select Edit.
  5. To add columns to the Recently Viewed list, select one or more fields from Available Fields and click Add. To remove columns, select one or more fields from Selected Fields and click Remove.
  6. Order columns by selecting one or more fields from Selected Fields and clicking Up or Down.
  7. Click Save.


ReferenceSelect Fields to Display in the Recently Viewed List on Object Home Pages in Lightning Experience



Sunday, March 19, 2017

Salesforce: VLOOKUP


Some of us, Salesforce admin, maybe familiar with the popular VLOOKUP() function in Ms Excel from our previous job. But how about VLOOKUP() function in Salesforce? Yes it is exist, but not really very similar. VLOOKUP() in Salesforce able to retrieve a field based on a key data, so they are still not too much different, but in Salesforce, until now Spring 17 release, it only for validation rule, while ideally this should be expand to Workflow and Formula Field, vote for this formula in Ideaexchange.

Here is the fact:
1. This function is only available in validation rules, not in formula field, workflow and so on, see this blog Functions versus Rules matrix.

2. Syntax: VLOOKUP(field_to_return, field_on_lookup_object, lookup_value).

3. The field_to_return must be an auto number, roll-up summary, lookup relationship, master-detail relationship, checkbox, date, date/time, email, number, percent, phone, text, text area, or URL field type.

4. The field_on_lookup_object must be the Record Name field on a custom object.

5. The field_on_lookup_object and lookup_value must be the same data type.

6. The value returned must be on a custom object.

7. You cannot delete the custom field or custom object referenced in this function.


Scenario: when save on Account, system should check if the competitor is correct by looking number of branches.

Solution: create a validation rule with VLOOKUP() function.
Number_of_Locations__c <=
VLOOKUP(
$ObjectType.Competitor__c.Fields.No_of_Branches__c, $ObjectType.Competitor__c.Fields.Name,
Name
)

This function will return No_of_Branches__c from Competitor__c object, based on Name field from Account (you can replace Name here with a custom_field__c) and compare with Name field from Competitor__c object. Number_of_Locations__c and No_of_Branches__c must be in the same field type.

If VLOOKUP() cannot find the competitor name, it will skip the validation rule, and the lookup value is not case sensitive.


ReferenceFormula Operators and Functions I–Z




Friday, March 3, 2017

Salesforce: Lightning Login with Fingerprint

In my earlier blog Introducing Lightning Login, we discussed about how to setup Lightning Login, but many of you ask why I do not see fingerprint option, if my device support it.

To use Lightning Login, your admin must first enable Lightning Login for your org., then assign you with Lightning Login User permission. Lightning Login requires Android version 5.0 (Lollipop) or later or iOS 8 or later. If you’re using an iPhone, enable fingerprint or PIN identification. To use your fingerprint on an Android phone, first set up a PIN, pattern, or password.


As you see from above flow:
1. Click—Look for the lightning bolt next to your Lightning Login–enabled username, and click your username.
2. Tap—On your mobile device, tap the notification from the Salesforce Authenticator app.
3. Touch—Verify your identity with your fingerprint or PIN. Presto! You’re logged in.

In step 3 Touch, you can use fingerprint or PIN, but we haven't see this in the earlier blog.
This is simply because as admin, you need to grant Two-Factor Authentication for User Interface Logins permission to the user, either by Profile or Permission Set.

Once this permission is added, if user have enable Lightning Login, after user tap Approve in the device, user will be asked for fingerprint.



In other scenario, if Two-Factor Authentication for User Interface Logins permission has been given and activate by user prior Lightning Login, when user Enroll for Lightning Login, user will be asked for fingerprint when they enroll.




Reference:


Wednesday, March 1, 2017

Salesforce: Introducing Lightning Login

Since Winter '17 release, Salesforce introduce Lightning Login, this has nothing related with Lightning Experience, and Lightning Login work with both Classic and Lightning Experience.

With Lightning Login, after open Salesforce login page, you just simply click your username and tap approve from your mobile device. If your phone support fingerprint, you can make this further secure by authenticate with fingerprint. So no more entering username and password, just click and approve!


How to implement Lightning Login?
Admin 
1. Activate "Lightning Login" in Session Setting.
2. Add permission "Lightning Login User" to Permission Set or Profile.
3. Assign permission to users if you use Permission Set.

User
1. Install Salesforce Authenticator in mobile app (this is the same app for 2FA implementation).
2. Navigate to your User Detail page and click Enroll link next to Lightning Login.



3. Register for Identity Verification, Salesforce will send you verification code.


4. Once verified, you need to add New Account in Authenticator app, copy the two-word phrase into Salesforce and click Connect.



5. Tap "Connect" button in the Authenticator mobile app. You will get another email from Salesforce that a new verification method was added to your account "approve notifications from Salesforce Authenticator".

6. Next, you need to Approve from your mobile app.



7. Done, Salesforce will email last email say that you've enrolled in Lightning Login, you can now log in using your username and an authenticator app instead of a password.

8. Logout and login back, make sure to tick "Remember me" checkbox, notice a small lightning icon is added next to your user photo.



Normal Login
Once all setup, here is the flow to login with Lightning Login
1. Login to Salesforce from login.salesforce.com (or your custom my domain)
2. Click your username (notice lightning icon added next to your photo)
3. Tap "Approve" button from your device with Authenticator app


How to Cancel Lighting Login?
Navigate to your User Detail page and click Cancel link next to Lightning Login and Disconnect from Salesforce Authenticator. 






Tuesday, February 21, 2017

How to run Regex in Microsoft Excel?

1. Show Developer tab in Excel ribbon
If you do not see the tab, follow this URL to enable it.
https://msdn.microsoft.com/en-us/library/bb608625.aspx


2. VBA
To run Regex in Excel, you need to use VBA (Visual Basic for Applications).
From Developer tab, click Visual Basic icon.



3. Enable Regex for VBA for the workbook
In "Microsoft Visual Basic for Applications" window select "Tools" from the top menu.
Select "References".
Check the box next to "Microsoft VBScript Regular Expressions 5.5" to include in your workbook.
Click "OK".




Use Case:
We would like to parse specific patterns from range of cells in Excel, each cell could contain 0, 1 or more matches.
Here sample of data that user enter manually over times, to a text field without a good standard:
- Monitor 2X225,32C235, 21D2251
- 21A225; or 2C235; 21Z0251 keyboard

We need to capture and parse those ID, this looks like manual job, but with regex, we can parse this automatically. Regex should work with any new modern programming language, such as: Java, .Net and etc., but since Excel support VBA, we can make use of it.

If you notice above IDs, here is the possibility of patterns:
- 9X999
- 99X999
- 99X9999

With some testing with www.regex101.com, here is the RegEx to parse it:
[0-9]{2}[A-Z][0-9]{4}|[0-9]{2}[A-Z][0-9]{3}|[0-9][A-Z][0-9]{3}

From VBA window, copy and paste following script:
 Private Sub splitUpRegexPattern()  
   Dim regEx As New RegExp  
   Dim strPattern As String  
   Dim MyRange As Range  
   Dim i As Integer  
   Dim strMatch As String  
   'Source Data  
   Set MyRange = ActiveSheet.Range("A2:A15")  
   For Each C In MyRange  
     ' Regex pattern  
     strPattern = "[0-9]{2}[A-Z][0-9]{4}|[0-9]{2}[A-Z][0-9]{3}|[0-9][A-Z][0-9]{3}"  
     If strPattern <> "" Then  
       With regEx  
         .Global = True  
         .IgnoreCase = True  
         .Pattern = strPattern  
       End With  
       Set Matches = regEx.Execute(C.Value)  
       ' Reset the variables  
       strMatch = ""  
       i = 1  
       ' Iterate through the Matches collection  
       For Each Match In Matches  
         strMatch = "'" & Match.Value  
         ' Display the matches at right columns  
         C.Offset(0, i) = strMatch  
         i = i + 1  
       Next  
     End If  
   Next  
 End Sub  

Result:


The step and script is tested with Microsoft Excel 2013 and 2016.



Sunday, February 19, 2017

Your Organization's Salesforce.com pages has moved

If your user get a splash warning message "Your Organization's Salesforce.com pages has moved. Redirecting...", what is this mean? and why this happened?



This warning message usually happened when your admin enable "My Domain" feature, but still allowed user login from https://login.salesforce.com

As admin, you can check this from Setup | Domain Management | My Domain, and look for Redirect Policy under My Domain Settings.


If Redirected to the same page within the domain is selected, users are immediately sent to the new URL, without notification.

If Redirected with a warning to the same page within the domain is selected, users briefly see a warning message before being redirected to the new URL. The warning gives users a chance to change their bookmarks and get used to using the new sub-domain URL. You can’t customize the message.

If Not redirected is selected, the user gets a “page not found” error. Eventually, you want your users to use only sub-domain URLs, but it’s a best practice to use Redirected with a warning to the same page within the domain for a short time after you deploy your sub-domain so that users can get used to the new URLs.


Reference:



Salesforce Web-to-Lead with Enable spam filtering

Web-to-Lead has been available for many years for Salesforce users, this feature is simple but allow you easily capture lead from your company website and the data goes directly to Salesforce.

The enhancements in Spring '17 release will allow you to enable spam filtering with reCAPTCHA from Google.

As per normal Web-to-Lead setup, navigate to Setup | Customize | Leads | Web-to-Lead, click "Create Web-to-Lead Form". Tick option for "Enable spam filtering (recommended)", then you need to create reCAPTCHA API Key Pair.

How to create reCAPTCHA API Key Pair?
1. Make sure you have Google account.
2. Navigate to Google reCAPTCHA page, login to Google account, and click Get reCAPTCHA button.
3. Enter label and domain name, make sure this is domain that you will use to host Web-to-Lead HTML.


4. Copy the Site Key and Secret Key.


Now, back to Salesforce setup page to enter reCAPTCHA API Key Pair created. Click lookup icon in reCAPTCHA API Key Pair, then click New button, enter API Key Pair Nickname, Secret Key and Site Key created earlier. Click Save button to store the keys for Web-to-Lead.


As per normal, continue with selecting fields to show in the web form, and the return URL.

Sample:




Reference:


Friday, January 27, 2017

Reverse VLOOKUP with INDEX + MATCH

VLOOKUP() in Excel is one of the most powerful and famous formula. This function is very easy to use to lookup a value from a table or range. You just need to refer a key value to the column located at the most left column of the range to get result value from another column in the same row. I'll not discuss more on VLOOKUP function in this blog, you can easily Google it or watch from Youtube.

One of the requirement to use VLOOKUP, which is also limitation of VLOOKUP, is the key value must be located at the most left column in the range, but that is not always how is out data structured. What happen when the key value located at the right of the result value?

Options:
1. Move the Result or Key value column 
Move the Result value column to the right of Key value, or move Key value column to the left of Result value, then use VLOOKUP.
This may work easily, but sometimes when you work with many columns and many user, move column is not really a desired option.


2. Copy the Key or Result value
Copy Key or Result value to have Key value located before of Result value, then use VLOOKUP. Same with option 1, sometimes option to move column in big worksheet and work many user is not really a good option.


3. INDEX + MATCH function
The INDEX function returns a value in a table based on the intersection of a row and column position within that table. The first row in the table is row 1 and the first column in the table is column 1.
The MATCH function searches for a specified item in a range of cells, and then returns the relative position of that item in the range.

With combination of INDEX + MATCH functions, we can get something similar with VLOOKUP, but the Key not must be located before Result column, see this sample:


What is the formula in I2? =INDEX(A:A,MATCH(H2,B:B,0),1)


A:A = result / target value
B:B = key
H2 = data for row 2
I2 = target result



Thursday, January 26, 2017

Salesforce URLFOR()


URLFOR() function in Salesforce is not widely use as it is only available in custom buttons, links, s-controls, and Visualforce pages.

Syntax: {!URLFOR(target, id, [inputs], [no override])}
target: URL or action, s-control, or static resource merge variable
id: a reference to the record (depends on the “target”)
inputs: optional parameters with format: [param1="A", param2="B"]
no override: optional boolean flag - default false. Set to true to display a standard Salesforce page, regardless of whether you have defined an override for it elsewhere.

 The most common URLFOR() used developer user in Visualforce pages to refer to a resource in Static resources, such as images or script.

Visualforce
<apex:image url="{!$Resource.ImagePba}" width="50" height="50" />
This ImagePba in sample above is Static Resource name, not original image file name.

Optionally, you can add URLFOR()
<apex:image url="{!URLFOR($Resource.ImagePba)}" width="50" height="50" />

But when you use resource in archive file (such as a .zip or .jar file) in static resource, URLFOR() is a must as second parameter.
<apex:image url="{!URLFOR($Resource.Images,'pba.png')}" width="75" height="75" />
<apex:image url="{!URLFOR($Resource.ImagesFolder,'image/campaign1.png')}" width="100" height="100" />
<apex:includeScript value="{!URLFOR($Resource.LibraryJS, '/base/subdir/file.js')}"/>


Custom Button or Link
Admin can make use of URLFOR() function with $Action global variable in custom Button or Link. The $Action global variable provides methods such as View, Clone, Edit, and Delete. Some objects support other additional actions, see all valid actions here.

URLFOR() determines your base URL, and the $Action determines what view of a record to go to (the view page, edit page, etc.). For example, to edit Account from Contact page, add the custom button or link in Contact: {!URLFOR($Action.Account.View, Account.Id)}.

More samples
New Account -- {!URLFOR($Action.Account.New)}
View Account -- {!URLFOR($Action.Account.View, Account.Id)}
Edit Account -- {!URLFOR($Action.Account.Edit, Account.Id)}
Clone Contact -- {!URLFOR($Action.Contact.Clone, Contact.Id)}
Account Tab -- {!URLFOR($Action.Account.Tab, $ObjectType.Account)}


Reference:



Sunday, January 22, 2017

Salesforce: Auto Lock Record

Use case: make opportunity become read-only when opportunity reach stage Closed Won.

Options: there are multiple solutions for this, from simple to advance with code:

1. Record Type & Page Layout
This would be one of the most famous solution without code, but this will make the system more difficult to maintain as the object will have additional record type set and additional page layouts. In short, when the opportunity reach Closed Won, with Workflow, change the record type to new record type and assign the new record type with page layout with read-only fields.

2. Record Ownership
This will work by change the record owner to a system user in highest role hierarchy. This will work well when the OWD sharing setting is Public Read-Only. But, often this solution will not work well, because the original record owner changed and it is important for reporting, although you can create custom user field to store it.

3. Validation Rule
By using function PRIORVALUE() and ISCHANGED() to detect any changes happened in Closed Won record. User will get error when save opportunity has been marked as Closed Won previously.

4. Trigger
Since Winter '16, Salesforce introduce lock() and unlock() methods in the System.Approval namespace.  Admin need to enable this feature, from Setup | CreateWorkflow & Approvals | Process Automation Settings. Then, select Enable record locking and unlocking in Apex.

Example:
 // Query the opportunities to lock  
 Opportunity[] opty = [SELECT Id from Opportunity WHERE Name LIKE 'Acme%'];  
 // Lock the opportunities  
 Approval.LockResult[] lrList = Approval.lock(opty, false);  
 // Iterate through each returned result  
 for(Approval.LockResult lr : lrList) {  
   if (lr.isSuccess()) {  
     // Operation was successful, so get the ID of the record that was processed  
     System.debug('Successfully locked opportunity with ID: ' + lr.getId());  
   }  
   else {  
     // Operation failed, so get all errors          
     for(Database.Error err : lr.getErrors()) {  
       System.debug('The following error has occurred.');            
       System.debug(err.getStatusCode() + ': ' + err.getMessage());  
       System.debug('Opportunity fields that affected this error: ' + err.getFields());  
     }  
   }  
 }  

5. Process Builder and Approval Process
In previous blog, we shared about users able to edit locked record and who will see Unlock Record button. As Process Builder able to call Approval Process, we'll make use of this combination to auto submit for approval when opportunity reach Closed Won. The approval process here would be auto approve, therefore it will leave a trace in the approval process.

a). Create Approval Process

b). Create Process Builder

Drawback for option (5): opportunity approval history will show action for approval submitted and approved, this is not ideal if you use opportunity with other approval process.



Reference:


Sunday, January 15, 2017

Adding Certs and Badges to Your Salesforce Community Profile

Don't let your hard earned Trailhead badges and Salesforce Certifications buried in your desk, make sure showing off all of them on your Salesforce Community profile!

1. Login to Success Community
Login to Success Community from https://success.salesforce.com. Once login, click your avatar and select "My Profile".



2. Edit Profile
Click "Edit" button then "Profile".

Scroll down to "Certifications & Badges" section and enable both "Show Salesforce certifications on my profile" and "Show Salesforce Trailhead Badges on my profile". Make sure to enter your account and verify it.


Click "Save Changes" and done. You will need to enter verification code sent your email.



3. Check Your Profile
Navigate back to your profile - https://success.salesforce.com/profile then click "Certification and Badges" - https://success.salesforce.com/ProfileCertificationsAndBadges, you should see your hard earned Trailhead Badges and Salesforce Certifications showing off now.



4. See other People Certs & Badges
Every user in Success Community will have unique User Id, which is start with 005, example: 00530000003TTvZAAW. When you click someone profile from Success Community, notice the URL, example: https://success.salesforce.com/_ui/core/userprofile/UserProfilePage?u=00530000003TTvZAAW&tab=sfdc.ProfilePlatformFeed

Get the User Id and paste it to following URL: https://success.salesforce.com/ProfileCertificationsAndBadges?u=00530000003TTvZAAW remember to change the Id to that particular User Id.

This is not convenience to manually copy and paste, ideally there should be a link from the user Chatter Feed to User Profile, so vote for this idea.

Another option is by search that people name from search text box and select People.



Search result as below, click the name then Certifications & Badges" link at left menu.



Excel Filter: Tips and Shortcut

As Salesforce admin, sometimes we need to prepare data before load into Salesforce correctly. Recently, I need to clean and prepare some pretty big amount of raw data. Microsoft Excel apparently is one the easiest and best available tool to clean and prepare the data before loading into Salesforce.

In this blog, I would like to share some tips learned from the exercise.

TIPS
- Ctrl+Shift+L – toogle enable and disable filter, make sure cursor in the range of value
Alt+A+C – clear ALL filters
- Place cursor at header, Alt+Down arrow to show drop down menu
- Place cursor at body, Alt+Down arrow to show drop down of available values (except number)
* the last one will work even no filter added

In drop down Filter menu (Alt+Down arrow)
- E key – type search
- C key – clear filter in current cursor column
- F+E key – select blank value
- F+N key – select non-blank value
- Up and Down arrow – move cursor, Space bar key to select, and Enter to perform action
- When cursor in range of values, Home – move to top value
- When cursor in range of values, End – move to bottom value
- Alt+Down Arrow+S – sort A to Z
- Alt+Down Arrow+O – sort Z to A
- Alt+Down Arrow+T – sort by Color sub menu
- Alt+Down Arrow+I – filter by Color sub menu
- Alt+Down Arrow+F – text or Date Filter sub menu



DO
1. Double click at bottom right of a cell will copy value to visible rows only


Double click bottom right corner to auto-fill value of C2 to visible rows below it (C4 and C6). When we clear the filter, only C4 and C6 is filled, while C3 and C5 is skipped. Value of C2 can be static or formula.


You can apply this to multiple columns too.


2. Similar to point 1, copy paste will to copy value to visible rows only


- Select range C2-D2 -- copy
- Select range C4-D6 -- paste
- Result: only value in C4, C6, D4, D6 will be copied, while row 3 & 5 skipped

** the same result if you select range C2-D6 for fill with a color, row 3 & 5 will not be colored


3. Copy paste will copy only from visible rows value 
- This is not applicable for manually hidden rows
- Select cells / range to copy, example: copy as below screenshot


Paste to new area, I put my cursor to cell A8 -- only visible cells are copied.



4. Deal with blank row
If you need to deal with blank row in filter, make sure to highlight/select the area (in sample below, select area A1-D10 or the whole A-D column), before hit Ctrl+Shift+L, otherwise filter will not include area below empty row (row 7 and below).



DON'T
1. Copy more than 1 row from source into target with filtered rows

Don't copy more than 1 row from source into target with filtered rows, this cause value in target hidden filtered rows will be overwritten, sample: copy 3 rows of "B" from source (B11-B13)

Paste it to target which is filtered rows, for this example: paste into cell C2

Instead of copy value "B" into C2, C4, C6 -- "B" will be copied into C2, C3, C4.

Summary, copy from multiple rows will skipped filtered target.

This action will only work well, if there is no skipped rows in the applied filter, example: Jawa in sample above is at continuous rows e.g. 2,3,4.


Excel Table
By using the Table features, you can manage the data in the table rows and columns independently from the data in other rows and columns on the worksheet.
- Ctrl+L – create Excel Table
- To delete Excel Table table without losing the data:
   - Select Convert to Range from DESIGN tab menu, or
   - Right-click on the table and click Convert to Range under Table menu
- Filtering controls are added to the table headers automatically
- Place cursor anywhere in table, Alt+Shift+Down arrow – show the drop down menu
- You can have filter for more than one range of data on a sheet