Appirio's Tech Blog

2011年12月28日水曜日

Salesforce.com上で数式項目を活用する

Salesforceを利用/導入していてプロジェクトの方針等によりプログラム開発を制限されたことはありませんか?私はこれまでそのようなことが多々あり標準機能で対応可能な範囲を探りながら、都度それぞれの実現方法を検討してきました。(「Apexを書けば早いのに」と思いながらも...)

そこで今回は、これまで私が比較的多く遭遇した部分で標準機能の数式項目を用いて実現可能なことについて記載していこうと思います。

ここで記載している数式項目とは...

  • 他の項目や式を元に値を自動的に計算するオブジェクトに作成できるカスタム項目のこと
  • ”IF”や”DATE”等の関数、”$User”や”$Organization”等のグローバル変数などが利用可能

和暦の表示

既に様々な方法で実現している方も多いと思いますが、以下のような数式を作成することにより日付項目を元にして和暦を表示することができます。
例では、取引先責任者の「誕生日(Birthdate)」を元にしています。その他の項目を和暦表示する場合は、「Birthdate」の部分を該当項目のAPI参照名で置き換えて下さい。
IF( NOT( ISNULL( Birthdate ) ),
  IF(
    /* 明治を判定 */
    AND( Birthdate >= DATE(1868, 9, 8), Birthdate <= DATE(1912, 7, 29) ),
    "明治" & IF( YEAR( Birthdate ) = 1868, "元", TEXT(YEAR( Birthdate ) - 1867) ),
    IF(
      /* 大正を判定 */
      AND( Birthdate >= DATE(1912, 7, 30), Birthdate <= DATE(1926, 12, 24) ),
      "大正" & IF( YEAR( Birthdate ) = 1912, "元", TEXT(YEAR( Birthdate ) - 1911) ),
      IF(
        /* 昭和を判定 */
        AND( Birthdate >= DATE(1926, 12, 25), Birthdate <= DATE(1989, 1, 7) ),
        "昭和" & IF( YEAR( Birthdate ) = 1926, "元", TEXT(YEAR( Birthdate ) - 1925) ),
        IF(
          /* 平成を判定 */
          Birthdate >=DATE(1989, 1, 8),
          "平成" & IF( YEAR( Birthdate ) = 1989, "元", TEXT(YEAR( Birthdate ) - 1988) ),
          TEXT( YEAR( Birthdate ) )
        )
      )
    )
  )
  & "年"
  & LPAD(TEXT( MONTH( Birthdate )), 2, "0") & "月"
  & LPAD(TEXT( DAY( Birthdate )), 2, "0") & "日",
  null
)

上記の数式の場合、年号毎の範囲は下記の通りとなり各最初の年は"元年"と表示されます。
範囲の微調整を行いたい場合は各”DATE”の中を修正します。
明治:1868/09/08 ~ 1912/07/29
大正:1912/07/30 ~ 1926/12/24
昭和:1926/12/25 ~ 1989/01/07
平成:1989/01/08 ~
※その他の日付(1868/09/08以前)の形式:YYYY年MM月DD日

ちなみにカスタム項目の日付の範囲は、”1700/01/01”〜”4000/12/31”です。”4000/12/31”を指定すると”平成2012年12月31日”と表示されます。
和暦表示に対するニーズは多くの場面で出て来ると思いますので知っていると便利かと思います。

時間(時間帯)の表示

以下のような数式を作成することにより日時から時間を取得することができます。
MID( TEXT( Nichiji__c ), 12, 2 )
ただし、このままではGMTでの時間が取得されてしまうので、もし利用する組織が日本標準時(GMT+09:00)のみであれば以下のようにすることで日本時間で取得することができます。
MID( TEXT( Nichiji__c + 9/24), 12, 2 )
「9」の部分を適宜GMTとの時差に変更することにより、利用環境にあわせた時間を取得できます。
例:
 太平洋標準時(GMT-08:00) -> -8
 インド標準時(GMT+05:30) -> 5.5

また、”IF”や”CASE”等の関数を利用することによって取得した時間から時間帯を表示することも可能です。
「10:00〜12:00」「10〜12」、「AM」「PM」…
IF( ISNULL( Nichiji__c), null, IF(VALUE( MID( TEXT(  TaioNichiji__c + 9/24 ), 12, 2 ) ) >= 12 ,"PM","AM") )
作成した数式項目はレポートでのグルーピング項目に指定することができるため、コールセンター等で時間帯ごとの問い合わせ数の集計などが可能です。

(標準の活用と言いながらトリガを利用するため)以降蛇足

UserオブジェクトにそのユーザのGMTとの時差を保持していれば、さらに便利に利用することができます。
MID( TEXT( Nichiji__c + $User.TimeZone__c /24 ), 12, 2 )
「TimeZone__c」に以下のようなTriggerを利用して各ユーザごとに値を設定することができます。
trigger updateUserInfo on User (before insert, before update) {
  Long timezone;
  Datetime nowDt = Datetime.now();
  for (User usr : Trigger.new) {        
    // GMTとユーザの時差(ミリ秒)
    timezone = Datetime.valueOf(nowDt.format('yyyy-MM-dd HH:mm:ss', usr.TimeZoneSidKey)).getTime() - Datetime.valueOf(nowDt.formatGMT('yyyy-MM-dd HH:mm:ss')).getTime();
    // ミリ秒単位を時間単位に変更
    usr.TimeZone__c = Decimal.valueOf(timezone).divide(3600000, 2);
  }
}

実行ユーザの情報を検索条件にしたView/Report

通常ViewやReportでは、日付の特別値(”今日”、”過去30日間”など)を検索条件に利用することはできますが、実行ユーザの値を検索条件に指定することはできません。しかし、数式項目を利用することにより実行ユーザの値を検索条件に指定できるようになります。
実現方法は単純で、「オブジェクト内の数式項目で表示条件を設定する」ことだけです。
具体的には、検索対象のオブジェクトに数式項目で条件を指定して、レコードが条件と合致するかどうかを戻り値で返します。数式で返される値をViewやReportで条件に指定することで実行ユーザの項目を条件にレコードを抽出することができるようになります。

例:実行ユーザが参照項目(User)に設定されている一覧を表示する

数式項目名:自担当フラグ
IF( $User.Id = LookupUserId__c, 1, 0)

数式項目で“OR”などの関数を利用することにより、複数の参照項目に設定されている一覧を表示することも可能になります。
また応用として数式項目では参照しているオブジェクトをたどって値を取得することができますので、複数オブジェクトの値を条件にしてViewを表示することが可能となります。

なおこれらの方法は数式項目内で”$User”を利用しているためViewやReportのパフォーマンスに良い設定とは言えません。
そのためレコード数や利用箇所等に十分に注意してください。タイムアウトする可能性が高いです。
また日付時間項目からTEXT変換後時間の取得部分などSalesforceの仕様が変更される可能性も0ではありませんのでご注意ください。

標準機能の活用が必要となった時/プログラムの作成に疲れた時の1つの手段として検討してみてください。

Posted by Hokazono Kazushi (Appirio Japan)

0 コメント:

コメントを投稿

 
2006-2011 Appirio Inc. All rights reserved.
アピリオ | リソースセンター(英語) | お問い合わせ先 | 採用情報 | プライバシーポリシー(英語)