By default, when user
click a tab, example: Account tab, user will see latest View selected by that
user and follow with recent Account at below.
But, are we able to
modify this?
YES, using Visualforce
page. Don't be afraid, you not really need to understand the whole visualforce
page script, just copy from script below :)
1. Always show a View
You can start create
visualforce page from Setup -
Develop - Pages, create New button,
enter the label and name, then copy and paste script below
<apex:page>
<apex:enhancedList listId="00B500000063yvG" height="600"
customizable="true" rowsPerPage="10"/>
</apex:page>
Explanation:
- listId, this is View Id, you
can grab it from normal URL, sample:https://na3.salesforce.com/001?fcf=00B500000063yvG this is always 15 characters
- height, this is mandatory
- customizable,
this to determine if user allow to Edit | Delete | Create New View, if false,
user will not see the links.
- rowsPerPage,
this to determine number of rows per page, maximum = 200
2. Always show
"Recently Viewed Objects"
<apex:page
showHeader="true" tabstyle="Opportunity">
<apex:ListViews type="Opportunity" />
</apex:page>
Okay, so we can
customize the tab using simple Visualforce page, next question, how to put it
on?
1. Overwrite existing
standard tab
·
Setup - Account (for
Account object) - Buttons, Links, and Actions
·
Look for Accounts
Tab (just change the object name for other object)
·
Click Edit link
·
Select Visualforce
Page option and page you save above
·
Save
2. Create new tab
·
Setup - Create - Tabs
·
Go to Visualforce
Tabs
·
Click New button
·
Select Visualforce
page you save above
·
Follow the wizard and
Save
Notes and Attachments
is not a new thing in Salesforce. I also do not see any enhancements in last
few Salesforce release. But, for some users, Notes and Attachments still a nice
feature and frequently used.
Here a few facts on Notes and Attachments good to remember:
Here a few facts on Notes and Attachments good to remember:
11.
It is not possible to
report on the Notes and Attachments related list.
12.
The Notes &
Attachments can be exported directly via the API.
13.
It is possible to
access your Notes & Attachments data by requesting a full data export of
your organization's data.
14.
The only way to get
attachment on an Salesforce email to Attachment is to download the attachment
to your local machine, then manually added as an Attachment from the local
machine location.
15.
Notes and attachments
marked as Private via the Private checkbox are accessible only to the person
who attached them, Administrators and users with View All Data permission.
16.
You must have
“Read/Write” access to parent record to be able to add Notes or Attachments to
the record.
17.
You also need to have
“Read/Write” access permission to parent record to be able to edit or delete
Notes or Attachments.
18.
You can write Apex
trigger for Notes & Attachments using Force.IDE
Special thanks
to Jason Lawrence for
the input of Feed Attachment, so if you attach File to Chatter Feed in an
Account or Opportunity, it will show as well in Notes & Attachments
as Feed Attachment.
Six months back, I
wrote this blog to
disable user login to SFDC temporary, maybe for major internal release.
In Winter '14 release, Salesforce introduce Freeze user feature. Administrator can easily freeze user, so he/she will not able to login to Salesforce temporary. But, if you have 500 users to freeze, it is not a nice job to open each user and click Freeze button.
Luckily, Salesforce provide API for this. It is a field called IsFrozen, located in a new object, called UserLogin. You only can see this object using API version 29.0 and above, so if you use Data Loader, make sure it is version 29.0 and above. You can query and update this object, but not create and delete as it will sync to User object.
Screenshot from Data Loader
In Winter '14 release, Salesforce introduce Freeze user feature. Administrator can easily freeze user, so he/she will not able to login to Salesforce temporary. But, if you have 500 users to freeze, it is not a nice job to open each user and click Freeze button.
Luckily, Salesforce provide API for this. It is a field called IsFrozen, located in a new object, called UserLogin. You only can see this object using API version 29.0 and above, so if you use Data Loader, make sure it is version 29.0 and above. You can query and update this object, but not create and delete as it will sync to User object.
Screenshot from Data Loader
SOQL to this object using Developer Workbench
SELECT Id, IsFrozen, IsPasswordLocked, LastModifiedById, LastModifiedDate, UserId FROM UserLogin
Posted by Johan Yu at 3:25 PM 2 comments:
Labels: Tips
Monday, November 25,
2013
LAST_WEEK
Using criteria LAST_WEEK in SOQL will return all records where the date starts from 12:00:00 AM (user Local Time Zone) on the first day of the week before the most recent first day of the week and continues for seven full days. First day of the week is determined by your locale.
Example: my user locale setting is English (United States) and today = Sat, 23 Nov 2013, I run query below:
SELECT Id, Name, CreatedDate FROM Account WHERE CreatedDate = LAST_WEEK ORDER BY CreatedDate DESC
this query will return accounts created between 10-16 Nov 2013, because for Locale is US English, a week runs Sunday to Saturday, whereas with UK English, a week spans Monday to Sunday.
SELECT Id, Name, CreatedDate FROM Account WHERE CreatedDate < LAST_WEEK ORDER BY CreatedDate DESC
Using criteria LAST_WEEK in SOQL will return all records where the date starts from 12:00:00 AM (user Local Time Zone) on the first day of the week before the most recent first day of the week and continues for seven full days. First day of the week is determined by your locale.
Example: my user locale setting is English (United States) and today = Sat, 23 Nov 2013, I run query below:
SELECT Id, Name, CreatedDate FROM Account WHERE CreatedDate = LAST_WEEK ORDER BY CreatedDate DESC
this query will return accounts created between 10-16 Nov 2013, because for Locale is US English, a week runs Sunday to Saturday, whereas with UK English, a week spans Monday to Sunday.
SELECT Id, Name, CreatedDate FROM Account WHERE CreatedDate < LAST_WEEK ORDER BY CreatedDate DESC
this query will return
accounts created before 10 Nov 2013.
LAST_N_DAYS:7
Using
LAST_N_DAYS:7 in SOQL will return all records where the date starts from
12:00:00 AM (user Local Time Zone) of the current day and continues for the
last 7 days.
SELECT Id, Name,
CreatedDate FROM Account WHERE CreatedDate = LAST_N_DAYS:7 ORDER BY CreatedDate
DESC
If today is Friday, 22
Nov 2013, using LAST_N_DAYS:7 will return account created between 16 - 22 Nov
2013, while LAST_WEEK will return account created between 10 - 16 Nov 2013.
N_DAYS_AGO:7
Using
N_DAYS_AGO:7 in SOQL will return all records where the date starts from
12:00:00 AM (user Local Time Zone) on the day 7 days before the current day and
continues for 24 hours. (The range does not include today.)
SELECT Id, Name,
CreatedDate FROM Account WHERE CreatedDate = N_DAYS_AGO:7 ORDER BY CreatedDate DESC
If today is Monday, 25
Nov 2013, using N_DAYS_AGO:7 will return account only created on 18
Nov 2013.
By default, Salesforce
Dashboard will show all values in Vertical Bar Chart, Horizontal Bar Chart,
Line Chart, Pie Chart, Donut Chart, Funnel Chart, Scatter Chart, and Table
component. Component below show All Chatters Group with number of members for
each Group.
But, how to show just
top 3 group with most members? It is easy in Salesforce:
19.
Edit the dashboard
20.
Click 'Edit
Attributes' icon
21.
Go to 'Formatting' tab
22.
Look for Maximum
Values Displayed and enter 3
23.
Make sure select Sort
by Value Descending
24.
Once you move your
mouse cursor out of that field, you will notice preview at the right change to
3
25.
Click OK
26.
Done
You can use the same way to show top 10 Sales
Rep, or top 5 area with minimum claim, etc.
1: Bulkify your Code
Bulkifying Apex code refers to the
concept of making sure the code properly handles more than one record at a
time. When a batch of records initiates Apex, a single instance of that Apex
code is executed, but it needs to handle all of the records in that given
batch. For example, a trigger could be invoked by an Force.com SOAP API call
that inserted a batch of records. So if a batch of records invokes the same
Apex code, all of those records need to be processed as a bulk, in order to
write scalable code and avoid hitting governor limits.
trigger sampletrigger on
contact (before insert) {
Contact con =
Trigger.new[0];
List<task> tsk = [select id, activitydate,status,priority
from task where whoid = :con.Id];
}
Correct Code :
trigger sampletrigger
on Account (before insert) {
//Loop
through all records in the Trigger.new collection
for(Contact c: Trigger.new){
system.debug(‘*******’);
}
}
2: Avoid SOQL Queries
inside FOR Loops
Never write SOQL
queries and DML Statemets in for Loops
trigger accountTestTrggr
on Account (before insert, before update) {
//For
loop to iterate through all the incoming Account records
for(Account
a: Trigger.new) {
//THIS FOLLOWING QUERY IS INEFFICIENT AND DOESN'T SCALE
//Since the SOQL Query for related Contacts is within the FOR loop, if this
trigger is initiated
//with more than 100 records, the trigger will exceed the trigger governor
limit of maximum // 100 SOQL
Queries.
List<Contact> contacts = [select id, salutation,
firstname, lastname, email from Contact where accountId =
:a.Id];
for(Contact c: contacts) {
System.debug('Contact Id[' + c.Id + '], FirstName[' + c.firstname +
'],LastName[' + c.lastname +']');
c.Description=c.salutation + ' ' + c.firstName + '
' + c.lastname;
//THIS FOLLOWING DML
STATEMENT IS INEFFICIENT AND DOESN'T SCALE
//Since the UPDATE dml
operation is within the FOR loop, if this trigger is initiated with more //than
150 records, the trigger will exceed the trigger governor limit of 150 DML
Operations
//maximum.
update c;
} }
Correct Code :
trigger
accountTestTrggr on Account (before insert, before update) {
//This queries
all Contacts related to the incoming Account records in a single SOQL query.
//This is also
an example of how to use child relationships in SOQL
List<Account> accountsWithContacts = [select id, name, (select id,
salutation,
description,
firstname,
lastname, email from Contacts) from Account where Id IN
Trigger.newMap.keySet()];
List<Contact> contactsToUpdate = new List<Contact>{};
// For loop to
iterate through all the queried Account records
for(Account a:
accountsWithContacts){
// Use the child relationships dot syntax to access the related Contacts
for(Contact c: a.Contacts){
System.debug('Contact Id[' + c.Id + '], FirstName[' + c.firstname + '],
LastName[' + c.lastname +']');
c.Description=c.salutation + ' ' + c.firstName + ' ' + c.lastname;
contactsToUpdate.add(c);
}
}
//Now
outside the FOR Loop, perform a single Update DML statement.
update
contactsToUpdate;
}
}
5: Streamlining Multiple
Triggers on the Same Object
It is
important to avoid redundancies and inefficiencies when deploying multiple
triggers on the same object. If developed independently, it is possible to have
redundant queries that query the same dataset or possibly have redundant for statements.
6: Querying Large Data
Sets
total
number of records that can be returned by SOQL queries in a request is 50,000.
If returning a large set of queries causes you to exceed your heap limit, then
a SOQL query for loop must be used
instead. It can process multiple batches of records through the use of internal
calls to query and queryMore.
if
the results are too large, the syntax below causes a runtime exception:
Account[]
accts = [SELECT id FROM account];
use a
SOQL query for loop as in one of the
following examples:
for
(List<Account> acct : [SELECT id, name FROM account WHERE name LIKE
'Acme']) {
// Your code here
update acct;
}
7. Use of the Limits Apex Methods to Avoid Hitting
Governor Limits
use a
combination of System.debug statements and the
Limits Apex class to generate some very useful output as it relates to governor
limits and the overall efficiency of your code.
System.debug('1.Number
of Queries used in this apex code so far: ' + Limits.getQueries());
8. Use @future Appropriately
the
Apex trigger inefficiently invokes an asynchronous method for each Account
record it wants to process:
trigger
accountAsyncTrigger on Account (after insert, after update) {
for(Account a: Trigger.new){
// Invoke the @future method for each Account
// This is inefficient and will easily exceed the governor limit of
// at most 10 @future invocation per Apex transaction
asyncApex.processAccount(a.id);
}
}
Apex
class that defines the @future method:
global
class asyncApex {
@future
public static void processAccount(Id accountId) {
List<Contact>
contacts = [select id, salutation, firstname, lastname, email
from Contact where accountId = :accountId];
for(Contact c: contacts){
System.debug('Contact Id[' + c.Id + '], FirstName[' + c.firstname + '],
LastName[' + c.lastname +']');
c.Description=c.salutation + ' ' + c.firstName + ' ' + c.lastname;
}
update contacts;
}
}
In
the below example the method will be invoked once there by avoiding governor
limits
trigger
accountAsyncTrigger on Account (after insert, after update) {
//By passing the @future method a set of Ids, it only needs to be
//invoked once to handle all of the data.
asyncApex.processAccount(Trigger.newMap.keySet());
}
global
class asyncApex {
@future
public static void processAccount(Set<Id> accountIds) {
List<Contact> contacts = [select id, salutation, firstname, lastname,
email from Contact where accountId IN :accountIds];
for(Contact c: contacts){
System.debug('Contact Id[' + c.Id + '], FirstName[' + c.firstname + '],
LastName[' + c.lastname +']');
c.Description=c.salutation + ' ' + c.firstName + ' ' + c.lastname;
}
update contacts;
}
}
9. Avoid Hardcoding IDs
Avoid
Hardcoding ID s as the record id will be different in different environments
like SandBox and Production
public class
ChildClass implements ChildInterface{
public void ready(){
System.debug('I am ready');
}
public void welcome(){
System.debug('U r Welcome');
}
public void bye() {
System.debug('Get Out');
}
}------------------------------------------------------------------------------
public interface ChildInterface extends SampleInterface{
void ready();
void bye();
}
-------------------------------------------------------------
----------------Child_FPC--------------------------------------
public abstract class Child_FPC implements SampleInterface{
//Incomplete CLass
}
----------------------------------------------------------------
------------------------SampleInterface-------------------------------------
public interface SampleInterface{
//method prototypes
//return_type mtd_name(i/ps,i/ps);
void welcome();
//data members not allowed
}
-----------------------------------------------------------------------------
------------------------VirtualParent----------------------------------------
public abstract class VirtualParent{
//data members
private Integer prt_pvt_mem = 10;
protected Integer prt_ptt_mem = 20;
public Integer prt_pub_mem = 30;
//member Methods
public abstract void getValues();
/* {
System.debug(prt_pvt_mem);
System.debug(prt_ptt_mem);
System.debug(prt_pub_mem);
}*/
}
-------------------------------------------------------------------------------
------------------ChildVP------------------------------------
public class ChildVP extends VirtualParent{
private Integer chd_pvt_mem = 40;
/* public override void getValues(){
// System.debug(prt_pvt_mem);
System.debug(prt_ptt_mem);
System.debug(prt_pub_mem);
System.debug(chd_pvt_mem);
}*/
}
--------------------------------------------------------------
----------------------------InhTest---------------------------------------
global class InhTest{
testMEthod static public void main(){
VirtualParent p_obj = new VirtualParent();
p_obj.prt_pub_mem = 60;
//p_obj.prt_ptt_mem = 60;
p_obj.display();
}
}
----------------------------------------------------------------------------
--------------------FinalPC--------------------------------------
public class FinalPC{
public void finalMtd(){
}
public virtual void VirtualMtd(){
}
/* public abstract void abstractMTd(){
}*/
}
------------------------------------------------------------------
-----------------------Height-------------------------------------
public class Height{
Integer feet;
Integer inches;
static Integer count = 0;
//Default constructor
public Height(){
feet = inches = 0;
count++;
}
//Parameterised constructor
public Height(Integer ft,Integer inch){
feet = ft;
inches = inch;
count++;
}
public static void getCount(){
System.debug('Count of objects = ' + count);
}
public void setValues(Integer ft,Integer inch){
feet = ft;
inches = inch;
}
public void getValues(){
System.debug('Feet = ' + feet);
System.debug('Inches = ' + inches);
//System.debug('Count = ' + count);
}
}
public class TestHeight{
public static testMethod void main(){
Height.getCount();
Height ct = new Height();
Height.getCount();
Height ct1 = new Height(25,52);
Height.getCount();
Height ct2 = new Height(12,6);
Height.getCount();
}
}
--------------------------------------------------------------------------
-------------------------VirtualPC---------------------------------------------
virtual public class VirtualPC{
public void finalMtd(){
}
public virtual void VirtualMtd(){
}
/*public abstract void abstractMTd(){
}*/
}
-------------------Child_VPC------------------------------------
public class Child_VPC extends VirtualPC{
}
-
-------------------------------------------------------------------------------
---------------------- AbstractPC----------------------------------------------
abstract public class AbstractPC{
public void finalMtd(){
}
public virtual void VirtualMtd(){
}
public abstract void abstractMTd();
}
---------------Child_APC--------------------------------------
public class Child_APC extends AbstractPC{
public override void abstractMTd(){
}
}
---------------------------------------------------------------
public void ready(){
System.debug('I am ready');
}
public void welcome(){
System.debug('U r Welcome');
}
public void bye() {
System.debug('Get Out');
}
}------------------------------------------------------------------------------
public interface ChildInterface extends SampleInterface{
void ready();
void bye();
}
-------------------------------------------------------------
----------------Child_FPC--------------------------------------
public abstract class Child_FPC implements SampleInterface{
//Incomplete CLass
}
----------------------------------------------------------------
------------------------SampleInterface-------------------------------------
public interface SampleInterface{
//method prototypes
//return_type mtd_name(i/ps,i/ps);
void welcome();
//data members not allowed
}
-----------------------------------------------------------------------------
------------------------VirtualParent----------------------------------------
public abstract class VirtualParent{
//data members
private Integer prt_pvt_mem = 10;
protected Integer prt_ptt_mem = 20;
public Integer prt_pub_mem = 30;
//member Methods
public abstract void getValues();
/* {
System.debug(prt_pvt_mem);
System.debug(prt_ptt_mem);
System.debug(prt_pub_mem);
}*/
}
-------------------------------------------------------------------------------
------------------ChildVP------------------------------------
public class ChildVP extends VirtualParent{
private Integer chd_pvt_mem = 40;
/* public override void getValues(){
// System.debug(prt_pvt_mem);
System.debug(prt_ptt_mem);
System.debug(prt_pub_mem);
System.debug(chd_pvt_mem);
}*/
}
--------------------------------------------------------------
----------------------------InhTest---------------------------------------
global class InhTest{
testMEthod static public void main(){
VirtualParent p_obj = new VirtualParent();
p_obj.prt_pub_mem = 60;
//p_obj.prt_ptt_mem = 60;
p_obj.display();
}
}
----------------------------------------------------------------------------
--------------------FinalPC--------------------------------------
public class FinalPC{
public void finalMtd(){
}
public virtual void VirtualMtd(){
}
/* public abstract void abstractMTd(){
}*/
}
------------------------------------------------------------------
-----------------------Height-------------------------------------
public class Height{
Integer feet;
Integer inches;
static Integer count = 0;
//Default constructor
public Height(){
feet = inches = 0;
count++;
}
//Parameterised constructor
public Height(Integer ft,Integer inch){
feet = ft;
inches = inch;
count++;
}
public static void getCount(){
System.debug('Count of objects = ' + count);
}
public void setValues(Integer ft,Integer inch){
feet = ft;
inches = inch;
}
public void getValues(){
System.debug('Feet = ' + feet);
System.debug('Inches = ' + inches);
//System.debug('Count = ' + count);
}
}
public class TestHeight{
public static testMethod void main(){
Height.getCount();
Height ct = new Height();
Height.getCount();
Height ct1 = new Height(25,52);
Height.getCount();
Height ct2 = new Height(12,6);
Height.getCount();
}
}
--------------------------------------------------------------------------
-------------------------VirtualPC---------------------------------------------
virtual public class VirtualPC{
public void finalMtd(){
}
public virtual void VirtualMtd(){
}
/*public abstract void abstractMTd(){
}*/
}
-------------------Child_VPC------------------------------------
public class Child_VPC extends VirtualPC{
}
-
-------------------------------------------------------------------------------
---------------------- AbstractPC----------------------------------------------
abstract public class AbstractPC{
public void finalMtd(){
}
public virtual void VirtualMtd(){
}
public abstract void abstractMTd();
}
---------------Child_APC--------------------------------------
public class Child_APC extends AbstractPC{
public override void abstractMTd(){
}
}
---------------------------------------------------------------
Posted 14th December 2013 by vikramSFDC
0
Add a comment
1. Unmanaged packages
do not include locked components but can be upgraded?
A. True
B. False
2. What of the
following statements is True?
A. Tasks allow
you to track the specific actions you plan to perform or have performed; Email
Alerts cannot track specific actions
B. Email Alerts
allow you to track the specific actions you plan to perform or have performed,
Tasks cannot track specific actions
C. Email Alerts
and Tasks allow you to track the specific actions you plan to perform or have
performed
D. Email Alerts
and Tasks cannot track the specific actions you plan to perform or have
performed
3. The opportunities
fields of the campaign statistics section on a campaign detail page will only
be populated for the campaign designated as the primary campaign source?
A. True
B. False
4. Is it possible to
have Sidebar search enabled with Global Search?
I would like to thank you for the efforts you have made in writing this article. I am hoping the same best work from you in the future as well.
ReplyDeleteCPQ Sales Force Training
Visit us: sales force CPQ Online Training