Friday 29 November 2013

Salesforce Demo: Cross object formulas - adding lead owner email to lead record

This video shows how to add the lead owners email to the lead record using a cross object formula.



One benefit of doing this is so that you can report on lead owners email (unique field) and potentially saves you using a vlookup command from report export from the user object and lead object.

Some objects support different object types for the Owner field, such as a User, Queue, or Calendar. On objects that support this behavior, when creating a cross-object formula using Owner, you must be explicit about the owner type you’re referencing.

For example, if you need owner email and you don’t use queues, your formula would be Owner:User.Email. If you do use queues, your formula could be:

IF( ISBLANK( Owner:User.Id ), Owner:Queue.QueueEmail, Owner:User.Email )

Here’s how you would select Owner object fields on a Lead in the Advanced formula tab:
Formula Span to Owner

Thursday 28 November 2013

SOQL Demo: Use Workbench to create a SOQL

Workbench can be used to build SOQL commands.Use this link to sign in to Workbench. You will need to be signed into your Salesforce environment.

Salesforce Object Query Language is very similar to SQL but not as powerful.  It's an easy language to learn.

SOQL uses the SELECT statement combined with filtering statements to return sets of data, which may optionally be ordered:

SELECT one or more fields
FROM an object
WHERE filter statements and, optionally, results are ordered

For example, the following SOQL query returns the value of the Id and Name field for all Account records if the value of Name is Sandy:

SELECT Id, Name
FROM Account
WHERE Name = 'Sandy'

This process is very much like producing a salesforce report but is more time effective way to get the data you need.

Soql Guide

Watch this video:




Upwards traversal - from child to parent - via lookup or master-detail relationship
SELECT Id, Account.Name, Account.Industry, Account.Website
    FROM Contact

    WHERE Account.NumberOfEmployees >= 200

referencing account fields (parent) from contact (child) using dot notation

SELECT Account.Owner.Profile.CreatedBy.Name FROM Contact

You can traverse multiple levels upwards

SELECT Id, customlookupfield__r.customfield__c from contact

Here we’re traversing a custom lookup field customlookupfield__c on the contact object. Notice how the “__c” changes to a “__r” when traversing that field
Downwards traversal - from parent to child - via related list
SELECT Id, Name, Industry, AnnualRevenue,
    ( SELECT Name, Email, BirthDate FROM Contacts )

    FROM Account
nested soql is like another field, nested object uses the plural, (child relationship name found in object settings)

Simple query
SELECT Name FROM Account WHERE Name like 'A%'
SELECT Id FROM Contact WHERE Name LIKE 'A%' AND MailingCity='California'

Query filter on DateTime
SELECT Name FROM Account WHERE CreatedDate > 2011-04-26T10:00:00-08:00
SELECT Name FROM Account WHERE CreatedDate > 2011-04-26T10:00:00Z

Query with Date Function
SELECT Amount FROM Opportunity WHERE CALENDAR_YEAR(CreatedDate) = 2011

Query filter on null 
SELECT AccountId FROM Event WHERE ActivityDate != null

Query Multi-Select Picklists
SELECT Id, MSP1__c from CustObj__c WHERE MSP1__c includes ('AAA;BBB','CCC')
this will return record with MSP__1 example: 'AAA;BBB;DDD' ; 'CCC;EEE'

Semi-Join Query
SELECT Id, Name FROM Account WHERE Id IN ( SELECT AccountId FROM Opportunity WHERE StageName = 'Closed Lost')

Reference Field Semi-Join Query
SELECT Id FROM Task WHERE WhoId IN ( SELECT Id FROM Contact WHERE MailingCity = 'Twin Falls' )

Anti-Join Query
SELECT Id FROM Account WHERE Id NOT IN ( SELECT AccountId FROM Opportunity WHERE IsClosed = false )

Reference Field Anti-Join Query
SELECT Id FROM Opportunity WHERE AccountId NOT IN ( SELECT AccountId FROM Contact WHERE LeadSource = 'Web' )

Multiple Semi-Joins Query
SELECT Id, Name FROM Account WHERE Id IN ( SELECT AccountId FROM Contact WHERE LastName LIKE 'apple%' )
AND Id IN ( SELECT AccountId FROM Opportunity WHERE isClosed = false )

Relationship Query: parent to child
SELECT Id, (SELECT Id from OpportunityLineItems) FROM Opportunity

Relationship Query: child to parent 
SELECT Id, Name, Account.Name FROM Contact

Relationship Query: Polymorphic 
A polymorphic relationship field in object being queried that can reference multiple object types. For example, the What relationship field of an Event could be an Account, or a Campaign, or an Opportunity.
SELECT Id FROM Event WHERE What.TYPE IN ('Account', 'Opportunity')

With OFFSET
Use OFFSET to specify the starting row offset into the result set returned by your query.
SELECT Id, Name FROM Opportunity ORDER BY Name OFFSET 5

With GROUP BY
From API version 18.0 and later, you can use GROUP BY with aggregate functions, such as COUNT(), SUM() or MAX()
SELECT Stagename, COUNT(Id) FROM Opportunity GROUP BY Stagename

SELECT LeadSource, COUNT(Name) FROM Lead GROUP BY LeadSource
SELECT Stagename, SUM(amount) FROM Opportunity GROUP BY Stagename
SELECT CALENDAR_YEAR(CloseDate), COUNT(Id) FROM Opportunity GROUP BY CALENDAR_YEAR(CloseDate) ORDER BY CALENDAR_YEAR(CloseDate)

With GROUP BY ROLLUP
Same with GROUP BY, with additional ROLLUP, it add subtotal for aggregated data in the last row
SELECT Stagename, COUNT(Id) FROM Opportunity GROUP BY ROLLUP(Stagename)


With GROUP BY ROLLUP with 2 fields
SELECT Status, LeadSource, COUNTId) FROM Lead GROUP BY ROLLUP(Status, LeadSource)

HAVING in GROUP BY
You can use a HAVING clause with a GROUP BY clause to filter the results returned by aggregate functions, same with WHERE with normal query
SELECT LeadSource, COUNT(Id) FROM Lead GROUP BY LeadSource HAVING COUNT(Id) > 2

Querying Currency Fields in Multi-currency Organizations
SELECT Id, Name FROM Opportunity WHERE Amount > JPY5000
without currency code it will use organization's default currency

Salesforce Demo: Creating a sales process, record types and a pagelayout

Sometimes it's just much easier to watch the video:


Tuesday 26 November 2013

Salesforce Demo: Creating a simple workflow rule

Sometimes it's just much easier to watch the video:


Note: Rather than use "criteria is met" as in this video, you could use "formula evaluates to true" and "Amount  >= 5000 &&   (IsClosed  = false)"

Salesforce: Mass add member to Chatter group

Salesforce.com give 5,000 chatter free licenses, it is good for an organisation to use Chatter for collaboration as it is free. But, adding hundreds or thousands of users to Chatter groups will take you weeks and make you wish for a better life.


Luckily.......
You can use Data Loader to mass add SF users to Chatter group.


1. Open Data Loader
2. Click on Insert
3. Username  &  Password (SecurityToken if applicable) 
4. Click  Next
5. Click Checkbox for Show All Salesforce Objects, Find Chatter Group Member(CollaborationGroupMember)












6. Click Browse then  *select file* (CSV Type) That contains the additions - you will need a column for Chatter Group Id and User ID
7. Click  Next Then Okay 
8. Click Create or Edit a Map then Auto-Match Fields to Columns (Where possible)
9. Manually map any additional fields left out of the mapping - Map "CollaborationGroupId" to Chatter Group Id and MemberId to User Id
10. Click Okay Then Next 
11. Click Browse To *select directory* to store the success & error files
12. Click Okay Then Click Finish 

Saturday 23 November 2013

Salesforce - Buttons to Mass delete records / Get ids / Show google maps / Create a new record - URL hack /Clone a record - URL Hack/ insert a complete record - onclick javascript

Mass Delete


This example creates a button that can be added to activity related lists and list views, and allows users to delete selected records at the same time.
1 Define a button for events with these atributes:
Display Type─List Button
behavioue - execute javascript
content source - onclick javascript
add this code:
{!REQUIRESCRIPT("/soap/ajax/9.0/connection.js")}
var records = {!GETRECORDIDS( $ObjectType.Event )};
var taskRecords = {!GETRECORDIDS( $ObjectType.Task)};
records = records.concat(taskRecords);

if (records[0] == null) {
alert("Please select at least one record.") }
else {
var errors = [];
var result = sforce.connection.deleteIds(records);
if (result && result.length){
var numFailed = 0;
var numSucceeded = 0;
for (var i = 0; i < result.length; i++){
var res = result[i];
if (res && res.success == 'true'){
numSucceeded++;
} else {
var es = res.getArray("errors");
if (es.length > 0) {
errors.push(es[0].message);
}
numFailed++;
}
}
if (numFailed > 0){
alert("Failed: " + numFailed + "\nSucceeded: " + numSucceeded + " \n Due to: " + errors.join("\n"));
} else {
alert("Number of records deleted: " + numSucceeded);
}
}
window.location.reload();
}

2 add button to activity list views
3 add button to  to any page layout that contains an activity related list. The button deletes any selected task or event in the list.

Getting Record IDs

This example creates a button that opens a popup window listing record IDs for user selected records. This is useful when testing to ensure you have the correct record IDs before processing them further.

1 Define a button for events with these atributes:
Display Type─List Button
behavioue - execute javascript
content source - onclick javascript
add this code:
idArray = {!GETRECORDIDS($ObjectType.Contact)};
alert("The Ids you have selected are: "+idArray);

2 add button to  to the appropriate related list on a page layout or list view layout.

Get Google Map

This example creates a button that opens a new window showing a google map.  This is useful for anyone wanting to make a site visit.

1 define a new button at customise - accounts - actions links buttons with these attributes:
Display Type─Detail Page Button
behavioue - display in new window
content source - URL
add this code:

http://maps.google.com/maps?q={!Account_BillingStreet}%20{!Account_BillingCity}%20{!Account_BillingState}%20{!Account_BillingPostalCode}
2 add button too account page layout

Create a new record - url hack

1 Define a button for events with these atributes:
Display Type─List Button
behavioue - display in exiting window without sidebar or header
content source - URL

2 Define the URL as below:

the code to insert will essentially open the edit pagelayout for the object you want to create a new record with some values prepopulated from another related record.  This is usefull to save the user some time linking records correctly.

the url doesn't need the “https://na15.salesforce.com/” so the url starts after the / with “/a0U/e” - a0U is an object code and e represents edit so to find this simply push edit on on a relevant record and check the url in the browser whilst on the edit page (https://na15.salesforce.com/a0U/e?) you dont need the "?"

/a0U/e

so this is now good enough to place on a related list via the page layout editor but you will want to add values

to add values you will need to add the ? its used as a seperator

now goto setup of the object you are creating a record for and click on the field you want to preopulate and grab the field id from the url, you will then write in your field id and objectname.fieldname like this

/a0U/e?00Ni000000EpsgY={!Opportunity.Description}

for a lookup field you add CF to the front of the id

CF00Ni000000EpsgO

as this is a lookup we add the relationship parameter  add “_lkid” to the end of the id

/a0U/e?CF00Ni000000EpsgO={!Opportunity.Name}&CF00Ni000000EpsgO_lkid={!Opportunity.Id}

notice & is used to seperate fields

/a0U/e?00Ni000000EpsgY={!Opportunity.Description}&CF00Ni000000EpsgO={!Opportunity.Name}&CF00Ni000000EpsgO_lkid={!Opportunity.Id}

finally add a return url incase user cancels midway or on the save of the record

&retURL={!Opportunity.Id}  this will take yu back to the original record where you have placed your button
/a0U/e?00Ni000000EpsgY={!Opportunity.Description}&CF00Ni000000EpsgO={!Opportunity.Name}&CF00Ni000000EpsgO_lkid={!Opportunity.Id}&retURL={!Opportunity.Id} 

Clone a record - URL Hack

Here's an example for cloning a user record:
/{!User.Id}/e?clone=1&retURL=%2F{!User.Id}&name_firstName=&name_lastName=&Alias=&Email=&Username=&CommunityNickname=

you can see that by leaving some fields blank (eg. name_firstName=)  that you will not copy that fields value into the cloned record

insert a complete record onclick javascript


a - button to create a record
b - button to create a related child record
c - button to create parent and related child record

button to create a record
1 Define a button for events with these atributes:
Display Type─List Button
behavioue - Execute JavaScript

content source - onclick

2 define the javascript code:

you must include the libraries so add the following on the first line

{!REQUIRESCRIPT("/soap/ajax/29.0/connection.js")}

you'll need to create an object variable to hold our data. for example “acct”, as an Account record.

var acct = new sforce.SObject("Account");

now just populate the fields on the object like so

acct.name = 'New Account';
acct.phone = '515-123-4567';

Now that I have all my fields defined, I’m ready to save the new record.

var result = sforce.connection.create([acct]);

last is 

if(result[0].getBoolean("success")){
window.location = "/" + result[0].id + "/e";
}else{
alert('Could not create record '+result);

}


button to create a related child record if you are creating a child record you will have to identify the lookupfield to the parent

var parent = new sforce.SObject(“parent__c”);
parent.id = “{!lookuptoparentfromchildfield__c.Id}”;

create the child

var child = new sforce.SObject(“child__c”);

set field values for child

child.lookuptoparentfromchildfield__c = parent.id;
child.childfield2__c = “Test”;

save record

var result = sforce.connection.create([child]);

verify result

// verify the results
if(result[0].getBoolean(“success”)){
window.location = “/” + result[0].id + “/e”;
}else{
alert(‘Could not create record ‘+result);
}

button to create parent and related child record
you could combine both into one button like this:

{!REQUIRESCRIPT("/soap/ajax/29.0/connection.js")}
var parent = new sforce.SObject("parent__c");
var start = new Date;

parent.name = 'parentname';
parent.account_name__c = "{!Account.Id}";
parent.contact_name__c = "{!Contact.Id}";
parent.Due_Date__c = new Date(start.setDate(start.getDate() + 1));
parent.stage__c = "New";
parent.currencyisocode = 'GBP';

var resultparent = sforce.connection.create([parent]);

if(resultparent[0].getBoolean("success")){
 var newparentId = resultparent[0].id;
 var child = new sforce.SObject("child__c"); 

child.easy_opportunity__c = newparentId; 
 child.Sale_Price__c = "0.00"; 
 child.Status__c = "New"; 
 child.Name = "childname"; 
 child.CurrencyIsoCode = 'GBP'; 

 var resultchild = sforce.connection.create([child]); 

 if(resultchild[0].getBoolean("success")){ 
  window.location = "/" + newparentId; 
 }else{ 
  alert('Could not create record '+resultchild); 
 }
}else{
 alert('Could not create record '+resultparent);

}

Salesforce: Lead conversion mapping

When you convert a lead, the standard lead fields are automatically converted to the account, contact, and opportunity fields listed below.

Lead FieldMaps to
AddressAccount: Billing Address
Contact: Mailing Address
Annual RevenueAccount: Annual Revenue
CampaignOpportunity: Primary Campaign Source
If the lead has multiple associated campaigns, the most recently associated campaign is inserted into the opportunity regardless of whether the user has sharing access to it.
CompanyAccount: Account Name
Contact: Account
Opportunity: Account Name
Opportunity: Opportunity Name
Company Name (Local)Account: Account Name (Local)
DescriptionContact: Description
Do Not CallContact: Do Not Call
This field is not updated for leads converted to existing contacts.
EmailContact: Email
Email Opt OutContact: Email Opt Out
This field is not updated for leads converted to existing contacts.
FaxAccount: Fax
Contact: Fax
Fax Opt OutContact: Fax Opt Out
First NameContact: First Name
First Name (Local)Contact: First Name (Local)
IndustryAccount: Industry
Last NameContact: Last Name
Last Name (Local)Contact: Last Name (Local)
Lead OwnerAccount: Owner
Contact: Owner
Opportunity: Owner
Lead SourceContact: Lead Source
Opportunity: Lead Source
MobileContact: Mobile
No. of EmployeesAccount: Employees
Partner AccountOpportunity: Partner Account
This field is not updated for leads converted to existing opportunities.
PhoneAccount: Phone
Contact: Phone
RatingAccount: Rating
TitleContact: Title
WebsiteAccount: Website

If you are not using custom fiscal years, the Close Date of the newly created opportunity is automatically set to the last day of the current fiscal quarter.

If you are using custom fiscal years, the Close Date is the last day of the current fiscal period. If you are using custom fiscal years and a fiscal year has not been defined for the current date, the Close Date is the end of the current calendar quarter.

While custom lead fields are converted to custom account, contact, and opportunity fields as specified by system administrator.
To specify the mapping for custom lead fields:
  1. From Setup, click Customize | Leads | Fields | Map Lead Fields.
  2. For each custom lead field, choose a custom account, contact, or opportunity field into which you want the information inserted when you convert a lead.
  3. Click Save.
Remember to map custom lead fields to other custom fields of the same data type, that is, map numeric lead fields to other numeric fields or long text area fields to other long text area fields. Some exceptions are:
  1. You can map between text and picklist fields. However, your data may become truncated if the mapped text field is not large enough to hold the entire lead picklist value.
  2. You can map fields of type Text or Text Area to long text area fields
  3. You can map auto-number fields to fields of type Text, Text Area, or Picklist.
  4. Do not map custom formula fields to other formula fields or any other type of field.
Remember to map custom lead fields of type number, currency, or percent to other number, currency, or percent fields of exactly the same length and decimal places. For example, if your lead currency field has a length of 3 and 2 decimal places, map it to another custom currency field with a length of 3 and 2 decimal places.
Any standard lead picklist fields that are blank are mapped to the default picklist values for the account, contact, and opportunity.