Labyrinth of Wisdom

-This is My Archive-


【買って良かったもの】エアコンからの直風を防止するグッズ

今の家の間取りが悪く、ベッドの配置的に顔にエアコンの風が直当たりしてしまう問題に直面していました。 f:id:Labyrinth_of_Wisdom:20180830163903p:plain

寝てる時に顔に風が直当たりするので、色々と具合が悪い。。 この問題を解決する為に色々グッズを探した結果、いい商品に出会えたので紹介します。

エアーウィング・プロ アイボリー - エアコンの直撃風を解消する風よけならダイアン・サービスのエアーウィング|株式会社ダイアン・サービス

株式会社ダイアン・サービスという会社から出ている、エアコンの吹き出し口をガードする商品です。 吹き出し口から出る風の経路が塞がれるので、風が横や上に逃げて直当たりを防ぐというめちゃシンプルな商品です。

エアコンの底面に両面テープで設置し、ガード本体の角度を調整することができます。 安っぽくないのでインテリアの雰囲気も崩れません。 f:id:Labyrinth_of_Wisdom:20180830164750p:plain

【Salesforce】承認プロセスからプロセスビルダーを呼び出す

承認プロセスにおいて、承認時などにアクションを呼び出すことができますが、ワークフローで使用するアクションしか呼び出せないのであまり複雑なことができません。 ですので承認プロセスからプロセスビルダーを呼び出せないかなと思って試してみたらできました! これで少し複雑なこともできるようになります。

まず通常通りに承認プロセスを作成します。 kayakuguri.github.io

承認時などに起こすアクションを設定できると思いますが、ここで「項目自動更新」を選択します。

この「項目自動更新」で更新する項目(チェックボックス型)がTrueになったら動作するプロセスビルダーを作成しておけば、承認プロセスからプロセスビルダーを呼び出すことができるようになります。

一つ注意点としては、「項目自動更新」アクションの設定画面で「項目変更後にワークフロールールを再評価する」にチェックを入れておかないとプロセスビルダーを呼び出してくれないので、気を付けてください。 f:id:Labyrinth_of_Wisdom:20180829115151p:plain

【Salesforce】Dropbox APIを使用してApexクラスからDropboxを操作する(前編)

Dropbox APIを使用して、ApexクラスからDropboxを色々操作してみたのでメモします。

今回は、Dropboxのアカウントは無料のものを使用します。

準備

1.Dropbox API利用者登録

まず下記リンク先でDropbox API利用者登録をします。

https://www.dropbox.com/developers/apps

方法は下記リンク参照。 qiita.com

ここで生成したアクセストークンは後で使用します。

2.リモートサイトの登録

次にSalsforce側でDropbox APIのURLを登録します。

Salesforceにログインし、下記にアクセスしてください。

設定>セキュリティのコントロール>リモートサイトの設定>新規リモートサイト

リモートサイト名には適当な値を入力してください。

今回は、「ファイルの作成」「ファイル名の取得」「ファイルの中身を取得」を行うので、下記のURLをそれぞれ登録します。

//ファイル作成・ファイル名取得に使用
https://api.dropboxapi.com

//ファイルの中身取得に使用
https://content.dropboxapi.com

Dropbox APIの公式サイトです。全編英語です。 www.dropbox.com

日本語でまとめている方がいたので、こちらの方が見やすいです。

Dropbox API v2 仕様まとめ · GitHub

接続

1.ファイル作成

準備が整ったので、実際に接続していきます。 はじめにファイル作成のサンプルを作ってみました。

フィールド変数にアクセストークン用の変数を用意して代入。本当はカスタム設定とかに記載する方が良いんですが今回は省略。 kayakuguri.github.io maroyaka.hateblo.jp

今回はファイル作成なので、ファイル作成用のURLをエンドポイントとして設定。 メソッドはポスト。

アクセストークンをセットし、ファイルの種類と配置先を指定。

これでDropbox内のSalesforce DocumentsフォルダにTest.txtが作成されます。

public class DropboxConnectController {

    //アクセストークン
    private static String acToken = 'Your_Access_Token';

    // ファイル作成
    public void createFileInDropbox(){
        HttpRequest req = new HttpRequest();
        req.setEndpoint('https://content.dropboxapi.com/2/files/upload');
        req.setMethod('POST');

        // アクセストークンをセット
        req.setHeader('Authorization', 'Bearer ' + acToken);
        // ファイルの種類
        req.setHeader('Content-Type', 'text/plain; charset=dropbox-cors-hack');
        // ファイルの格納先
        req.setHeader('Dropbox-API-Arg','{ "path":"/Salesforce Documents/Test.txt" }');
        
        Http http = new Http();
        HTTPResponse res = http.send(req);
        System.debug('ステータスコード:'+res.getStatusCode());
        System.debug(res.getBody());
    }

}

【Salesforce】独自クラスのオブジェクトを作成して画面に表示 (内部クラス)

一通りプログラミングやってきた方には基本的なことだと思うので今さらな内容だと思うんですが、独自クラスでオブジェクトを作るという事の意味が何となく分かったのでメモ。

内部クラスInnerClass

TestInnerClassControllerクラスにInnerClassのリスト型変数icListをフィールド変数としてセットし、get/setしてVFから値を取得・配置できるようにします。

public class TestInnerClassController{

    // フィールド変数
    public InnerClass[] icList {get; set;}
}

このInnerClassという型はSalesforceで用意されている型ではないので、自分でどういう型なのかを設定してやる必要があります。

これが独自クラスを作成するという事になります。

今回はTestInnerClassControllerクラスの中にInnerClassクラスを作るので、内部クラスになります。

    // 内部クラス
    public class InnerClass{
        public String name {get; set;}
        public Integer age {get; set;}
    }

このInnerClassクラスはどういう型なのかというと、String型の変数nameとInteger型の変数ageを変数として持っており、get/setできるようにしています。

これでInnerClassクラスの設定は終わりました。

独自クラスを扱う

InnerClassクラスの設定が終わったので、Salesforceで用意されているString型のように呼び出して使用することが出来ます。

コンストラクタでicListをnewします。

for文を3回ループさせて、icListに要素を追加していきます。

InnerClass型なので、変数nameageを使うことが出来ます。

    // コンストラクタ
    public TestInnerClassController(){
        icList = new List<InnerClass>();
        for(Integer i=0; i<3; i++){
            InnerClass ic = new InnerClass();
            ic.name = 'テスト太郎' + i +'号';
            ic.age = 20 + i;
            icList.add(ic);
        }
        System.debug(icList);
    }

VFで表示する

独自クラスの変数icListに値が格納されたので、Visualforceのapex:pageBlockTableタグなどで複数件表示することが出来ます。

<apex:page controller="TestInnerClassController" >
    <apex:pageBlock title="内部クラステスト" >
        <apex:pageBlockTable value="{!icList}" var="ic">
            <apex:column >
                <apex:outputText value="{!ic.name}" />
            </apex:column>
            <apex:column >
                <apex:outputText value="{!ic.age}" />
            </apex:column>
        </apex:pageBlockTable>
    </apex:pageBlock>
</apex:page>

こんな感じになります。 f:id:Labyrinth_of_Wisdom:20180125111149p:plain

自分で独自クラスを定義してやれば、画面上だけで使用するチェックボックスとかを無駄にオブジェクトのカスタム項目に作らなくていいので便利ですね。

最終的なコントローラはこんな感じです。

public class TestInnerClassController{

    // フィールド変数
    public InnerClass[] icList {get; set;}

    // 内部クラス
    public class InnerClass{
        public String name {get; set;}
        public Integer age {get; set;}
    }

    // コンストラクタ
    public TestInnerClassController(){
        icList = new List<InnerClass>();
        for(Integer i=0; i<3; i++){
            InnerClass ic = new InnerClass();
            ic.name = 'テスト太郎' + i +'号';
            ic.age = 20 + i;
            icList.add(ic);
        }
        System.debug(icList);
    }
}

【Salesforce】表示のみのチェックボックス作成方法

Visualforceで表示のみのチェックボックスを、<apex:outputField>以外で表現する方法ないのかなと思って調べたらありました。

tyoshikawa1106.hatenablog.com

以下サンプルです。

public class CheckBoxController{
    public Boolean checkBox {get; private set;}

    // コンストラクタ
    public checkBoxController(){
        checkBox = true;
    }
}
<apex:page controller="CheckBoxController">
    <apex:image value="/img/checkbox_{!IF(testCheckBox, '', 'un')}checked.gif" title="{!IF(testCheckBox, 'Checked', 'Not Checked')}" />
</apex:page>

<apex:image>valuetitle属性に対象の変数を入れてやればOK。 チェックボックスの画像を引っ張ってきて表示するみたいですね。

少々面倒ですが、この方法を使用すればクラス内で定義したBoolean型の変数もVisualforceでチェックボックス型として使用できます。

apex:outputCheckBoxみたいなタグ作ってくれないですかねー。

【Salesforce】Dropbox for Salesforceで独自のフォルダ階層を作成する

はじめに

DropboxSalesforceを連携する必要があったので試してみました。

基本的な設定は下記リンクを参照してもらえればOKです。 www.terrasky.co.jp

リンク先にもある通り、各種オブジェクトのレコード詳細画面からDropboxにデータをアップすると、基本設定だとフォルダの階層が以下になります。 ※対象オブジェクトを取引先として話を進めます。

\Dropbox\SalesforceDocuments\取引先\レコードの名前

今回僕がやりたかったのは、これを下記の様なフォルダ階層にしたいという事でした。

\Dropbox\SalesforceDocuments\取引先\得意先\レコードの名前

取引先の中でも得意先とそうじゃないものにフォルダ分けしたい、みたいな感じですね。

設定方法

方法はDropboxの公式に載ってました。リンク先の独自のフォルダ名構造を作成するという所です。

Salesforce 向け Dropbox:管理者の高度な設定 – Dropbox

ただ具体例がないのでよく分からないなと思い、色々試してみたら何とか出来ました。

まずカスタム項目「得意先」チェックボックス型で作成します。API名は「Tokuisaki」です。

次にカスタム項目「カスタム Dropbox パス」を数式のテキスト型で作成します。API名は「Custom_Dropbox_Path」です。

返ってくる値の式を以下のようにします。

IF(Tokuisaki__c, '取引先/得意先/' & Name & '/',  '取引先/' & Name & '/')

これで得意先のチェックがついた取引先レコードにファイルをアップしたら、独自のフォルダ階層が実現できます。

\Dropbox\SalesforceDocuments\取引先\得意先\レコードの名前

得意先にチェックがついてなかった場合は通常通りのフォルダ階層になります。

\Dropbox\SalesforceDocuments\取引先\レコードの名前

【Salesforce】一定の文字数で改行して画面に表示する方法

Visualforceで一定の文字数を指定して自動改行をするメソッドを作ったので、自分用にメモ。

意外と使いどころが多いんじゃないかと思います。PDFページとか文字が突き抜けでしまうので。 cloudcompass.seesaa.net

Apexクラス

第一引数に改行したい文字、第二引数に改行したい文字数を指定。

\r\nを削除している行がありますが、これはオブジェクトのテキストエリア型などから値を取得してくる場合に有効なので書いています。

decimalStRowsを取得する部分も、Salesforceが勝手に四捨五入するという動きがあるので、確実に処理するためにDecimal型にしてます。(これをやらないと値が揺れる)

public class kaigyoTextController {
      
    public String kaigyoText {get;private set;}
    
    public kaigyoTextController(){
        kaigyoText = autoKaigyo('あいうえおかきくけこ', 4);
    }
    
    private String autoKaigyo(String st, Integer kaigyoLength){
        String rtnSt;
        Integer stLength = st.length();
    // 改行コード削除
        st = st.replaceAll('\r\n','');

        // 文字が空白、または文字数が指定改行文字数以下の場合はそのままの値を返す
        if(String.isBlank(st) || stLength <= kaigyoLength){
            rtnSt = st;
        }else{
            // 小数点を出す為にDecimal型で計算
            Decimal decimalStRows = Decimal.valueOf(stLength) / Decimal.valueOf(kaigyoLength);
            // 切り上げ処理で内容の行数を取得
            Integer stRows = Integer.valueOf(decimalStRows.round(System.RoundingMode.UP));
            // 最初の改行まで取得+改行コード付与
            rtnSt = st.substring(0, kaigyoLength) + '<br/>';
            // 2行目以降をループ処理
            for(Integer i = 1; i < stRows; i++){
                if(kaigyoLength*(i + 1) < stLength){
                    rtnSt += st.substring(kaigyoLength*i, kaigyoLength*(i + 1)) + '<br/>';
                }else{
          // 最後の文字まで取得
                    rtnSt += st.substring(kaigyoLength*i);
                }
            }
        }
        return rtnSt;
    }
}

Visualforce

フィールド変数kaigyoTextをgetしているのでそれを表示しているだけです。 ただし一点注意点として、escape属性をFalseにしてやらないと、コントローラで追加した<br/>が効かないので注意してください。

<apex:page controller="TestFormController" >
    <apex:outputText value="{!kaigyoText}" escape="false" />
</apex:page>

f:id:Labyrinth_of_Wisdom:20171005115511p:plain