Labyrinth of Wisdom

-This is My Archive-


データ型「複数選択リスト」をWeb To リード(ケース)のフォームでチェックボックス表示

Salesforceにおいて、オブジェクトの項目タイプに複数選択リストというのがありますが、これをHTML上でチェックボックスで表現したい場合のメモ。

事前準備

Web ToリードのHTML生成方法は過去記事をチェックしてください。

複数選択リスト

Web To リードでHTMLを生成すると下記の様になります。

<META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=UTF-8">

<form action="https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8" method="POST">

  <input type=hidden name="oid" value="xxxxxxxxxxxxxxx">
  <input type=hidden name="retURL" value="http://">

  <p>
    <label for="yyyyyyyyyyyyyyy">希望曜日:</label>
    <select id="yyyyyyyyyyyyyyy" multiple="multiple" name="yyyyyyyyyyyyyyy" title="2_参加可能曜日・時間">
      <option value="月曜">月曜</option>
      <option value="火曜">火曜</option>
      <option value="水曜">水曜</option>
      <option value="木曜">木曜</option>
      <option value="金曜">金曜</option>
      <option value="土曜">土曜</option>
      <option value="日曜">日曜</option>
    </select>
  </p>
  <p>
    <input type="submit" name="submit">
  </p>
</form>

見た目はこんな感じ。いけてないですね。 f:id:Labyrinth_of_Wisdom:20160518163334p:plain

チェックボックス

先ほどのコードを下記の様に変更していきます。

<META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=UTF-8">

<form action="https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8" method="POST">

  <input type=hidden name="oid" value="xxxxxxxxxxxxxxx">
  <input type=hidden name="retURL" value="http://">

希望曜日:
  <p>
    <input type="checkbox" id="yyyyyyyyyyyyyyy" name="yyyyyyyyyyyyyyy" value="月曜">月曜
    <input type="checkbox" id="yyyyyyyyyyyyyyy" name="yyyyyyyyyyyyyyy" value="火曜">火曜
    <input type="checkbox" id="yyyyyyyyyyyyyyy" name="yyyyyyyyyyyyyyy" value="水曜">水曜
    <input type="checkbox" id="yyyyyyyyyyyyyyy" name="yyyyyyyyyyyyyyy" value="水曜">木曜
    <input type="checkbox" id="yyyyyyyyyyyyyyy" name="yyyyyyyyyyyyyyy" value="木曜">金曜
    <input type="checkbox" id="yyyyyyyyyyyyyyy" name="yyyyyyyyyyyyyyy" value="金曜">土曜
    <input type="checkbox" id="yyyyyyyyyyyyyyy" name="yyyyyyyyyyyyyyy" value="土曜">日曜
  </p>
  <p>
    <input type="submit" name="submit">
  </p>

</form>

するとチェックボックスに変わっています。すっきりしましたね。

データもちゃんと反映されると思います。 f:id:Labyrinth_of_Wisdom:20160518163438p:plain

まとめ

Salesforceの話というよりは、ほぼHTMLの話のような気もしますが、気にしない気にしない。

参考

HTMLタグ/フォームタグ/チェックボックスを作る - TAG index Webサイト

リストビューに「レコードを複数選択して削除するボタン」を追加する

はじめに

Salesforceのリストビュー画面で、選択した複数のレコードを削除するボタンのサンプルを書きます。

標準だと一つづつレコードを消していくか全部消すしかないので、これがあると便利です。

オブジェクトの種類でアクセスする場所が違うので気を付けてください。

  • 標準オブジェクトの場合

設定 > カスタマイズ > 任意のオブジェクト(キャンペーン等) > ボタン、リンク、およびアクション > 新規ボタンまたはリンク

  • カスタムオブジェクトの場合

設定 > 作成 > オブジェクト > 任意のオブジェクト > ボタン、リンク、およびアクション > 新規ボタンまたはリンク

カスタムボタン作成

それぞれの種類に適した場所にアクセス後、下記の設定を行います。

表示の種類 => リストボタン

動作 => JavaScriptを実行

内容のソース => OnClick JavaScript

そしてテキストフィールドに下記のサンプルコードを記入してください。

3行目の対象オブジェクトは状況に応じて 変更してください。

{!REQUIRESCRIPT("/soap/ajax/9.0/connection.js")}

// 対象のオブジェクトを指定する
var records = {!GETRECORDIDS( $ObjectType.Hogehoge__c )};

if (records[0] == null) {
    alert("削除対象にチェックがついていません。");
} else if(confirm(records.length + "個のレコードを削除しますがよろしいですか?")){
        sforce.connection.deleteIds(records);// ここで削除
        location.reload();// 削除成功後に画面をリロード
} else {
        alert("キャンセルされました。");
}

リストビューに表示

これだけだとリストビューにボタンが表示されないので、ボタンが表示されるように設定します。

  • 標準オブジェクトの場合

設定 > カスタマイズ > 任意のオブジェクト(キャンペーン等) > 検索レイアウト > ***リストビュー

  • カスタムオブジェクトの場合

設定 > 作成 > オブジェクト > 任意のオブジェクト > 検索レイアウト > ***リストビュー

こんな感じでボタンが追加される。

f:id:Labyrinth_of_Wisdom:20160517180129p:plain

参考

ワークフロー機能ざっくりまとめ

はじめに

Salesforceのワークフローは使いこなせればとても便利な機能です。 プログラミングもしなくてもレコードの値を自動で変えたり、アラートメールを送ったりできるので、色んな使用方法が考えられます。

ただ設定方法がいまいち分かりにくいと思ったので、今回自分なりにまとめてみました。

ワークフローの大まかな流れ

コードで示した方が流れが伝わりやすいと思って書いてみました。

If(評価条件 == True){
    If(ルール条件 == True){
        ワークフローアクション実行
    }
}

// もしくは

If(評価条件 == True && ルール条件 == True){
    ワークフローアクション実行
}

要は評価条件ルール条件の二段階のチェックを通れば、ワークフローアクションが実行されるって感じですかね。 こう考えると凄くすっきりしました。

そして条件とワークフローアクションにもそれぞれ種類があります。

各条件とワークフローアクションの種類

評価条件

対象オブジェクトのレコードへのアクセスが下記のどれか一つに当てはまる時に、ルール条件のチェックを行います。

f:id:Labyrinth_of_Wisdom:20160511142912p:plain

ルール条件

数式や条件を指定し、ワークフローアクションを行うかどうかのチェックを行います。

例: f:id:Labyrinth_of_Wisdom:20160511142501p:plain

ワークフローアクション

ワークフローアクションを行うタイミングは2つあり、自分で設定することが出来ます。

一つ目がルール条件がTrueだった時に即座に行われるルール適用時のアクション、二つ目がルール条件がTrueだった時に時間指定でアクションを実行する時間ベースのアクションです。

アクションの内容は、ルール適用時も時間ベースも共通で下記の5つ。

  • 新規ToDo
  • 新規メールアラート
  • 新規項目自動更新
  • 新規アウトバウンドメッセージ
  • 既存アクションの選択

時間ベースのアクション実行のタイミングを設定するにはタイムトリガを追加する必要があります。

例:

f:id:Labyrinth_of_Wisdom:20160511142548p:plain

f:id:Labyrinth_of_Wisdom:20160511142601p:plain

例まとめ

今回の例をまとめます。

・評価条件
  キャンペーンオブジェクトのレコードが新たに作成された時
  もしくは後記するルール条件を満たすように編集された時

・ルール条件
  キャンペーンオブジェクトの項目「状況」の値が「進行中」の時

・時間ベースのアクション
  評価条件とルール条件を満たした場合、
  レコードの終了日から一日後に、レコードの「状況」を「完了」に変更

ワークフローの確認

待機中のワークフローは設定 > 監視 > 時間ベースのワークフローにアクセスし、条件を指定して検索することが出来ます。 f:id:Labyrinth_of_Wisdom:20160517130700p:plain

終わりに

ワークフローの設定方法を自分なりに噛み砕いてまとめてみましたが、いかがだったでしょうか? Salesforceは多機能なので使いこなすのが難しいですが、頑張っていきたいと思います。

【Apex】スケジュールを操作する

Apexコードを使ってスケジュールの作成・削除を行うことが出来ます。

これらを使えば、特定のクラスが呼び出された後にスケジュールをセットしたり削除したりすることが出来ます。

サンプルコード

CreateScheduleクラスを呼び出すと、ジョブ名「3時のおやつ」で2016年中毎日15時にScheduledTestクラスを呼び出すスケジュールが作成されます。

global class CreateSchedule {

    public static void execute(){
      String jobName = '3時のおやつ';
      
      // 2016年毎月毎日15時(年は省略可)
      String jobTime = '0 0 15 * * ? 2016';

      // スケジュールを作成
      System.schedule(jobName, jobTime, new ScheduledTest());
    }
}

今回は開発者コンソールから呼び出せるクラスを書いてみました。

開発者コンソール>Debug>Open Execute Anonymous Window

にアクセスし、下記のコードを記述してExecuteをクリックしてください。 CreateScheduleクラスが呼び出されます。

CreateSchedule.execute();

スケジュールが作られたかどうかを確認するには、

設定>ジョブ>スケジュール済みジョブ

にアクセスしてください。作成されたスケジュールが一覧で表示されています。

毎日15時になるとScheduledTestクラスが呼び出されます。 ただ毎日呼び出されると鬱陶しいので、呼ばれたらセットされたスケジュールを消すようにしてみました。 このクラスが呼ばれると、セットされたスケジュールが消され、コンソールにメッセージが表示されます。

global class ScheduledTest implements Schedulable {

    global void execute(SchedulableContext sc) {
      String jobName = '3時のおやつ';

      // スケジュールオブジェクトからレコードを取得
      List<CronTrigger> ct = [SELECT Id
                                FROM CronTrigger
                                WHERE CronJobDetail.JobType = '7'
                                AND CronJobDetail.Name = :jobName
                                LIMIT 1];

      // スケジュール削除
      System.abortJob(ct[0].Id);

      System.debug('今日のおやつはカールだよ');
    }
}

このスケジュールクラスは特殊で、Schedulableインターフェースを実装していたりします。スケジュールオブジェクトにアクセスするSOQL文もかなり特殊ですよね。

これらは決まった様式なので、最初の内はあまり深く考えなくてもいいかもしれません。 とりあえずはこの様式に当てはめて、自分の行いたい処理を書けばOKだと思います。

参考

おまけ

スケジュールの管理画面を作成されている方がおられました。 ここまでいけばかなりユーザも使いやすいですね。

www.terrasky.co.jp

【Apex】クラス呼び出し後の画面遷移 (PageReference型の使い方)

クラス呼び出し後の画面遷移の仕方がよくわからなかったので調べてみました。

サンプルコードを使って、PageReference型の簡単な使い方を解説します。

VisualForceページ_Page1

コントローラにJumpTestを指定し、ボタンでjumpメソッドを呼び出します。

<apex:page controller="JumpTest">
  <h1>ここはPage1です</h1>
  <apex:form >
    <apex:commandButton action="{!jump}" value="Page2へジャンプ!" />
  </apex:form>
</apex:page>

Apexクラス_JumpTest

JumpTestクラスの中に、戻り値PageReference型のjumpメソッドがあります。

メソッドの最後にreturnでVisualForceページPage2を返します。 ここで指定した画面に遷移します。

因みにreturn nullだと元の画面に遷移します。(今回で言うとPage1)

public class JumpTest(){
  public PageReference jump(){
    return Page.Page2;
  }
}

VisualForceページ_Page2

<apex:page>
  <h1>ジャンプ成功!ここはPage2です!</h1>
</apex:page>

Google Chromeでレポート作成がうまくできなかった話

なかなか同じ状態の人はいないと思うのですが、SalesForceのレポート作成が出来ない現象が起こりハマってしまったのでメモ。

すべてのタブ>レポート

にアクセスしてレポートを作成しようと思ったら、ページ左部のフォルダの部分が延々とダウンロード中で、先に進めなくなりました。

f:id:Labyrinth_of_Wisdom:20160510173015p:plain

そこから新規レポートにアクセスして作成ボタンを押してもエラー。

f:id:Labyrinth_of_Wisdom:20160510173056p:plain

なんじゃこりゃ?と色々検索しても解決策が見つからず。 諦めかけてた時に、ひょっとしたらブラウザが悪さしてるのかな?と思いIEで立ち上げると正常表示されました!(使用していたブラウザはGoogle Chrome)

ここでさらに閃き、ひょっとしたらプラグインが何か悪さしてるんじゃ!?と思いインストールしてるプラグインを見てみると怪しいモノが。

AdBlock 2.56 (広告ブロックのプラグイン)

f:id:Labyrinth_of_Wisdom:20160510173141p:plain

これを無効にすると・・・

表示された!

f:id:Labyrinth_of_Wisdom:20160510173209p:plain

f:id:Labyrinth_of_Wisdom:20160510173219p:plain

最初からブラウザを変えてやればすぐ気が付いたんでしょうが、激ハマりしてしまいました。 今後Webでこういうことがあった場合は、まずブラウザを疑ってみるという考え方を身に付けようと思います。

因みに Adblock Plus 1.11 に変更したら問題は起こりませんでした。

f:id:Labyrinth_of_Wisdom:20160510173230p:plain

【Apex】DB操作を取り消す方法(ロールバック)

データベースへの更新を取り消すロールバックをApexで実装したかったので、調べた結果をまとめたいと思います。

ついでにその際に起こった欠番現象にも少し触れています。

サンプルコード

複数のオブジェクトを更新するサンプルコード。

try文で一つでもDmlExceptionのエラーがあると、catch文に移動してロールバックポイントまで戻ります。

今回のサンプルではaccountもしくはcampaigninsertがどちらか一方でもDmlExceptionを引き起こした場合、両方のインサートが取り消されます。

Account account = new Account(Name = 'aaa');
Campaign campaign = new campaign(Name = 'bbb');

// ロールバックした際に戻るポイント
Savepoint sp = Database.setSavepoint();

try{
    insert account;
    insert campaign;
}catch(DmlException e){
    // 引数に戻るポイントを指定
    Database.rollback(sp);
}

欠番の可能性

オブジェクトのカラムに自動連番がある、かつロールバックが何回か発生した後でinsertに成功した場合には番号に抜け(欠番)が生じる可能性があります。

例:

  • 1回目

    insert account => 成功 , insert campaign => 失敗

    ロールバック実行 => レコード登録取り消し

  • 2回目

    insert account => 成功 , insert campaign => 成功

    レコード登録成功

  • 結果

Accountオブジェクト

No. Name
2 aaa

Campaignオブジェクト

No. Name
1 bbb

このようにロールバックをしていても、Accountオブジェクトレコードの番号は2で採番されてしまいます。 なんか気持ち悪い・・・。(レコードはちゃんと一個しかないんですが)

ただ、それらは気にするものでもないという意見がこちらに書かれているので、僕はそれを見習おうかと思います。 気になる方は一度見てみてください。

その他ロールバックの詳しいことは下記の参考サイトが詳しいです。

参考

[salesforce]APEXコードにおけるトランザクションとロールバック – deferloader