カテゴリ「SOQL」の記事

2014年8月18日 (月)

意外と知らないSalesforce Tips (4~5)

前回からの続きです。
今回は4つめと5つめをお送りします。

4. オブジェクトでトピックを利用する

Spring'14からChatterのトピック機能がオブジェクトでも利用できる様になりました。
トピックはTwitterで言うところのハッシュタグみたいなもので、レコードの整理に使うことができます。

・使うための準備
オブジェクトに対してトピック機能を有効化する必要があります。
Spring'14以降に作成した組織の場合はトピックを使用可能なすべての標準オブジェクトは、デフォルトで機能が有効になっている様です。

トピックの有効化は「カスタマイズ>トピック>オブジェクトのトピック」から行います。

Mame20140818_01

オブジェクトのトピックが有効になると、そのオブジェクト種別のレコードで公開タグが無効になるので、公開タグを使っている場合は注意が必要です。

・使ってみる
トピックをレコードに追加するには詳細画面を開いて、タイトルの下にある「クリックしてトピックを追加」リンクをクリックします。
(すでにトピックが追加済みの場合はリンク名が「トピック」になります)

Mame20140818_02

トピック名を入力して「完了」をクリックするとトピックが追加されます。

Mame20140818_03

追加されたトピック名をクリックすると、対象のトピックが付与されているレコードが一覧で表示されます。

Mame20140818_04

Mame20140818_05

また、トピックはビューの絞り込み条件に指定することもできます。
トピックを絞り込み条件に指定する場合は、絞り込みの項目で「トピック」を選びます。

Mame20140818_06

次はApexからトピックを操作してみます。
ConnectApiネームスペースのTopicsクラスがこの辺りの処理の為のメソッドを持っています。

トピックを追加するレコードのIDとトピック名を指定してトピックを追加します。
(第1引数はコミュニティのIDでコミュニティに対してトピックを追加する時でなければ、nullを指定します。)

String communityId = null;
String recordId = 'a04U000000Jj29h';
String topicName = 'トピックテスト';
ConnectApi.Topic objTopic = ConnectApi.Topics.assignTopicByName(communityId, recordId, topicName);

トピックのIDを指定して削除します。
(第1引数のコミュニティIDの扱いは追加の時と同じです。)

String communityId = null;
String topicId = '0TOU00000008ePB';
ConnectApi.Topics.deleteTopic(communityId, topicId);

トピックが追加されているレコードの一覧はTopicAsssignmentオブジェクトから取得できます。

Select Id, EntityId, TopicId FROM TopicAssignment WHERE TopicId = '0TOU00000008eP6OAI'

EntityIdにレコードのID、TopicIdにトピックのIDが入っています。
(組織でコミュニティが有効化されている場合はオブジェクトにNetworkIdカラムが追加され、ここにコミュニティのIDが入ります。)

・権限
トピック機能を扱うにはトピックの権限とレコードに対する権限が必要です。

一般ユーザ権限説明
トピックを割り当てる レコードへのトピックの追加・削除に必要です。
トピックを作成 トピックそのものを作成するのに必要です。
トピックを削除 トピックそのものを削除するのに必要です。
トピックを編集 トピックそのものを編集するのに必要です。

トピックを割り当てるには対象のレコードを更新できる必要があります。
参照権限のみの場合は、参照はできますが、割り当てはできません。

トピック機能は種類の異なるオブジェクトを関連づける事もできるので、うまく使って効果的にレコードを整理してみてください。

5. レコードの閲覧日時と参照日時を参照する

最近使ったXXX的な一覧を作ってみたくなったことはありませんか。
まさにそのためだけに作られたような項目が Summer'13 から各オブジェクトに追加されています。

「LastReferencedDate」と「LastViewedDate」がその項目です。

この2つの項目はどちらも読み取り専用の項目で、違いは項目の値が更新されるタイミングです。
詳細は次の表にまとめましたのでご覧ください。

 LastReferencedDateLastViewedDate
レコードの詳細画面を見たとき 更新される 更新される
レコードを画面からルックアップして参照項目に設定したとき 更新される 更新されない

このように画面で操作したときは上のタイミングで項目が更新されるのですが、Apexからの操作の場合は何もしなければこの2項目は更新されません。
Apexから更新したい場合は次のオプションを付けたSELECT文を発行することでこれらの項目を更新することができます。

詳細画面を見たときと同じ更新を行う
  ・・・ 「FOR VIEW」オプションを付与します。

SELECT Id,Name,AccountId,LastViewedDate,LastReferencedDate FROM Contact
WHERE ID='003U00000024dJgIAI' FOR VIEW

レコードを画面からルックアップして参照項目に設定したときと同じ更新を行う
  ・・・ 「FOR REFERENCE」オプションを付与します。

SELECT Id,Name,AccountId,LastViewedDate,LastReferencedDate FROM Contact WHERE
ID='003U00000024dJgIAI' FOR REFERENCE

機会があったら使ってみてください。

それでは。

2011年11月21日 (月)

SOQLでのコレクションとバインド変数の使用方法

今日は、SOQLでのコレクション(List、Set、Map)バインド変数に関する小技をご紹介。

○SetやMapでSOQLの結果を直接受け取る方法

SOQLの結果は通常Listで受け取りますが、↓のように、コンストラクタを使って、SetやMapで直接受け取ることができます。

// Listの場合

List<Account> accList = [Select Id From Account];


// Setの場合

// これはコンパイルエラー
Set<Account> accSet = [Select Id From Account];

// コンストラクタにSOQL結果のListを渡すとうまくいく
Set<Account> accSet
  = new Set<Account>([Select Id From Account]);


// Mapの場合

// これはコンパイルエラー
Map<Id, Account> accMap = [Select Id From Account];

// コンストラクタにSOQL結果のListを渡すとうまくいく
Map<Id, Account> accMap
  = new Map<Id, Account>([Select Id From Account]);

○IN句でコレクションを使用する方法

SOQLのIN句では、バインド変数にListとSetを使用できます。Mapは使用できませんが、Mapのvaluesメソッド または keySetメソッドで返すList または Setを渡すようにすると使用できます。

// Listの場合
List<String> nameList = new List<String>();
nameList.add('佐藤');
nameList.add('木村');

List<Contact> ctcList
  = [Select Id From Contact Where LastName IN :nameList];


// Setの場合
Set<String> nameSet = new Set<String>();
nameSet.add('佐藤');
nameSet.add('木村');

List<Contact> ctcList
  = [Select Id From Contact Where LastName IN :nameSet];


// Mapの場合
Map<String, String> nameMap = new Map<String, String>();
nameMap.put('佐藤', '佐藤');
nameMap.put('木村', '木村');

// これはコンパイルエラー
List<Contact> ctcList
  = [Select Id From Contact Where LastName IN :nameMap];

// Mapの値セットを渡したい時は、valuesメソッドで返すListを渡すとうまくいく
List<Contact> ctcList
  = [Select Id From Contact Where LastName IN :nameMap.values()];

// Mapのキーセットを渡したい時は、keySetメソッドで返すSetを渡すとうまくいく
List<Contact> ctcList
  = [Select Id From Contact Where LastName IN :nameMap.keySet()];

○動的SOQLでバインド変数を使用する方法

[]内のSOQLの中でないと、バインド変数は使用できないと思われがちですが、動的SOQLでもバインド変数が使用可能です。
↓のように、Database.queryメソッドに渡すSOQL文字列にそのままバインド変数を記述すれば使用できます。

// 動的SOQLでもバインド変数が使えます
String soql = 'Select Id From Case Where Priority In :priorityList';

List<String> priorityList = new List<String>();
priorityList.add('高');
priorityList.add('中');

List<Case> caseList = Database.query(soql);

2011年2月14日 (月)

SOQLのサブクエリの結果の取得方法

今回はSOQLのサブクエリの結果の取得方法をご紹介。

そんなの知ってるよ、という方が多いかもしれませんが、Web上にサンプルが少ないようなので紹介しておきます。

下記は、指定した取引先番号の取引先に紐付く取引先責任者情報を取得するサンプルApexコードです。

例のように、サブクエリの結果セットは、「.子リレーション名」で取得できます(ac.Contactsの部分)。

Account[] accounts = 
    [
    Select
        AccountNumber,
         (Select LastName, FirstName From Contacts)
    From
        Account
    Where
        AccountNumber = '10001'
    ];

List<Contact>contactList = new List<Contact>();
for(Account ac : accounts) {
    for(Contact c : ac.Contacts) {
        Contact contact = new Contact();
        contact.LastName = c.LastName;
        contact.FirstName = c.FirstName;
        contactList.add(contact);
    }
}

2010年7月29日 (木)

集計関数

Spring '10から集計関数が利用できるようになりました。
APIバージョン18以上で使用可能のようです。

利用できる集計関数は以下の6種類。

関数名 結果
Avg 平均値
Count レコード件数
Count_Distinct nullと重複値を除いたレコード件数
Max 最大値
Min 最小値
Sum 合計値

こんな感じで↓使用します。

Select Count(Id) From Account Where Name Like 'a%'

グループ化したい場合は、Group By句と共に利用します↓

Select Name, Max(BudgetedCost) From Campaign Group By Name

Apexではクエリ結果を、
AggregateResult(複数の場合はList<AggregateResult>)で受け取り、AggregateResultオブジェクト.get('名称')で値を取得します。

集計関数の名称は↓のように付けます(maxNumが名称)。

Select Name, Max(Num__c) maxNum From Order__c Group By Name

集計関数の結果取得部分のソースコードはこんな感じ。

List<AggregateResult> aggregateList = 
[
Select
Name,
Max(Num__c) maxNum
From
Order__c
Group By
Name
];

for(AggregateResult a : aggregateList) {
Integer maxNum = Integer.valueOf(a.get('maxNum'));

// 処理
}

2010年7月23日 (金)

SOQLでのリレーションの辿り方

SQLでは動的に列を指定して表を結合することができますが、SOQLでは動的に結合することはできません(そもそも結合ができない)。

SOQLではオブジェクト間に予めリレーションを設定しておくことにより、リレーションを辿ってのデータ参照が可能となります。

ということで、今日はSOQLでのリレーションの辿り方をご紹介。

子オブジェクトから親オブジェクトへのリレーションの辿り方

子オブジェクトから親オブジェクトへは、リレーション名を使用してリレーションを辿ります。

リレーション名は、参照/主従関係のカスタム項目名 + __r となります(標準項目のリレーション名は予め設定されています)。

SOQLのFrom句には必ず基点となるベースオブジェクトを指定しますが、ベースオブジェクトから最大5段階まで親のリレーションを辿ることができます。

●親リレーションを辿るサンプル

Select 
  c.Name,
  a.Name,
  u.Name
From
  Contact c, ★ベースオブジェクト
  Contact.Account a,
  Contact.Account.CreatedBy u

親オブジェクトから子オブジェクトへのリレーションの辿り方

親オブジェクトから子オブジェクトへは、 子リレーション名を使用してリレーションを辿ります。

以前は、子リレーション名を特に指定しない場合、自動的にランダムな名称が設定されてしまい、Select Id From R00NA0000001a2bkoko ・・・などと、かなり分かりづらいSOQLを書くハメになったりもしましたが、Summer '10からは、子リレーション名が必須項目となり、そのようなこともなくなりました。

子リレーション名は自オブジェクトの複数形で付けることが一般的なようです(分かりやすいですしね)。例えば、ContactからAccountへリレーションを結ぶ場合は、子リレーション名をContactsにします。

SOQLでは、メインクエリのFrom句にベースオブジェクト名を、サブクエリのFrom句に子リレーション名を指定して、データを取得します。

ここで重要なのは、親から子へは1段階しかリレーションを辿ることはできない、ということ。指定したベースオブジェクトの子オブジェクトのみリレーションを辿ることが可能です。子の子や親の子などはアクセス不可です。

●子リレーションを辿るサンプル(ContactsがAccount→Contactへ辿る子リレーション名)

Select 
  a.Name,
  (Select c.Name From Contacts c)
From
  Account

●ベースオブジェクトから親5段階、子1段階の範囲であれば、同時にデータ取得が可能

Select 
  a.Name,
  u.Name,
  (Select c.Name From Contacts c),
  (Select n.Title From Notes n)
From
  Account a,
  Account.Owner o,
  Account.Owner.CreatedBy u

●下記のように、From句にベースオブジェクトを2つ指定することは不可

Select 
  a.Name,
  u.Name
From
  Account a,
  User u

親から子へ1段階しか辿ることができないというのは、かなり大きな制約です。データモデルの設計時には必ず覚えておきましょう。

と言いつつ、もうそろそろ、2段階、3段階と子リレーションを辿れるようになるんじゃないか?と淡い期待もしてたりします(集計関数も使えるようになりましたしね)。

採用情報

株式会社フレクトでは、事業拡大のため、
・Salesforce/Force.comのアプリケーション開発
・HerokuやAWSなどのクラウドプラットフォーム上
でのWebアプリケーション開発
エンジニア、マネージャーを募集中です。

未経験でも、これからクラウドをやってみたい方、
是非ご応募下さい。

フレクト採用ページへ

会社紹介

  • 株式会社フレクトは、
      ・認定コンサルタント
      ・認定上級デベロッパー
      ・認定デベロッパー
    が在籍している、セールスフォースパートナーです。
    また、heroku partnersにも登録されています。
    herokuパートナー
    株式会社フレクト
    Salesforce/Force.com
    導入支援サービス
    弊社の認定プロフェッショナルが支援致します。
    ・Visualforce/Apexによるアプリ開発
    ・Salesforceと連携するWebアプリ開発
    も承っております。
    セールスフォースご検討の際は、
    お気軽にお問合せください。

Twitter

リファレンス

■Developer's Guide(リファレンス)
・Apex  HTML | PDF | 日本語PDF | ガバナ制限
・Visualforce  HTML | PDF
・Web Services API  HTML | PDF | 日本語PDF
・Bulk API  HTML | PDF
・REST API  HTML | PDF | 日本語PDF
・Metadata API  HTML | PDF
・Migration Tool  HTML | PDF
・AJAX Toolkit  HTML | PDF
・Data Loader PDF | 日本語PDF

■早見表 (日本語)
数式
Apex
Visualforce
Web Services API
Chatter