2017.05.23

重複管理をしてみよう ~登録時に重複チェック~

  • このエントリーをはてなブックマークに追加
  • follow us in feedly

皆さん、こんにちは。
最近暑いですね。。これでも全国的にはまだまだ梅雨明けしていないので、これからが夏本番。頑張っていきましょうー!
もう夏ですね

さて本題です。Salesforceの重複管理機能を使っていますか?

重複管理は、レコード登録時に登録済みの重複レコードを検出し、重複結果を管理するための機能です。データクレンジングに苦労されている方達の手間を軽減できるかと思います。
今回はこの重複管理をSkyVisualEditorページに適用してみます。

とは言ってみたものの、SkyVisualEditorの標準機能には重複管理機能はありません。
ですので、「拡張Apexクラス」機能と非公開の「コードブロック」コンポーネントを使って実現します。

「コードブロック」コンポーネントとは
SkyVisualEditor Studio画面にて直接VisualforceページコードやHTMLを記述できる機能です。
現在、非公開となっていますが、ご要望があれば公開しますので個別に連絡をお願いします。

重複エラーが発生した時は、下記のスクリーンショットのように以下の機能を実装することが可能です。

  • 重複エラーメッセージを表示
  • 重複していると思われる登録済みのレコードを表示
  • 重複エラーメッセージ表示しても強制保存可能な保存ボタンに切り替え

重複エラーメッセージ表示時画面

では、これを実装するための手順を紹介します。

1. Salesforceの重複管理設定を行う
2. 「拡張Apexクラス」機能にて以下をコーディング
  2-1. 重複チェック有りの保存処理重複チェック無しの強制保存処理
  2-2. 登録済みの重複レコード取得処理
3. 「コードブロック」を使って登録済みの重複レコードを表示
4. 「保存」処理ボタンを2つ(重複チェック有り、重複チェック無し)配置

1. 重複管理設定を行う

Salesforceの重複管理設定箇所
Salesforceの設定として、重複ルール(対象項目や条件等)の設定を行います。設定方法については弊社TechBlog「重複データに勝つ! 10分で分かる! 重複管理」にあるのでご参照ください。

2. 「拡張Apexクラス」機能にてコーディング

SkyVisualEditor Studio画面のApexクラス拡張機能メニュー
重複チェックを実施する保存処理や重複レコード取得処理をApexクラスでコーディングし、Studio画面の「Apexクラス拡張」機能にて設定します。
前提として、下記のような取引先ページに対してコーディングをすることとします。
重複管理設定前のStudio画面

下記のApexクラスコードを"Studioで直接編集"にて記述します。Salesforce組織に直接デプロイして頂き、"デプロイ済みクラスを指定"しても良いです。

global with sharing class DuplicateRuleExtender extends SkyEditor2.Extender{
  DuplicateRule extension;
  private List<sObject> duplicateRecords;
  public boolean hasDuplicateResult{get;set;}
  public boolean hasNotDuplicateResult{get;set;}
  
  public DuplicateRuleExtender(DuplicateRule extension){
    this.extension = extension;
    this.hasDuplicateResult = false;
    this.hasNotDuplicateResult = true;
  }
  
  /** 登録済みの重複レコード取得 **/
  public List<sObject> getDuplicateRecords() {
    return this.duplicateRecords;
  }
  
  /** 保存(重複チェク有り) **/
  public PageReference duplicateCheckSave() {
    Database.DMLOptions dml = new Database.DMLOptions();
    dml.DuplicateRuleHeader.allowSave = false;
    return duplicateSave(dml);
  }
  
  /** 強制保存(重複チェク無し) **/
  public PageReference duplicateForceSave() {
    Database.DMLOptions dml = new Database.DMLOptions();
    dml.DuplicateRuleHeader.allowSave = true;
    return duplicateSave(dml);
  }
  
  private PageReference duplicateSave(Database.DMLOptions dml) {
    Database.SaveResult saveResult = Database.insert(extension.record, dml);
    if (!saveResult.isSuccess()) {
      for (Database.Error error : saveResult.getErrors()) {
        if (error instanceof Database.DuplicateError) {
          Database.DuplicateError duplicateError = (Database.DuplicateError)error;
          Datacloud.DuplicateResult duplicateResult =
                                              duplicateError.getDuplicateResult();
          
          String errorMsg = 'Duplicate Error: '+duplicateResult.getErrorMessage();
          ApexPages.Message errorMessage =
                       new ApexPages.Message(ApexPages.Severity.ERROR, errorMsg );
          
          ApexPages.addMessage(errorMessage);
          this.duplicateRecords = new List<sObject>();
          Datacloud.MatchResult[] matchResults =duplicateResult.getMatchResults();
          Datacloud.MatchResult matchResult = matchResults[0];
          Datacloud.MatchRecord[] matchRecords = matchResult.getMatchRecords();
          for (Datacloud.MatchRecord matchRecord : matchRecords) {
            System.debug('MatchRecord: ' + matchRecord.getRecord());
            this.duplicateRecords.add(matchRecord.getRecord());
          }
          
          this.hasDuplicateResult = !this.duplicateRecords.isEmpty();
          this.hasNotDuplicateResult = !this.hasDuplicateResult;
          
          SkyEditor2.Messages.addErrorMessage(errorMsg);
        }
      }
      return null;
    }
    return (new ApexPages.StandardController(extension.record)).view();
  }
}

今回はコード内容について説明は省かせて頂きますので、詳細は下記Apex開発者ガイドをご参照ください。
  Apex開発者ガイド:DuplicateResult クラス
  Apex開発者ガイド:DMLOptions.DuplicateRuleHeader クラス

3. 「コードブロック」を使って登録済みの重複レコードを表示

コードブロックコンポーネント
一般には非公開の「コードブロック」コンポーネントを使用します。
「コードブロック」コンポーネントをStudio画面上部に配置し、下記Visualforceページをコーディングします。

<apex:pageBlock title="重複レコード" rendered="{!extender.hasDuplicateResult}">
  <apex:pageBlockTable value="{!extender.duplicateRecords}" var="item">
    <apex:column>
      <apex:facet name="header">{!$ObjectType.Account.fields.Name.label}</apex:facet>
      <apex:outputLink value="/{!item['Id']}">{!item['Name']}</apex:outputLink>
    </apex:column>
    <apex:column>
      <apex:facet name="header">{!$ObjectType.Account.fields.OwnerId.label}</apex:facet>
      <apex:outputField value="{!item['OwnerId']}" />
    </apex:column>
    <apex:column>
      <apex:facet name="header">{!$ObjectType.Account.fields.LastModifiedDate.label}</apex:facet>
      <apex:outputField value="{!item['LastModifiedDate']}" />
    </apex:column>
  </apex:pageBlockTable>
</apex:pageBlock>

コーディング後のStudio画面は以下のようになります。尚、このコードブロックは開閉が可能なので、目立たないように小さくすることも可能です。
コードブロック配置時のStudio画面

このコードブロックに重複データを表示させます。

4. 「保存」処理ボタンを2つ(重複チェック有り、重複チェック無し)配置

カスタム保存ボタンを2つ配置
カスタムボタンを2つ配置し、下記プロパティを設定します。
表示条件を設定することで、初期表示画面では「保存」ボタンが表示され、重複チェック有りの保存処理を呼び出します。
重複データが存在した時は、「保存」ボタンが非表示となり「保存(アラートを無視)」ボタンが表示されます。「保存(アラートを無視)」ボタンは重複アラートを無視して強制保存する処理を呼び出します。

表示条件 動作選択 action
保存 {!extender.hasNotDuplicateResult} JavaScript/Apex呼び出し {!extender.duplicateCheckSave}
保存(アラートを無視) {!extender.hasDuplicateResult} JavaScript/Apex呼び出し {!extender.duplicateForceSave}

保存ボタンプロパティ

以上で設定は完了です。
このように、Salesforceに新規機能が追加された場合等、SkyVisualEditorが対応していない機能も実装することが可能です。

Apexクラスコードは書きたくない! 標準機能にしてほしい!!
という要望がありましたら、是非リクエストをお願いします。

1 件

関連する記事