こんにちは!
株式アクシスのアドベントカレンダー14日目担当山内です!
2回目の投稿ということで何を書こうか迷っていましたが、最近は案件でsalesforceを触っているので、salesforceについて色々書いていこうと思います。
色々とはいいましたが、特に過去のエラーなどを書き溜めたりしていないので汗、思い出しつつ、これからも追記しつつやっていこうと思います。
already output
先日こんなエラーと(厳密にはデバッグログ)に出会いました。
DEBUG|{-1.00=(-1.00), 1.00=(already output), 1.50=(already output), 1.75=(already output)}
お、おーるれでぃあうとぷっと!?
まったくもって意味不明でした。
発生した状況としてはこんなイメージ。
Map<String, List<String>> map = new Map<String, List<String>>();
List<String> list = new List<String>();
for(Integer i = 0; i < 10; i++) {
    list.add(i);
    map.put("hoge", list);
    list.clear();
}
これの何がいけないかと言うと、for文の中の最終行、list.clear()がNG。
これがlist = new List<String>ならOK。
公式ドキュメントによると
循環参照で使用する場合、出力は無限再帰を防ぐために切り捨てられます。大きなコレクションに使用する場合、合計ヒープサイズと最大 CPU 時間を超えないように出力が切り捨てられます。
コレクションごとに最大 10 項目が出力に含まれ、その後に省略記号 (…) が続きます。
同じオブジェクトがコレクションに複数回含まれている場合、そのオブジェクトは出力に 1 回のみ表示されます。後続の参照は (already output) と表示されます。
引用:Mapクラス
最後の方に書いてますが、一つのオブジェクトをputで詰めていいのは一回までのようです。
調べれば結構する出てきたんですが、「ん、なんだ?」ってソースコードを眺めていたので、混乱しましたw
visualforceでの連動項目
salesforceのオブジェクトには選択リストというものがあります。
この選択リストは他の選択リストと連動関係になれます。まあ、いわゆる親子みたいな。
たとえば親フィールドがParents__c、子フィールドがChild__cだとします。
それをvisualforceで以下のように書きます。
<apex:inputField value="{!Parent__c}">
<apex:inputField value="{!Child__c}">
こう書くだけで、それぞれがセレクトボックスで表示されます。
そして親を選択すると、その親に紐づく子のみが選択できる状態になります。
親に紐づく子がいない場合は、子のセレクトボックスはdisabledになります。
すばらしい!
サポートされていないカスタム項目のデータ型を変換しようとしました。
これは変更されたオブジェクト定義のメタファイルをデプロイしようとしたときに発生したエラ-です。
今回僕がこのエラーに遭遇したケースは、管理者がオブジェクトのデータ型を変更して、その変更した状況に合わせようとして、オブジェクト定義のメタファイルを更新した。という状況です。
コード上でそのデータを使用している場合は基本的に型の変更ができないようです(使用としたらエラー出た)。
なのでその管理者も、一つ一つコメントアウトしていってからデータの型を変更したそうなので、まあ、とくにかく大変です。。。
選択リストの値を取得する
選択リストの値を一覧で取得したいってことはあると思うし、なんか簡単に取れると思うんですが、ほんのちょっとだけ面倒なんですよね。
例えばさっきのParent__cを例に取ると、このParent__cはFamilyというオブジェクトのフィールドだとすると、
Family__c.Parent__c.getDescribe().getPicklistValues();こうするとPicklistEntryクラスというListが取得できて、そのPicklistEntryクラスのgetLabelメソッドとgetValueメソッドで選択リストのlabelとvalueが取得できる。
んー、なんかスッテプが多いんだよなぁ。
全角数字を半角数字に
まあsalesforceうんぬんの話ではないですが、apexでこう書いたよってのを備忘録的に記載。
public static String replaceFullToHalf(String str) {
    List<Integer> codePointList = new List<Integer>();
    for (integer i = 0; i < str.length(); i++) {
        // 文字のコードポイント取得
        Integer codePoint = str.codePointAt(i);
        // 1~9(全角)
        if (65296 <= codePoint && codePoint <= 65305) {
            // 全角数値を半角数値に変換してリストに追加
            codePoint -= 65248;
            codePointList.add(codePoint);
        } else {
            // 半角数値以外はそのままリストに追加
            codePointList.add(codePoint);
        }
    }
    return String.fromCharArray(codePointList);
}
思考停止のコピペで動くはずです。
随時追加してきたい
とりあえずこのくらいです。
思い出したら追記していって、モリモリにしていこうと思います。
あとどれくらいsalesforceしているかはわかりませんが。。。w
結構便利なとこがあったり、「んんんんーっっ!!?」って思うとこもあったり、結構毎日新しいことがあるので、結構楽しくsalesforceを触ってます。
結論:型推論のない静的型付け言語は面倒くさい。