Pages

Tuesday, September 24, 2013

Salesforce: Mass Upload files to Attachment using Data Loader


Background: user need to mass upload files as attachment in Account or Opportunity.

Solution: Using Data Loader to mass upload files to attachment. If you need to regularly do mass upload, you can schedule Data Loader, see this user guide.

For loading file as Files (not as Attachment), check this blog Mass Upload files to Files using Data Loader.

1. Prepare CSV file
You can use Ms Excel to create new CSV file with following columns:
  • ParentId - Id of the record to which the attachment should be associated 
  • Name - Name of the attachment (you can put file name here)
  • ContentType - Format of the extension (e.g. image/jpeg, application/vnd.ms-excel, etc), if you not sure, you can run SOQL query to Attachment object for similar file type. However, this field is not mandatory, so you can leave it blank or un-map it.
  • OwnerId - Id for the owner of the attachment (UserId). If you not put any UserId here, your UserId will be OwnerId
  • Body - File path to the attachment on the local machine (C:\temp\how to make gold.png)

2. Login to Apex Data Loader
  • Select the "Insert" button. 
  • In the 'Select Salesforce Object' window, select the 'Show all Salesforce Objects' checkbox and then select "Attachment". 
  • Choose the CSV file you have prepare above. 
  • In the mapping step, map the following fields:


Click "OK" to proceed with the insert. It may take a few minutes depends on the number of file and file size, but the attachments should be successfully uploaded to your Salesforce.

Hope this help.

Monday, September 23, 2013

Salesforce: Hidden Tab for Custom Object

Tab is one of the very useful feature in Salesforce and it is very simple. It provide user ability to create view to list all records or records with some criteria.

After create a custom object, admin can simply create a new tab from Setup - Create - Tabs and select Custom Object Tabs then create New button. But, if you are not using Unlimited Edition, there are number of maximum tab we can create based on the Salesforce edition, see the limit here.

Here a tip to create a hidden tab for custom object, meaning admin do not need to create new Tab, but we can use the function, here we go:

1. After custom object created, get the 3 characters Id Prefix
How to get the the prefix?

  • If you are using Force.com IDE, look for salesforce.schema for that object


2. Type the prefix after Salesforce.com URL 
Example: object prefix is a03, type in the URL https://na3.salesforce.com/a03
Change 'na3' with your Salesforce.com instance and make sure NOT to add / after the prefix.





Sunday, September 22, 2013

Salesforce: Log A Call with Activity Type auto populated

Type is a standard picklist field in Salesforce Activity object. User can add / remove values in the picklist.

When user click "Send an Email" button from Activity History related list of Account, Contact, Opportunity, or from any other object page layout, system admin can define default value equal to "Email" (for example). So, task created will be always assigned to Email.

But, when user click "Log A Call" button (also in Activity History related list ), Type will be blank. This is not ideal, system should be smart enough to auto-populate Type to Call (or any other value default in the system set by system admin).

Is the any workaround? YES. Here we go:
  • Create a custom button from: Setup - Customize - Activities - Task Buttons, Links, and Actions
  • Click "New Button or Link" button
  • Enter following data as screenshot below:
  • Click "Save" button to save it.
  • Go to object page layout, such as Contact page layout, edit the page layout and scroll to "Activity History" related list
  • Untick standard "Log A Call" button and add custom button created above

  • Done
But, here is the downside, if you notice in screenshot above, you see many buttons: "Contact Log A Call", "Account Log A Call", etc... this is because you need a button for each object. This is caused by the URL in the button
/00T/e?who_id={!Contact.Id}&tsk10=Call&retURL=%2F{!Contact.Id}

See there is Contact Id in who_id parameter, and for Account and Opportunity, you need to put their Id to what_id parameter.

Friday, September 13, 2013

Salesforce: change email address without confirmation


As security measure in Salesforce, when admin change user email address (maybe in sandbox, typo or other reasons), Salesforce will send an verification email to the new email address, user need to verify by click a link in the email. Before user verify the link, email address will not change, no matter how many times you do it, even using API.

But, can admin change the email address without confirmation email? Yes, here is the trick:
  • Click Edit on user detail page
  • Change the email address AND check "Generate new password and notify user immediately" checkbox (all the way at the bottom of the edit screen) at the same time
  • Click Save button
Salesforce will change email address immediately, no confirmation is needed! But, of course password will be reset and user will get email from Salesforce with a new temporary password. This is still better than ask user to verify email changed then reset password.


Thursday, September 12, 2013

Salesforce: SOQL Reference

Using a query tool of your choice (e.g., the Developer Console Query Editor, Workbench), you can execute the SOQL (Salesforce Object Query Language) query to get raw data from Salesforce, where some of this is unavailable from the report.

Simple query
SELECT Id, Name FROM Account WHERE Name LIKE 'A%'
SELECT Id, Name FROM Account WHERE Name LIKE 'A%' AND BillingCity = 'Redwood City'
SELECT Id, Name FROM Account WHERE CurrencyIsoCode = 'USD' OR CurrencyIsoCode = 'SGD'

Query with LIKE and NOT
SELECT a.Id, a.Name FROM Account a WHERE NOT a.Name LIKE 'A%'
SELECT Id, Name FROM Account WHERE AND BillingCity = 'Redwood City' AND (NOT Name LIKE '%Vendor%')
** NOT should be put before the field name
** Notice usage of a variable

However, in some fields like the Id or polymorphic relationship field, we cannot use LIKE.
For Task and Event object, if you know the related object, you can filter with the object name
SELECT Id, WhatId, What.Type, What.Name  FROM Task WHERE What.Type IN ('Account','Opportunity') LIMIT 100

Query filter on DateTime
SELECT Name FROM Account WHERE CreatedDate >= 2011-04-26T10:00:00-08:00 this is GMT-8
SELECT Name, CreatedDate FROM Account WHERE CreatedDate > 2011-04-26T10:00:00Z this is GMT

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

Query filter on a null value
SELECT Id, AccountId FROM Event WHERE ActivityDate != Null
same result using <> 
SELECT Id, AccountId FROM Event WHERE ActivityDate <> Null

SELECT Id, AccountId FROM Event WHERE ActivityDate = Null

SELECT Id, AccountId FROM Event WHERE AccountId = Null
same result using '' SELECT Id, AccountId FROM Event WHERE AccountId = ''
But you can't use '' for the Date field and for the Number field


Query Multi-Select Picklists
SELECT Id, Country__c from Account WHERE Country__c INCLUDES ('Indonesia;Singapore','Malaysia')

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' )
To query attachment from an object only
SELECT Id, Name, ParentId FROM Attachment WHERE ParentId IN ( SELECT Id FROM Account )

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,Name from OpportunityLineItems) FROM Opportunity
SELECT Id, (SELECT Id,Name from Account_Requests__r) FROM Account
Notice for the child object name in yellow highlight, it is plural. You can get the name from the lookup field in the child object "Child Relationship Name" and add __r for custom field.

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

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

SELECT Id, WhatId, 
  TYPEOF What WHEN Account THEN BillingState, BillingCity END 
FROM Task WHERE WhatId IN (SELECT Id FROM Account)


SELECT 
  TYPEOF What
    WHEN Account THEN Phone, NumberOfEmployees
    WHEN Opportunity THEN Amount, CloseDate
    ELSE Name, Email
  END
FROM Event

Select ALL
In standard SQL, we can use SELECT * from table_name, but this is not available in SOQL
In API 51.0, Salesforce introduced 
  FIELDS(ALL)—to select all the fields of an object.
  FIELDS(CUSTOM)—to select all the custom fields of an object.
  FIELDS(STANDARD)—to select all the standard fields of an object
Sample: SELECT FIELDS(ALL) FROM Account LIMIT 200
Reference FIELDS()

Using 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
OFFSET 0 means no record is removed in the result, OFFSET 1 means the first row will not be shown, etc.

Using NULLS {FIRST|LAST}
If records are null, you can use ORDER BY to display the empty records first or last. By default, null values are sorted first. You can use ORDER BY with the optional LIMIT qualifier in a SELECT statement.
SELECT Name FROM Account WHERE industry = 'media' ORDER BY BillingPostalCode ASC NULLS LAST LIMIT 125

Using COUNT
Returns the number of rows matching the query criteria
SELECT COUNT() FROM Account WHERE Name LIKE 'a%'
SELECT COUNT(Id) FROM Account WHERE Name LIKE 'a%'
If you are using a GROUP BY clause, use COUNT(fieldName) instead of COUNT()

Using COUNT_DISTINCT
Returns the number of distinct non-null field values matching the query criteria
SELECT COUNT_DISTINCT(Company) FROM Lead
This will return the number of distinct values from the Company field

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

SELECT LeadSource, COUNT(Name) FROM Lead GROUP BY LeadSource

SELECT StageName, SUM(amount), MAX(amount), MIN(amount), AVG(amount) FROM Opportunity GROUP BY StageName

SELECT CALENDAR_YEAR(CloseDate) Year, CALENDAR_MONTH(CloseDate) Month, COUNT(Id) TotalCount FROM Opportunity WHERE IsClosed = False GROUP BY CALENDAR_YEAR(CloseDate), CALENDAR_MONTH(CloseDate) ORDER BY CALENDAR_YEAR(CloseDate) ASC



Note: you cannot use a formula field for grouping.

Using Alias with GROUP BY
You can use an alias for any field or aggregated field in a SELECT statement in a SOQL query. Use a field alias to identify the field when you’re processing the query results in your code.
SELECT StageName, SUM(amount) Jumlah, MAX(amount), MIN(amount), AVG(amount) FROM Opportunity GROUP BY StageName ORDER BY SUM(amount) Desc

Using GROUP BY ROLLUP
Same with GROUP BY, with additional ROLLUP, it adds subtotal for aggregated data in the last row
SELECT StageName, COUNT(Id) FROM Opportunity GROUP BY ROLLUP(StageName)


Using GROUP BY ROLLUP with 2 fields
SELECT Status, LeadSource, COUNT(Id) FROM Lead GROUP BY ROLLUP(Status, LeadSource)

*Yellow highlight = total subgroup
*Green highlight = total all  


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, Amount, CurrencyIsoCode FROM Opportunity WHERE Amount > SGD5000 ORDER BY Amount
** without currency code it will use the organization's default currency
** Amount in query result will be in record currency



Reference: 

Edit Data in Salesforce Report

Using report builder, creating a tabular report in Salesforce is something very easy can be done by any users. But, how about adding an Edit link in the report, would it be awesome? Once user click the link, it will bring user to the page layout in edit mode without have to open the record, so less click!!! (as long as user have the permission to edit the data)

Here sample for Opportunity:

1. Create a formula field in Opportunity
  • Do not need to add the field to any page layout, but make it visible to Profiles as required
  • Set Formula Return Type = Text
  • Type Label = Action
  • Formula = HYPERLINK('006/e?id='&Id, 'Edit' , '_blank'), this formula will open new tab in the web browser when user click Edit link in report, or change _blank to _self if you prefer user to open the record in the same tab, meaning it will close the report.

2. Create Opportunity report
  • Select Tabular format report
  • Drag fields needed to the report and add the filters as normal report
  • Drag Action field from field list, preferably at the most left.


Note: if you need to have Action field for each object in the report, you need to create the formula field for that object.

Page-level ad