Friday, December 29, 2017

Deep study on Salesforce count() vs count(fieldName)

Some useful links that related with count :

"Count is used to discover the number of rows that a query returns. "
You will notice , there two versions of syntax for COUNT():

  • count()
  • count(fieldName)

I experienced using both but I am not really deep into WHY COUNT() and WHY COUNT(fieldName) until today I did some reading and testing.I found the differences is quite interesting.

Difference in Query Editor result :

No field return.It directly say Total Rows:17
Total Rows:1 and it returns field which 17.

Difference in Apex code :

Can be assigned to Integer directly.

Integer count =[SELECT COUNT() FROM Contact WHERE Account.Name Like 'Test%' ];
system.debug('count '+ count);

You cannot assigned it to Integer or object, you must assign it to AggregateResult.It will throw error if you try to assign it Integer or object.

List countWithFieldName =[SELECT COUNT(Name) FROM Contact WHERE Account.Name Like 'Test%' ];
system.debug('countWithFieldName '+ countWithFieldName);

Extra use and limitation :


  • It is simple, JUST TO RETURN THE NUMBER OF ROW.That's it.The ability to be assigned directly to Integer make it better for that purpose.
  • It cannot be used with other field in query example
Select COUNT(),Name from Account will throw error.
  • It cannot be used with ORDER BY.
  • It cannot be used with GROUP BY for API version 19.0 later
  • Database.countQuery also serves the same purpose
1String QueryString =
2    'SELECT count() FROM Account';
3Integer i =
4    Database.countQuery(QueryString);


  • It provide extra benefit if we want to generate reports for analysis by adding GROUP BY.
  • ORDER BY need to be used together with GROUP BY.
  • As you can see, you can have other field together with COUNT in SELECT statement.

Useful for reporting

What do you think?
Let me know.

Tuesday, December 12, 2017

Salesforce Certified Platform App Builder

On 4th Dec 2017 Malaysia time, I am officially certified as Salesforce Platform App Builder.Honestly I don't feel it easy due to tricky question.

TopicPercentage Correct
Data Modeling and Management83%
Salesforce Fundamentals80%
User Interface50%
App Deployment80%
Business Logic and Process Automation56%

Personally I believe working in Salesforce will not be enough if we have no idea how the questions will be asked in exam.Sometimes I get confuse with the sentences and easily fall into the trap.The feeling is like taking Science exam in Malay language and although I am Malay I still need to be careful with keyword and how tricky it could be.

Once you plan to sit for exam, I highly advice you to check out how the question being asked.This can be done by check out the Exam Guide, quizes or mock up questions.Be careful on mockup question's answer because it might not 100% accurate.Usually I will read the question and directly check out the topic to compare with the answer.Please do not memorize the answer but find WHY the answer was given.

Here I would like to share of the topic/question that I faced during the exam.I am not able to recall 100% the exact question but I believe some of content maybe helpful for you.

  1.  There one object that all employee should able to see it, Sales department should be able to edit based on regional.How you going to setup for this scenario
  2. The organization would like to share the record to all employee but only HR can view certain field.
  3. System admin try to convert master detail field to lookup field but fail to do so? Why?
  4. System admin try to convert Lookup field to Master detail field.Select how.It will give you the list of options.
  5. A company has custom object Interview and Candidate. How to know how many candidates for one interview ?
  6. Many to Many relationships 
  7.  Self relationships
  8. Which sandbox we can use Sandbox Template?
  9. The Sales Manager would like to use Visual Flow in creating guide for Sales rep, how to make Visual Flow accessible to the user?It can be tricky question because it might list all options to launch Visual Flow. You might want to check how Visual flow can be run at back end and how it can be deployed as wizard.
  10. The criteria of external id
  11. Is it possible? Will changes  cause data loss? Picklist to Multipicklist, Text to Rich Text?

Also please focus on the questions that will be asked the most first.You can check out the percentage here .I am participating in Trailhead a lot, I believe it helps.There one Trailmix that dedicated to Salesforce Platform App Builder Credential

All the Best

Saturday, October 14, 2017

Google Analytic Overview

I spent some time to understand Google Analytic(GA) as I have some project that might require it.

What is Google Analytic?
Google Analytics is a freemium web analyticsservice offered by Google that tracks and reports website traffic. Google launched the service in November 2005 after acquiring Urchin. Google Analytics is now the most widely used web analyticsservice on the Internet.Read more...
Simply say, it use to track our website such page view etc. which enable us to see the performace of our website.

There some pro and cons of using GA that has been mentioned in several sites.I just listed down what I want to know but I provide resource below so you can grab it for more info.

  1. It's free so everyone can use it.We can setup up to 100 analytic account  .
  2. It's almost complete feature even for free version .It has has almost every metric we may want to analyze such bounce rate, average time spent on page, etc.
  3. It can be used in different enviroment such as website or mobile.
  4. The information resources are  available widely.Google setup Google Analytic Academy . Wow, an academy just for this, surely there a lot to learn =)
  1. For free version, Google may have some advantage of retailer data.
  2. It might no so user friendly for none technical background user.Honestly, I feel a little bit difficult to start such as add new account and understand the term.But it's possible to learn and also I believe Google will improvise user interface.
  3. If you have high traffic website, you might want to consider Google Analytic 360 which is expensive ~$150,000 per year.

Some screenshot on creating analytic account.

The Create new account is nowhere to be found.You have to click on Admin then select on dropbox.

Some share setting that you might want to consider especially if your site is sensitive.

Sample of javascript that you might need to paste on your site header.

Analytic Account structure in Google Analytic
source:Account Structure
An Analytics account is a way to name and organize how you track one or more properties (e.g. websites, mobile apps, point-of-sale devices) using Analytics. Each Analytics user has access to at least one account, either one they created themselves, or one that they were given access to by someone else. In each Analytics account, at least one property (such as a website) is being tracked. As shown above, an Analytics account can be used to track a single property, or it can track many distinct ones, depending upon the requirements of its use.Read more...

Resources that I found useful :

Monday, October 02, 2017

Label on InputField and OutputField is not working

Actually I faced this issue quite few times and  because I didn't take note on it  I keep forgetting and asking the same question again.

Today, I got chance to do some testing to understand the behavior of apex:Inputfield and apex:outputField tag.

Note that apex:inputField / apex:outputField is tied to the field's object which mean we cannot use it without sObject.I like it's Calendar widget for date field but because it does not have capability to support class property, I need to tie it with Standard/Custom object's date field.

Here the example of usage

public class TestClass {

Date myDate {get;set;} //this will not work with  <apex:inputfield value="{!myDate}"  ...
Opportunity opp {get;set;} //this will work on <apex:inputfield value="{!opp.CloseDate}" ...


Other thing that we need to take note is the label will work in apex:pageBlock and only if the apex:pageBlock in the proper structure.

Checkout this code.

<apex:page standardController="Opportunity" showHeader="false" sidebar="false" >
        <apex:pageBlock title="Proper Page Block" mode="edit">
                <apex:commandButton action="{!save}" value="Save"/>
            <apex:pageBlockSection title="My Content Section" columns="2">
                <apex:inputField value="{!}"/>
                 <apex:inputField value="{!opportunity.type}" label="Custom Type"/>
                   <apex:outputField value="{!opportunity.accountId}" />
        <apex:pageBlock title="Not Proper Page Block" mode="edit">
                 <apex:inputField value="{!}" label="Custom Name"/>
                 <apex:inputField value="{!opportunity.type}"/>
                   <apex:outputField value="{!opportunity.accountId}" label="Account"/>
        Experiment outside page block : <apex:inputField value="{!}" label="Custom Name 1"/>
          <apex:outputField value="{!opportunity.accountId}" label="Account"/>

This is the output.Notice that apex:inputField and apex:outputField will not work without apex:pageBlock or improper structure apex:pageBlock.

Conclusion, in order to utilize apex:inputField and apex:outputField we need to use it with sObject and use it apex:pageBlock.

More info :

Wednesday, September 13, 2017

My journey on converting Attachment to Files in Salesforce

Everyone know that soon Salesforce will remove related list of Attachment & Note in Page Layout(implementation expected in Winter'18). This is indicate that we should start using Salesforce Files that have better features especially for sharing.

I started researching on this exercise somewhere in 2016 and I feel very grateful that I found a very good tool developed by Douglas C. Ayers.I have been testing the tool  in my organization and thanks to him because this app helps a lot of organization šŸ˜ƒ.

I am writing here to share experience. I am happy to inform that we completed our conversion successfully.These are few steps that perhaps you find it useful.Bear in mind that this approach may not suitable for you.Please do some research before implementing it.
  1. Refresh UAT with the latest Production data , install the app and run a lot of testing till you gain confidence.We hit the Content Publication Limits Exceeded which is annoying because we know our total Attachment is not even reach 200000.So we called Salesforce and it turned up they set it to 25 000 as default.So it's good to give them a call if you know that you should not hit the limit.
  2. Install to Production and make sure your setting it based on your need.
  3. Before we run , we need to plan conversion properly and to do so we need a report.Data loader can be used to retrieve it.I found that converting to Excel is very useful.Basically you may want to know how many object that have Attachment ,how many Attachment that we need to convert,ParentId etc. The simple query like below might be helpful
  4. Select Id,ParentId,Parent.Type,OwnerId ,Owner.IsActive from Attachment
  5. I just get complicated by creating visual force which is something like below.I labeled ParentType as 'Unknown' if the field value is null. 
  6. Decide which object that we want to convert, we may want to skip Unknown or 00X.Also we might want to put the sequence on which object that we should convert first.I prefer this approach because we can easily reduce the risk if something went wrong.We might want to start converting the object that has less Attachment first.
  7. ObjectTotal AttachmentNeed to convertSequenceConvertedRemark
    Marketing Support524Y2
    Account Plan4Y1

  8. Before start converting in Production, communicate with user.Ensure that they are aware on what happen to their Attachment and educate them about Files related list that they are going to see  in Page Layout once the conversion is completed.
  9. I copy ParentId  from the  query in previous step and use Excel to remove duplicate.For example, I copy ParentId of Opportunity and paste it into Excel and remove duplicate.We want to have unique parentId. As you can see, instead of running automate conversion for all, I manually paste the ParentId per object.
  10. Once the job is completed, I manually remove Attachment related list from Page Layout and replace it with Files related list.This will avoid user to keep uploading old Attachment in future.
  11. The job is faster that I expected. Once it completed, I checked Convert Attachment to Files log just in case there an error.Luckily we faced no error.
  12. Once I finished converted all of Attachment for object that we planned, I go to option Automate Conversion and run the schedule job in case there  old Attachment left over. We decided to run the schedule until end of this year.

  13. That's all. I hope you find this tips helpful.

Tuesday, August 29, 2017

Set Proxy for Migration Tool

When you  setup ANT and you believe it being setup correctly but still it still fail when you perform task, there are possibilities that your organization is using proxy.Example error that you receive when you run ant task.

Caused by: Failed to send request to https://
 Here I list down of steps that I did to overcome this:

  1. Ask Network team what is the proxy host and port in your organization.Is username and password is required?
  2. Define proxy in target.In build.xml , create target name like below.
  3. <target name="proxy">
            <property name="" value="xx.xx.xx.xx" />
            <property name="proxy.port" value="xxxx" />
            <!--If there username and password required
      <property name="proxy.user" value="UserName" />
            <property name="proxy.pwd" value="Password" />-->
            <setproxy proxyhost="${}" proxyport="${proxy.port}"  />

  4. Set depends to true for task that you going to perform.For example in given build.xml , I set depends for test and describeMetadata
  5.  <target name="test" depends="proxy"><!--set depends here-->
          <!-- Upload the contents of the "mypkg" package -->
          <sf:deploy username="${sf.username}" password="${sf.password}" sessionId="${sf.sessionId}" serverurl="${sf.serverurl}" maxPoll="${sf.maxPoll}" deployRoot="mypkg" rollbackOnError="true"/>
          <mkdir dir="retrieveOutput"/>
          <!-- Retrieve the contents into another directory -->
          <sf:retrieve username="${sf.username}" password="${sf.password}" sessionId="${sf.sessionId}" serverurl="${sf.serverurl}" maxPoll="${sf.maxPoll}" retrieveTarget="retrieveOutput" packageNames="MyPkg"/>
    Another example, I set at describeMetadata task.
    <!-- Retrieve the information on all supported metadata type -->
        <target name="describeMetadata" depends="proxy">
          <sf:describeMetadata username="${sf.username}" password="${sf.password}" sessionId="${sf.sessionId}" serverurl="${sf.serverurl}"/>
Now when I run ant test , the result will be like this :

C:\salesforce_ant_39.0\sample>ant test
Buildfile: C:\salesforce_ant_39.0\sample\build.xml
[sf:deploy] Using proxy: xx.xx.xx.xx:xxxx
[sf:deploy] Using proxy: xx.xx.xx.xx:xxxx
[sf:deploy] Request for a deploy submitted successfully.
[sf:deploy] Request ID for the current deploy task: 0Af4E00000QdHqLSAV
[sf:deploy] Waiting for server to finish processing the request...
[sf:deploy] Request Status: Pending
[sf:deploy] Request Status: Pending
[sf:deploy] Request Status: Pending
[sf:deploy] Request Status: Succeeded
[sf:deploy] *********** DEPLOYMENT SUCCEEDED ***********
[sf:deploy] Finished request 0Af4E00000QdHqLSAV successfully.
    [mkdir] Created dir: C:\salesforce_ant_39.0\sample\retrieveOutput
[sf:retrieve] Using proxy: xx.xx.xx.xx:xxxx
[sf:retrieve] Using proxy: xx.xx.xx.xx:xxxx
[sf:retrieve] Request for a retrieve submitted successfully.
[sf:retrieve] Request ID for the current retrieve task: 09S4E0000019PkVUAU
[sf:retrieve] Waiting for server to finish processing the request...
[sf:retrieve] Request Status: Pending
[sf:retrieve] Request Status: Succeeded
[sf:retrieve] Finished request 09S4E0000019PkVUAU successfully.
Total time: 1 minute 35 seconds
More details regarding Migration Tool can be found here.

Wednesday, August 16, 2017

Winmerge give me misguide message.

I am using Winmerge to compare code. For some reason, it give keep saying that the files are different while I really confident that I haven't touch the file.When I open the file , there no difference visibly shown which give me a little headache.

Turn out that I need to modify setting in Winmerge.Go to Edit, click on Options.

Now the view is better.

Saturday, July 01, 2017

Let it be...

Definition :

The let statement declares a block scope local variable, optionally initializing it to a value.

What different between var and let ?

It is mathematical statement.Remember in Math class, our teacher always mention let , for example:
If we let A be the statement "You are rich" and B be the statement "You are happy", then the negation of "A or B" becomes "Not A and Not B."
The question already answered in : Why was the name 'let' chosen for block-scoped variable declarations in JavaScript?

The different , notice the code below is using var, once you define same variable in local scope in second time , it will overwrite  the variable in global scope,

function varTest() {
  var x = 1;
  if (true) {
    var x = 2;  // same variable!
    console.log(x);  // 2
  console.log(x);  // 2

Using let, help to identify which belong to which.
function letTest() {
  let x = 1;
  if (true) {
    let x = 2;  // different variable
    console.log(x);  // 2
  console.log(x);  // 1
For details please refer to : let