function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Joseph BleauJoseph Bleau 

Is it possible to leverage SF.com built-in fuzzy matching on addresses within APEX code?

Hi all,

I'm hoping to leverage SF's existing fuzzy matching capability specifically with regards to addresses. Before I just implement their solution for myself I'm hoping the functionality is exposed somewhere.

See: https://help.salesforce.com/HTViewHelpDoc?id=matching_rules_matching_methods.htm&language=en_US#matching_rules_matching_methods

Specifically their fuzzy street matching algorithm (weighting number, street address, and suffix differently).

Is this possible?

Thanks,
Joe 
NagendraNagendra (Salesforce Developers) 
Hi Joseph,

You can use apex to show the duplicate records if any exists, that match your criteria, Check this working code below:

Visual Force Page:
<apex:pageBlock title="LeadDetail">

         <apex:pageBlockButtons location="top">
        <apex:commandButton value="Search" action="{!Search}" />
        <apex:commandButton value="Create" action="{!save}"/>
        </apex:pageBlockButtons>         

        <apex:pageBlockSection >
            <apex:pageBlockSectionItem >
            <apex:outputlabel value="Last Name" for="rep"/>
            <apex:inputField id="rep" value="{!newlead.lastname}" />
        </apex:pageBlockSectionItem>  
            <apex:inputField value="{!lead.company}" rendered="{!showmsg }"/>
            <apex:inputField value="{!lead.status}" rendered="{!showmsg }"/> 

      </apex:pageBlockSection>


     <apex:pageBlock title="Duplicate Records" rendered="{!hasDuplicateResult}">
        <apex:pageMessages />
        <apex:outputPanel layout="block" style="overflow:auto;width:750px;height:250px" >

        <apex:pageblocksection >

        <apex:pageblockTable value="{!test}" var="ac" columns="2" rendered="{!showmsg}">

<apex:column >
                <apex:facet name="header">Name</apex:facet>
               <apex:outputText value="{!ac.name}"></apex:outputText>
            </apex:column> 

           <apex:column >
           <apex:facet name="header">Status                         
                </apex:facet>
                <apex:outputText value="{!ac.status}"></apex:outputText>
           </apex:column>
Apex Class:
public class accountDedupeController {


 Private final Lead led;
 public lead newlead{get;set;}
public accountDedupeController(ApexPages.StandardController stdController) {
    this.led = (Lead)stdController.getRecord();
    showmsg = false;
    system.debug('3333333333333'+led.Lastname);
}
Public boolean showmsg{get;set;}    

public list<lead> test{get;set;}

public pagereference search(){
    system.debug('3333333333333'+led.Lastname);
    showmsg = true;
    string query;
    query = 'select id, name, firstname,lastname, status from lead where lastname like'+ '\'%'+ led.Lastname +'%\'';

    test= database.query(query);
    system.debug('22222222222'+query);
    system.debug('111111'+test+test.size());

    return null;
}

// Initialize a variable to hold the account record you're processing
private final lead lead;

// Initialize a list to hold any duplicate records
private List<sObject> duplicateRecords;

// Define variable that’s true if there are duplicate records
public boolean hasDuplicateResult{get;set;}

// Define the constructor
public accountDedupeController() {

    // Define the values for the account you’re processing based on its ID
    Id id = ApexPages.currentPage().getParameters().get('id');
    this.lead = (id == null) ? new lead() : 
        [SELECT Id, Name
         FROM Lead WHERE Id = :id];

    // Initialize empty list of potential duplicate records
    this.duplicateRecords = new List<sObject>();
    this.hasDuplicateResult = false;
}



 // Return account and its values to the Visualforce page for display
   public lead getlead() {
        return this.lead;
    }

    // Return duplicate records to the Visualforce page for display
    public List<sObject> getDuplicateRecords() {
        return this.duplicateRecords;
    }

// Process the saved record and handle any duplicates
public PageReference save() {

    // Optionally, set DML options here, use “DML” instead of “false” 
    //   in the insert()
     Database.DMLOptions dml = new Database.DMLOptions(); 
     dml.DuplicateRuleHeader.allowSave = true;
     dml.DuplicateRuleHeader.includeRecordDetails = true;
     dml.DuplicateRuleHeader.runsAsCurrentUser = true;
    Database.SaveResult saveResult = Database.insert(lead, false);

    if (!saveResult.isSuccess()) {
        for (Database.Error error : saveResult.getErrors()) {
            // If there are duplicates, an error occurs
            // Process only duplicates and not other errors 
            //   (e.g., validation errors)
            if (error instanceof Database.DuplicateError) {
                // Handle the duplicate error by first casting it as a 
                //   DuplicateError class
                // This lets you use methods of that class 
                //  (e.g., getDuplicateResult())
                Database.DuplicateError duplicateError = 
                        (Database.DuplicateError)error;
                Datacloud.DuplicateResult duplicateResult = 
                        duplicateError.getDuplicateResult();

                // Display duplicate error message as defined in the duplicate rule
                ApexPages.Message errorMessage = new ApexPages.Message(
                        ApexPages.Severity.ERROR, 'Duplicate Error: ' + 
                        duplicateResult.getErrorMessage());
                ApexPages.addMessage(errorMessage);

                // Get duplicate records
                this.duplicateRecords = new List<sObject>();

                // Return only match results of matching rules that 
                //  find duplicate records
                Datacloud.MatchResult[] matchResults = 
                        duplicateResult.getMatchResults();

                // Just grab first match result (which contains the 
                //   duplicate record found and other match info)
                Datacloud.MatchResult matchResult = matchResults[0];

                Datacloud.MatchRecord[] matchRecords = matchResult.getMatchRecords();

                // Add matched record to the duplicate records variable
                for (Datacloud.MatchRecord matchRecord : matchRecords) {
                    System.debug('MatchRecord: ' + matchRecord.getRecord());
                    this.duplicateRecords.add(matchRecord.getRecord());
                }
                this.hasDuplicateResult = !this.duplicateRecords.isEmpty();
            }
        }

        //If there’s a duplicate record, stay on the page
        return null;
    }

    //  After save, navigate to the view page:
    return (new ApexPages.StandardController(lead)).view();
    }

}
Please mark this thread as solved if it's resolved so that it gets removed from the unanswered queue which results in helping others who are really in need of it.

Best Regards,
Nagendra.P


 
David Roberts 4David Roberts 4
Hi Nagrenda,
This look interesting but I can't make it work.
I've added what I can guess are the missing lines to the vf page and built a test function for the controller extension but I can't fathom what it is supposed to do.
Can you supply the full vf page please?
Best regards,
Dave.
David Roberts 4David Roberts 4
Here's my attempt at the page:

<apex:page standardController="Lead" extensions="accountDedupeController">
<apex:form >
<apex:pageBlock title="LeadDetail">
 
         <apex:pageBlockButtons location="top">
        <apex:commandButton value="Search" action="{!Search}" />
        <apex:commandButton value="Create" action="{!save}"/>
        </apex:pageBlockButtons>        
 
        <apex:pageBlockSection >
            <apex:pageBlockSectionItem >
            <apex:outputlabel value="Last Name" for="rep"/>
            <apex:inputField id="rep" value="{!newlead.lastname}" />
        </apex:pageBlockSectionItem> 
            <apex:inputField value="{!lead.company}" rendered="{!showmsg }"/>
            <apex:inputField value="{!lead.status}" rendered="{!showmsg }"/>
 
      </apex:pageBlockSection>
</apex:pageblock>
 
     <apex:pageBlock title="Duplicate Records" rendered="{!hasDuplicateResult}">
        <apex:pageMessages />
        <apex:outputPanel layout="block" style="overflow:auto;width:750px;height:250px"/ >
 
        <apex:pageblocksection >
 
        <apex:pageblockTable value="{!test}" var="ac" columns="2" rendered="{!showmsg}">
 
<apex:column >
                <apex:facet name="header">Name</apex:facet>
               <apex:outputText value="{!ac.name}"></apex:outputText>
            </apex:column>
 
           <apex:column >
           <apex:facet name="header">Status                        
                </apex:facet>
                <apex:outputText value="{!ac.status}"></apex:outputText>
           </apex:column>
           </apex:pageblockTable>
           </apex:pageblocksection>
          
  </apex:pageblock> 
  </apex:form>      
</apex:page>
 
David Roberts 4David Roberts 4
My test class:

@isTest(SeeAllData=true)
private class FuzzyExtensionTest {
 
    static testMethod void myUnitTest() {
        PageReference pageRef = Page.leadDetail;
        system.debug('pr2='+pageRef);
        Test.setCurrentPage(pageRef);
        //test 00Q8E000002mavh albert
        pageRef.getParameters().put('id','00Q8E000002mavh');
        accountDedupeController theCont = new accountDedupeController();
        string tempstr;
       
        
        
        
        Lead theLead = theCont.getLead();
        system.debug(theLead);
       
 
    
    }//myUnitTest
 
}//FuzzyExtensionTest
 
David Roberts 4David Roberts 4
My extension class

public class accountDedupeController {
 
 
Private final Lead led;
public lead newlead{get;set;}
public accountDedupeController(ApexPages.StandardController stdController) {
    this.led = (Lead)stdController.getRecord();
    showmsg = false;
    system.debug('3333333333333'+led.Lastname);
}
Public boolean showmsg{get;set;}   
 
public list<lead> test{get;set;}
 
public pagereference search(){
    system.debug('3333333333333'+led.Lastname);
    showmsg = true;
    string query;
    query = 'select id, name, firstname,lastname, status from lead where lastname like'+'\'%'+ led.Lastname +'%\'';
 
    test= database.query(query);
    system.debug('22222222222'+query);
    system.debug('111111'+test+test.size());
 
    return null;
}
 
// Initialize a variable to hold the account record you're processing
private final lead lead;
 
// Initialize a list to hold any duplicate records
private List<sObject> duplicateRecords;
 
// Define variable that’s true if there are duplicate records
public boolean hasDuplicateResult{get;set;}
 
// Define the constructor
public accountDedupeController() {
 
    // Define the values for the account you’re processing based on its ID
    Id id = ApexPages.currentPage().getParameters().get('id');
    system.debug('lead id='+id);
    this.lead = (id == null) ? new lead() :
        [SELECT Id, Name, firstname, lastname, status
         FROM Lead WHERE Id = :id];
 
    // Initialize empty list of potential duplicate records
    this.duplicateRecords = new List<sObject>();
    this.hasDuplicateResult = false;
}
 
 
 
// Return account and its values to the Visualforce page for display
   public lead getlead() {
        return this.lead;
    }
 
    // Return duplicate records to the Visualforce page for display
    public List<sObject> getDuplicateRecords() {
        return this.duplicateRecords;
    }
 
// Process the saved record and handle any duplicates
public PageReference save() {
 
    // Optionally, set DML options here, use “DML” instead of “false”
    //   in the insert()
     Database.DMLOptions dml = new Database.DMLOptions();
     dml.DuplicateRuleHeader.allowSave = true;
     //dml.DuplicateRuleHeader.includeRecordDetails = true;
     //dml.DuplicateRuleHeader.runsAsCurrentUser = true;
    Database.SaveResult saveResult = Database.insert(lead, false);
 
    if (!saveResult.isSuccess()) {
        for (Database.Error error : saveResult.getErrors()) {
            // If there are duplicates, an error occurs
            // Process only duplicates and not other errors
            //   (e.g., validation errors)
            if (error instanceof Database.DuplicateError) {
                // Handle the duplicate error by first casting it as a
                //   DuplicateError class
                // This lets you use methods of that class
                //  (e.g., getDuplicateResult())
                Database.DuplicateError duplicateError =
                        (Database.DuplicateError)error;
                Datacloud.DuplicateResult duplicateResult =
                        duplicateError.getDuplicateResult();
 
                // Display duplicate error message as defined in the duplicate rule
                ApexPages.Message errorMessage = new ApexPages.Message(
                        ApexPages.Severity.ERROR, 'Duplicate Error: ' +
                        duplicateResult.getErrorMessage());
                ApexPages.addMessage(errorMessage);
 
                // Get duplicate records
                this.duplicateRecords = new List<sObject>();
 
                // Return only match results of matching rules that
                //  find duplicate records
                Datacloud.MatchResult[] matchResults =
                        duplicateResult.getMatchResults();
 
                // Just grab first match result (which contains the
                //   duplicate record found and other match info)
                Datacloud.MatchResult matchResult = matchResults[0];
 
                Datacloud.MatchRecord[] matchRecords = matchResult.getMatchRecords();
 
                // Add matched record to the duplicate records variable
                for (Datacloud.MatchRecord matchRecord : matchRecords) {
                    System.debug('MatchRecord: ' + matchRecord.getRecord());
                    this.duplicateRecords.add(matchRecord.getRecord());
                }
                this.hasDuplicateResult = !this.duplicateRecords.isEmpty();
            }
        }
 
        //If there’s a duplicate record, stay on the page
        return null;
    }
 
    //  After save, navigate to the view page:
    return (new ApexPages.StandardController(lead)).view();
    }
 
}