2017年5月31日水曜日

Salesforce : Apex : API名を取得して表示するVisualforceページを作成

オブジェクトを選択リストで選択して、オブジェクトの項目のAPI名一覧を表示するようなVisualforceページを作成した。

■Visualforceページ
<apex:page controller="ApiListController">
    <apex:form >
        <apex:outputLabel value="オブジェクト選択" for="sobject_select_list"/>
        <apex:selectList id="sobject_select_list" value="{!selectItem}" size="1">
            <apex:selectOptions value="{!options}"/>
        </apex:selectList>
        <apex:commandButton value="検索" action="{!getApiInfo}" />
        <apex:pageBlock >
            <apex:pageBlockTable value="{!apiList}" var="item">
                <apex:column value="{!item.apiLabelName}"/>
                <apex:column value="{!item.apiName}"/>
            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>
</apex:page>

■Apexクラス
public class ApiListController {
    /**
     * 選択リストの選択値
     */
    public String selectItem { get; set; }
    
    /**
     * API名のリスト
     */
    public List<ApiListColumn> apiList { get; set; }

    /**
     * オブジェクトの項目の情報を取得する
     */
    public void getApiInfo() {
        Schema.SObjectType sot = Schema.getGlobalDescribe().get(selectItem);
        Schema.DescribeSObjectResult dsr = sot.getDescribe();

        Map<String, Schema.SObjectField> fsMap = dsr.fields.getMap();
        apiList = new List<ApiListColumn>();
        for (Schema.SObjectField sof : fsMap.values()) {
            ApiListColumn alc = new ApiListColumn();
            alc.apiLabelName = sof.getDescribe().getLabel();
            alc.apiName = sof.getDescribe().getName();
            apiList.add(alc);
        }
    }
    
    /**
     * 選択リストのオプション設定
     */
    public List<SelectOption> getOptions() {
        Map<String, Schema.SObjectType> m = Schema.getGlobalDescribe();
        List<SelectOption> options = new List<SelectOption>();
        for (Schema.SObjectType sot : m.values()) {
            Schema.DescribeSObjectResult dsr = sot.getDescribe();
            options.add(new SelectOption(dsr.getName(), dsr.getLabel() + ' : ' + dsr.getName()));
        }
        return options;
    }
    
    /**
     * API名一覧のカラム定義クラス
     */
    public class ApiListColumn {
        public String apiLabelName { get; set; }
        public String apiName { get; set; }
    }
}

動作の確認をしてみる。

検索前の状態。選択リストにきちんとオブジェクトがセットされているのが分かる。

検索ボタンをクリックして項目の一覧を表示。

2017年5月30日火曜日

Salesforce : Apex : Visualforceで項目のAPI名一覧を作成する

"<apex:pageBlockTable>"タグを利用してVisualforceで項目のAPI名一覧を作成する。"<apex:pageBlockTable>"タグを利用すると簡単に一覧表を作成できる。

■Visualforceページ
<apex:page controller="ApiListController">
    <apex:form >
        <apex:pageBlock>
            <apex:pageBlockTable value="{!apiList}" var="item">
                <apex:column value="{!item.apiLabelName}"/>
                <apex:column value="{!item.apiName}"/>
            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>
</apex:page>

■Apexクラス
public class ApiListController {
    /**
     * API名のリスト
     */
    public List<ApiListColumn> apiList { get; set; }
    
    /**
     * コンストラクタ
     */
    public ApiListController() {
        getApi();
    }
    
    /**
     * オブジェクトの項目の情報を取得する
     */
    private void getApi() {
        Schema.SObjectType sot = Schema.getGlobalDescribe().get('Contact');
        Schema.DescribeSObjectResult dsr = sot.getDescribe();

        Map<String, Schema.SObjectField> fsMap = dsr.fields.getMap();
        apiList = new List<ApiListColumn>();
        for (Schema.SObjectField sof : fsMap.values()) {
            ApiListColumn alc = new ApiListColumn();
            alc.apiLabelName = sof.getDescribe().getLabel();
            alc.apiName = sof.getDescribe().getName();
            apiList.add(alc);
        }
    }
   
    /**
     * API名一覧のカラム定義クラス
     */
    public class ApiListColumn {
        public String apiLabelName { get; set; }
        public String apiName { get; set; }
    }
}

getApiメソッドでAPI名の一覧が取得する。今回は、取引先責任者のみ取得するようにした。一覧の各カラムに値を渡すために、ApiListColumnというクラス内クラスを作った。

■画面

2017年5月29日月曜日

Salesforce : Apex : Visualforceで複数選択リスト表示

Visualforceで複数選択リストを表示する。

■Visualforceページ
<apex:page controller="SampleListController">
    <apex:form>
        <apex:selectList value="{!selectItem}" size="5" multiselect="true">
            <apex:selectOptions value="{!options}"/>
        </apex:selectList>
    </apex:form>
</apex:page>

複数選択リストを表示するときは、選択リストと同様に"<apex:selectList>"タグと"<apex:selectOptions>"タグを使う。"multiselect"にtrueをセットすると、選択リストが複数選択リストに変わる。

■Apexクラス
public class SampleListController{
    /**
     * 選択リストの選択値
     */
    public String[] selectItem { get; set; }
    
    /**
     * 選択リストのオプション設定
     */
    public List<SelectOption> getOptions() {
        List<SelectOption> options = new List<SelectOption>();
        options.add(new SelectOption('A', 'あいうえお'));
        options.add(new SelectOption('B', 'かきくけこ'));
        options.add(new SelectOption('C', 'さしすせそ'));
        options.add(new SelectOption('D', 'たちつてと'));
        options.add(new SelectOption('E', 'なにぬねの'));
        options.add(new SelectOption('F', 'はひふへほ'));
        options.add(new SelectOption('G', 'まみむめも'));
        options.add(new SelectOption('H', 'やゆよ'));
        options.add(new SelectOption('I', 'らりるれろ'));
        options.add(new SelectOption('J', 'わをん'));
        return options;
    }
}

Apexクラスも選択リストのときとほとんど変わらない。違うのは選択値を受け取るときにStringではなく、String[]を使うこと。複数選択できるので配列を使うことになる。

■画面

2017年5月28日日曜日

Salesforce : Apex : Visualforceで選択リスト表示

Visualforceで選択リストを表示する方法。

■Visualforceページ
<apex:page controller="SampleListController">
    <apex:form>
        <apex:selectList value="{!selectItem}" size="1">
            <apex:selectOptions value="{!options}"/>
        </apex:selectList>
    </apex:form>
</apex:page>

選択リストを表示するには"<apex:selectList>"タグと"<apex:selectOptions>"を利用する。

■Apexクラス
public class SampleListController {
    /**
     * 選択リストの選択値
     */
    public String selectItem { get; set; }
    
    /**
     * 選択リストのオプション設定
     */
    public List<SelectOption> getOptions() {
        List<SelectOption> options = new List<SelectOption>();
        options.add(new SelectOption('A', 'あいうえお'));
        options.add(new SelectOption('B', 'かきくけこ'));
        options.add(new SelectOption('C', 'さしすせそ'));
        options.add(new SelectOption('D', 'たちつてと'));
        options.add(new SelectOption('E', 'なにぬねの'));
        options.add(new SelectOption('F', 'はひふへほ'));
        options.add(new SelectOption('G', 'まみむめも'));
        options.add(new SelectOption('H', 'やゆよ'));
        options.add(new SelectOption('I', 'らりるれろ'));
        options.add(new SelectOption('J', 'わをん'));
        return options;
    }
}

Apexのほうでは、SelectOptionクラスを使うことで選択リストのアイテムの設定を行える。

■画面

2017年5月26日金曜日

Salesforce : Apex : 項目のAPI名を取得する

昨日は項目のAPI名に悩まされたということを書いた。それで、実は以前からオブジェクトの項目のAPI名の一覧が欲しいと思っていた。

Schema.SObjectType sot = Schema.getGlobalDescribe().get('Contact');
Schema.DescribeSObjectResult dsr = sot.getDescribe();

Map<String, Schema.SObjectField> fsMap = dsr.fields.getMap();
for (Schema.SObjectField sof : fsMap.values()) {
    System.debug(
        'ラベル名:' + sof.getDescribe().getLabel() + '  ' +
        'API名:' + sof.getDescribe().getName());
}

これを実行すると以下のような結果になる。
USER_DEBUG [6]|DEBUG|ラベル名:取引先責任者 ID  API名:Id
USER_DEBUG [6]|DEBUG|ラベル名:削除  API名:IsDeleted
USER_DEBUG [6]|DEBUG|ラベル名:マスタレコード ID  API名:MasterRecordId
USER_DEBUG [6]|DEBUG|ラベル名:取引先 ID  API名:AccountId


1行目の'Contact'の部分を変更することで任意のオブジェクトについてのAPI名をすべて取得することができる。

2017年5月25日木曜日

Salesforce : 項目のAPI名には悩まされたことを思い出す

Salesforceで項目のAPI名を知りたいときは画面を見れば確認できるし、大抵の場合はこれで十分。


そうなのだが、実はこの画面に表示されていないようなAPI名も存在しており、そうした隠された(?)項目をApexで参照したくなることもよくあるのだ。どんなAPI名なのかというのは調べないといけない。

例えば上の画像は「取引先責任者」の項目が表示されているのだけれど、スクロールして下のほうを見てみるととんでもないことが判明する。


なんと、「名」と「姓」のAPI名が書かれていない。取引先責任者を登録するときは、「名」と「姓」を別々に入力するのに、この画面ではAPI名が分からず、どうやってApexで取得したらいいのか初めてやったときは途方に暮れた。

ちなみに、「名」が"FirstName"で、「姓」が"LastName"。

他にも、「取引先名」は参照項目でAPI名がAccountとなっているのだけれど、下記のSOQLはエラーになってしまう。

SELECT Id, Account FROM Contact
No such column 'Account' on entity 'Contact'.
Accountなんて存在しないよと言われてしまうのだ。でも、画面にはしっかりとAccountと記載されている。


理由はよく分からないが、存在していない(少なくともSOQLでは取得できない)API名が記載されてしまっている。なので、Accountを取得したいときのSOQLは下記のようになる。

SELECT Id, AccountId FROM Contact

これで参照先の取引先IDが取得できるので、さらにもう一回取引先を取得するようなSOQLを発行する必要がある。これも初めてやろうとしたときは悩んだところだ。何度もスペルミスしていないかチェックしなおしたことを覚えている。そして、AccountIdに行きついたときは何だか騙された気分になった。

2017年5月24日水曜日

Salesforce : Apex : オブジェクトのAPI参照名を取得する2

先日、オブジェクトのAPI参照名を取得するという内容を書いた。さらに調べを進めていくと、どうもやり方が違うようだ。値は取得出来ていそうな気もするのだが、MapのKEYから値を取得するという方法にも違和感があるので、こちらのやり方の方が良さそうではある。
Schema.SObjectType.getDescribe()
これを使うとAPI参照名だけでなく、ラベル名などオブジェクトに関連する様々な情報を取得することができる。

Map<String, Schema.SObjectType> m = Schema.getGlobalDescribe();

for (Schema.SObjectType sot : m.values()) {
    Schema.DescribeSObjectResult dsr = sot.getDescribe();
    System.debug('ラベル = ' + dsr.getLabel() + '; API名 = ' + dsr.getName());
}

USER_DEBUG [5]|DEBUG|ラベル = 契約; API名 = Contract
USER_DEBUG [5]|DEBUG|ラベル = 契約履歴; API名 = ContractHistory
USER_DEBUG [5]|DEBUG|ラベル = 契約タグ; API名 = ContractTag


プログラムを実行すると、こんなログが取れて、ラベルとAPI名を取得できていることが確認できる。

2017年5月23日火曜日

Salesforce : Apex : Schema.SObjectType

昨日、オブジェクトのAPI名を取得する方法を調べた。"Schema"クラスの"getGlobalDescribe"というメソッドで取れそうだというところまで分かったのだけれど、戻り値に何が戻ってくるのかがよく分かっていない。
Map<String, Schema.SObjectType>
これが戻り値でKEYのほうにAPI名がセットされているようだった。じゃあ、Valueのほうには何がセットされているのだろうか。そもそも、"Schema.SObjectType"が何者なのかが分からない。

  • getDescribe()
  • newSObject()
  • newSObject(id)
  • newSObject(recordTypeId, loadDefaults)

"Schema.SObjectType"は上記の4つのメソッドを持っていて、簡単に言ってしまえば、sObjectの作成を行ったり、sObjectの詳細情報を取得することができる。

Map<String, Schema.SObjectType> m = Schema.getGlobalDescribe();

String key = 'Account';
if (m != null && m.containsKey(key)) {
    Account a = (Account)m.get(key).newSObject();
    a.Name = 'テスト取引先';
   insert a;
}

このソースを動かしてみると、取引先が作成されるのを確認できた。

参考
https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_class_Schema_SObjectType.htm


2017年5月22日月曜日

Salesforce : オブジェクトのAPI参照名を取得する

オブジェクトのAPI参照名を取得する方法を調べた。わざわざ調べる人も少ないようで、あまり情報がなくて困ったけれど、下記のURLに記載がある。さすが、Salesforce Developerのためのサイトだ。
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_schema.htm

これによれば、"Schema"というクラスの"getGlobalDescribe"というメソッドを呼び出せば取得できるよということになると思う。

"getGlobalDescribe"は戻り値として
Map<String, Schema.SObjectType>
を返却してくれる。説明を読むと
names (keys)
sObject tokens (values)
と書かれているので、MapのKEYになっているのがAPI参照名になるのではなかろうかと予測した。"sObject tokens"のほうに何が入っているのかは想像もつかないので、そのうち調べようと思う。

Execute Anonymous Windowに下記のコードを書いて確認する。

Map<String, Schema.SObjectType> m = Schema.getGlobalDescribe();
for (String keyValue : m.keySet()) {
    System.debug(keyValue);
}

ログに
USER_DEBUG [3]|DEBUG|contract
USER_DEBUG [3]|DEBUG|contracthistory
USER_DEBUG [3]|DEBUG|contracttag


といった感じで出力されている。見慣れたものから見慣れないものまでかなりの量があるけれど、見たところAPI参照名と思われる。

2017年5月21日日曜日

Windows PowerShell : SyntaxHighlighter用にソースコードを加工するスクリプト

ブログにソースコードをのせるうえでSyntaxHighlighterを使って装飾を施している。プログラムを書いて、コピーして貼り付ける前に一仕事必要なのだ。

"<"や">"といった文字はアスキーコードに変換しないと、ちゃんと表示されない。また、HTMLを書いて埋め込む形になるのだが<pre>タグで囲う必要がある。どの言語を用いたソースコードなのかは<pre>タグのclassで指定する。

こうした作業が徐々に面倒に感じるようになったので、スクリプトを書いて自動化した。

$brush = $Args[0] 
if ( [string]::IsNullOrEmpty( $brush ) ) { 
    "Error" 
    return 
} 
Add-Type -Assembly System.Windows.Forms 
$val = [Windows.Forms.Clipboard]::GetText()
$val = $val -creplace "<", "&lt;"
$val = $val -creplace ">", "&gt;"
$val = "<pre class=`"brush:" + $brush + ";`">" + $val + "</pre>"
$OutputEncoding = [Text.Encoding]::Default
$val | Clip

使いかたは、ブログにのせたいプログラムをコピーしてスクリプトを動かすだけ。

引数にbrushで指定する言語名(javaとか、powershellとか、cppとか)を渡してやることで、自動的に<pre>タグの追加、アスキーコードへの変換を行うようになっている。

SyntaxHighlighterで装飾するには<script>タグを使うという<pre>タグ以外にも方法は用意されているのだが、<script>タグを使うと何故か私のブログだとソースコードが表示されなくなってしまう。

2017年5月19日金曜日

Windows PowerShell : 文字列がnullまたはemptyかどうかをチェックする方法

Windows PowerShellで文字列がnullまたはemptyかどうかをチェックする方法。

スクリプトに引数を渡してもらいたくても、実行者がちゃんと渡してくれるかどうかは分からない。そこで、"$Args"の中身がnullまたはemptyでないかということをチェックして、nullまたはemptyであればエラーとしてはじくというようなことを考えた。

nullまたはemptyをチェックするには、
[string]::IsNullOrEmpty([判定する文字列])
というのを使う。trueが帰ってくればnullまたはemptyである。

$val = $Args[0]

if ( [string]::IsNullOrEmpty( $val ) ) {
    "NULL"
} else {
    $val
}

これを実行して結果を見てみると、きちんと判定されていることが分かる。


2017年5月18日木曜日

Windows Powershell:エスケープシーケンス

Windows Powershellで文字列に「"」ダブルクォーテーションなどを入力したいときはエスケープしてあげないとエラーとなってしまう。

下記のようなスクリプトを書いて実行してみると、


$val = ""ABCDEFG""

エラーとなってしまう。

発生場所 C:\workspace\test.ps1:1 文字:10
+ $val = ""ABCDEFG""
+          ~~~~~~~~~
式またはステートメントのトークン 'ABCDEFG""' を使用できません。
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : UnexpectedToken
文字列に「"」ダブルクォーテーションを含もうとすると、エラーとなってしまうので「`」バッククォートを入れることでエスケープする必要がある。

$val = "`"ABCDEFG`""
$val

結果


2017年5月17日水曜日

Windows PowerShellでスクリプトで引数を受け取る・渡す

Windows PowerShellにおけるスクリプトでも引数の受け取り方と、渡し方について書き留めておく。


引数の受け取り方

まず、引数の受け取り方だがスクリプト内では、
$Args
で引数を操作することができる。配列になっているので、第一引数なら"$Args[0]"、第二引数なら"$Args[1]"というように指定する。



引数の渡し方

引数を渡すときは、
./test.ps1 あいうえお かきくけこ
このような感じで、スクリプト名のあとに半角スペースを入れて渡したい値を指定すればよい。複数指定したければ、第一引数のあとに半角スペースを入れて、渡したい値を指定する。



実際の動きを見てみる。

スクリプト(test.ps1)

$Args[0]
$Args[1]

上記のようなスクリプトを呼び出す。


 引数で渡した値が出力される。

2017年5月16日火曜日

Windows PowerShellで文字列置換

Windows PowerShellで文字列置換をする方法は2通りある。


  • replace
  • creplace



replace



"Hello World!" -replace "h", "A"

replace を使う場合の構文は
[置換を実施する文字列] -replace [置換前文字列] [置換後文字列]
というようになる。replaceは大文字、小文字を区別しないので上記スクリプトを実行すると以下のような結果がコンソールに表示される。
 Aello World!


creplace


creplaceの構文はreplaceとほとんど同じで、"-replace"となっている部分を"-creplace"に置き換えればよい。creplaceはreplaceと異なり、大文字、小文字を区別するので、


"Hello World!" -creplace "h", "A"

このスクリプトの実行結果は、
Hello World!
となる。スクリプトを書き換えて、


"Hello World!" -creplace "H", "a"

結果を見てみると、
aello World!
置換が正常に行われていることが分かる。 

2017年5月15日月曜日

Windows PowerShellでクリップボードを操作

Windows PowerShellでクリップボードの操作をする方法。



クリップボードから値を取得する


これだけで、クリップボードから取得できる。



# クリップボードから取得
Add-Type -Assembly System.Windows.Forms
$val = [Windows.Forms.Clipboard]::GetText()



クリップボードに値をセットする


クリップボードに値をセットするときは日本語が文字化けするのでエンコードに注意する。



# クリップボードへ値のセット
$OutputEncoding = [Text.Encoding]::Default
"テスト" | Clip

"$OutputEncoding = [Text.Encoding]::Default"のようにしてエンコードを変更してあげると、文字化けせずにクリップボードに値のセットができる。

2017年5月14日日曜日

Windows PowerShellでスクリプト実行できるようにする

Windows PowerShellではデフォルトの設定だとスクリプトの実行を行えない。スクリプトを実行するには実行ポリシーを変更しないといけない。Windows PowerShellのスクリプトファイルの拡張子は"ps1"となる。

ローカルで簡単な処理を自動化するのに長らく "bat" を使ってきたが、Windows PowerShellが登場して久しい。そこで、思い切ってWindows PowerShellでやろうと思い立って、やり方を調べてみた。



実行ポリシーの種類


実行ポリシーは4種類ある。
※リモートはインターネットからダウンロード or 別サーバの"ps1"
  • Restricted
    • ローカル:×
    • リモート:×
  • AllSigned
    • ローカル:署名付きのみ○
    • リモート:署名付きのみ○
  • RemoteSigned
    • ローカル:○
    • リモート:署名付きのみ○
  • Unrestricted
    • ローカル:○
    • リモート:○(実行するかどうか確認される)
  • Bypass
    • ローカル:○
    • リモート:○


実行ポリシーの確認


まずはWindows PowerShellで現在の実行ポリシーを確認する。





Get-ExecutionPolicy

私の環境だと下記のような文字が表示された。
Restricted



実行ポリシーの変更


実行ポリシーの変更は以下のような構文。





Set-ExecutionPolicy 引数

引数には"Unrestricted"などの実行ポリシーの名称を渡す。

私の場合、自分で作ったローカルの"ps1"を実行したいので"Unrestricted"に設定を変更した。





Set-ExecutionPolicy Unrestricted



スクリプトの実行


スクリプトを実行しようとして、スクリプトファイルをダブルクリックしてもテキストエディタが表示されてしまう。"ps1"はダブルクリックでは実行できない。Windows PowerShellを立ち上げて、コマンドから実行する必要がある。

私の環境だと下記のようになった。

作成した"ps1"



"Hello World!"

実行コマンド
C:\workspace\test.ps1

結果


2017年5月12日金曜日

Salesforce : プロセスビルダーでChatterへの投稿

プロセスビルダーでChatterへの投稿を試してみる。

アクション種別で「Chatterに投稿」を選択すると、Chatterへの投稿を行える。




上の画像だと投稿先は「Chatterグループ」になっているが、ユーザを指定して投稿することもできる。




ユーザの指定は全ユーザから選択するだけでなく、レコードの所有者を選択するなど、レコードからユーザを選択することも行える。




アクションを設定してプロセスを有効化すればChatterへの投稿が行われるようになる。



2017年5月11日木曜日

Salesforce : Visualforceで画面遷移処理

Visualforceで画面遷移をする方法。

取引先を標準コントローラとするVisualForceを作成したとき、取引先の詳細ページへのリンクを貼りたいなんてことがある。そうしたときは、こんな感じでVisualForceを作ると取引先へのリンクを貼れる。





<apex:page standardController="Account">
    <apex:outputLink value="{! URLFOR( '/' + Account.Id ) }">リンク</apex:outputLink>
</apex:page>

ポイントになるのは"URLFOR"の部分。パラメータに相対パスを渡してあげると、勝手に組織のルートURLを付加してくれる。上記の場合は、取引先のIDを渡しているので、取引先への詳細ページへのリンクが生成される。

「ルートURL」とか、「組織のURL」とか、こういった単語で検索してもなかなか見つからない。

Salesforceのベテランであれば当然の知識なんだろうけれど、私なんかだと忘れてしまいがちなので、毎度調べている。やったことあるけど・・・、あれなんだっけ・・・、なんて思いながらかなりもどかしい想いをして調べることになるのでここにメモしておく。

2017年5月10日水曜日

Salesforce : プロセスビルダーでフローを呼び出す

プロセスビルダーでフローを呼び出すようなプロセスを作ることができる。と言ってもどんなプロセスでも呼び出せるわけではない。


1.プロセスから呼び出せるフロー


自動起動フロー


プロセスから呼び出せるフローは種別に「自動起動フロー」を選択しないといけない。この「自動起動フロー」というのは、プロセスやApexから起動を行うことのできるフローのことだ。

フローを作成して保存するときに表示されるフロープロパティで指定する。あとから変更できないようなので忘れずに。



有効化を忘れずに


フローを作成し終えたら忘れずに「有効化」すること。有効じゃないフローはプロセスから呼び出すことはできない。



2.プロセスの作成


プロセスの作成については、他のプロセスの作成方法と特に変わることはない。

アクションを定義するときにアクション種別に「フロー」を設定してあげればいい。フローでフロー変数を使っていれば、引数としてプロセスから値を渡すこともできる。



これだけ設定すればフローを呼び出すプロセスの完成。

2017年5月9日火曜日

Salesforce : フローについて

プロセスビルダーからフローを呼び出すことができるのだけれど、そういえばフローってなんだと聞かれても答えられる自信がない。フローを作成するまえに、フローとは何かというのを調べたのでまとめておく。

1.フローとは


プロセスビルダーと同じで、ビジネスプロセスを自動化するためのもの。ビジュアルデザイナを使ってノンコーディングで作成できる。


2. フローでできること


  • Apexコードの呼び出し
  • レコードの作成
  • 任意のレコードの更新
  • レコードの削除
  • フローの呼び出し
  • Chatterへの投稿
  • メール送信
  • 承認申請
  • 画面表示

プロセスビルダーとの大きな違いは画面表示して、ユーザーに入力をさせながら処理を進めることができること。逆にユーザーが入力不要でバックグラウンドで処理が完結するようであれば、プロセスビルダーの使用を検討したほうがよさそうだ。

あとは、レコードの削除が行えることと、フローからはプロセスの呼び出しができないところが違う。


3. その他


調べるうえで、用語が分かりづらくて最初のうちは何の話なのか混乱することがあった。

  • Visual Workflow
  • Cloud Flow Designer
  • フロー

フローのことを調べていると、これら3つの用語が入り混じっていて、私が調べたいことについて言及しているのかどうかが判断できなかったのだ。

Visual Workflow:
フローの設計から管理、実行までのプロセスを完結できる製品。

Cloud Flow Designer:
フローを作成するためのビジュアルデザイナ。

フロー:
プロセスを自動化したもの。

Visual Workflowという製品では、Cloud Flow Designerというビジュアルデザイナを用いてプロセスの自動化を行える。自動化されたプロセスはフローと呼ばれる。

こういう説明になるのだろうか?

2017年5月8日月曜日

Salesforce : プロセスから別プロセスを呼び出す

プロセスビルダーで作成したプロセスを別のプロセスから呼び出すことができる。

プロセスを新規作成するときに、プロセスを開始するタイミングに「別のプロセスから呼び出されたとき」を選択して作成すると、別のプロセスから呼び出すことのできるプロセスになる。



プロセスを開始するタイミングに「レコードが変更されたとき」を選択したときと同じように設定することでプロセスが作成できる。異なるのはオブジェクトを選択したときに、「レコードを作成したときのみ」や「レコードを作成または編集したとき」といったプロセスが動作するタイミングを選択できないことだ。あと、スケジュール済みのアクションも作成できない。別プロセスから呼び出されることが前提なので当然か。



従来のプロセスと同じように設定すればいいのだけれど、1つだけ注意しないといけないことがある。オブジェクトの選択で選択したオブジェクトによって、どのプロセスから呼び出せるかということがコントロールされることだ。

例えばAオブジェクトを指定したなら、このプロセスを呼び出せるプロセスのオブジェクトもAオブジェクトもしくは、Aオブジェクトを参照(親子関係も含む)しているオブジェクトを選ばないと、せっかく作ったプロセスも呼び出すことができない。

あとは、作成したプロセスを呼び出すプロセスを作る。

アクション種別で「プロセス」を指定して、プロセス欄で呼び出したいプロセスを選択すればOK。

2017年5月7日日曜日

C++ : CEditの読取専用/無効化/非表示

C++をたまにしか使わないというのもあるのだが、どうしてもC++でEditboxを読取専用にしたり、無効化したり、非表示したりするやり方を忘れてしまう。毎回調べて、「ああ、そういえばこうやるんだった」なんて考えている。


GetDlgItem(EDIT1)->SetReadOnly(TRUE); // 読取専用
GetDlgItem(EDIT2)->EnableWindow(FALSE); // 無効化
GetDlgItem(EDIT3)->ShowWindow(SW_HIDE); // 非表示

これだけなんだけど、調べるとすぐに分からなかったりするんだよね。

2017年5月5日金曜日

Salesforce : プロセスビルダーでレコードの更新

プロセスビルダーでレコードの更新を試してみる。と言っても、レコードを追加するのとほとんどやることは変わらない。アクションを選択するとき、アクション種別に「レコードを更新」を指定するだけだ。



レコード欄をクリックすると、更新するレコードを選択するためのダイアログが表示されるので要件に従って選択する。ここでは、「プロセスを開始したNew_Object__cレコードを選択」を選ぶ。



あとは更新する項目と更新値を選べばプロセスビルダーの設定は終わり。



New Objectを新規追加する。



レコードが更新されている。


2017年5月4日木曜日

Salesforce : プロセスビルダーでレコードの追加を自動化

プロセスビルダーではレコードの追加をノンコーディングで自動化できるので試してみる。

"New Object"が新規登録されたときに、"New Object2を作成"にチェックが入っていたら、"New Object2"にレコード追加を行うものを作る。




プロセスビルダーで条件の設定。"New Object2"がTrueのときのみ処理を実施するように設定する。



アクションを定義する。アクション種別に「レコードを作成」を選択すると、レコード追加を行えるようになる。追加するオブジェクトはレコードタイプで選択する。New Object2名にNew Object名をセットするように設定して、プロセスを有効化する。



New Objectを新規作成する。



New Object2を確認するとレコードが追加されていることが分かる。


2017年5月3日水曜日

Salesforce : プロセスビルダーでApexを呼び出すときに複数の引数を渡す

プロセスビルダーからApexに複数の引数を渡す。あまり深く考えずに、下記のようにプログラムを書いてみた。

public class Test {
    @InvocableMethod
    public static void test(List<String> names, List<String> param2) {
        String name = names[0];
        System.debug('名前 = ' + name);
    }
}

これでいいのかと思ったらエラーとなってしまった。
Only one parameter is supported on methods with @Invocable annotation
"InvocableMethod"アノテーションをつけたメソッドはひとつしか引数をとれないようなのだ。こうしたときに使うのが"InvocableVariable"。引数をまとめたクラスを作ることで複数の引数を渡すことができるようになる。そこでApexをこんなふうに書き換えてみる。

public class Test {
    @InvocableMethod
    public static void test(List<RequestParams> requests) {
        RequestParams request = requests[0];
        System.debug('ID = ' + request.objId);
        System.debug('名前 = ' + request.name);
    }
    
    public class RequestParams {
        @InvocableVariable
        public Id objId;
        @InvocableVariable
        public String name;
    }
}

プロセスビルダーの設定を行う。


「Apex変数を設定する」を見てみると、"InvocableVariable"アノテーションをつけた変数が選択できるようになっている。"objId"にオブジェクトのID、nameにオブジェクトの名称をセットするようにして保存。

オブジェクトを新規登録してみる。


開発者コンソールでログを見てみると、IDと名前を取得できていることが分かる。
USER_DEBUG [5]|DEBUG|ID = a081000002zyipgAAA
USER_DEBUG [6]|DEBUG|名前 = かきくけこ

2017年5月2日火曜日

Salesforce : プロセスビルダーで呼び出したApexに引数を渡す

プロセスビルダーで呼び出すApexに引数を渡すことができる。プロセスビルダーから引数を受け取るときはList型の引数を受け取ることになる。

public class Test {
    @InvocableMethod
    public static void test(List<String> names) {
        String name = names[0];
        System.debug('名前 = ' + name);
    }
}

Apexで引数を受け取れるようにすると、プロセスビルダーを設定するときに「Apex変数を設定」という欄が表示されるので、引数ごとにどんな値をセットするのかを設定していく。


ここでは、オブジェクトの「New Object名」という項目にセットされた値を引数として渡すように設定してある。


保存するとプロセスが走るので開発者コンソールでログを確認する。
USER_DEBUG [5]|DEBUG|名前 = あいうえお
ちゃんと引数を受け取れているようだ。

2017年5月1日月曜日

Salesforce : プロセスビルダーからApexを呼び出す

プロセスビルダーからApexを呼び出せるようなので試してみた。Apexを呼び出せるようにするためにはApexにアノテーションが必要。
@InvocableMethod
このアノテーションをつけることでプロセスビルダーから呼び出せるようになる。

public class Test {
    @InvocableMethod
    public static void test() {
        System.debug('★★★テスト★★★');
    }
}

Apexの用意ができたら、プロセスビルダーの設定を行う。アクションを追加で、アクション種別をApex、アクション名は任意、Apexクラスに先ほど作成したApexクラスを設定する。


プロセスビルダーを有効化して、プロセスビルダーを呼び出してみると開発者コンソールにログが吐き出されるので、Apexが呼び出されていることが分かる。
USER_DEBUG [4]|DEBUG|★★★テスト★★★