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

SFDC:Dreamforce2018 - 番外編「スーパー 8 ユニオン スクエア」に宿泊しました

$
0
0

Dreamforceに参加する際に個人的に一番悩むことになるのが宿泊するホテルの予約です。5泊前後と約1週間近く滞在が必要になることもありますが、イベント期間中のサンフランシスコのホテル代が軒並み高めお値段になるためです。今回はそんな中比較的安かった「スーパー 8 ユニオン スクエア」に宿泊してみました。
※正式名称は『Super 8 by Wyndham San Francisco/Union Square Area』

f:id:tyoshikawa1106:20181009222750p:plain


パウエルストリート駅から徒歩7分ほどで行ける距離にあるホテルです。
f:id:tyoshikawa1106:20181009224803p:plain


Webサイトはこちら。

https://www.wyndhamhotels.com/super-8/san-francisco-california/super-8-san-francisco-union-square-area/overview


周りのホテルが5日間で20万〜50万となかなかのお値段の中、約7万で宿泊できたリーズナブルなホテルでした。市税などを含めた金額でも約9万円で宿泊可能でした。

外観

f:id:tyoshikawa1106:20180924152441j:plain:w300

f:id:tyoshikawa1106:20180929085554j:plain:w300

部屋①

f:id:tyoshikawa1106:20180924154613j:plain:w300

f:id:tyoshikawa1106:20180924154621j:plain:w300

f:id:tyoshikawa1106:20180924154747j:plain:w300

部屋②

f:id:tyoshikawa1106:20180924154543j:plain:w300

f:id:tyoshikawa1106:20180924154553j:plain:w300

朝食ルーム (共用スペース)

f:id:tyoshikawa1106:20180925073632j:plain:w300

f:id:tyoshikawa1106:20180925073656j:plain:w300


周りのホテルと比べて料金はとても安かったのですが、レビューなどを観るとけっこう不安になることが書いてあったので、少し心配したりしていたのですがとても良いホテルでした。(部屋が2つあるのはそうしたプランで予約したためなので、一部屋のプランも用意されています。)

スタッフが親切

説明が丁寧。困ったときに相談に乗ってくれる。挨拶してくれる。などなど。

清潔な部屋

きちんと清掃されて快適な状態でした。
冷房・暖房・テレビも用意されています。
ミニバーもありました。ちなみに部屋にあるのは冷蔵庫ではなく冷凍庫でした。(水入れたら凍りかけてた)

WiFiが快適

快適の基準は人ぞれぞれですが、ひとまず速度が遅くて困ることはありませんでした。初日の接続設定でiPhoneだけ接続できなかったのですが調べたところデバイス側の問題だったみたいです。(PCとタブレットはスムーズに接続できた。)

Memo:ホテルのWiFiにiPhoneで接続できなかったときの対応方法 - tyoshikawa1106のブログ

朝食付き

豪華ではありませんが、パンやコーンフレーク、バナナなどが用意されています。コーヒーやジュースも用意されているのでとても助かりました。

Dreamforceの会場と比較的近い

これが意外と重要で会場とけっこう近い位置にあります。疲れて休憩したくなったときに気軽にホテルに戻って休憩できます。BART等での移動も不要なため、交通費も抑えることができます。


上記のような感じでかなり良いホテルでした。設備が古いとレビューに記載があったとおり、建物はけっこう古い感じです。ただストレスを感じるような状況ではありませんでした。一点残念..というか文化の違いだと思いますが、バスルームはシャワー専用のようになっていてお湯は貯められないようになっていました。(けっこうそういうホテルはあるみたいです。)

治安の話

このホテルですが住所上はテンダーロインという区域にあります。アメリカの住所事情には詳しくありませんが、ネットで検索するとテンダーロインは危ないという情報がすぐに出てきます。なので治安の部分が少し不安だったのですが、今回の滞在で特に危ない場面に遭遇することはありませんでした。


ひとまず「スーパー 8 ユニオン スクエア」自体はテンダーロインの端にあります。会場の一つになっている「Hilton San Francisco Union Square」ホテルから徒歩一分の場所です。ヒルトンホテルの入り口から看板が見えるぐらい近い場所にあります。大通りに面した人通りの多い場所に入り口があるのでそれほど不安になる環境ではありませんでした。
f:id:tyoshikawa1106:20181010073538p:plain


また、Dreamforce開催期間は参加者がDreamforceバッグを持って移動していますが、バッグを持っている人たちもけっこう通りを歩いていたりするので一歩足を踏み入れたら最後というような場所ではありませんでした。(Dreamforceバッグを配っているのは安全面のためでもあるんじゃないかなと思いました。)


宿泊客も旅行者や子供連れの方が宿泊していました。ホテルのロビーと朝食ルームぐらいでしか会いませんが、朝の挨拶等気さくに話しかけてくれていい雰囲気でした。(Dreamforce参加者ももちろん見かけました。)


治安は安全ですとは保証はできませんが、「深夜に意味もなくブラブラしない。」「細い路地に入らない。」「ボーっと歩かない」など普通に注意すれば特に問題ないんじゃないかと思いました。(Dreamforce開催期間は人が多くなるのでそういった面でも少し心配が減っている気がします。)

来年の予約の話

来年開催されるDreamforce2019は11月の開催です。予約取れるかなと検索したところ他のホテルも含めて満室となっていました。今9月でまだ一年以上先の状況のため受付自体始まっていない可能性がある気がします。
f:id:tyoshikawa1106:20181010074726p:plain


予約の際はBooking.comを利用しているのですが、予約キャンセルOKになっている場合が多いので、Dreamforceに行こうと思った場合ひとまずホテルを押させておいても良い気がします。Hotels.comというサービスの場合は10泊すると1泊無料になるサービスがありますが、Dreamforceの滞在で5日分ぐらい貯まるのでそちらで探してみても良いのかなと思いました。

まとめ

ホテル「スーパー 8 ユニオン スクエア」は探していた条件にすごくマッチしていて良いホテルでした。5日間の滞在となるので快適と思えるホテルを見つけられたのは良かったと思います。

関連記事

Dreamforce 2017で宿泊したホテルについてはこちらです。


SFDC:Dreamforce2018 - 番外編「Clipper Card」をつかってみました

$
0
0

サンフランシスコ国際空港到着後に市内へ移動するにはタクシー、UBER、BARTといくつか選択肢がありますが、今回はBARTを利用しました。
f:id:tyoshikawa1106:20180924115344j:plain:w300


BARTの切符購入をしようと思ってポチポチ操作していたところ、以前見た紙の切符ではなくClipper Cardがでてきました。(3ドル追加料金がかかりましたが..)
f:id:tyoshikawa1106:20180924120249j:plain:w300


PASMOやSUICAみたいなタッチで支払いができるICカードです。操作ミスに近い形での購入でしたが結果的には紙の切符より便利でした。


ちなみに紙の切符はこんな感じ。紙の切符もチャージして繰り返し使える仕組みでした。
f:id:tyoshikawa1106:20181014172114p:plain:w300


耐久度的にはICカードの方がしっかりしているのでClipperを一枚持っておいた方が良さそうな感じでした。

クリッパーカード - Wikipedia


ClipperですがBART専用のICカードだと思っていましたが、その他のサービスでも利用できる仕組みみたいです。
f:id:tyoshikawa1106:20181014175443p:plain:w300

Clipper Home


またICカードへのチャージ (Add Value)はWebサイトから行えるようになっています。(おそらくカードの購入も)
f:id:tyoshikawa1106:20181014175822p:plain:w300

https://www.clippercard.com/ClipperCard/register.jsf


Clipperカードには裏面に専用の番号が記載されています。こちらの番号をつかってアカウントを作成できるみたいです。・・ですが試してみようと思ったところユーザの住所登録が必要になり米国以外の住所は想定されていなさそうでした。(よく考えてみれば日本に住んでる人がアカウントを作成する必要なんて無いので当たり前でした...)
f:id:tyoshikawa1106:20181014180352p:plain:w300


Webサイトをポチポチ見ていたところアカウントがなくてもチャージができることはできるみたいです。(紛失時の再発行等の対応は不可になりそうです。)
※画面はGoogle翻訳で変換後のもの。
f:id:tyoshikawa1106:20181014180657p:plain:w300


Google翻訳で変換しながら覗いてみたのですがチャージまで進めるには少し大変そうでした。
f:id:tyoshikawa1106:20181014181123p:plain:w300


Webサイトで事前にチャージしておければ便利そうでしたが、切符購入機でチャージしてみたとき、何も問題なくスムーズに進められたので現地についてから対応してもそれほど問題はないと思います。


その他Twitter経由でClipperの使い方について教えてもらう機会がありました。

  • CalTrainでやMuni、ケーブルカー、バス、フェリーなどで利用できる
  • Walgreensならクレカで入金が行える


Walgreenとは薬局チェーンの会社とのことだと思います。

ウォルグリーン - Wikipedia


検索したところこちらのサイトが参考になりました。店舗にいってチャージをしてもらえそうです。(他にもいくつかサイトが見つかりました。)


今回はBART以外での利用は必要ありませんでしたが、バスやケーブルカーなどの利用が必要な場合は調べておくと便利な使い方が見つかるかもしれません。


余談ですがClipperサービスのTwitterアカウントもありました。

関連記事

2017年にサンフランシスコに行ったときの記事です。BARTで切符を書いたときの記録が残っています。

SFDC:Dreamforce2018 - サンフランシスコ移動ログ

$
0
0

Googleマップのタイムライン機能で移動ログを取得できました。ところどころGPSの記録がおかしくなっている部分がありましたが、だいたいこんな感じでした。サンフランシスコに到着後、空港と市内への移動 (BART) と会場からヒルトンホテルへの移動 (シャトルバス)は以外は徒歩で移動できました。

9月24日 - Day 0

サンフランシスコに到着した日。
f:id:tyoshikawa1106:20181014184140p:plain


空港から市内へ。
f:id:tyoshikawa1106:20181014184154p:plain


Dreamforceの参加者バッチをもらってホテルチェックインと市内観光。
f:id:tyoshikawa1106:20181014184241p:plain

9月25日 - Day 1

ホテルから会場へ。夜はDreamforceのパーティーに。
f:id:tyoshikawa1106:20181014184332p:plain

9月26日 - Day 2

ホテルから会場へ。夜はDreamfestでMETALLICAとジャネット・ジャクソンのライブに行きました。
f:id:tyoshikawa1106:20181014184504p:plain

9月27日 - Day 3

一番GPSの記録がうまく残っていませんでしたが、ホテルと会場の往復と市内の散歩に行った日です。
f:id:tyoshikawa1106:20181014184656p:plain

9月28日 - Day 4

朝はユニオン・スクエア近くで朝食。昼は会場へ。夜はグレース大聖堂近くのステーキハウスに食事に行きました。
f:id:tyoshikawa1106:20181014184757p:plain

9月29日 - Day 5

朝、ホテルをチェックアウトして空港へ。9時過ぎだと混雑してました。もっと早く行ったほうが良さそうです。SFO→NRTの部分は記録残っていませんでした。。
f:id:tyoshikawa1106:20181014184909p:plain


Googleマップのタイムライン機能は結構おもしろいと思います。

関連記事

SFDC:商品を商談に追加するようユーザに促す機能を試してみました

$
0
0

商品を商談に追加するようユーザに促す機能を試してみました。この機能を有効化すると商談作成後に商談商品の登録画面が表示されるようになります。商談の設定画面で有効化できます。

f:id:tyoshikawa1106:20181019203340p:plain

商談を作成する

f:id:tyoshikawa1106:20181019203615p:plain

価格表の選択画面が表示される

f:id:tyoshikawa1106:20181019203633p:plain

商品の選択画面が表示される

f:id:tyoshikawa1106:20181019203712p:plain

単価や数量の入力画面が表示される

f:id:tyoshikawa1106:20181019203844p:plain

商品が登録され商談作成完了

f:id:tyoshikawa1106:20181019203932p:plain


金額項目に手入力させないときに有効化する機能みたいです。

参考

SFDC:System.assertEqualsのエラーメッセージ指定を試してみました

$
0
0

Apexのテストクラス作成時にはSystem.assertEqualsを使って想定された結果となっているかをチェックできます。下記の場合はエラーメッセージを格納する変数の値が空白値となっているかをチェックできます。

System.assertEquals(String.isEmpty(result.errorMessage), true);


空白値が想定されている部分でエラーが発生した場合、次のようなエラーメッセージが表示されます。
f:id:tyoshikawa1106:20181023010042p:plain


trueを想定しているところにfalseが返って来ているとメッセージが表示されています。テストとしては正しく判定が行われていますが、想定外のエラーの調査には少し分かりづらいメッセージとなります。そんなときは3つ目の引数としてエラーメッセージを指定することが可能です。

System.assertEquals(String.isEmpty(result.errorMessage), true, '任意のエラーメッセージ');


例えば次のように値の必須チェックを行っているApexクラスがあります。
f:id:tyoshikawa1106:20181023010325p:plain


テストクラス作成時にテストデータの用意で本来は値をセットする部分にnullをセットしました。これで必須チェックエラーでテストが失敗する状態です。
f:id:tyoshikawa1106:20181023010621p:plain


System.assertEqualsを次のように変更します。result.errorMessage変数の値が空値でなかった際にテスト結果にresult.errorMessage変数の値を表示する書き方となります。
f:id:tyoshikawa1106:20181023011749p:plain

System.assertEquals(String.isEmpty(result.errorMessage), true, result.errorMessage);


これでテスト実行すると次のようにresult.errorMessage変数の値がテスト結果に表示されます。
f:id:tyoshikawa1106:20181023011958p:plain


エラーメッセージは任意の値をセットできるので状況に応じて指定してあげると予期せぬエラーが発生したときに調査がしやすくなります。

SFDC:WebサイトへのForce.comサイトページの埋め込みを試してみました

$
0
0

SalesforceのVisualforceページを外部に公開したい場合はForce.comサイトを仕組みを使用します。ページ全体をForce.comサイトで開発できるときは話が簡単ですが、既存のWebサイト内にある入力フォームだけをForce.comサイトで構築したい場合は少し検討が必要な部分があるので今回その部分について確認してみました。

JP:Sites - developer.force.com

はじめに

Salesforceと関係無いWebサイトにForce.comサイトページを表示するにはiframeで表示させます。ですが、ただiframeで表示するだけだとモバイル端末でアクセスした際にレイアウトが崩れてしまいます。


社外の様々な人たちがアクセスする外部サイトの場合は画面サイズに合わせてレイアウトが調整されるレスポンシブ対応を考慮する必要があります。


※iframeのレスポンシブ対応についてはこちらのサイトがとても参考になりました。

iframeのレスポンシブ対応はもの凄く簡単 | ウェブデザインスクールをお探しならWEB塾 超現場主義|東京(上野)・長野・浜松・札幌

iframeのレスポンシブ対応についての動作検証

まずは通常のWebサイトだけでiframeのレスポンシブ対応がうまくいくかを確認してみます。Webサイトの立ち上げはHerokuとLightning Design SystemのGetting Startedの手順で用意しました。

f:id:tyoshikawa1106:20181027180537p:plain

Heroku - Lightning Design System

Step 1: Initialize your project

ディレクトリ作成

$ mkdir demo_slds_heroku
$ cd demo_slds_heroku


初期設定

$ npm init


npm initで入力する内容

name:
version:
description:
entry point: (index.js) [server.js]
test command:
git repository:
keywords:
author:
license: (ISC)


package.jsonの内容

{
  "name": "demo_slds_heroku",
  "version": "0.0.0",
  "description": "demo_slds_heroku",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
Step 2: Install node dependencies - Express
$ npm install express --save
Step 3: Create public/index.html
$ mkdir public
$ touch public/index.html

index.htmlの内容

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="x-ua-compatible" content="ie=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Playground</title>
  </head>
  <body>
    Kaixo!
  </body>
</html>
Step 4: Create server.js
$ touch server.js


server.jsの内容

var express = require('express');
var app = express();
var port = process.env.PORT || 8080;

// Serve static files
app.use(express.static(__dirname + '/public'));

// Serve your app
console.log('Served: http://localhost:' + port);
app.listen(port);


localhostの起動

$ node server.js

f:id:tyoshikawa1106:20181027181632p:plain


ここでGoogleマップを埋め込んでみます。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="x-ua-compatible" content="ie=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Playground</title>
  </head>
  <body>
    <div>
      <iframe src="略" width="600" height="450" frameborder="0" style="border:0" allowfullscreen></iframe>
    </div>
  </body>
</html>


この時点ではiframeの幅や高さが固定のためブラウザの幅小さくなると表示されない領域が発生することを確認できます。
f:id:tyoshikawa1106:20181027181918p:plain

f:id:tyoshikawa1106:20181027181931p:plain:w250


続いて最初に記載したリンク先の手順どおりにcssを適用させます。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="x-ua-compatible" content="ie=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Playground</title>
    <style>
      .google_map{
        position:relative;
        width:100%;
        height:0;
        padding-top:75%;
      }
      .google_map iframe{
        position:absolute;
        top:0;
        left:0;
        width:100%;
        height:100%;
      }
    </style>
  </head>
  <body>
    <div class="google_map">
      <iframe src="略" width="600" height="450" frameborder="0" style="border:0" allowfullscreen></iframe>
    </div>
  </body>
</html>


無事にiframeの内容がページ幅に合わせて動的に切り替わることを確認できました。
f:id:tyoshikawa1106:20181027182404p:plain

f:id:tyoshikawa1106:20181027182418p:plain:w250


目的の動作検証を行うことができましたが、Lightning Design Systemを適用してHerokuへデプロイまでやっておきます。

Step 5: Download the Salesforce Lightning Design System

f:id:tyoshikawa1106:20181027182705p:plain

Step 6: Add components

styleタグの中身を別のcssファイルに移動したり、ヘッダーをつけてこんな感じ。
f:id:tyoshikawa1106:20181027183934p:plain

index.htmlの中身

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="x-ua-compatible" content="ie=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" type="text/css" href="/assets/styles/salesforce-lightning-design-system.css" />
    <link rel="stylesheet" type="text/css" href="/css/style.css" />
    <title>Playground</title>
  </head>
  <body>
    <div class="slds-grid slds-wrap">
      <!-- Header -->
      <nav class="slds-col slds-size_1-of-1">
        <div class="slds-page-header">
          <div class="slds-page-header__row">
            <div class="slds-page-header__col-title">
              <div class="slds-media">
                <div class="slds-media__figure">
                  <span class="slds-icon_container slds-icon-standard-opportunity" title="opportunity">
                    <svg class="slds-icon slds-page-header__icon" aria-hidden="true">
                      <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/assets/icons/standard-sprite/svg/symbols.svg#opportunity" />
                    </svg>
                    <span class="slds-assistive-text">Heroku Demo</span>
                  </span>
                </div>
                <div class="slds-media__body">
                  <div class="slds-page-header__name">
                    <div class="slds-page-header__name-title">
                      <h1>
                        <span class="slds-page-header__title slds-truncate" title="Rohde Corp - 80,000 Widgets">Heroku Demo</span>
                      </h1>
                    </div>
                  </div>
                  <p class="slds-page-header__name-meta">T.Yoshikawa Labs</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </nav>
      <!-- Main -->
      <main class="slds-col slds-size_1-of-1 slds-p-around_small">
        <div class="slds-section">
          <h3 class="slds-section__title slds-theme_shade slds-m-bottom_small">
            <span class="slds-truncate slds-p-horizontal_small" title="Section Title">Google Map</span>
          </h3>
          <!-- Google Map -->
          <div class="google_map">
            <iframe src="略" width="600" height="450" frameborder="0" style="border:0" allowfullscreen></iframe>
          </div>
        </div>
      </main>
    </div>
  </body>
</html>


こうなります。
f:id:tyoshikawa1106:20181027183907p:plain

Step 7: Deploy to Heroku
$ touch Procfile

Procfileの内容

web: node server.js


Herokuにログイン

$ heroku login
Email: [your@email.com]
Password: [typing will be hidden]

$ git init
$ heroku create [name-of-your-project]

$ git add .
$ git commit -m "Initial commit"
$ git push heroku master

$ heroku open


こんな感じでHerokuにデプロイしてページを表示できるようにしました。
f:id:tyoshikawa1106:20181027185708p:plain

WebサイトへのSalesforceサイトの組み込み

それではSalesforceサイトの組み込みを試してみます。はじめに外部に公開するためサイト設定でドメインを指定します。
f:id:tyoshikawa1106:20181027190026p:plain


埋め込むためのVisualforceページを用意します。
f:id:tyoshikawa1106:20181027190446p:plain


サイト設定でVisualforceページを表示できるように設定します。これでSalesforceにログインしなくてもアクセスできるVisualforceページを用意できました。
f:id:tyoshikawa1106:20181027190658p:plain


※iframeに別ドメインのサイトを埋め込むことになるのでクリックジャック保護レベルの設定で許可が必要になると思います。
f:id:tyoshikawa1106:20181027203559p:plain


あとは動作確認できるように入力フォームを実装します。
f:id:tyoshikawa1106:20181027191833p:plain


簡易的につくっていますがコードはこんな感じ。

<apex:page showHeader="false" sidebar="false">
    <head>
        <apex:slds />
    </head>
    <body>
        <div xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="vf-page">
            <div class="slds-p-around_small">
                <!-- Field 01 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-01">Form Label 01</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-01" class="slds-input" />
                    </div>
                </div>
                <!-- Field 02 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-02">Form Label 02</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-02" class="slds-input" />
                    </div>
                </div>
                <!-- Field 03 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-03">Form Label 03</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-03" class="slds-input" />
                    </div>
                </div>
                <!-- Field 04 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-04">Form Label 04</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-04" class="slds-input" />
                    </div>
                </div>
                <!-- Field 05 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-05">Form Label 05</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-05" class="slds-input" />
                    </div>
                </div>
                <!-- Field 06 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-06">Form Label 06</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-06" class="slds-input" />
                    </div>
                </div>
                <!-- Field 07 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-07">Form Label 07</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-07" class="slds-input" />
                    </div>
                </div>
                <!-- Field 08 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-08">Form Label 08</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-08" class="slds-input" />
                    </div>
                </div>
                <!-- Field 09 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-09">Form Label 09</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-09" class="slds-input" />
                    </div>
                </div>
                <!-- Field 10 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-10">Form Label 10</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-10" class="slds-input" />
                    </div>
                </div>
                <!-- button -->
                <div class="slds-m-top_small">
                    <button class="slds-button slds-button_brand">問い合わせ</button>
                </div>
            </div>
        </div>
    </body>
</apex:page>


Salesforceサイト側のページが用意できたのでHerokuで用意したWebサイトへiframeで組み込んでみます。まずはレスポンシブ対応無しバージョン。画面サイズに関わらず幅や高さが固定されてしまい正しく表示されません。
f:id:tyoshikawa1106:20181027192757p:plain


続いてレスポンシブ対応ありバージョンです。画面の幅に合わせてフォームが自然に表示されました。
f:id:tyoshikawa1106:20181027194442p:plain


幅を小さくしたときはこのように表示されます。
f:id:tyoshikawa1106:20181027194518p:plain:w200


これでSalesforceサイトのページをWebサイトに埋め込むことができました。iframeによる表示となりますが、Salesforceでつくった入力フォームを自然な見た目で表示することができます。


実際のモバイル端末でアクセスして確認してみました。※iPhone
f:id:tyoshikawa1106:20181027195001p:plain:w200

f:id:tyoshikawa1106:20181027195023p:plain:w200


問題なさそうです。実際のプロジェクトではAndroid端末やIEなどのブラウザで問題ないかも確認してみ他方が良いと思います。(大丈夫だと思いますが)

iframeの高さ指定

サンプルでは%になっていますが、入力フォームなど横幅は変わっても高さを変えたくない場合は、px指定にすることで対応できます。

f:id:tyoshikawa1106:20181027195223p:plain

iframeとページ遷移

当然ですがiframe内でページ遷移するとiframeの中だけでページ遷移が行われます。
f:id:tyoshikawa1106:20181027200908p:plain


JS処理でのページ遷移の場合は下記のような感じにすると親フレームでページ遷移できるので忘れないようにします。

parent.location.href=<url>;


WebサイトへのForce.comサイトページの埋め込みはこんな感じで実現できました。

サンプルコード

最後に今回検証したときのサンプルコードです。

index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="x-ua-compatible" content="ie=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" type="text/css" href="/assets/styles/salesforce-lightning-design-system.css" />
    <link rel="stylesheet" type="text/css" href="/css/style.css" />
    <title>Playground</title>
  </head>
  <body>
    <div class="slds-grid slds-wrap">
      <!-- Header -->
      <nav class="slds-col slds-size_1-of-1">
        <div class="slds-page-header">
          <div class="slds-page-header__row">
            <div class="slds-page-header__col-title">
              <div class="slds-media">
                <div class="slds-media__figure">
                  <span class="slds-icon_container slds-icon-standard-opportunity" title="opportunity">
                    <svg class="slds-icon slds-page-header__icon" aria-hidden="true">
                      <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/assets/icons/standard-sprite/svg/symbols.svg#opportunity" />
                    </svg>
                    <span class="slds-assistive-text">Heroku Demo</span>
                  </span>
                </div>
                <div class="slds-media__body">
                  <div class="slds-page-header__name">
                    <div class="slds-page-header__name-title">
                      <h1>
                        <span class="slds-page-header__title slds-truncate" title="T.Yoshikawa Labs">Heroku Demo</span>
                      </h1>
                    </div>
                  </div>
                  <p class="slds-page-header__name-meta">T.Yoshikawa Labs</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </nav>
      <!-- Main -->
      <main class="slds-col slds-size_1-of-1 slds-p-around_small">
        <!-- Salesforce Form -->
        <div class="slds-section">
          <!-- Salesforce Form Header -->
          <h3 class="slds-section__title slds-theme_shade slds-m-bottom_small">
            <span class="slds-truncate slds-p-horizontal_small" title="Section Title">Salesforce Form</span>
          </h3>
          <!-- Salesforce Form Main -->
          <div class="iframe-section">
            <iframe src="<your salesforce page url>" width="600" height="600" frameborder="0" style="border:0" allowfullscreen></iframe>
          </div>
        </div>
        <!-- Google Map -->
        <div class="slds-section">
          <!-- Google Map Header -->
          <h3 class="slds-section__title slds-theme_shade slds-m-bottom_small">
            <span class="slds-truncate slds-p-horizontal_small" title="Section Title">Google Map</span>
          </h3>
          <!-- Google Map Main -->
          <div class="iframe-section">
            <iframe src="<your google map url>" width="600" height="450" frameborder="0" style="border:0" allowfullscreen></iframe>
          </div>
        </div>
      </main>
    </div>
  </body>
</html>
style.css
.iframe-section {
  position:relative;
  width:100%;
  height:0;
  padding-top:650px;
}
.iframe-section iframe {
  position:absolute;
  top:0;
  left:0;
  width:100%;
  height:100%;
  min-height: 600px;
}
Salesforce Form Page
<apex:page showHeader="false" sidebar="false">
    <head>
        <apex:slds />
        <script type="text/javascript">
          function move() {
                parent.location.href="<your salesforce thanks page url>";
            }
        </script>
    </head>
    <body>
        <div xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="vf-page">
            <div class="slds-p-around_small">
                <!-- Field 01 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-01">Form Label 01</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-01" class="slds-input" />
                    </div>
                </div>
                <!-- Field 02 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-02">Form Label 02</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-02" class="slds-input" />
                    </div>
                </div>
                <!-- Field 03 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-03">Form Label 03</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-03" class="slds-input" />
                    </div>
                </div>
                <!-- Field 04 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-04">Form Label 04</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-04" class="slds-input" />
                    </div>
                </div>
                <!-- Field 05 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-05">Form Label 05</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-05" class="slds-input" />
                    </div>
                </div>
                <!-- Field 06 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-06">Form Label 06</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-06" class="slds-input" />
                    </div>
                </div>
                <!-- Field 07 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-07">Form Label 07</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-07" class="slds-input" />
                    </div>
                </div>
                <!-- Field 08 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-08">Form Label 08</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-08" class="slds-input" />
                    </div>
                </div>
                <!-- Field 09 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-09">Form Label 09</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-09" class="slds-input" />
                    </div>
                </div>
                <!-- Field 10 -->
                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="form-element-10">Form Label 10</label>
                    <div class="slds-form-element__control">
                        <input type="text" id="form-element-10" class="slds-input" />
                    </div>
                </div>
                <!-- button -->
                <div class="slds-m-top_small">
                    <button class="slds-button slds-button_brand" onclick="move()">問い合わせ</button>
                </div>
            </div>
        </div>
    </body>
</apex:page>
Salesforce Form Thanks Page
<apex:page showHeader="false" sidebar="false">
    <head>
        <apex:slds />
        <style>
        	* {
            	background-color: #255E9E;
                font-size: 20px;
                color: #fff;
            }
        </style>
    </head>
    <body>
        <div xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="vf-page">
            <div class="slds-p-around_small">
                Thanks!
            </div>
        </div>
    </body>
</apex:page>

SFDC:Force.comサイトとページビュー制限について

$
0
0

Force.comサイトとページビュー制限についてです。Force.comサイトはSalesforceにログインせずに外部からアクセスできるWebサイトを構築できる仕組みです。

f:id:tyoshikawa1106:20181104230325p:plain

JP:Sites FAQ - developer.force.com


基本的にあまり気にする必要はありませんが、月に表示可能な数に上限があります。

Force.com Sitesは月のページビューをベースに価格付けを行います:

  • Enterprise Editionには月間500,000ページビューまで含まれます
  • Unlimited Editionには月間1,000,000ページビューまで含まれます

追加の月刊ページビューをオーダーすることもできます:

  • $1,000/月で1,000,000の追加ページビュー(全Edition共通)


アクセス数が多いサイトをForce.comサイトで構築する場合は追加ページビューの購入を検討する必要があります。


ページビューの上限を超えたときの挙動ですが下記で紹介されていました。
f:id:tyoshikawa1106:20181104230626p:plain

https://resources.docs.salesforce.com/208/latest/ja-jp/sfdc/pdf/limits_limitations.pdf


少し超えた場合は即座に利用不可になるのではなく、管理者などに通知メールが届きます。制限を超えたあと、そのまま放置するか、大きく超えた場合(300%)はサイトが表示されなくなるようです。

  • 組織が月間ページビュー制限の 110% に達した場合、サイト管理者と請求管理者にメール通知が送信されます。
  • 組織で 4 か月連続してページビュー制限の 110% を超えた場合、次のカレンダー月が始まるまで、またはページビューを追加購入するまで、サイトが無効になります。メール通知が、サイト管理者と請求管理者、および関連するアカウントエグゼクティブに送信されます。
  • 指定されたカレンダー月で、組織がページビュー制限の 300% に達した場合、次のカレンダー月が始まるまで、またはページビューを追加購入するまで、サイトが無効になります。メール通知が、サイト管理者と請求管理者、および関連するアカウントエグゼクティブに送信されます。


ページビュー数はサイトの設定画面で確認できます。
f:id:tyoshikawa1106:20181104230901p:plain


またレポートやダッシュボードで確認できるようにすることも可能なようです。
f:id:tyoshikawa1106:20181104230957p:plain

Help | Training | Salesforce

SFDC:売上予測の目標の登録を試してみました

$
0
0

Sales Cloudユーザ向けの便利機能、売上予測の目標データ登録を試してみました。

f:id:tyoshikawa1106:20181107191630p:plain


この機能を利用するには設定で有効化する必要があります。
f:id:tyoshikawa1106:20181107191704p:plain


目標の登録方法の詳細はヘルプにまとめられています。

コラボレーション売上予測の目標データの読み込み

売上予測の目標の流れ

売上予測には実は下記のようにいくつかの種類があります。基本的には『OpportunityRevenue: 商談 - 収益』がよく利用されていると思います。
f:id:tyoshikawa1106:20181107191938p:plain


売上予測の目標の登録はデータローダかSalesforce APIによる対応が必要になります。登録には「売上予測種別ID」が必要になります。開発者コンソールで下記クエリを実行して取得するのが簡単だと思います。

SELECT Id,DeveloperName FROM ForecastingType


取得結果はこんな感じ。0Dbから始まるIDが「売上予測種別ID」です。
f:id:tyoshikawa1106:20181107192228p:plain


売上予測種別IDが確認できたらデータローダでインポートするためのCSVファイルを用意します。必要な情報は下記のとおりです。ユーザ名の列は取り込み時には不要ですが、あるとデータを準備する作業がやりやすいと思います。(...ヘルプでそう紹介されていました。)
f:id:tyoshikawa1106:20181107192352p:plain

f:id:tyoshikawa1106:20181107192509p:plain:w300


目標を取り込む際に指定するオブジェクトは「売上予測目標 (ForecastingQuota)」オブジェクトです。
f:id:tyoshikawa1106:20181107192606p:plain


項目マッピングはこんな感じです。
f:id:tyoshikawa1106:20181107192632p:plain


これで取り込み処理を実行すると売上予測の目標の列に値がセットされます。これでその月の商談の受注額が目標に到達しているかひと目で確認できるようになります。
f:id:tyoshikawa1106:20181107192808p:plain

売上予測の使い方

売上予測で確認できることはレポートと似たような感じですが、レポートよりも営業目線で必要な情報がわかりやすく表示されます。例えば対象年月のマスをクリックするとその部分に該当する商談が一覧表示されます。
f:id:tyoshikawa1106:20181107193121p:plain


また放置状態となってしまっている商談も視覚化されます。例えば現在11月なので下記の赤枠の部分は本来完了予定にもかかわらず未完了のままの商談になります。
f:id:tyoshikawa1106:20181107193427p:plain


こうした未完了商談は期限が過ぎたタイミングで再度完了予定日を調整したり、失注ステータスに更新してクローズしたりと対応することで対応漏れを防ぎ、あいまいな状態のまま放置されることを回避することができます。

売上予測とレポート

売上予測の目標を登録後、レポートを活用することでグラフ表示による比較が可能になります。目標をつかったレポート作成にはカスタムレポートタイプの作成が必要になります。下記の構成で作成してみてください。(子オブジェクト側は関連レコードの有無は問いませんの方を選択します。)
f:id:tyoshikawa1106:20181107193945p:plain


細かい条件は利用用途によって変更することになりますが例としてざっくりこんな感じ。
f:id:tyoshikawa1106:20181107194303p:plain


これで目標と商談の受注した金額を比較するためのグラフが作成できました。
f:id:tyoshikawa1106:20181107194407p:plain


レポート作成の際に商談の金額とは別に売上予測 金額という類似の項目もあるので注意してください。今回の設定手順の場合は「売上予測 金額」項目は欲しい情報とは異なる項目になります。
f:id:tyoshikawa1106:20181107194609p:plain


毎月の目標と金額の比較は上記のような感じで可能になりますが、Salesforceでは累積レポートの作成も可能です。累積レポートの設定方法は下記サイトに詳しくまとめられていました。

http://deferloader.blog.uhuru.co.jp/?p=5156


レポート設定のこの部分から集計項目を作成します。
f:id:tyoshikawa1106:20181107195001p:plain:w300


形式タブで開始日を選びます。
f:id:tyoshikawa1106:20181107195019p:plain:w300


続いて数式を記載しますがフルエディタに切り替えるとやりやすいと思います。
f:id:tyoshikawa1106:20181107195130p:plain


式は下記のような感じ。上のリンクの参考サイトの数式をそのまま使いました。

目標の累積
ForecastingQuota.QuotaAmount:SUM +
IF (ISNULL (PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate)), 0, PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate))+
IF (ISNULL (PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 2)), 0, PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 2))+
IF (ISNULL (PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 3)), 0, PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 3))+
IF (ISNULL (PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 4)), 0, PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 4))+
IF (ISNULL (PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 5)), 0, PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 5))+
IF (ISNULL (PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 6)), 0, PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 6))+
IF (ISNULL (PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 7)), 0, PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 7))+
IF (ISNULL (PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 8)), 0, PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 8))+
IF (ISNULL (PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 9)), 0, PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 9))+
IF (ISNULL (PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 10)), 0, PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 10))+
IF (ISNULL (PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 11)), 0, PREVGROUPVAL(ForecastingQuota.QuotaAmount:SUM, ForecastingQuota.StartDate, 11))
金額の累積
ForecastingFact_Opp.Amount:SUM +
IF (ISNULL (PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate)), 0, PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate))+
IF (ISNULL (PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 2)), 0, PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 2))+
IF (ISNULL (PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 3)), 0, PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 3))+
IF (ISNULL (PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 4)), 0, PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 4))+
IF (ISNULL (PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 5)), 0, PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 5))+
IF (ISNULL (PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 6)), 0, PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 6))+
IF (ISNULL (PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 7)), 0, PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 7))+
IF (ISNULL (PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 8)), 0, PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 8))+
IF (ISNULL (PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 9)), 0, PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 9))+
IF (ISNULL (PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 10)), 0, PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 10))+
IF (ISNULL (PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 11)), 0, PREVGROUPVAL(ForecastingFact_Opp.Amount:SUM, ForecastingQuota.StartDate, 11))

一見複雑ですが、よく見るとわかりやすい数式です。
f:id:tyoshikawa1106:20181107195515p:plain


項目のAPI名ですが、「ForecastingFact_Opp.Amount」というように数式用の記載のされ方になっている部分があります。API名がわからないときは挿入ボタンで挿入すると確認できます。
f:id:tyoshikawa1106:20181107195434p:plain


累積するには「PREVGROUPVAL」関数を利用しますが、下記のように空欄になって表示されることがあります。詳細行を非表示にしたりグルーピング項目を一つにすることで正しい値が表示されるようになります。
f:id:tyoshikawa1106:20181107200111p:plain


グラフの設定では通常の縦棒グラフを選択、X軸に開始日を指定してY軸に先程作成した集計項目を指定します。「+基準」で複数項目を指定できます。
f:id:tyoshikawa1106:20181107200353p:plain:w300

f:id:tyoshikawa1106:20181107200342p:plain:w300


これで累積棒グラフの表示が可能になります。(※試してみた感じではこうした累積の比較グラフを作成する際に積み上げ棒グラフとの組み合わせはできないみたいです。)
f:id:tyoshikawa1106:20181107200512p:plain


こうしてレポートを用意したあとはダッシュボードでグラフをまとめることでより便利になります。
f:id:tyoshikawa1106:20181107201100p:plain


チームの目標はもちろん、営業メンバーごとに目標と金額の比較グラフを用意するとうまくいっている人や苦戦している人を確認しやすくなり、苦戦している人がいる場合はフォローにはいるなどの判断がしやすくなると思います。


売上予測の目標を登録することでこうした便利な使い方も可能になります。

売上予測目標とSOQL

売上予測の目標はデータローダでの登録が必要になりますが、一度登録した目標は開発者コンソールから編集が可能になります。クエリはこんな感じ。

Select Id, PeriodId, StartDate, ProductFamily, QuotaAmount, QuotaQuantity, QuotaOwnerId, IsQuantity, IsAmount, CreatedDate, CreatedById, LastModifiedDate, LastModifiedById, SystemModstamp, ForecastingTypeId FROM ForecastingQuota

f:id:tyoshikawa1106:20181107201813p:plain


Salesforce APIでも取り込めるとのことなので、データ管理ようのVisualforceあたりを開発しておくと良いのかもしれません。(実装可能かは未確認ですが)


SFDC:個人取引先と住所項目

$
0
0

個人取引先を有効化すると取引先オブジェクトに個人取引先用の項目が追加されます。API名がPersonとついているものがそうです。個人取引先用項目というと少し特殊な感じがしますが、取引先責任者の項目を取引先側で参照可能になるという感じです。

f:id:tyoshikawa1106:20181108082025p:plain


取引先と取引先責任者で重複するような項目はほとんどありませんが住所項目は別です。下記のようにそれぞれの項目が用意されています。

  • 取引先: 住所 (請求先) ・・・BillingAddress
  • 取引先責任者: 住所 (郵送先)・・・MailingAddress


個人取引先項目はPersonがついている方を優先したほうが良いと思うので、基本的にはMailingAddressの方に値をセットしていったほうが良いと思うのですが、取引先オブジェクトとして扱うのでBillingAddressにも値を保持しておいたほうが後々安心な気がします。


ということでこうした重複項目はApexトリガのBefore処理で値を自動セットしておくといいと思います。
f:id:tyoshikawa1106:20181108082533p:plain


何もしていないと片方の住所項目にしか値がセットされませんが・・・
f:id:tyoshikawa1106:20181108082607p:plain


トリガで処理を実装すれば、ユーザは特に意識することなく裏側で自動的に値がセットされるようになります。
f:id:tyoshikawa1106:20181108082622p:plain


使いみちがあるかちょっと怪しい気もしますがあとから必要になって対応するよりは導入時に対処しておいたほうが良い気がしました。

SFDC:Salesforceアプリのテキストを送信を試してみました

$
0
0

Salesforceアプリのテキストを送信を試してみました。取引先のページレイアウト設定を行うと確認できますがテキストの送信という標準アクションが存在します。

f:id:tyoshikawa1106:20181108123213p:plain


このアクションは配置してもPCの画面では何も表示されません。
f:id:tyoshikawa1106:20181108123246p:plain


ですがSalesforceモバイルアプリから確認するとテキストを送信のアクションが表示されます。こちらはモバイル専用アクションとなるようです。
f:id:tyoshikawa1106:20181108123540j:plain:w200


選択すると外部アプリが立ち上がります。iOSのみでの確認ですが標準のメッセージアプリが起動すると思います。
f:id:tyoshikawa1106:20181108122659j:plain:w200


この手順でメッセージを送信するSMSとして扱われるみたいです。またSalesforceモバイルアプリとは独立して起動されるため、送信されたメッセージが活動の記録などに登録されるということはなさそうです。イメージ的にはメッセージアプリ起動のショートカットのような感じです。


Salesforceとデータ連携はされませんが、SMS主体でやりとりしている場合には便利なショートカットになるかもしれません。類似のアクションで電話というアクションもあります。


電話のアクションですが実行すると2つのアクションを選択できました。

  • 電話をかける
  • 電話をかけずに記録


記録の方はそのまま活動の記録の入力欄が表示されます。電話をかけると発信が行われ通話終了後に活動の記録の入力欄が表示される流れでした。(ざっくりした検証だったので、もしかすると見間違えがあるかも..)


あまり使う機会がない機能だと思ってましたがけっこう便利かもしれません。

SFDC:商談の商品と共にコピーする機能と商品スケジュールについて

$
0
0

現在、Lightning Experienceでは利用できないため、なくなる機能の可能性がありますが、Salesforce Classicでは商談コピー時に商品も一緒にコピーのメニューが用意されています。

f:id:tyoshikawa1106:20181109082314p:plain


商品も一緒にコピーした場合は、商品スケジュールも一緒に作成されます。
f:id:tyoshikawa1106:20181109082545p:plain


このときのApexトリガの挙動について確認しました。
f:id:tyoshikawa1106:20181109082619p:plain

商品スケジュールが存在しない場合

商品スケジュールが存在しない状態で商談と商品のコピーを行った場合、商談商品トリガはINSERT処理のみ実行されます。
f:id:tyoshikawa1106:20181109082734p:plain

商品スケジュールが存在する場合

商品スケジュールが存在する状態で商談と商品のコピーを行った場合は、商談商品トリガはINSERT処理とUPDATE処理が実行されました。
f:id:tyoshikawa1106:20181109082919p:plain


コピーにより商品が作成され、INSERT処理が実行されたあとに、商品に紐付く商品スケジュールもコピーされる処理が実行されます。商品スケジュールが紐ついたタイミングで商品のUPDATE処理が実行されるという流れのようです。


商談商品トリガで商品スケジュールに関する処理を作成する際にはコピー時の挙動についても注意が必要でした。

SFDC:商品スケジュールのデータの持ち方

$
0
0

商品スケジュールのデータの持ち形についてです。Apexでは次のような感じでINSERT処理を実行できます。

f:id:tyoshikawa1106:20181109084716p:plain

※実際にはループ処理の中でINSERT処理しちゃだめです。


上記処理の結果、画面にはこのように表示されます。収益の値が5000のデータを3件登録したので15000という値になっています。画面を見る感じでは同じ日付のデータは一件にマージされている感じでした。
f:id:tyoshikawa1106:20181109084806p:plain


ところがSOQLクエリでデータを確認してみると・・・裏側ではデータは3つにわかれたままとなっています。
f:id:tyoshikawa1106:20181109084946p:plain


このデータを画面で編集すると
f:id:tyoshikawa1106:20181109085050p:plain


裏側のデータも一件にマージされます。
f:id:tyoshikawa1106:20181109085115p:plain


同じ日付で複数の商品スケジュールが作成されるのはApexから登録したときのみの挙動となっているようです。開発の際にはこのあたりの注意も必要になります。

SFDC:個人取引先の取引先名を数式で取得

$
0
0

個人取引先を利用する際に少しハマった話。商談に紐付く取引先名を数式で取得しようしたら値が空の場合がありました。個人取引先の場合は「Account.Name」では取得できないみたいです。


こうやって取得できます。

IF(Account.IsPersonAccount,
Account.LastName + ' ' + Account.FirstName,
Account.Name
)

f:id:tyoshikawa1106:20181122072555p:plain

SFDC:リードの取引開始と個人取引先について

$
0
0

リードの取引開始ボタンをクリックすることで、リードに登録された情報を元に取引先、取引先責任者、商談を作成することができます。B to C向けの個人取引先の場合はどうなるのかなと検索したところ、ヘルプに記載がありました。

f:id:tyoshikawa1106:20181207033735p:plain

リードの取引開始に関する考慮事項


会社名を入力していると法人取引先、会社名が未入力の場合は個人取引先と自動で切り替えてくれるみたいです。そもそも会社名は必須じゃないのかと確認したところ、ページレイアウト設定で必須を解除することが可能でした。

f:id:tyoshikawa1106:20181207033901p:plain


実際に試してみた画面がこちらです。

法人取引先

f:id:tyoshikawa1106:20181207033928p:plain

個人取引先

f:id:tyoshikawa1106:20181207033952p:plain


取引開始ボタンクリック後に特に意識することなく切り替わるので個人取引先のときには不便になるといった心配は不要でした。実際に運用で利用する場合はレコードタイプを「法人リード」「個人リード」と用意してそれぞれにページレイアウトを用意するのが良いみたいです。(法人リードの場合は会社項目に必須を残しておく)

SFDC:Salesforce World Tour Tokyo 2018に参加しました

$
0
0

2018年12月05日(水)に開催されたSalesforce World Tour Tokyo 2018に参加しました。場所は東京ビッグサイトです。

f:id:tyoshikawa1106:20181205082931j:plain:w300

f:id:tyoshikawa1106:20181205083120j:plain:w300


会場に入ると受付前にセキュリティチェックのゲートがありました。早めの時間に行ったためかスムーズに通ることができました。

f:id:tyoshikawa1106:20181205083938j:plain:w300


セキュリティチェックを済ませたあとは受付に行って受講票を見せてパスケースを受け取ります。そのときにパンフレットなども頂きました。

f:id:tyoshikawa1106:20181205084302j:plain:w300


会場内はこんな感じでした。モーニングセッションで早めに来たので空いている時間帯です。
f:id:tyoshikawa1106:20181205084329j:plain:w300

f:id:tyoshikawa1106:20181205084339j:plain:w300

f:id:tyoshikawa1106:20181205084509j:plain:w300


最初に聴きに行ったセッションはこちらです。

第4次産業革命におけるシステム管理者の重要性と管理者向け最新機能

f:id:tyoshikawa1106:20181205084944j:plain:w300


管理者向けのセッションです。アストロくんやクラウディ北川さんのパフォーマンスも見ることができました。
f:id:tyoshikawa1106:20181205091825j:plain:w300


内容的にはこんな感じ。

  • 第四次産業革命の話。企業は顧客と繋がることを求められてる。
  • ゲストでHEAVEN Japanの方登壇
  • Lightning の使い方の話。ログイン後に予定を確認するホーム画面の使い方。ユーティリティバーの活用例としていつでもメモできる。
  • リストビューの検索機能の話
  • 活動の記録とクイックテキスト
  • Lightning フロービルダーとか新機能の話
  • EXCELからカスタムオブジェクトを作成できる→API名は動的にセットされる
  • Einstein予測ビルダーの話。→経験や勘に頼るしかなかった情報をAIが用意できる。


新機能はパイロット版や今後提供予定のものが含まれていました。
f:id:tyoshikawa1106:20181205091856j:plain:w300


モーニングセッションはこんな感じ。海外のSalesforce社の人も日本のイベントを見に来ていていました。
f:id:tyoshikawa1106:20181205085339j:plain:w300


次に予定していた基調講演まで少し時間に余裕があったのでちらっと会場を歩いてみました。ドリンクが提供されていたりもしました。飲み物を特に用意していなかったので会場で貰えて助かりました。
f:id:tyoshikawa1106:20181205093347j:plain:w300

基調講演:A Celebration of Trailblazers

基調講演の会場はこんな感じ。
f:id:tyoshikawa1106:20181205093930j:plain:w300

f:id:tyoshikawa1106:20181205094018j:plain:w300


Salesforceのマスコットと記念撮影をしてもらうこともできました。
f:id:tyoshikawa1106:20181205094116j:plain:w300


基調講演の開始はドラムパフォーマンス 鼓和-core-さんのパフォーマンスから始まりました。光と音のパフォーマンスがすごかったです。
f:id:tyoshikawa1106:20181205101214j:plain:w300

日本を代表するドラムパフォーマンス集団「鼓和-core-」


パフォーマンスのあとはセールスフォースジャパンの小出CEOが登壇されました。
f:id:tyoshikawa1106:20181205101818j:plain:w300

  • 第四次産業革命の話
  • セブンアンドアイホールディングによる活用の話と企業と顧客の繋がりの変化について
    • これからは顧客ひとりひとりにパーソナライズされたサービス提供の時代になる..的な話
  • ベンチャーキャピタル Trailblazer Fundの話


スペシャルゲストでネオスの方が登壇されました。
f:id:tyoshikawa1106:20181205103935j:plain:w300


セールスフォース創業者の一人でCTOのパーカーハリスも来日して登壇されていました。
f:id:tyoshikawa1106:20181205105749j:plain:w300

  • Customer360の話
  • MuleSoft の話
  • Einstein Voiceの話


EinsteinVoiceはSalesforce を音声で操作できる製品です。開発チームの方も来日されてHey SiriからSalesforceアプリにアクセスするデモを見せてくれました。音声がスムーズに認識されて操作されるのはすごかったです。(まだ英語のみの対応の可能性もありますが..)

f:id:tyoshikawa1106:20181205105942j:plain:w300

f:id:tyoshikawa1106:20181205110107j:plain:w300


その後はセールスフォースジャパンの秋津さんからWILLERの事例の話とMuleSoftをつかったシステム連携とコンタクトセンター向けに構築したServiceCloudのコンソールアプリのデモがありました。
f:id:tyoshikawa1106:20181205110943j:plain:w300


MuleSoftによりSalesforceと外部の予約システムを連携して問い合わせ対応できる仕組みを構築した流れはすごかったです。
f:id:tyoshikawa1106:20181205111930j:plain:w300


事例の話をしてくれたWILLERさんは高速バスなどのサービスを提供している企業です。

【公式】高速バス・夜行バスを簡単に予約|ウィラートラベル


最後にセールスフォースジャパンの田崎さんがDreamforceでも話のあったユニリーバの活用事例を紹介してくれました。
f:id:tyoshikawa1106:20181205113751j:plain:w300

f:id:tyoshikawa1106:20181205114050j:plain:w300

f:id:tyoshikawa1106:20181205114240j:plain:w300

f:id:tyoshikawa1106:20181205114315j:plain:w300


基調講演のあとはいろんなブースが出ている部屋へ。
f:id:tyoshikawa1106:20181205115157j:plain:w300

f:id:tyoshikawa1106:20181205115326j:plain:w300

f:id:tyoshikawa1106:20181205115908j:plain:w300

f:id:tyoshikawa1106:20181205124927j:plain:w300


お昼はサンドイッチが用意されていました。
f:id:tyoshikawa1106:20181205120351j:plain:w300


ランチを済ませたあとは、スタンプラリーでいろんなブースを回ってみました。最初に行ったのはこちら。
f:id:tyoshikawa1106:20181205120747j:plain:w300


アドエビスはWEBサイトのCV率を確認するマーケティング用の製品なのですが、Salesforceと連携できるんだと気になったので行ってみました。月額3万円で利用できるAppExchangeが用意されているみたいです。話を聞いたところWeb-to-リードのフォームを前提としていましたが、おそらく自作のWebフォームにも適用できるんじゃないかなと思います。(そうじゃないとだいぶ用途が狭まるので..)


次はSales Cloudのブースです。行ったタイミングがちょっとだけ悪かったみたいで詳しい人が離れてますとのことでしたが、ちょっとお話聞かせてもらうことができました。
f:id:tyoshikawa1106:20181205122601j:plain:w300


その次はアクセンチュアさんのブースに行きました。SWTT2018で唯一のDiamondスポンサー。大きなブースでいくつかの種類の話を聞けるようになっていました。AIとサーベイの話を聞かせてもらいましたが、AIで顧客の回答を分析してどのような感情を持っているかを判断できるアプリのデモを見せてもらいました。
f:id:tyoshikawa1106:20181205123330j:plain:w300


ブースには書籍も。
f:id:tyoshikawa1106:20181205123326j:plain:w300


その次はGrapeCityのブース。こちらもスポンサーブース。
f:id:tyoshikawa1106:20181205122615j:plain:w300


EXCEL形式で入力できるアプリのデモを見せてもらいました。



ここでService Cloud Keynoteの時間が来たので別の部屋へ移動。少し遅れてしまったのですが、運良くまだ前の席が空いていました。

Service Cloud Product Keynote

f:id:tyoshikawa1106:20181205125124j:plain:w300

f:id:tyoshikawa1106:20181205125217j:plain:w300

  • Service Cloud コンソールの話
  • AOKIホールディングスの方の事例話
  • 顧客対応のルーティンワークを自動化の話
  • AIチャットのデモ
  • コンソールからチャット対応
  • Apple business chatもサポートする話
  • Field Service Cloudの話

f:id:tyoshikawa1106:20181205125613j:plain:w300

f:id:tyoshikawa1106:20181205125843j:plain:w300

f:id:tyoshikawa1106:20181205130440j:plain:w300

f:id:tyoshikawa1106:20181205131333j:plain:w300

f:id:tyoshikawa1106:20181205131445j:plain:w300


Service Cloud Keynoteのセッションはこんな感じでした。


当初の予定ではこの次はSales Cloud Keynoteのセッション予定だったのですが、TwitterでHerokuのセッションが始まる情報を見つけ、そちらを聴きに行ってみました。

Herokuセッション

f:id:tyoshikawa1106:20181205133009j:plain:w300

f:id:tyoshikawa1106:20181205133057j:plain:w300

f:id:tyoshikawa1106:20181205133324j:plain:w300

f:id:tyoshikawa1106:20181205133615j:plain:w300


今までHerokuアプリはインターネットに接続して利用する前提でしたがイントラネットなどのクローズドな環境でも動かせるようになった話を聞きました。

f:id:tyoshikawa1106:20181205134016j:plain:w300

f:id:tyoshikawa1106:20181205134107j:plain:w300


Herokuのプラットフォームでアドオンサービスとして提供されているKafkaが、SalesforceのPlatform Event側の仕組みでも利用されるようになるそうです。リアルタイムでの通知とかで使えるとのことでAPI覚える必要がなくなる的な話がありました。
f:id:tyoshikawa1106:20181205134335j:plain:w300


あとはDockerのお話。
f:id:tyoshikawa1106:20181205134711j:plain:w300

f:id:tyoshikawa1106:20181205134837j:plain:w300


ここまでのまとめ。
f:id:tyoshikawa1106:20181205134914j:plain:w300


最後にHerokuの活用事例ということでリーフラス株式会社の方が登壇されました。
f:id:tyoshikawa1106:20181205135701j:plain:w300

リーフラス株式会社


Herokuのセッションのあとはスタンプラリー完成のため会場まわりに時間を使うことにしました。
f:id:tyoshikawa1106:20181205140353j:plain:w300

f:id:tyoshikawa1106:20181205141030j:plain:w300

f:id:tyoshikawa1106:20181205141736j:plain:w300

f:id:tyoshikawa1106:20181205142357j:plain:w300

f:id:tyoshikawa1106:20181205142404j:plain:w300

f:id:tyoshikawa1106:20181205142648j:plain:w300

f:id:tyoshikawa1106:20181205143144j:plain:w300

f:id:tyoshikawa1106:20181205143227j:plain:w300

f:id:tyoshikawa1106:20181205143814j:plain:w300

f:id:tyoshikawa1106:20181205144308j:plain:w300

f:id:tyoshikawa1106:20181205145034j:plain:w300


時間はかかりましたが無事にコンプリートしました。教えてもらって気づいたのですがSalesforceという文字が出来上がる予定だったみたいです。(おみくじにいくのが遅かったためシールがなくなってしまったみたいです...)
f:id:tyoshikawa1106:20181205145152j:plain:w300


全部集めて2回分引けたので何か当たるかなと抽選クジ引いてきたのですが二回ともハズレ...ブース周りは楽しめたので良かったです。
f:id:tyoshikawa1106:20181205151157j:plain:w300


残りの時間も会場ぶらぶらして過ごしました。
f:id:tyoshikawa1106:20181205155033j:plain:w300

f:id:tyoshikawa1106:20181205151251j:plain:w300

f:id:tyoshikawa1106:20181205152159j:plain:w300

f:id:tyoshikawa1106:20181205163447j:plain:w300

f:id:tyoshikawa1106:20181205154722j:plain:w300

f:id:tyoshikawa1106:20181205165145j:plain:w300

f:id:tyoshikawa1106:20181205164954j:plain:w300

f:id:tyoshikawa1106:20181205173106j:plain:w300


Salesforce World Tour Tokyo 2018はこんな感じでした。今年も参加できて良かったです。


SFDC:個人取引先とデータの操作

$
0
0

SalesforceでB2C向けの顧客管理を行うときは個人取引先を使用します。

f:id:tyoshikawa1106:20181221194144p:plain


個人取引先のデータは取引先オブジェクトに格納されます。取引先責任者の標準項目はPerson〜というAPI名でアクセスできます。
f:id:tyoshikawa1106:20181221194354p:plain


Accountオブジェクトにクエリを投げると値を取得できます。
f:id:tyoshikawa1106:20181221194621p:plain

f:id:tyoshikawa1106:20181221194602p:plain


Updateも普通にできます。
f:id:tyoshikawa1106:20181221194731p:plain

f:id:tyoshikawa1106:20181221194804p:plain


個人取引先はPersonContactIdに取引先責任者のIDを保持しています。
f:id:tyoshikawa1106:20181221194959p:plain


個人取引先のContact側の情報はAccountと同じようにクエリで取得できます。
f:id:tyoshikawa1106:20181221195115p:plain

f:id:tyoshikawa1106:20181221195102p:plain


ContactレコードでUpdateも実行できます。
f:id:tyoshikawa1106:20181221195217p:plain

f:id:tyoshikawa1106:20181221195340p:plain


取引先責任者に外部IDがあった場合です。
f:id:tyoshikawa1106:20181221195601p:plain


カスタム項目は取引先オブジェクトで「__pc」という拡張子でアクセスできます。
f:id:tyoshikawa1106:20181221195642p:plain

f:id:tyoshikawa1106:20181221200228p:plain


外部ID項目が存在しているのでUPSERTで利用できるかと思いきや、エラーとなりました。
f:id:tyoshikawa1106:20181221200833p:plain

f:id:tyoshikawa1106:20181221200900p:plain


通常の取引先だったら外部IDでUPSERTできるので処理の書き方自体は大丈夫。
f:id:tyoshikawa1106:20181221200758p:plain


Contactオブジェクトの場合はどうでしょう。
f:id:tyoshikawa1106:20181221201043p:plain


こちらは正常に実行できました。取引先責任者が更新されれば個人取引先のデータにも自動で反映されます。
f:id:tyoshikawa1106:20181221201153p:plain


取引先責任者の外部ID項目をつかってUPSERT処理を行う場合は、Contactオブジェクトに対して処理を行えばいいみたいです。


個人取引先はパッと複雑ですがB2Cのデータを管理するときにはかなり柔軟な対応が可能となる機能です。ストレージの消費量の懸念点はありますが、システム構築のしやすさ向上の効果は大きいのでおすすめの機能です。

SFDC:データ登録時に複数メールを順番に送信する方法

$
0
0

Salesforceにデータを登録する際に同じ宛先に複数のメールを順番に送信する方法についてです。あまり無いケースだと思いますが、必ずメールAが受取人に届いたあとにメールBを送りたいといった要件が発生したときの対応方法です。複数送信ということでパッと思いつくのが下記の設定方法です。

f:id:tyoshikawa1106:20190120180754p:plain


ですがワークフロールールのアクションの実行順序は保証されていないので必ずしも同じ順番で送信されるわけではありません。

ワークフローの考慮事項


実行順序を担保したい場合は、プロセスビルダーで設定するのが良いと思います。
f:id:tyoshikawa1106:20190120181342p:plain


これで要件を満たす形で設定完了...と思ったのですが、思わぬ挙動がありました。メールクライアントによって表示順が異なる場合があります。下記のようにGmailではメールAが届いたあとにメールBが届いたのですが、Appleのメールクライアントでは稀に順番が逆転しました。

Gmail

f:id:tyoshikawa1106:20190120181458p:plain

Apple

f:id:tyoshikawa1106:20190120181641p:plain


下記の形でメールアラート処理の間に項目自動更新を挟む形でも解決できませんでした。

  1. メールA送信
  2. メールB送信フラグを更新
  3. メールB送信


順番を担保したい場合はメールB送信処理を遅らせる必要があるみたいです。


この問題を解決する方法ですが、プロセスビルダーのスケジュール済みアクションを使用することで解決できます。スケジュールの間隔は「日」または「時」のみ指定可能で「分」はありませんでした。ですが、「0時間前」という形で指定することで1時間以内に送信することができます。
f:id:tyoshikawa1106:20190120182339p:plain

f:id:tyoshikawa1106:20190120182450p:plain


2つ目のだいたい1分〜3分遅れで送信されると思います。(状況によってはもっと時間がかかるかもしれません)
f:id:tyoshikawa1106:20190120182742p:plain


この手順でメールAのあとにメールBが送信されるという要件を確実に満たせると思います。

プロセスビルダーのスケジュール済アクションのメリット

プロセスビルダーのスケジュール済アクションで、レコードの更新を行う場合は実行条件を指定できます。
f:id:tyoshikawa1106:20190120183401p:plain


ワークフロールールの時間ベースのアクションの場合は、項目自動更新アクションをそのまま呼び出すので細かい設定ができないようです。
f:id:tyoshikawa1106:20190120183822p:plain

こうしたスケジュール済み処理で判定処理を組み込む必要がある場合はプロセスビルダーの方がやりやすいと思います。

参考

SFDC:メールテンプレートでレコードURLを差し込む方法

$
0
0

レコード登録時に社内向けのメールアラートを作成するときにレコードURLを差し込みたい場合があると思います。そんなときのためにメールテンプレートの設定で差込項目を選択する際に「詳細リンク」という項目が用意されています。

f:id:tyoshikawa1106:20190120184625p:plain


詳細リンクをつかうことでレコードURLが組織に合わせて自動で生成されます。(本番環境で実行されたときは本番環境ドメインのレコードURLが生成され、Sandboxで実行された場合はSandboxドメインのレコードURLが生成されます。)
f:id:tyoshikawa1106:20190120184734p:plain


別の方法としては各オブジェクトごとにレコードURLを保持する数式項目があります。ドメイン部分はカスタム設定で保持することで本番、Sandboxでそれぞれ指定することが可能です。


数式項目でも一見問題なさそうですが、下記の問題が発生する可能性があります。

  1. Sandbox組織で設定完了
  2. 本番環境にリリース
  3. 本番環境でカスタム設定を指定し忘れる
  4. ドメイン部分が空白値となることでリンクURLにならない


上記問題の場合、一度設定してしまえばもう問題なさそうにも見えますが、Sandboxリフレッシュ時にカスタム設定の値がクリアされるため同じように問題が発生する可能性があります。


メールテンプレートでレコードURLを差し込みたいときは標準で用意された詳細リンクをつかうのが間違いなさそうです。

SFDC:商談フェーズとレコードタイプの関係

$
0
0

商談はフェーズ管理を正しく整理、設定することでユーザが次に何をすればいいかを可視化することができます。

f:id:tyoshikawa1106:20190120191640p:plain


フェーズを設定するとフェーズごとに入力フォームのレイアウトを切り替えたくなるかもしれません。後半のフェーズに関する項目に値を入力するときに下にスクロールする手間が発生するためです。また、現在のフェーズで入力してほしい項目を上に持ってくることでユーザがどこで入力すればいいかで悩むことがなくなります。
f:id:tyoshikawa1106:20190120192125p:plain


上記要望を簡単に実現する方法としてフェーズごとにレコードタイプを用意する方法が思いつくかもしれません。確かに1フェーズ1レコードタイプとすることでそれぞれ専用のページレイアウトを割り当てることができます。ですがこの方法は長期的に運用していく上でトラブルの原因になると思います。


わかりやすい部分でパスの設定があります。パスは「1つのレコードタイプに1つのパス」という構成で成り立ちます。もしフェーズごとにレコードタイプを用意した場合、レコードタイプの数だけパスを用意する必要が出てくることになります。コピーや一括更新は行えないため、成功へのガイダンスのメッセージや表示項目を無駄に多く登録する必要が発生してメンテナンスしずらい組織となります。
f:id:tyoshikawa1106:20190120193534p:plain


このパス設定への影響だけでもフェーズごとにレコードタイプを用意するのはデメリットの方が大きいと思います。また、本来レコードタイプはデータの種別を分別するためのものです。例えば法人向けのビジネスの会社ということで下記のようにフェーズ設定を行ったとします。

法人向け商談
  • フェーズA
  • フェーズB
  • フェーズC
  • フェーズD
  • フェーズE


上記設定で運用を開始したあとに個人向けの商談管理が必要になった場合、通常であれば法人/個人の2つのレコードタイプを用意すれば済みましたが、フェーズごとにレコードタイプを用意しているとこうなります。

個人向け商談
  • フェーズF
  • フェーズG
  • フェーズH
  • フェーズI
  • フェーズJ


はじめ5個あったレコードタイプが、一気にレコードタイプが10個に増えました。レコードタイプが増えれば増えるほどページレイアウト設定やパス設定を行う際に作業する箇所が多くなるので、ちょっと修正でも無駄に作業時間が多く発生してしまいます。


レコードタイプは法人/個人など大きな括りで用意するようにして、フェーズごとに用意するというのは避けた方が良いと思います。

フェーズごとにレイアウトを分けたい時の対応方法

上記のとおりレコードタイプを用意して対応するのはデメリットの方が大きいです。そのため別の方法が必要になりますが、標準機能のみでの対応はおそらくムリだと思います。こういう場合はVisualforceページ(もしくはLightningコンポーネント)を開発して対応することで結果的にメンテナンス性を損なわずに実現できると思います。

SFDC:クイックテキストの設定を試してみました

$
0
0

クイックテキストはテキストエリアの項目などに定型文を差し込むことができる機能です。きまった文章を入力することが多い場合に活用できます。特定の値を差し込むこともできるみたいです。(メールテンプレートみたいなイメージ) この機能は設定で有効 / 無効を切り替えることができます。

f:id:tyoshikawa1106:20190121044029p:plain


設定ページではクイックテキストのボタンを非表示にできるオプションも用意されています。ユーザに表示したくない場合はこちらで切り替えができるみたいです。
f:id:tyoshikawa1106:20190121044213p:plain:w300


有効化は設定ページから行いますが、クイックテキストの定型文作成はアプリケーションランチャーから行います。
f:id:tyoshikawa1106:20190121044309p:plain


レコードを作成するときと同じように登録できました。
f:id:tyoshikawa1106:20190121044343p:plain


オブジェクトと項目を選択して文中に差し込みできます。
f:id:tyoshikawa1106:20190121044520p:plain


作成例としてはこんな感じ。
f:id:tyoshikawa1106:20190121044638p:plain


テキストエリア型の項目などにフォーカスがあったときにアイコンが表示されます。
f:id:tyoshikawa1106:20190121044726p:plain


クリックすると作成済みのクイックテキストが表示されます。
f:id:tyoshikawa1106:20190121044916p:plain


対象を選択すると本文に差し込まれます。差し込み項目の値をすぐにセットされた状態となりました。
f:id:tyoshikawa1106:20190121044858p:plain


以上がクイックテキストの使い方の流れです。問い合わせ対応や日報などの業務で活用できると思います。

おまけ

うっかり削除してしまったときはゴミ箱に残っているのでそこから復元できました。
f:id:tyoshikawa1106:20190121045313p:plain

Viewing all 1438 articles
Browse latest View live


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