New Batch#100 (10th Nov 2021) - Salesforce Admin + Dev Training (WhatsApp: +91 - 8087988044) :https://t.co/p4F3oeQagK

Saturday 10 November 2012

Difference between 15 digit Id and 18 digit Id in Salesforce

In salesforce each record Id represents a unique record within an organisation. There are two versions of every record Id in salesforce :
  • 15 digit case-sensitive version which is referenced in the UI
  • 18 digit case-insensitive version which is referenced through the API

The last 3 digits of the 18 digit ID are a checksum of the capitalizations of the first 15 characters, this ID length was created as a workaround to legacy systems which were not compatible with case-sensitive IDs.

The API will accept the 15 digit ID as input but will always return the 18 digit ID.

You can create a custom formula field that returns type text, place the code below  in the formula field , you will got an 18 digit ID that you can easily add to any report.

Id
& MID("ABCDEFGHIJKLMNOPQRSTUVWXYZ012345",(
    IF(FIND(MID(Id,1,1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ")>0,1,0)
    +IF(FIND(MID(Id,2,1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ")>0,2,0)
    +IF(FIND(MID(Id,3,1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ")>0,4,0)
    +IF(FIND(MID(Id,4,1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ")>0,8,0)
    +IF(FIND(MID(Id,5,1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ")>0,16,0)
    )+1,1)
& MID("ABCDEFGHIJKLMNOPQRSTUVWXYZ012345",(
    IF(FIND(MID(Id,6,1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ")>0,1,0)
    +IF(FIND(MID(Id,7,1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ")>0,2,0)
    +IF(FIND(MID(Id,8,1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ")>0,4,0)
    +IF(FIND(MID(Id,9,1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ")>0,8,0)
    +IF(FIND(MID(Id,10,1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ")>0,16,0)
    )+1,1)
& MID("ABCDEFGHIJKLMNOPQRSTUVWXYZ012345",(
    IF(FIND(MID(Id,11,1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ")>0,1,0)
    +IF(FIND(MID(Id,12,1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ")>0,2,0)
    +IF(FIND(MID(Id,13,1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ")>0,4,0)
    +IF(FIND(MID(Id,14,1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ")>0,8,0)
    +IF(FIND(MID(Id,15,1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ")>0,16,0)
    )+1,1)

How to calculate the 18 Digit Id from 15 Digit Id programatically:

//Our 15 Digit Id
String id = '00570000001ZwTi' ;

string suffix = '';
integer flags;

for (integer i = 0; i < 3; i++) {
          flags = 0;
          for (integer j = 0; j < 5; j++) {
               string c = id.substring(i * 5 + j,i * 5 + j + 1);
               //Only add to flags if c is an uppercase letter:
               if (c.toUpperCase().equals(c) && c >= 'A' && c <= 'Z') {
                    flags = flags + (1 << j);
               }
          }
          if (flags <= 25) {
               suffix = suffix + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.substring(flags,flags+1);
          }else{
              suffix += '012345'.substring(flags - 26, flags-25);
          }
     }

//18 Digit Id with checksum
System.debug(' ::::::: ' + id + suffix) ;

Apex Data Loader errors

1. Insert failed: inactive user
Ans. If you are trying to insert record for inactive user then this error come.

2. Entity deleted
Ans. If you are trying to insert any lookup filed of deleted record this error will come

3. Time Zone mismatch (unexpected result occur)
Ans. you should set the settings of data loader ( time zone filed) according to your sandbox or production environment. Otherwise it will compare with the previous day value of the current date day value.

Before event in trigger

* In before mode of the trigger, If you are trying to update records of the object on which you are performing the trigger operation then no need to use DML statements manually, automatically salesforce will update those records.
* If you are trying to update other object records then you should use DML statements.
--------------------
* Suppose one of the record which is not there in sObject based on that record only if you can perform operation(like inserting other records based on that record), in this case :
insert record in before mode(Trigger.isBefore) then based on that record you can insert other records in after mode(Trigger.inAfter)
--------------------

Data Loader batch size

* If the batch size is 50 then if one of the record in those 50 records failed to insert due to error all remaining records in that batch also fail.
* If you try to insert those failed records again with batch size '1' then most of the records will get insert apart from those records which causing problem really.

Wednesday 17 October 2012

maximum trigger depth exceeded MyObject__c trigger

* The above error is mainly because of the recursive execution of the trigger after update again and again.
* To control the recursive trigger, use if condition or any other controllable steps to avoid the recursion.
Refer:
http://boards.developerforce.com/t5/Apex-Code-Development/Classic-Error-maximum-trigger-depth-exceeded-Opportunity-trigger/td-p/209817

Using case in formula fields of sfdc

CASE(MONTH(Mon_Field__c ), 01, 'January/2012', 02, 'February/2012',03, 'March/2012',04,'April/2012',05, 'May/2012',06,'June/2012',07,'July/2012',08,'August/2012',09, 'September/2012',10,'October/2012',11,'November/2012',12,'December/2012','')

* In the above formula, to display year dynameically intead of 'January/2012' use like below:
'January/'+Text( YEAR(Mon_Field__c ))

Scheduling Batch Class after 6 minutes whenever a batch finish method executed in salesforce

AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,
         TotalJobItems, CreatedBy.Email
         FROM AsyncApexJob WHERE Id =:BC.getJobId()];

* Above syntax is to retrieve information regarding to the jobs.
             Batch_classname bs = new Batch_classname();
             Datetime sysTime = System.now();
             sysTime = sysTime.addminutes(6);
             String chron_exp = '' + sysTime.second() + ' ' + sysTime.minute() + ' ' +
             sysTime.hour() + ' ' + sysTime.day() + ' ' + sysTime.month() + ' ? ' + sysTime.year();           
             System.schedule('Update Actual'+sysTime.getTime(),chron_exp, bs);

Tuesday 16 October 2012

Scheduling batch class for every 5 minutes using system.schedule method in salesforce

Batch_scheduledclassname bs = new Batch_scheduledclassname bs();
String sch = '0 6 * * * ? ';
System.schedule('My Job1', sch, bs);

Note: While writing schedular class don't forget to use datebase.executeBatch method which inturn will run the apex batch class.
* Above 6 means every hour 6th minute.
* If you want to schedule the calss for every 5 minutes then you need paste above code with some changes for 10 times in developer console.
* Changes are:
- instead of 6 replace with 12,18,24..... like that.
- Change the Batch Job name My Job1 to some other name whenever we want to submit new job

Tuesday 2 October 2012

Using Batch Apex to Change the Account Owners


global class AccountOwnerReassignment implements 
             Database.Batchable<SObject>, Database.Stateful{
    
    User fromUser{get; set;}
    User toUser{get; set;}
    Double failedUpdates{get; set;}
    //Parameter Construcotr
    global AccountOwnerReassignment(User fromUser, User toUser){
        this.fromUser = fromUser;
        this.toUser = toUser;
        failedUpdates = 0;
    }
    
    global Database.queryLocator 
                    start(Database.BatchableContext ctx){
        return Database.getQueryLocator([SELECT id, name, ownerId 
                        FROM Account WHERE ownerId = :fromUser.id]);
    }
    
    global void execute(Database.BatchableContext ctx, List<Sobject> scope){
        List<Account> accs = (List<Account>)scope;
        
        for(Integer i = 0; i < accs.size(); i++){
            accs[i].ownerId = toUser.id;
        }
        
        List<Database.SaveResult> dsrs = Database.update(accs, false);
        for(Database.SaveResult dsr : dsrs){
            if(!dsr.isSuccess()){
                failedUpdates++;
            }
            
        } 
    }
    
    global void finish(Database.BatchableContext ctx){
    
        AsyncApexJob a = [SELECT id, ApexClassId, 
                       JobItemsProcessed, TotalJobItems, 
                       NumberOfErrors, CreatedBy.Email 
                       FROM AsyncApexJob 
                       WHERE id = :ctx.getJobId()];
        
        String emailMessage = 'Your batch job '
             + 'AccountOwnerReassignment '
             + 'has finished.  It executed ' 
             + a.totalJobItems 
             + ' batches.  Of which, ' + a.jobitemsprocessed 
             + ' processed without any exceptions thrown and ' 
             + a.numberOfErrors +
             ' batches threw unhandled exceptions.'
             + '  Of the batches that executed without error, ' 
             + failedUpdates 
             + ' records were not updated successfully.';
        
        Messaging.SingleEmailMessage mail = 
              new Messaging.SingleEmailMessage();
        String[] toAddresses = new String[] {a.createdBy.email};
        mail.setToAddresses(toAddresses);
        mail.setReplyTo('noreply@salesforce.com');
        mail.setSenderDisplayName('Batch Job Summary');
        mail.setSubject('Batch job completed');
        mail.setPlainTextBody(emailMessage);
        mail.setHtmlBody(emailMessage);
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] 
                           { mail });
    }    
}
In Developer Console Paste below code:

User fromUser = [select id,firstname from user where firstname = 'name of the user'];
User toUser = [select id,firstname from user where firstname = 'name of the user'];                 
Database.executeBatch(new AccountOwnerReassignment(fromUser,toUser));
Note: Name of the user means, Goto Managed Users>Click on particuar user> At the top below the User one name will display that name we should give in place of 'name of the user'

Calling Batch Apex from Trigger:
* Goto App Setup> Customize> Account> Triggers

Trigger AccountOwnerReassignment on Account (before insert) {
    List<Account> al = Trigger.new;
    for(Account a:al) {
        User fromUser = [select id,firstname from user where alias = 'alias name'];
        User toUser = [select id,firstname from user where alias = 'alias name'];                 
        try {
            Database.executeBatch(new AccountOwnerReassignment(fromUser,toUser));
        }
        Catch(Exception E) {
        }
    }
}
Note: In case, no rows queried from the SOQL Queries below error will arise.
Error: Invalid Data. Review all error messages below to correct your data.Apex trigger AccountOwnerReassignment caused an unexpected exception, contact your administrator: AccountOwnerReassignment: execution of BeforeInsert caused by: System.QueryException: List has no rows for assignment to SObject: Trigger.AccountOwnerReassignment: line 4, column 1

Refer:
http://developer.force.com/cookbook/recipe/using-batch-apex-to-reassign-account-owners

Monday 1 October 2012

Changing hyperlink from one color to another color



<script type="text/javascript"> 
  function turnRed(id) { 
  alert("hi"); 
  var myPara = document.getElementById(id); 
  alert(myPara); 
  myPara.style.color = "green"; 
  } 
  </script> 
  <apex:commandLink action="{!gogoogle}" target="_blank" value="Go Google" id="check" style="color:red" onclick="turnRed('{!$Component.check}')"/>

Sunday 30 September 2012

custom login page

Refer:
http://boards.developerforce.com/t5/Visualforce-Development/custom-login-page/m-p/501739

Saturday 29 September 2012

Div and Span html tags difference

Div: We can define a section and apply CSS Styles.
Span: We can define an element or area of a section and we can apply CSS Styles.
Refer:
http://www.slideshare.net/biswadip/span-and-div-tags-in-html
http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_span

Friday 28 September 2012

CSS for changing the color of a hyper link


<apex:page sidebar="false" standardController="Sample__c">
    <head>
    <style type="text/css">
    a:link {
    COLOR: #FF0000;
    }
    a:visited {
    COLOR: #008000;
    }
    a:hover {
    COLOR: #FF0000;
    }
    a:active {
    COLOR: #00FF00;
    }
</style> 
    </head>
    <apex:form >
        <!-- Designing Sidebar -->
        <table>
         <tr>
          <th width="200" valign="top">
        <apex:outputPanel >
            <apex:pageblock title="Sidebar">
                <apex:pageblockSection columns="1">
                    <apex:commandlink value="One"/>
                    <apex:commandlink value="Two"/>
                </apex:pageblockSection>
            </apex:pageblock>
        </apex:outputPanel>
        <!-- All pages comes here -->
         </th>
         <th>
        <apex:outputPanel >
            <apex:pageblock title="One">    
                <apex:pageblockSection >
                    <apex:inputField value="{!Sample__c.name}"/>
                    <apex:inputField value="{!Sample__c.City__c}"/> 
                </apex:pageblockSection>
            </apex:pageblock>
            <apex:pageblock title="Two"> 
                <apex:pageblockSection >
                    <apex:inputField value="{!Sample__c.Mobile__c}"/>
                    <apex:inputField value="{!Sample__c.Salary__c}"/> 
                </apex:pageblockSection>
            </apex:pageblock>
        </apex:outputPanel>
          </th>
         </tr>
        </table> 
    </apex:form>
</apex:page>

<apex:page sidebar="false" standardController="Sample__c" Extensions="sample">
<body text="#507070" link="#900000" alink="#D06000" vlink="#C08000" bgcolor="#FFD078">
    <apex:form >
        <!-- Designing Sidebar -->
        <table>
         <tr>
          <th width="200" valign="top">
        <apex:outputPanel >
            <apex:pageblock id="Sidebar">
                <apex:pageblockSection columns="1" title="Sidebar" collapsible="false">
                    <apex:commandlink value="One" action="{!pageOne}" style="color: #CC0000"/>
                    <apex:commandlink value="Two" action="{!pageTwo}"/>
                </apex:pageblockSection>
            </apex:pageblock>
        </apex:outputPanel>
        <!-- All pages comes here -->
         </th>
         <th>
        <apex:outputPanel >
            <apex:pageblock title="One" rendered="{!page1}">    
                <apex:pageblockSection >
                    <apex:inputField value="{!Sample__c.name}"/>
                    <apex:inputField value="{!Sample__c.City__c}"/> 
                </apex:pageblockSection>
            </apex:pageblock>
            <apex:pageblock title="Two" rendered="{!page2}"> 
                <apex:pageblockSection >
                    <apex:inputField value="{!Sample__c.Mobile__c}"/>
                    <apex:inputField value="{!Sample__c.Salary__c}"/> 
                </apex:pageblockSection>
            </apex:pageblock>
        </apex:outputPanel>
          </th>
         </tr>
        </table> 
    </apex:form>
    </body>
</apex:page>

Refer:
http://www.goldcoastwebdesigns.com/change-hyperlink-color.shtml

Tuesday 25 September 2012

Data Loader CLI

Data Loader CLI (Command Line Interpreter):
* For automating the batches and schedule them using windows "Task Scheduler".
* We can perform import as well as export.
Windows-7 Task Scheduler
* We can do all the same things from the command line - insert data, update data, upsert data, delete data or extract data.
* Instead of "export", we should use "extract".
* We can move data to and from a comma-separated variable file (.csv) or to and from a relational database, such as Oracle or SQL Server, that has a standard JDBC driver.
* With a default installation on a Windows machine, all the Data Loader files will be placed in the Program Files\salesforce.com\Apex Data Loader APIversion directory, where APIversion corresponds to the API version.
* The process command, encrypt command will be in the bin subdirectory, and the configuration files will normally be in the conf subdirectory.
*The main configuration file used by the CLI is the process-conf.xml file.
* The process-conf.xml file contains a description for every potential process that could be called from the command line.
* Each of these processes is referred to as a Process Bean. 
* In this simple example, there is only one Process Bean in the process-conf.xml file.
* In normal practice, though, you would have a number of Process Bean sections in the configuration file, so calling out the specific process would make sense.
* The process-conf.xml file consists of a set of property-value pairs.
* The file used for this sample process is shown below, with an explanation of the key entries following the listing.
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean id="csvInsertArtist"
          class="com.salesforce.dataloader.process.ProcessRunner"
          singleton="false">
        <description>Inserts artist names from CSV file into Artist custom object.</description>
        <property name="name" value="csvInsertArtist"/>
        <property name="configOverrideMap">
            <map>
                <entry key="sfdc.debugMessages" value="false"/>
                <entry key="sfdc.debugMessagesFile" value="c:\dataloader\csvInsertArtist.log"/>
                <entry key="sfdc.endpoint" value="https://www.salesforce.com"/>
                <entry key="sfdc.username" value="<i>Your Salesforce ID</i>"/>
                <entry key="sfdc.password" value="<i>Your encrypted Salesforce password</>"/>
                <entry key="sfdc.timeoutSecs" value="540"/>
                <entry key="sfdc.loadBatchSize" value="200"/>
                <entry key="sfdc.entity" value="Artist__c"/>
                <entry key="process.operation" value="insert"/>
                <entry key="process.mappingFile" value="c:\dataloader\artistmap.sdl"/>
                <entry key="process.outputError" value="c:\dataloader\errorInsertArtist.csv"/>
                <entry key="process.outputSuccess" value="c:\dataloader\successInsertArtist.csv"/>
                <entry key="dataAccess.name" value="c:\dataloader\Artists_1_100.csv" /> 
                <entry key="dataAccess.type" value="csvRead" /> 
                <entry key="process.initialLastRunDate" value="2007-06-06T00:00:00.000-0800"/>
            </map>
        </property>
   </bean>
</beans>
 Configuration properties:
The process-conf.xml file contains properties for one or more Process Beans. Some of the more important properties are
  • name - used to identify the bean in the config.properties file and when you call it from the CLI
  • sfdc.entity - the Salesforce object that is the target of the actions. The value of this property is case sensitive.
  • process.operation - identifies the type of operation
  • process.mappingFile - identifies the mapping between the fields in the source file (dataAccess.name) and the Salesforce object. This mapping file is a .sdl file. The mapping file is the same format as the .sdl file created by the GUI when you save a mapping scheme.
  • dataAccess.type - identifies the operation to perform on the source file
  • sfdc.username - your Salesforce.com user name 
* To schedule the file we should open windows Task Scheduler.
C:\Program Files (x86)
C:\Program Files (x86)\salesforce.com\Data Loader\bin
process ../conf csvInsertArtist

* C:\Program Files (x86)
C:\Program Files (x86)\salesforce.com\Data Loader\bin
process ../conf csvInsertArtist
-- Save it as filename.bat--
Refer:
Data Loader CLI

Report should be available only to CEO, for others it should be hide, how can we do it?

For a specific Report:
* Specific Report can be controlled by creating a custom report folder and assigning just the CEO as a viewer of this folder. All reports in the folder will be visible to the CEO only in that scenario.
* Observe below screen shots:


 For the Reports Tab:
* Reports Tab can be controlled by the User Profile

Sunday 23 September 2012

Adding a custom button to page layout

* Go to Object detail page> Go to Custom buttons and links section > create a custom button
* After creating custom button Go to page layout of the object> there you can find buttons and links option> click on that and drag to custom buttons and links area

Friday 21 September 2012

Is it possible to refer static resources files in formula fields

Unfortunately, it does not. The reason is that static resources cannot be referenced in formula fields.

But no big deal, because each static resource gets its own unique URL. So you could go to your static resource and click ‘Click here to view this file’ 
 
Refer:
http://improveit360.blogspot.in/2010/09/how-to-use-static-resource-images-in.html

Wednesday 12 September 2012

Annotations

Annotations:
* An Apex annotation modifies the way a method or class is used, similar to annotations in Java.
* Annotations are defined with an initial @ symbol, followed by the appropriate keyword.
* To add an annotation to a method, specify it immediately before the method or class definition.
global class MyClass {
     @future
     Public static void myMethod(String a)
     {
          //long-running Apex code    
     }
}
Annotations supported by Apex
Annotation Name
Description
@Deprecated
* Use the deprecated annotation to identify methods, classes, exceptions, enums, interfaces or variables that can no longer be referenced in subsequent release of the managed package in which they reside.
* This is useful when you are refactoring code in managed package as the requirements evolve.
* New subscribers cannot see the deprecated elements, while the elements continue to function for existing subscribers and API integrations.
Syntax:
@deprecated
//This method is deprecated, use myOptimizedMethod(String a, String b) instead
Public void myMethod(String a) {
}

@Future

@IsTest

@ReadOnly

@RemoteAction


Latest Versions in SFDC



Name
Latest Version
Apex Data loader
29.0
Force.com API
29.0
Force.com IDE
29.0.0 (compatible with Eclipse 4.2 and 4.3)
Salesforce.com
Winter' 2014


Labels