Quantcast
Channel: tyoshikawa1106のブログ
Viewing all 1438 articles
Browse latest View live

SFDC:Lightning Experience ナビゲーションメニューを試してみました

$
0
0

Spring'16になってLightning Experienceのナビゲーションメニューをカスタマイズできるようになりました。設定にナビゲーションメニューが新しく追加されています。

f:id:tyoshikawa1106:20160214202502p:plain


新規ボタンをクリックすると新しいメニューを作成できます。
f:id:tyoshikawa1106:20160214202706p:plain


ドラッグ&ドロップで表示したいメニューを選択できます。
f:id:tyoshikawa1106:20160214203015p:plain


最後にこのメニューを利用するプロファイルを指定します。
f:id:tyoshikawa1106:20160214203131p:plain


これでナビゲーションメニューの作成とプロファイルへの割り当てが完了しました。
f:id:tyoshikawa1106:20160214203334p:plain


標準オブジェクトだけでなく、VisualforceタブやLightningComponentタブも表示できます。
f:id:tyoshikawa1106:20160214203623p:plain


Salesforce Classicではホームタブを必ず表示する必要がありましたが、Lightning Experienceでは非表示にすることもできました。
f:id:tyoshikawa1106:20160214203916p:plain


新しく追加されたナビゲーションメニューの設定ですが、Salesforce Classicからはアクセス出来ないようになっていました。
f:id:tyoshikawa1106:20160214204212p:plain


プロファイルの設定画面からナビゲーションメニューの割り当てもできないみたいでした。


ちなみにタブのアイコンはタブ設定の独自のスタイルから変更できます。
f:id:tyoshikawa1106:20160214204609p:plain

f:id:tyoshikawa1106:20160214204638p:plain:w300


好きなアイコンに指定できますが、カラフルなアイコンにすると標準アイコンとの色の違いが少し気になるかもしれません。


あと割り当てられたナビゲーションメニューを削除するとデフォルト設定が自動で割り当てられていました。


SFDC:Visualforce × AngularJSとautoscrollについて

$
0
0

AngularJSをつかってシングルページアプリケーションを開発するときですが、何も気にせず実装すると画面遷移時にスクロール位置がそのままになってしまいます。

f:id:tyoshikawa1106:20160217203612p:plain



f:id:tyoshikawa1106:20160217203643p:plain


どうすればスクロール位置を上に戻せるのかなと検索したところ、stackoverflowで解決方法が紹介されていました。


autoscroll="top"を宣言すればいいみたいです。
f:id:tyoshikawa1106:20160217204309p:plain


これで画面遷移後にスクロール位置が一番上に戻ってくれるようになりました。

SFDC:Spring'16のログインフォレンジック有効化を試してみました

$
0
0

Spring'16でログインフォレンジック機能が正式にリリースされました。ログインフォレンジックを使用すると、組織のユーザのログインアクティビティを追跡および監査しやすくなるそうです
f:id:tyoshikawa1106:20160218122524p:plain

有効化手順ですが、設定の監視→ログのところに『イベント監視設定』が追加されていました。ここからログインフォレンジックを有効化できました。

f:id:tyoshikawa1106:20160218122337p:plain


通常は有料の機能ですがDE環境では動作確認用に無料で利用できるみたいです。(ちょっと料金の仕組みはわかりませんでした) また、順次有効化されている機能とのことでまだ利用できない組織もありました。


PlatformEventMetricsというオブジェクトが用意されているみたいです。(API36.0〜?)
f:id:tyoshikawa1106:20160218125303p:plain


ヘルプはこちら

Metrics in Login Forensics


有効化後、特に設定メニューが増えたりといったことはありませんでした。おそらくクエリ実行ができるようになっただけだと思います。


SOQLクエリはエラーになったので、REST APIから試してみたのですが、こちらもうまくいきませんでした。

String resourceURL = '/services/data/v36.0/query?q=SELECT+Id+FROM+PlatformEventMetrics';

Http http = new Http();
HttpRequest req = new HttpRequest();
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
req.setHeader('Content-Type', 'application/json');
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + resourceURL);
req.setMethod('GET');
HttpResponse res = http.send(req);
System.debug(res);
String result = res.getBody();
System.debug(result);

有効化した後、どう利用するかはよくわかりませんでした。

SFDC:DashboardとStandardController

$
0
0

今まで試したことが無かったのですがDiscussionForumに気になる質問があったので、対応できるか確認してみました。StandardControllerにDashboardオブジェクトを指定できるかについてです。

Salesforce Developer Community

やりたいことはchatterタグにDashboardIDをセットできるかということです。次のコードで試してみました。

<apex:page standardController="Dashboard" showHeader="true" sidebar="false" tabStyle="Dashboard">
    <chatter:followers entityId="{!Dashboard.Id}"></chatter:followers>
    <chatter:follow entityId="{!Dashboard.Id}"></chatter:follow>
    <chatter:feed entityId="{!Dashboard.Id}"></chatter:feed>
</apex:page>


まずDashboardのChatterフィードを有効化します。
f:id:tyoshikawa1106:20160220224232p:plain


これでうまくいくか確認してみると、無事にChatter情報を表示することができました。
f:id:tyoshikawa1106:20160220224339p:plain


StandardControllerにDashboardオブジェクトを指定して利用することはできるみたいです。あとはDashboardにVisualforceを埋め込む機能があるので、それで対応できるかなと考えました。


ところがDashboardにVisualforceを埋め込んで表示するとStandardControllerのIDが取得できませんでした。

<apex:page standardController="Dashboard" showHeader="false" sidebar="false" tabStyle="Dashboard">
    <div>
        <apex:outputText value="ID = " />
        <apex:outputText value="{!Dashboard.Id}" />
    </div>
    <chatter:followers entityId="01Zi0000000MyuF"></chatter:followers>
    <chatter:follow entityId="01Zi0000000MyuF"></chatter:follow>
    <chatter:feed entityId="01Zi0000000MyuF"></chatter:feed>
</apex:page>

f:id:tyoshikawa1106:20160220230812p:plain

f:id:tyoshikawa1106:20160220230835p:plain


entityIdを固定値で指定したとき、きちんと認識されたので、chatterタグの利用自体はできるみたいです。


standardControllerではなくControllerを用意して値を渡すことはできるか確認してみました。

<apex:page controller="VFDashboardController" showHeader="false" sidebar="false" tabStyle="Dashboard">
    <div>
        <apex:outputText value="{!label}" />
        <apex:outputText value="{!dashboardId}" />
    </div>
    <chatter:followers entityId="{!dashboardId}"></chatter:followers>
    <chatter:follow entityId="{!dashboardId}"></chatter:follow>
    <chatter:feed entityId="01Zi0000000MyuF"></chatter:feed>
</apex:page>
public with sharing class VFDashboardController {
    
    public Id dashboardId {get; set;}
    public String label {get; set;}
    
    public VFDashboardController() {
        this.label = 'Dashboard ID = ';
        this.dashboardId = System.currentPageReference().getParameters().get('id');
    }
}

コントローラ側で定義した文字列を表示することはできましたが、URLパラメータからIDを取得するようなことはできないみたいです。
f:id:tyoshikawa1106:20160220231450p:plain


VFページを埋め込む際にダッシュボードIDを利用するのちょっとむずかしそうでした。(ちなみにapex:detailタグはダッシュボードページの情報を取得できないみたいです。)

Salesforce DUG Tokyo Meetup #11 に参加しました

$
0
0

JPタワーにあるSalesforceオフィスで開催された開発者向けMeetupに参加しました。今回で11回目です。
f:id:tyoshikawa1106:20160223185651j:plain:w300

f:id:tyoshikawa1106:20160223185700j:plain:w300

f:id:tyoshikawa1106:20160223185445j:plain:w300


自分もSpring'16のApex新機能についてLTをやらせて貰いました。
f:id:tyoshikawa1106:20160224001001j:plain:w300


LTでつかったスライドはこちらです。


小ネタですが、SlideShareにアップしたときに一部文字がちゃんと表示されないトラブルに遭遇しました。フォントを別のものに変更したら解決したので、LTのときとはフォントは別のものになっています。



新機能はいくつかありますが、個人的に特に抑えておきたいのは以下の機能です。

  • Apexテストスイート
  • Apexテスト失敗しきい値設定
  • Apexからのレコードロック判定
  • Connect API (Chatter in Apex)

※他にも便利な新機能はたくさんあったので、くわしくはスライドまたはリリースノートをご確認ください。


特にConnect APIの部分に興味を惹かれました。スライドにも記載しましたが、実際にVisualforceページで作ってみてデモ動画も用意してあります。


Connect API自体はずっと前からあったのですが、引数の準備などが少し複雑でちょっと入りづらい感じでした。ですが今回AngularJSをつかってJavaScript Remotingメインの処理で試してみたところ、すんなり実装することができました。


Connect APIはConnectApi.AnnouncementInputクラスやConnectApi.BannerPhotoクラスなど少し特殊な形で戻り値を受け取ることになり、戻ってくる値もさまざまな変数にセットされて戻ってきます。


ApexのSystem.debugでチェックすると、ちょっと確認しきれなかったのですが、JS側に渡してconsole.logで確認することで、確認しやすくなりました。


今回作成したサンプルコードはGitHubにアップしてあります。Connect APIは気になるけどちょっと良くわからないという人の力になれると思います。


また、今回自分の方で確認しきれなかったところで、Apexのレコードロック判定の話があります。LT後に米井さんからも少し補足して頂けましたが、ちょっと落とし穴があるみたいです。


LT終わった直後でソワソワしてちゃんと聞けてなかったのですが、以前ツイートしてくれていたレコードロック判定は「Apexからのレコードロックが有効」になっていないとExceptionになるという話だったと思います。(別の話だったらスミマセン。。)

f:id:tyoshikawa1106:20160224003639p:plain


こんな感じで思わぬ落とし穴があったりするので、一度自分のDeveloper環境で動かしてみると良さそうです。


まだちゃんと確認できていなくて今日あまり話せなかった部分については、また今度ちゃんと試してブログにまとめてみたいと思います。


今回のMeetupでもふだん話す機会のないような人たちともお話することができました。特にForce.com開発をやってるよって話が聞けたりしてとても楽しかったです。


最後に今回もSalesforceさんから🍕と🍺をごちそうになりました。すごくおいしかったです。ありがとうございました。
f:id:tyoshikawa1106:20160223213437j:plain:w300

SFDC:RemoteActionから日付と日時を登録する方法

$
0
0

Visualforceのapexタグをつかってデータ登録するときは、データ型とか特に意識する必要はありませんが、JavaScript Remotingな画面開発ということでRemoteActionをつかって日付/日時を登録する場合は、すこし意識することがあります。


たとえば日付型のsObject項目に値をセットする場合は次のように変換する必要があります。

SLAExpirationDate__c: new Date(accountDate).getTime()
参考

Visualforce × AngularJS - Qiita

日付型に値をセットする方法は確認できましたが、これが日時型の場合はどうなるのか、多言語化対応でユーザの地域が変更されたときはどう対応するのがいいのか、


・・・という疑問が解決していなかったのでこの辺りを調べてみました。

はじめに

JavaScriptで日時を操作する場合、moment.jsというライブラリを利用すると対応がしやすくなるそうです。これを使った方法について確認してみました。

Moment.js | Home

日時の登録方法

Apexの日時型

Apexでは日時型の項目は次のようにDateTime型として宣言します。

public DateTime startTime {get; set;}
HTMLの入力フォーム

HTMLでは時間型の値を入力するためにinputタグにtype="time"が用意されています。これで入力フォームを用意できます。
(このフォームでは時間のみの入力となるため、日付部分は1970-1-1のようなデフォルト値がセットされていました。)

<input name="startTime" ng-model="wrapper.startTimeInput"
        class="slds-input" type="time" required="true" />

f:id:tyoshikawa1106:20160224103841p:plain

RemoteActionで渡す際の変換方法

RemoteActionでこの変数に渡す方法ですが、moment.jsをつかえば次のように宣言するだけで済みました。

moment([year, month, date, hour, minute, second]).toDate().toUTCString();


まずinputタグに入力された日付情報はmoment("要素")で取得できます。

var targetDate = moment(scope.wrapper.workDateInput);

このあとformat()をつかって任意の形式に変換することも可能です。

// 年月日の場合
console.log('targetDate = ' + targetDate.format("YYYY-MM-DD"));
// 時間の場合 (HH=24h表記 / hh=12h表記)
console.log('startTime = ' + startTime.format("HH:mm:ss"));

日付情報を取得したあとは、下記方法で年や月などの情報を取得することができます。

// moment()で取得した日付情報
var d = targetDate;
// 年
var year = d.year();
// 月
var month = d.month();
// 日
var date = d.date();
// 時
var hour = t.hour();
// 分
var minute = t.minute();
// 秒
var second = t.second();

※日はdayではなくdateなので注意してください。


これで最初の方法で日時変換することができます。変換後はRemoteActionでDateTime型の変数にセットできるようになりました。

// 日付取得
var targetDate = moment(scope.wrapper.workDateInput);
// 時間取得
var startTime = moment(scope.wrapper.startTimeInput);
// 日時に変換してセット
scope.wrapper.workTime.startTime = getDateTime(targetDate, startTime);

// 日時変換
function getDateTime(d, t) {
    // 年月日取得
    var year = d.year();
    var month = d.month();
    var date = d.date();
    console.log(year + '-' + (month + 1) + '-' + date);
    // 時分秒取得
    var hour = t.hour();
    var minute = t.minute();
    var second = t.second();
    console.log(hour + ':' + minute + ':' + second);
    // 日時に変換して戻す
    return moment([year, month, date, hour, minute, second]).toDate().toUTCString();
}

f:id:tyoshikawa1106:20160224105833p:plain


登録イメージです。
f:id:tyoshikawa1106:20160224105457p:plain

f:id:tyoshikawa1106:20160224105545p:plain


日時型の値渡しはこんな感じで変換してあげれば大丈夫そうです。

日付の値渡し

日付の場合ですが、まず次の方法でinput type="date"で入力された値を確認してみました。

// 対象日付取得
var targetDate = moment(scope.wrapper.workDateInput);
console.log('targetDate = ' + targetDate.format("YYYY-MM-DD HH:mm:ss"));

これで入力した日付かつ0時0分0秒の値を取得できることを確認できました。
f:id:tyoshikawa1106:20160224110409p:plain


ということで次の書き方で問題なさそうです。

// 日付変換
function getDate(d) {
    return moment(d).toDate().toUTCString();
}


確認して見るとこんな感じ
f:id:tyoshikawa1106:20160224110803p:plain

f:id:tyoshikawa1106:20160224110841p:plain


これでinput type="date" で入力された値も無事にApexに渡して保存できました。今回は時間部分に9時間のズレがでていないか確認するためにDateTime型の項目に値を登録して確認しましたが、Date型の項目にも同じように保存できると思います。

多言語化

ユーザのタイムゾーンを変更したケースです。
f:id:tyoshikawa1106:20160224112257p:plain


情報方法ではSalesforceユーザのタイムゾーンが日本時間でない場合にズレが発生しました。
f:id:tyoshikawa1106:20160224112508p:plain


正確には日本のタイムゾーンとして日時登録されていました。
f:id:tyoshikawa1106:20160224112541p:plain


多言語化対応が必要な場合に関してはもう少し考慮が必要そうです。


多言語化の問題だけ残っていますが、ひとまず上記方法でapexタグに頼らないJavaScript Remotingメインの画面開発でも日付/日時を登録できると思います。


SFDC:Apex テストクラスのテストスイートの作成を試してみました

$
0
0

f:id:tyoshikawa1106:20160218105053p:plain

よく使用される Apex テストクラスのテストスイートの作成

使い方

開発者コンソールを使用してテストスイートを作成するには、[Test (テスト)] | [New Suite (新規スイート)] を選択します。テストスイートに含めるクラスを選択するには、[Test (テスト)] | [Suite Manager (スイートマネージャ)] | Your Test Suite (あなたのテストスイート) | [Edit Suite (スイートを編集)] を選択します。開発者コンソールを使用して、最大 200 個のテストクラスを含むテストスイートを作成または変更できます。

開発者コンソールから 1 つ以上のテストスイートのメンバークラスを実行するには、[Test (テスト)] | [New Suite Run (新規スイートの実行)] を選択します。

テストスイートの作成手順

New Suiteを選択します。
f:id:tyoshikawa1106:20160218105942p:plain


名前を決めます。
f:id:tyoshikawa1106:20160218105349p:plain


テスト実行したいクラスを選択します。Saveボタンで設定完了です。
f:id:tyoshikawa1106:20160218105851p:plain

テストスイートの編集・削除手順

Suite Managerを選択します。
f:id:tyoshikawa1106:20160218110241p:plain


対象のテストスイートを選択後、EditボタンまたはDeleteボタンをクリックして編集/削除を行えます。
f:id:tyoshikawa1106:20160218110401p:plain

テストスイートのテスト実行

New Suite Runを選択します。
f:id:tyoshikawa1106:20160218110734p:plain


するとテストスイートに追加したテストクラスをまとめてテスト実行できます。
f:id:tyoshikawa1106:20160218110955p:plain


テストスイートの使い方はこんな感じです。機能ごとに関連するクラスをまとめたテストスイートを作っておくと便利そうです。

SFDC:Spring'16のApexテストの失敗するテスト実行の停止を試してみました

$
0
0

f:id:tyoshikawa1106:20160218111608p:plain

リリースノート

概要

多数の Apex テストを実行すると、予想以上に時間がかかることがあります。実行の終了を待ってから、多くのテストに失敗したことが判明することは望ましくありません。

指定した数のテストに失敗したら新しいテストの実行を停止するように、テスト実行を設定できるようになりました。テストの実行結果を待ち、無駄な時間を費やす必要がなくなりました。

後日組織で問題を修正した後に、テストを再実行することになるわけですから。開発者コンソールと Tooling API の両方で実行するテスト実行で、テストの失敗が許容される回数を設定できます。この機能は、Lightning Experience と Salesforce Classic の両方で使用できます。

利用手順

開発者コンソールのテスト実行画面にSettingボタンが追加されています。
f:id:tyoshikawa1106:20160218112051p:plain


ここでテスト失敗しきい値を入力します。
f:id:tyoshikawa1106:20160218112208p:plain

  • 0 ~ 1,000,000 の整数値に設定できます
  • "1"を入力した場合は、2回目のエラー発生時にテストが終了します。
  • "3"を入力した場合は、4回目のエラー発生時にテストが終了します。
  • 未入力または"-1"を入力した場合は、エラーが発生してもテストが終了しません。


実際にエラーを出してみます。 正常にテスト実行されるクラスにエラーを2つ追加します。
f:id:tyoshikawa1106:20160218113300p:plain


しきい値に"1"を入力します。
f:id:tyoshikawa1106:20160218113405p:plain:w300


これでテストを実行すると、エラーが2つなので強制終了され・・・・ませんでした。
f:id:tyoshikawa1106:20160218113652p:plain


このような書き方の場合はひとつ目のエラー発生時にそのメソッドのテストは終了するため、ふたつ目のエラーにたどり着かないからです。


ということで2つのメソッドでエラーになるよう修正して実行しました。
f:id:tyoshikawa1106:20160218114040p:plain

これでふたつ目のエラーが発生した際にテスト実行が強制終了されることを確認できました。


テスト実行が終了されるのはそのクラスのみとなっています。その他のクラスのテストは継続して実行されるみたいです。
f:id:tyoshikawa1106:20160218114448p:plain

利用時の注意点

大きい値にすると、パフォーマンスが低下する可能性があることに注意してください。失敗が許容される 1,000 件のテストごとに約 3 秒がテスト実行に追加されます。これにはテストの実行にかかる時間は含まれません。


最終チェックとしてテスト実行する際に設定しておくと便利そうです。


SFDC:Spring'16のテストクラスに関するバグ修正

$
0
0

Spring'16でテストクラス関連のバグ修正あったみたいです。
f:id:tyoshikawa1106:20160218115059p:plain

リリースノート

Apex テストで確実に制限をリセットするための Test.startTest() のコール

Test.startTest() メソッドと Test.stopTest() メソッドで囲まれたテストコードのブロックで、ガバナ制限の独自のブロックを確実に受信できるようになりました。
Test.startTest() は、トランザクション単位の制限カウンタを保存し、カウンタを一時的に 0 にリセットします。
Test.stopTest() は、制限カウンタを Test.startTest() 前の値に戻します。テストメソッドが完了すると、すべてのトランザクション単位の制限は 0 にリセットされます。
以前は、SOQL クエリなどの場合の一部の制限は、Test.startTest()/Test.stopTest() ブロック内ではリセットされないことがありました。

Apex テストでの重大な MIXED_DML_OPERATION エラーを回避するための @future の使用

単一トランザクション内の混合データ操作言語 (DML) 操作は許可されていません。同じトランザクション内で設定の sObject と設定以外の sObject に対する DML は実行できません。

代わりに、非同期ジョブの一部として 1 つのデータ型の DML を実行し、別の非同期ジョブまたは元のトランザクションで他のデータ型を実行できます。この代替方法は広く使用されています。

ただし、この代替方法が Apex テストのコンテキスト内で使用された場合、エラーが発生していました。このバグは修正されました。

サンプルコード

@isTest
public class UserAndContactTest {
    public testmethod static void testUserAndContact() {
        InsertFutureUser.insertUser();
        Contact currentContact = new Contact(
            firstName = String.valueOf(System.currentTimeMillis()),
            lastName = 'Contact');
        insert(currentContact);
    }
}
public class InsertFutureUser {
    @future(Delay='0')
    public static void insertUser() {
        Profile p = [SELECT Id FROM Profile WHERE Name='Standard User'];
        UserRole r = [SELECT Id FROM UserRole WHERE Name='COO'];
        User futureUser = new User(firstname = 'Future', lastname = 'User',
            alias = 'future', defaultgroupnotificationfrequency = 'N',
            digestfrequency = 'N', email = 'test@test.org',
            emailencodingkey = 'UTF-8', languagelocalekey='en_US', 
            localesidkey='en_US', profileid = p.Id, 
            timezonesidkey = 'America/Los_Angeles',
            username = 'futureuser" + System.now() +  "@test.org',
            userpermissionsmarketinguser = false,
            userpermissionsofflineuser = false, userroleid = r.Id);
        insert(futureUser);
    }
}

Apex テストでの通貨と小数の比較

Apex テストで通貨値と小数値を比較するときに例外が発生するバグが修正されました。通貨値と小数値の両方が含まれるデータサイロを使用して、それらのデータ型を関心のあるコンテンツと比較できるようになりました。

WSDL ベースの非同期コールアウトのテスト

以前は、WSDL ベースの同期コールアウトまたは WSDL ベース以外の非同期コールアウトをテストできました。ただし、インポートした WSDL から行われた非同期コールアウトをテストすると、テストが内部 Salesforce エラーで失敗していました。このバグは修正されました。

SFDC:Spring'16のApex Flex キュー内のジョブ検索を試してみました

$
0
0

f:id:tyoshikawa1106:20160218141715p:plain

リリースノート


FlexQueueItem オブジェクトをクエリして、Flex キュー内の非同期 Apex ジョブの位置を検索できるようになりました。


こういう操作が必要になることがなかったのであまりわかっていませんが、次のクエリが実行できるようになったみたいです。

Flex キュー内の AsyncApexJob の位置を検索する
SELECT JobPosition FROM FlexQueueItem
        WHERE JobType = 'BatchApex' AND AsyncApexJobId = '707xx000000DABC'
特定の位置にあるジョブを検索する
SELECT AsyncApexJobId FROM FlexQueueItem
        WHERE JobType = 'BatchApex' AND JobPosition = '2'
Flex キュー内のすべての一括処理ジョブを検索する
SELECT JobType, JobPosition, AsyncApexJob.ApexClass.Name, AsyncApexJob.CreatedDate,
    AsyncApexJob.CreatedBy FROM FlexQueueItem WHERE JobType='BatchApex' AND
    AsyncApexJob.ApexClass.Name LIKE '%'BatchAJob'%' ORDER BY JobPosition DESC
注意点

FlexQueueItemオブジェクトにクエリを実行する場合、WHERE句のJobTypeを必ず指定する必要があります。
f:id:tyoshikawa1106:20160218142246p:plain


とりあえずこういうことができるようになったことは覚えておきたいと思います。

SFDC:Spring'16のプラットフォームキャッシュ関連の新機能について確認しました

$
0
0

プラットフォームキャッシュまわりがいろいろ改善されたみたいです。

プラットフォームキャッシュトライアルによるパフォーマンス改善のテスト

f:id:tyoshikawa1106:20160218150453p:plain

リリースノート

アプリケーションでプラットフォームキャッシュを使用して、パフォーマンス改善をテストするためにトライアルキャッシュ空間を要求できるようになりました。

Enterprise Edition、Unlimited Edition、および Performance Edition にはいくつかのキャッシュが含まれていますが、多くの場合キャッシュを追加することでパフォーマンスがさらに改善されます。

トライアル要求が承認されたら、容量をパーティションに割り当て、さまざまなシナリオでキャッシュの使用を試すことができます。

トライアルキャッシュをテストすることで、追加キャッシュを購入すべきかどうかを十分な情報に基づいて決定できます。この機能は、Salesforce Classic でのみ使用できます。

プラットフォームキャッシュの購入

アプリケーションの大幅なパフォーマンス向上が期待できるプラットフォームキャッシュ空間を購入できるようになったみたいです。この機能はSalesforce Classicでのみ利用できます。

f:id:tyoshikawa1106:20160218143603p:plain

リリースノート

  • Enterprise Edition (デフォルトで 10 MB)
  • Unlimited Edition (デフォルトで 30 MB)
  • Performance Edition (デフォルトで 30 MB)


アプリケーションに効果のあるキャッシュの量を判別するために、トライアルキャッシュを要求して組織で試すことができます。特に次の場合は、プラットフォームキャッシュによるパフォーマンス向上が期待できます。

  • 多くの Apex カスタマイズが行われている組織
  • 同時ユーザ数の多い組織
  • 複雑な計算やクエリを行う組織やアプリケーション
  • また、ISV はキャッシュを購入して、お客様に提供するアプリケーションで使用できます。
  • キャッシュ空間は、10 MB ブロック単位の年間契約で販売されます。
  • プラットフォームキャッシュを購入するには、Salesforce の担当者まで連絡する。


プラっとフォームキャッシュはあまりさわったことがありませんが、こういうものがあるということは覚えておこうと思います。

SFDC:Spring'16の新規および変更された Chatter in Apex クラスを確認してみました

$
0
0

f:id:tyoshikawa1106:20160218164445p:plain

リリースノート

Announcements

ConnectApi.Announcements クラスでお知らせのお知らせの取得やお知らせの投稿ができるようになります。

お知らせの取得
  • getAnnouncements(communityId, parentId) — お知らせの最初のページを取得します。
  • getAnnouncements(communityId, parentId, pageParam, pageSize) — お知らせの指定したページを取得します。
お知らせの投稿
  • postAnnouncement(communityId, announcement) — お知らせを投稿します。

Chatter アンサー

ConnectApi.Zones クラスでChatterアンサーの言語別の記事および質問の検索ができるようになります。

  • searchInZone(communityId, zoneId, q, filter, language) — キーワードでゾーンを検索します。結果の言語を指定し、記事または質問を検索するかどうかを指定します。言語値は、Salesforce でサポートされるロケールコードである必要があります。

フィード

ConnectApi.ChatterFeeds クラスでSalesforce にアップロード済みの複数のファイルをフィード投稿に添付ができるようになります。

  • すでにアップロードされている最大 5 個のファイルをフィード投稿に添付するには、新しい postFeedElement(communityId, feedElement) メソッドを使用して、ConnectApi.FeedElementCapabilitiesInput クラスに新しい files プロパティを指定します。複数のファイルのコメントへの添付はサポートされません。

postFeedElement(communityId, feedElement, feedElementFileUpload) メソッドは使用できなくなりました。バージョン 36.0 以降では、同一のコールでフィード投稿を作成してバイナリファイルをアップロードすることができません。

グループ

ConnectApi.ChatterGroups クラスでグループのバナー写真の削除などができるようになります。

グループのバナー写真の削除
  • deleteBannerPhoto(communityId, groupId) — グループのバナー写真を削除します。
  • グループのバナー写真を削除できるのは、グループ所有者、グループマネージャ、および「すべてのデータの管理」権限を持つユーザです。
グループのバナー写真の取得
  • getBannerPhoto(communityId, groupId) — グループのバナー写真を取得します。
グループのバナー写真の設定
  • setBannerPhoto(communityId, groupId, fileId, versionNumber) — グループのバナー写真をアップロード済みのファイルに設定します。
  • setBannerPhoto(communityId, groupId, fileUpload) — グループのバナー写真をまだアップロードされていないファイルに設定します。
  • setBannerPhotoWithAttributes(communityId, groupId, bannerPhoto) — アップロード済みのファイルをグループのバナー写真に設定してトリミングします。
  • setBannerPhotoWithAttributes(communityId, groupId, bannerPhoto, fileUpload) — グループのバナー写真をまだアップロードされていないファイルに設定し、必要なトリミングを行います。
  • グループのバナー写真を設定できるのは、グループ所有者、グループマネージャ、および「すべてのデータの管理」権限を持つユーザです。
ゲストユーザがメンバー情報にアクセス可能
  • コミュニティでログインなしのアクセスが許可されている場合は、ゲストユーザが次のメソッドを使用できます。これらのメソッドは、ゲストユーザがアクセスできる情報を返します。
  • getMembers(communityId, groupId) — グループのメンバーに関する情報の最初のページを取得します。
  • getMembers(communityId, groupId, pageParam, pageSize) — グループのメンバーに関する情報の指定したページを取得します。

ナレッジ

ConnectApi.Knowledge クラスでコミュニティのトレンド関係の処理ができるようになります。

コミュニティのトレンド記事の取得
  • getTrendingArticles(communityId, maxResults) — コミュニティのトレンド記事を取得します。
コミュニティのトピックのトレンド記事の取得
  • getTrendingArticlesForTopic(communityId, topicId, maxResults) — コミュニティのトピックのトレンド記事を取得します。

おすすめ

  • ConnectApi.Recommendations クラスでおすすめ情報の取得ができるようになります。

コミュニティマネージャ (「コミュニティの作成および設定」または「コミュニティの管理」権限を持つユーザ) は、コミュニティのおすすめ利用者、おすすめ定義、およびスケジュール済みおすすめに対するアクセス、作成、削除を行うことができます。「すべてのデータの編集」権限を持つユーザも、おすすめ利用者、おすすめ定義、およびスケジュール済みおすすめに対するアクセス、作成、削除を行うことができます。

ユーザのおすすめの取得
  • getRecommendationsForUser(communityId, userId, contextAction, contextObjectId, maxResults, channel) — コンテキストユーザへのユーザ、グループ、ファイル、レコード、トピック、カスタムのおすすめ、および静的なおすすめを返します。
  • getRecommendationsForUser(communityId, userId, action, contextAction, contextObjectId, maxResults, channel)—指定されたアクションのコンテキストユーザへのおすすめを返します。
  • getRecommendationsForUser(communityId, userId, action, objectCategory, contextAction, contextObjectId, maxResults, channel) — 指定されたアクションおよびオブジェクトカテゴリのコンテキストユーザへのおすすめを返します。

各メソッドにはそれぞれ一致する set test メソッドがあります。

スケジュール済みおすすめの作成
  • createScheduledRecommendation(communityId, recommendationDefinitionId, rank, enabled, recommendationAudienceId, channel) — スケジュール済みおすすめを指定されたパラメータで作成します。
使用できなくなったおすすめのメソッド

おすすめの 5 つの新しいメソッドにより、次のおすすめのメソッドは使用できなくなりました。

  • getRecommendationsForUser(communityId, userId, contextAction, contextObjectId, maxResults) および一致する set test メソッド
  • getRecommendationsForUser(communityId, userId, action, contextAction, contextObjectId, maxResults) および一致する set test メソッド
  • getRecommendationsForUser(communityId, userId, action, objectCategory, contextAction, contextObjectId, maxResults) および一致する set test メソッド
  • getScheduledRecommendations(communityId)
  • createScheduledRecommendation(communityId, recommendationDefinitionId, rank, enabled, recommendationAudienceId)
トピックのおすすめの取得

トピックのおすすめはコミュニティでのみ使用できます。
次の既存のメソッドを使用して、トピックのおすすめを取得します。

  • getRecommendationForUser(communityId, userId, action, objectId) — 指定されたアクションおよびオブジェクト ID のコンテキストユーザへのおすすめを返します。
  • getRecommendationsForUser(communityId, userId, contextAction, contextObjectId, maxResults, channel) — コンテキストユーザへのユーザ、グループ、ファイル、レコード、トピック、カスタムのおすすめ、および静的なおすすめを返します。
  • getRecommendationsForUser(communityId, userId, action, contextAction, contextObjectId, maxResults, channel)—指定されたアクションのコンテキストユーザへのおすすめを返します。
  • getRecommendationsForUser(communityId, userId, action, objectCategory, contextAction, contextObjectId, maxResults, channel) — 指定されたアクションおよびオブジェクトカテゴリのコンテキストユーザへのおすすめを返します。

各メソッドにはそれぞれ一致する set test メソッドがあります。

トピックのおすすめの拒否

次の既存のメソッドを使用して、トピックのおすすめを拒否します。

  • rejectRecommendationForUser(communityId, userId, action, objectId) — 指定されたアクションおよびオブジェクト ID のコンテキストユーザへのおすすめを拒否します。

Topics

ConnectApi.Topics クラスでトピックの作成を行えます。

  • createTopic(communityId, name, description) — トピックを作成します。「トピックの作成」権限を持つユーザのみがトピックを作成できます。

UserProfiles

ConnectApi.UserProfiles クラスでユーザのバナー写真に関する処理ができるようになります。

ユーザのバナー写真の削除
  • deleteBannerPhoto(communityId, userId) — ユーザのバナー写真を削除します。
ユーザのバナー写真の取得
  • getBannerPhoto(communityId, userId) — ユーザのバナー写真を取得します。
ユーザのバナー写真の設定
  • setBannerPhoto(communityId, userId, fileId, versionNumber) — ユーザのバナー写真をアップロード済みのファイルに設定します。
  • setBannerPhoto(communityId, userId, fileUpload) — ユーザのバナー写真をまだアップロードされていないファイルに設定します。
  • setBannerPhotoWithAttributes(communityId, userId, bannerPhoto) — アップロード済みのファイルをユーザのバナー写真に設定してトリミングします。
  • setBannerPhotoWithAttributes(communityId, userId, bannerPhoto, fileUpload) — ユーザのバナー写真をまだアップロードされていないファイルに設定し、必要なトリミングを行います。

SFDC:Spring'16の新規 Apex クラスを確認してみました

$
0
0

Spring'16の新規 Apex クラスを確認してみました。

f:id:tyoshikawa1106:20160218172310p:plain

リリースノート

Auth 名前空間のクラス

AuthProviderCallbackState クラス

新しい Auth.AuthProviderCallbackState クラスは、ユーザ認証用の要求 HTTP ヘッダー、本文、およびクエリパラメータを Auth.AuthProviderPlugin.handleCallback メソッドに提供します。このクラスでは、ヘッダー、本文、クエリパラメータを個別に渡す代わりに、情報をグループ化して渡すことができます。

AuthProviderTokenResponse クラス

新しい Auth.AuthProviderTokenResponse クラスは、Auth.AuthProviderPlugin.handleCallback メソッドからの応答を保存します。

Reports 名前空間のクラス

BucketField クラス

新しい Reports.BucketField クラスには、レポートのバケット項目を説明するメソッドがあります。

getBucketType()

バケットタイプを返します。

getDevloperName()

バケットの API 参照名を返します。

getLabel()

ユーザに表示されるバケットの名前を返します。

getNullTreatedAsZero()

null 値が数値の 0 に変換される場合は true、そうでない場合は false を返します。

getOtherBucketLabel()

PICKLIST タイプのバケットで Other としてグループ化される項目の名前を返します。

getSourceColumnName()

バケット項目の API 参照名を返します。

getValues()

バケット項目でグループ化されるレポート値を返します。

setBucketType(value)

バケットの BucketType を設定します。

setBucketType(bucketType)

バケットの BucketType を設定します。

setDevloperName(devloperName)

バケットの API 参照名を設定します。

setLabel(label)

ユーザに表示されるバケットの名前を設定します。

setNullTreatedAsZero(nullTreatedAsZero)

バケット内の null 値が 0 に変換されるか (true)、否か (false) を指定します。

setOtherBucketLabel(otherBucketLabel)

(BucketType PICKLIST のバケットで) Other としてグループ化される項目の名前を設定します。

setSourceColumnName(sourceColumnName)

バケット項目の名前を指定します。

setValues(values)

バケットに含まれる値の種別を指定します。

toString()

文字列を返します。

BucketFieldValue クラス

新しい Reports.BucketFieldValue クラスには、バケット項目で「バケット化された」値に関する情報があります。

getLabel()

ユーザに表示されるバケットカテゴリの名前を返します。

getRangeUpperBound()

(NUMBER タイプのバケットで) このバケットカテゴリに含まれる値の最大範囲制限を返します。

getSourceDimensionValues()

(PICKLIST タイプと TEXT タイプのバケットで) このバケットカテゴリに含まれるソース項目からの値のリストを返します。

setLabel(label)

ユーザに表示されるバケットカテゴリの名前を設定します。

setRangeUpperBound(rangeUpperBound)

(NUMBER タイプのバケットで) このバケットカテゴリに含まれる値の最大範囲制限を設定します。

setSourceDimensionValues(sourceDimensionValues)

(PICKLIST タイプと TEXT タイプのバケットで) このバケットカテゴリに含まれるソース項目からの値を指定します。

toString()

文字列を返します。

CrossFilter クラス

新しい Reports.CrossFilter クラスには、クロス条件に関する情報が含まれます。

getCriteria()

relatedEntity を絞り込む方法に関する情報を返します。主エンティティの評価対象となる relatedEntity のサブセットを説明します。

getIncludesObject()

主オブジェクトに relatedEntity との関係がある場合は true、そうでない場合は false を返します。

getPrimaryEntityField()

クロス条件が評価されるオブジェクトの名前を返します。

getRelatedEntity()

primaryEntityField の評価対象となるオブジェクトの名前 (クロス条件の右側) を返します。

getRelatedEntityJoinField()

primaryEntityField と relatedEntity の結合に使用される項目の名前を返します。

setCriteria(criteria)

relatedEntity を絞り込む方法を指定します。主エンティティを relatedEntity のサブセットと関連付けます。

setIncludesObject(includesObject)

返されるオブジェクトに relatedEntity との関係があるか (true)、否か (false) を指定します。

setPrimaryEntityField(primaryEntityField)

クロス条件が評価されるオブジェクトの名前を指定します。

setRelatedEntity(relatedEntity)

primaryEntityField の評価対象となるオブジェクトの名前 (クロス条件の右側) を指定します。

setRelatedEntityJoinField(relatedEntityJoinField)

primaryEntityField と relatedEntity の結合に使用される項目の名前を指定します。

toString()

文字列を返します。

ReportCsf クラス

新しい Reports.ReportCsf クラスには、カスタム集計項目に関する情報が含まれます。

getAcrossGroup()

acrossGroupType が CUSTOM の場合、列のグルーピングの名前を返します。そうでない場合は null を返します。

getAcrossGroupType()

集計の表示場所を返します。

getDecimalPlaces()

カスタム集計項目にある数値の小数点以下の桁数を返します。

getDescription()

ユーザに表示されるカスタム集計項目の説明を返します。

getDownGroup()

downGroupType が CUSTOM の場合、行のグルーピングの名前を返します。そうでない場合は null を返します。

getDownGroupType()

カスタム集計項目の集計の表示場所を返します。

getFormula()

カスタム集計項目の値に対して実行される操作を返します。

getFormulaType()

数式の種類を返します。

getLabel()

ユーザに表示されるカスタム集計項目の名前を返します。

setAcrossGroup(acrossGroup)

範囲のグルーピングの列を指定します。

setAcrossGroupType(value)

集計の表示場所を設定します。

setAcrossGroupType(acrossGroupType)

集計の表示場所を設定します。

setDecimalPlaces(decimalPlaces)

数値の小数点以下の桁数を設定します。

setDescription(description)

ユーザに表示されるカスタム集計項目の説明を設定します。

setDownGroup(downGroup)

downGroupType が CUSTOM の場合、行のグルーピングの名前を設定します。

setDownGroupType(value)

集計の表示場所を設定します。

setDownGroupType(downGroupType)

集計の表示場所を設定します。

setFormula(formula)

カスタム集計項目の値に対して実行される操作を設定します。

setFormulaType(value)

カスタム集計項目の数値の形式を設定します。

setFormulaType(formulaType)

カスタム集計項目で使用される数値の形式を設定します。

setLabel(label)

ユーザに表示されるカスタム集計項目の名前を設定します。

toString()

文字列を返します。

TopRows クラス

新しい Reports.TopRows クラスは、行制限条件を説明します。

getDirection()

レポートの行の並び替え順を返します。

getRowLimit()

レポートに表示される行の最大数を返します。

setDirection(value)

レポートの行の並び替え順を設定します。

setDirection(direction)

レポートの行の並び替え順を設定します。

setRowLimit(rowLimit)

レポートに含まれる行の最大数を設定します。

toString()

文字列を返します。

SFDC:Spring'16の変更された Apex クラスを確認してみました

$
0
0

次の既存のクラスで、メソッドまたは定数が新規追加または変更されました。

f:id:tyoshikawa1106:20160218174509p:plain

リリースノート

Auth.AuthConfiguration クラス

新しいメソッド

isCommunityUsingSiteAsContainer()

コミュニティが Site.com ページを使用する場合は true、使用しない場合は false を返します。

Auth.SessionManagement クラス

新しいメソッド

generateVerificationUrl(policy, description, destinationUrl)

ユーザが登録している検証方法を使用するユーザ ID 検証フローを開始し、ID 検証画面への URL を返します。たとえば、機密の取引先詳細が表示されるカスタム Visualforce ページがある場合、ユーザがそのページを表示する前に ID 検証を要求することができます。

getRequiredSessionLevelForProfile(profileId)

特定のプロファイルで必要なログインセキュリティセッションレベルを示します。

validateTotpTokenForKey(totpSharedKey, totpCode, description)

時間ベースのワンタイムパスワード (TOTP) コード (トークン) が特定の共有鍵に対して有効かどうかを示します。

validateTotpTokenForUser(totpCode, description)

時間ベースのワンタイムパスワード (TOTP) コード (トークン) が現在のユーザに対して有効かどうかを示します。

変更されたメソッド

validateTotpTokenForKey(sharedKey, totpCode)

廃止。代わりに、validateTotpTokenForKey(totpSharedKey, totpCode, description) を使用してください。

validateTotpTokenForUser(totpCode)

廃止。代わりに、validateTotpTokenForUser(totpCode, description) を使用してください。

Cache.Org クラス

新しいメソッド

getName()

デフォルトのキャッシュパーティションの名前を返します。

新しい定数

MAX_TTL_SECS

Time to Live (TTL) 値の設定時に使用可能な定数が Org クラスで提供されます。

Cache.Session クラス

新しいメソッド

getName()

デフォルトのキャッシュパーティションの名前を返します。

新しい定数

MAX_TTL_SECS

Time to Live (TTL) 値の設定時に使用可能な定数が Session クラスで提供されます。

QuickAction.QuickActionResult クラス

新しいメソッド

getSuccessMessage()

クイックアクションに関連付けられた成功メッセージを返します。

Reports.ReportMetadata クラス

新しいメソッド

getBuckets()

レポート内のバケット項目のリストを返します。

getCrossFilters()

レポートに適用されているクロス条件に関する情報を返します。

getCustomSummaryFormula()

レポートのカスタム集計項目に関する情報を返します。

getTopRows()

返される行数と並び替え順など、行制限の検索条件に関する情報を返します。

setBuckets(buckets)

レポートにバケット項目を作成します。

setCrossFilters(crossFilters)

レポートにクロス条件を適用します。

setCustomSummaryFormula(customSummaryFormula)

カスタム集計項目をレポートに追加します。

setTopRows(topRows)

行制限の検索条件をレポートに適用します。

System.SandboxPostCopy クラス

新しいメソッド

runApexClass

Sandbox 環境をビジネス対応にするために、データ操作またはビジネスロジックタスクを自動化します。Sandbox 作成時に、タスクを実行する Apex クラスを 1 つ指定します。Sandbox がコピーされるたびにこのクラスが実行され、組織 ID、Sandbox ID、および Sandbox 名のコンテキストを提供します。

System.Approval クラス

新しいメソッド

isLocked(id)

ID id のレコードがロックされている場合は true、ロックされていない場合は false を返します。

isLocked(ids)

レコード ID とそのロック状況の対応付けを返します。レコードがロックされている場合、状況は true です。レコードがロックされていない場合、状況は false です。

isLocked(sobject)

sobject レコードがロックされている場合は true、ロックされていない場合は false を返します。

isLocked(sobjects)

レコード ID とロック状況の対応付けを返します。レコードがロックされている場合、状況は true です。レコードがロックされていない場合、状況は false です。

System.Site クラス

新しいメソッド

getPasswordPolicyStatement()

Napili テンプレートで作成されたコミュニティのパスワード要件を返します。

isValidUsername(username)

特定のユーザ名が有効な場合は true、有効ではない場合は false を返します。

validatePassword(user, password, confirmPassword)

特定のパスワードが、現在のユーザの組織全体またはプロファイルベースのパスワードポリシーで指定された要件を満たすかどうかを示します。

System.System クラス

新しいメソッド

isQueueable()

キュー可能 Apex ジョブが実行中のコードを呼び出した場合は true を返します。そうではない場合 (Apex 一括処理ジョブまたは future メソッドがコードを呼び出した場合を含む) は false を返します。

変更されたメソッド

isBatch()

Apex 一括処理ジョブが実行中のコードを呼び出した場合は true、呼び出していない場合は false を返します。API バージョン 35.0 以前では、キュー可能 Apex ジョブがコードを呼び出した場合も true を返します。

System.Test クラス

新しいメソッド

setCreatedDate(recordId, createdDatetime)

テストコンテキスト sObject の CreatedDate を設定します。

System.UserInfo クラス

変更されたメソッド

getUiTheme()

現在のユーザに推奨されるテーマを返します。Salesforce1 と Lightning Experience をサポートするために、有効な戻り値の範囲が拡張されました。

getUiThemeDisplayed()

現在のユーザに表示されるテーマを返します。Salesforce1 と Lightning Experience をサポートするために、有効な戻り値の範囲が拡張されました。

SFDC:Spring'16の新規 Apex Enumについて確認してみました

$
0
0

Spring'16の新規 Apex Enumについて確認してみました。

f:id:tyoshikawa1106:20160218180718p:plain

リリースノート

Auth.VerificationPolicy 列挙
  • Auth.VerificationPolicy 列挙には ID 検証ポリシー値が含まれ、SessionManagement.generateVerificationUrl メソッドで使用されます。
Reports.BucketType 列挙
  • バケットに含まれる値のタイプ。
Reports.CsfGroupType 列挙
  • レポートにカスタム集計形式の集計を表示するグループレベル。
Reports.FormulaType 列挙
  • カスタム集計項目の数値の形式。

SFDC:Spring'16の新規 Apex 例外について確認してみました

$
0
0

Spring'16の新規 Apex 例外について確認してみました。

f:id:tyoshikawa1106:20160218181351p:plain

リリースノート

Cache 名前空間

ItemSizeLimitExceededException
  • 最大サイズ制限を超える項目を指定してキャッシュ put コールが行われた場合に発生します。

SFDC:Spring'16の新規 Apex インターフェースについて確認してみました

$
0
0

Spring'16の新規 Apex インターフェースについて確認してみました。

f:id:tyoshikawa1106:20160218181541p:plain

リリースノート

Auth.AuthProviderPlugin インターフェース

Salesforce へのシングルサインオン用に OAuth ベースのカスタム認証プロバイダプラグインを作成するには、AuthProviderPlugin を使用します。

getCustomMetadataType()

Salesforce へのシングルサインオン用に OAuth ベースのカスタム認証プロバイダのカスタムメタデータ型 API 名を返します。

handleCallback(authProviderConfiguration, callbackState)

認証プロバイダのサポート対象認証プロトコルを使用して、OAuth アクセストークン、OAuth の秘密または更新トークン、現在のユーザへの要求が開始されたときに渡された状態を返します。

initiate(authProviderConfiguration, stateToPropagate)

ユーザが認証のためにリダイレクトされる URL を返します。

System.SandboxPostCopy インターフェース

Sandbox が作成または更新された後のタスクを完了するには、SandboxPostCopy を使用します。実行するメソッドを含むクラスを作成し、Sandbox を作成するときにそのクラスを指定します。

SFDC:System.ApprovalのisLockedを試してみました

$
0
0

Spring'16で追加されたSystem.ApprovalクラスのisLockedを試してみました。Apex内でレコードがロックされているか判定することができます。

f:id:tyoshikawa1106:20160225224009p:plain

public Boolean checkRecordLocked(Id recordId) {
    if (String.isNotEmpty(recordId)) {
        if (System.Approval.isLocked(recordId)) {
            return true;
        }
    }
    return false;
}


レコードのロックとは承認申請中のこの状態です。
f:id:tyoshikawa1106:20160225224254p:plain


isLocked判定を利用すれば登録処理前にロックされているか判定したりできます。
f:id:tyoshikawa1106:20160225224440p:plain

f:id:tyoshikawa1106:20160225224509p:plain


isLocked判定の注意点として、プロセスの自動化設定で「Apex でのレコードのロックおよびロック解除を有効化」にチェックをつけておく必要があります。
f:id:tyoshikawa1106:20160224003639p:plain


これがないとisLocked判定実行時に『Apex approval lock/unlock api preference not enabled.』エラーが発生してしまいます。
f:id:tyoshikawa1106:20160225224808p:plain


System.ApprovalのisLockedはこんな感じです。


ちなみにisLockedの引数がNULLの場合はExceptionエラーになりました。
f:id:tyoshikawa1106:20160225224959p:plain


事前にIDの存在判定を入れておいた方が良さそうでした。
f:id:tyoshikawa1106:20160225225020p:plain

SFDC:RemoteActionと標準ページへのVF埋め込み

$
0
0

標準ページへ埋め込むVisualforceページ開発でRemoteActionを利用するときの注意点です。RemoteActionの書き方はこんな感じです。

<apex:page standardController="Account" extensions="VFMessageController" showHeader="false">
    <div id="vf-page">
        <div id="vf-message" style="padding: 5px;"></div>
    </div>
    <script type="text/javascript">
        (function(){
            "use strict";
            
            // 初期処理
            function init() {
                
                VFMessageController.getMessage(function(result, event) {
                    if(event.status) {
                        console.log(result);
                        document.getElementById('vf-message').innerHTML = result;
                    } else {
                        alert(event.message);
                    }
                });
            }
            
            init();
        })();
    </script>
</apex:page>
public with sharing class VFMessageController {
    
    public VFMessageController(ApexPages.StandardController stdController) {
        
    }
    
    @RemoteAction
    public static String getMessage() {
        return 'VF Message!!';
    }
}


これでエラーもなく正常に実行されることを確認できます。
f:id:tyoshikawa1106:20160225231143p:plain


これをこのまま標準ページに埋め込んでみます。
f:id:tyoshikawa1106:20160225232035p:plain


単体では正常に表示されたVFページですが標準ページに埋め込むと・・・
f:id:tyoshikawa1106:20160225232150p:plain


このようにエラーになってしまいます。

Javascript proxies were not generated for controller VFMessageController: may not use public remoted methods inside an iframe.


標準ページに埋め込むVFではRemoteActionは利用できないのかと思ったりしたのですが、原因はpublic宣言にありました。このような使い方をする場合は、publicではなくglobalと宣言する必要があるみたいです。

global with sharing class VFMessageController {
    
    global VFMessageController(ApexPages.StandardController stdController) {
        
    }
    
    @RemoteAction
    global static String getMessage() {
        return 'VF Message!!';
    }
}


これで先程のエラーが解決して無事に表示されるようになりました。
f:id:tyoshikawa1106:20160225232541p:plain


今回、RemoteActionの戻り値はただのString型変数ですが、自作のWrapperクラスの場合はそちらもglobalの宣言にする必要がありました。


以上、RemoteActionと標準ページへのVF埋め込みについてです。

SFDC:RemoteActionとセッションに対して無効なリモート要求

$
0
0

DE組織で開発中、RemoteActionで処理を行っていたVisualforceページで突然エラーが発生しました。

セッションに対して無効なリモート要求。ページを更新して、要求を再送信します。


iframe内で利用しているVFページだったのですが、直接表示をしてみたところ、別のエラーメッセージが表示され、Trustのリンクが記載されていました。


もしかしてと確認してみると対象インスタンスのパフォーマンス低下が発生していました。
f:id:tyoshikawa1106:20160226121726p:plain


ほんのすこし待ってもう一度確認したところ、正常に実行されるようになりました。突然『セッションに対して無効なリモート要求』というエラーが発生した場合はTrustを確認してみると良さそうです。

Viewing all 1438 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>