2012年5月7日月曜日

外部ファイル出力について-その2

外部ファイルのリンクを作成する場合、普通にaタグでリンクさせるとファイルは出力されるもののページも遷移してしまい、何もない画面になってしまいます。ヘッダーも表示されないので戻るボタンを押すしかなく、少々具合が悪いです。
この問題は非表示のインラインフレームを作成することで回避可能です。具体的には以下のようなコードになります。
   Visual Force Page

2012年5月2日水曜日

外部ファイル出力について-その1

SalesForceのレポートは簡単かつ強力なのですが、お客様によってはExcelでの出力を求められる機会は少なくないと思います。そこでWord,Excel,PDFの各形式でのファイル出力を試してみました。

まず、もとになる表をVisualForceで作成してみます。
今回はコントローラを使用せず、単純にTableタグで作成された表を使用します。(素材はこちらのサイトを使用させていただきました。)
このページのapex:pageタグはこのようになっています。なにもありません。
   Visual Force Page


1.Microsoft Word

apex:pageタグを以下のように編集すると、Microsoft Word形式で出力できます。
   Visual Force Page

captionタグ、thタグで囲まれた部分は、改ページ時に次ページ以降にも列見出しとして継承されていることがわかります。また、わかりずらいのですが表の中のリスト項目に注目してください。このリストの要素はcodeタグで囲まれているのですが、この部分は自動的に等幅フォント(MSゴシック)が使用されています。
なお、ファイル名の拡張子をdocxとするとエラーになります。


2.Microsoft Excel

apex:pageタグを以下のように編集すると、Microsoft Excel形式で出力できます。
   Visual Force Page

セルの結合もきちんと反映されています。codeタグで囲まれた部分も等幅フォントになっています。ただし、印刷時にWordのような見出し行の固定は設定されませんでした。
当然、計算式を埋め込んだりもできません。


3.PDF

PDFの場合は、MSOffice系とは方法が異なります。VisualforceからPDF出力をする場合、pageタグのrenderAs要素に"PDF"を設定するのですが、そのままではブラウザに表示されてしまいファイルに名前を付けて保存することができません。そのためPDFで書き出すページをインクルードさせてファイル出力を行います。従って、VisuarForceページは、2つ必要になるわけです。
まず、ファイルを出力するページは、こんな感じです。出力対象ページをインクルードしているだけの簡単なものです。
   Visual Force Page

次にインクルードされるページです。PDF出力する場合は、ヘッダーに書式を書かなければなりません。
書式の書き方はこちらのサイトを参考にさせていただきました。
   Visual Force Page
どうもPDFの書式設定はあまり自由度がないみたいなので(特にフォントまわり)、Office環境があるなら、WordかExcelで出力したほうが見栄えは良くできそうです。

2012年5月1日火曜日

date型とdatetime型についてあれこれ-その2

続きです。

4.和暦変換
APEXには残念ながら元号は用意されていないので、和暦の変換は関数を作る必要があります。

   APEX クラス

日付型の比較対象データを作成するのに、date.newinstance()を使用しない方法がありそうなのですが、
今のところ良い知恵がありません。

date型とdatetime型についてあれこれ-その1

SalesForceのdatetime型の取り扱いは少々注意が必要です。

1.現在の取り方の違い
データ型メソッド結果
date型date.today()Tue May 01 00:00:00 GMT 2012
datetime型datetime.now()Tue May 01 06:31:59 GMT 2012
string型に変換datetime.now().format('yyyy/MM/dd hh:mm:ss')2012/05/01 03:31:59

datetime型でタイムスタンプを取得する場合、now()を使用するとタイムゾーンがGMTで返ってきてしまいます。
formatを使用すると、ローカルのタームゾーンに変換されます。datetime型の場合、メソッドを活用することでタイムゾーンを変えることができます。
詳しくはこちら。http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_datetime.htm

2.date型のフォーマット
date型のフォーマットは、書式を細かく設定するものではないようです。
date.today().format('yyyy/MM/dd') は、エラーになります。
date型のフォーマットは、ユーザーのロケーションに合わせた日付の形式に変えてくれるだけのようで、
date.today().format() とすると、単純に 2012/05/01 という文字列が返ってきます。

3.datetime型のフォーマット
datetime型のformatメソッドの書式はJavaと同様です。VB出身者はフォーマットの書式で戸惑うかもしれません。
ポイントは大文字と小文字で意味が異なるという点です。
書式結果
yyyy/MM/dd hh:mm:ss2012/05/01 04:00:29 ○
yyyy/mm/dd hh:mm:ss2012/00/01 04:00:29 ×
yyyy/MM/DD HH:MM:SS2012/05/122 16:05:759 ×
YYYY/MM/DD HH:MM:SS は、エラーになります。

参考:書式パターン文字一覧
文字説明
G 紀元 AD
y 1996, 96
M July, Jul, 07
w 年における週 27
W 月における週 2
D 年における日 189
d 月における日 10
F 月における曜日 2
E 曜日 Tuesday, Tue
a 午前/午後 PM
H 一日における時(0~23) 0
k 一日における時(1~24) 24
K 午前/午後の時(0~11) 0
h 午前/午後の時(1~12) 12
m 30
s 55
S ミリ秒 978
z タイムゾーン Pacific Standard Time, PST, GMT-08:00
Z タイムゾーン -0800

2012年4月13日金曜日

複数の言語が含まれているデータをインポートする


ひとつのオブジェクトの中に、複数の言語が存在するデータをインポートする方法です。
例えば、何かの名称のマスターとして使用する場合に、日本語名、英語名、韓国名、中国語名のカラムがある場合のデータインポート方法です。
オブジェクトを作成し、名称を翻訳サイト等で変換しながら各項目に入力してみると、問題無く各言語が登録できます。
しかし、データローダを使用する場合はどうでしょうか?

ExcelでCSVを作成する場合、文字コードがShift-JISで保存されます。そのため、保存したCSVをメモ帳で開くと、韓国語や一部の中国語が文字化けしているのがわかります。
このファイルをデータローダに読み込ませても、文字は化けたままです。したがって、UTF-8に正しく変換されたCSVを用意する必要があります。

なんとかExcelのデータをUTF-8で保存できないかと調べたところ、Excel2007では「Web文書」で保存する時にオプションでUTF-8が選べることがわかりました。

以下、具体的な方法です。
「名前を付けて保存」ダイアログのツールメニューからWebオプションを選択します。
エンコードを「Unicode(UTF-8)」に設定します。
文書形式を「Webページ」で保存すると、UTF-8にエンコードされたデータが保存されます。
しかし、この文書はHTMLなので当然データローダにかけることはできません。また、ブラウザの画面をコピーしてメモ帳に貼り付けても、CSVにはなりません。

そこでExcelの計算式を利用して、カンマ区切りのデータを1セルに納めてしまいます。

再度「Webページ」で保存し、ブラウザで開きます。
文書全体を選択し、メモ帳に貼り付け、CSV形式で保存すると、データローダで読み込める多言語のCSVファイルになります。

多少面倒ではありますが、1件ずつ手打ちするよりは良いと思います。

2012年4月6日金曜日

VisualForceで jQuery Mobile を使用する。

SalesForceがMobileSDKと関連ドキュメントを続々リリースしているようなので、この先あまりニーズは無いかもしれませんが、VisualForce での jQuery Mobile を使用する場合のポイントです。

1.jQueryの取得
jQueryのホームページから、jQuery、jQueryMobileのリソースをダウンロードし、静的リソースに格納。
なお、CSSはThemeRollerを使うと便利ですが、このへんの使い方は割愛します。

2.VisualForcePageの作成
VisualForceでjQueryMobileを使用するには、VisualForce内にhead部とbody部を作成し、通常のjQueryMobileと同様のコードを書けば、問題無く動作します。
タグと静的リソースの参照は以下のようになります。
   Visual Force Page

ポイント1
<apex:page>
タグの"standardStylesheets"を"false"にすること。こうしないとページにSalesForceのスタイルシートが適用されてしまいます。

ポイント2
機器の縦横の向きを変更した場合に、自動的に表示幅を合わせるために、metaタグでviewportの設定をしています。jQueryMobileのサンプルでは、
<meta name="viewport" content="width=device-width, initial-scale=1"/>
となっていますが、これだとiPhone,iPadではうまく動作しませんでした(横向きにしたときにサイズがオーバーする)。
<meta name="viewport" content="width=device-width, minimum-scale=1, maximum-scale=1"/>
とすることで、正しく表示されるようになりました。

なお、一応これでVisualForceの画面がモバイルサイトっぽくなりますが、あくまでこれは個別のページをjQueryMobileで表示しているに過ぎず、ログイン画面やホーム画面はPC用の画面のままということになります。

2012年3月30日金曜日

VisualForceからJavaScriptを経由してApexのメソッドにパラメータを渡す。

VisualForceからApexのメソッドにパラメータを渡す。 の発展形です。
VisualForceからJavaScriptを経由してApexメソッドにパラメータを渡します。

基本は以下の株式会社ウフル様の技術ブログに書いてある通りです。
[salesforce]JavaScriptからVisualforceコントローラのメソッドにアクセスする方法

以下、実際自分が作成したコードを、パラメータの流れを追う形で整理してみます。

1.JavaScriptの呼び出し
VisualForceのコマンドボタンから、JavaScriptの関数を呼び出します。
JavaScriptには、引数'hoge'が渡されます。
   Visual Force Page

2.JavaScriptから、ActionFunctionの呼び出し
1で引数として渡された値をもとに、色々とJavaScriptの処理を行います。
ここでは単純にapex:actionFunctionの引数として使用します。
ActionFunctionの関数名は、actionfunctionタグの"name"属性に定義されている名称です。
   JavaScript

3.ActionFunctionからコントローラのApexメソッドを呼び出し
ActionFunctionの"name"属性には、このActionFunctionの名前を定義します。
そして"action"属性には、コントローラのメソッド名を設定します。
JavaScriptから渡されたパラメータは、"apex:param"タグで定義されたパラメータで受け取ります。
なお、ActionFunctionは、不要でもreRender属性を設定しないと動かないようです。
   Visual Force Page

4.Apexメソッドの実行
コントローラ側では、パラメータを受け取るための変数を用意し、getparametersメソッドを使用して、パラメータを取得します。この際、getに設定するパラメータ名は"apex:param"の"name"属性に設定した名称になります。
   コントローラ

これで、VisualForceからコントローラのメソッドを呼び出す前に、JavaScriptでいろいろとできるようになります。

2012年3月23日金曜日

メールサービスの利用について-受信

メールを受信して、その内容をオブジェクトに取り込むこともできます。

まずMessaging.InboundEmailHandler インターフェースを実装した Apex クラスを作成します。
このクラスの作成方法は、メールサービスの設定画面を開くと表示されます。






Force.com IDE を使う場合はAPEXクラスの新規作成時にテンプレートが用意されています。







   APEXクラス


本文にルールを決めて個別の項目に振り分けることもできるみたいです。

クラスができたら、メールサービスを設定します。
メールサービスから、新規メールサービスを選択し、各種設定を行います。
次に新規メールアドレスをクリックして、メールサービスのメールアドレスの設定をします。設定後に固有のメールアドレスが作成されます。
このアドレスにメールを送ると、上記のクラスを介してオブジェクトにデータとして取り込まれます。
SalesForceから発行されるメールアドレスは長いので、別途メール受付用のアドレスを独自ドメインで取得し、メールサービスのアドレスに転送するのが現実的だと思います。内容やタイトルによるアドレスの振り分け等も転送する側に設定したほうが、後々便利だと思います。

やってみると、あっけないくらい簡単です。

メールサービスの利用について-送信

これは完全に私自信の備忘録になります。

1.トリガでメール送信を行う。
なにかデータを更新した際に、メールで通知を行う場合です。
このような処理では、ワークフロールールを用いて、メールアラートを実行させるのが一番簡単です。しかしより複雑な機能を持たせたい場合には、トリガ内でメールサービスを利用する必要があります。

まずは、管理者設定のメール管理から、組織のアドレスを設定を選択して、組織のメールアドレスを追加します。これを差出人のメールアドレスとして使用します。ワークフロールールを使用する際にもこの設定を使うことができます。

あとはトリガに処理を書いていきます。
   APEXトリガ

実際はもっと例外の処理とか入れてますけど、メール送信の部分だけ抜き出すとこんな感じになります。
メール本文にはメールテンプレートが使えそうですが、そこまでは試してません。

デプロイでつまずいたことまとめ-その1

初めてのデプロイで、初歩的なことからつまずきまくったのでメモ。

1.作業の流れ
  1. Force.com IDEで、全オブジェクトを取得。
    (今回はVisualForcePageのデプロイは無し)
  2. DevelopperForceでテストコードを流し、コードカバー率が足りていることを確認。
  3. 本番環境に初期設定するデータを用意。必要があれば、開発環境からデータローダでエクスポートしておく。
  4. 本番用の組織にログイン。新規アプリケーションの設定。アプリケーションのロゴも登録。
  5. メール送信用に組織で使用するのメールアドレスを登録。
  6. Force.com IDEを使用して、オブジェクトをデプロイ。
  7. 続いて、タブ、レイアウト、ワークフロー、レポート、ダッシュボード等をデプロイしていく。
  8. クラス、コードをデプロイする前に、ここまで正しくデプロイされていることを確認。
  9. アプリケーションに表示タブを登録
  10. プロファイルでデプロイしたアプリケーションの各種設定を行う。
  11. Force.com IDEを使用して、Apexクラス、トリガをデプロイ。
  12. メールサービスの設定
  13. データローダで初期設定データをインサート
2.つまずいたこと
  • データローダの接続先を変更するときに、パスワードにセキュリティートークンを付加しなければならない。これに気がつかずなぜログインが拒否されるのか、しばらく悩むことに。
  • 初期設定データを本番環境にインサートする前にテストコードを実行。入力必須項目が参照項目だったために、テストデータ入力時にエラー。本来は参照対象となるデータもテストコードの初期処理の中で作成しておくべき。
  • オブジェクトに参照先が未定義の検索項目があり、エラーになった。IDEでobjectファイルを開いてみると、確かに該当するタグが残っていた。IDEでタグを削除したところ、正常にデプロイ。DevelopperForceで動いていても、ゴミが残ることがあるようだ。
  • DevelopperForce上で機能していたテストコードが、デプロイ時にエラーとなる場合、ログを見るとエラーになった理由がきちんと記載されている。英語だがかなり具体的にエラー個所を指し示してくれている印象。かなり助かる。調べてみるとほとんどはテストコードのエラーではなく、環境の設定漏れ等からくるテスト対象のリソースで発生するエラーだった。ここを勘違いしてテストコードを修正して乗り切ろうとするとどんどん深みにハマる。
  • デプロイ時のテストにインサートの処理が含まれていると、自動採番の値がカウントアップされてしまう。
    おなじみウフルさんのブログにも書いてありました。
    [salesforce]テストコード内からレコード作成時に自動採番項目がカウントアップされてクリアできない問題
  • クラスやトリガは、可能な限りいっぺんにデプロイしたほうが良さそう。今回、個別にデプロイしたためにデプロイする順番で多少苦労した。つまり、クラスBのメソッドをトリガAで呼び出しているときには、当然クラスBからデプロイしなければならない。
  • ワークフローについては、DevelopperForceのルールの名称とForce.com IDEで取得したワークフローの名称が異なるので注意が必要。Force.com IDEのワークフローは、オブジェクト単位でまとめられてるっぽい。

ほんとにサンプル用の小さなアプリだったのに、試行錯誤で丸一日かかってしまいました。経験豊富な方々は効率的なやり方を知ってるんだろうな。
そのへん、ぜひ聞いてみたい...。

2012年3月20日火曜日

VisualForceからApexのメソッドにパラメータを渡す。

一覧表画面を作成して、そこから詳細画面にリンクする仕組みを作成しています。

いちばん簡単なのは一覧表の項目にoutputlinkを設定する方法です。
   Visual Force Page
しかし、今回は画面が遷移する前に固有の処理を追加したいので、APEXのメソッドを使用することにします。
固有の処理の部分では、レコードのidを使用したいので、パラメータとして渡します。
   Visual Force Page
メソッドにパラメータを渡す時には、メソッドのパラメータ名(name)と、パラメータの受け渡しに使用するインスタンスの指定(assignTo)の両方が必要です。

で、こちらが受け取る側。
   コントローラ

1.5時間悩みました...。
最近英語のサイト見るのが苦でなくなってきた気がします。

コントロールのサイズ変更-その2

2.ラジオボタンのサイズ変更
ipadを使用して、お客様にアンケートを入力していただく場合などには、便利なのではないかと思います。
ラジオボタンでは、styleに直接スタイルを定義して、サイズを整えます。

本当は、ここでもスタイルシートを別に定義して、styleclass属性に設定してみたのですが、うまくいきませんでした。
おそらく何か方法があるはずなんですけれど、今のところこの方法でしか実現できていません。






このくらいだと、指でも操作しやすいのではないでしょうか。ちなみに、ボタンでなくラベルの文字にタッチでOKです。

2012年3月19日月曜日

コントロールのサイズ変更-その1

VisualForceを使うと、比較的容易にSalesForceと同じような画面が作成できます。しかも、画面のカスタマイズの自由度は想像以上に高いです。少しコードを追加するだけで、SalesForceの画面をぐんと使いやすくできます。

1.ボタンのサイズを変更する。
SalesForceのデフォルトではボタンのサイズについては特に設定していないらしく、Valueで設定した文字でサイズが表示されます。




ボタンのスタイルはCSSのbtnクラスで上書きすることが可能です。以下のようなスタイルシートを設定してみます。
   CSS

   Visual Force Page

こんな感じになります。

しかも、pageBlockButtunsの中だけでなく同一ページのボタンは全てこのサイズで統一されるので、万一折り返しが発生しても見栄えがスッキリします。

入力画面をキャンセルした時に入力チェックが邪魔をする。

オブジェクトの新規入力画面を作成して、独自に「キャンセル」ボタンを作成しました。デフォルトのcancelアクションとは別のページに遷移させたかったので、コントローラにメソッドを追加しました。ところが、キャンセルボタンを押したところで入力チェックに引っかかってしまい、ページが遷移しません。
入力必須項目が未入力のため、エラーになってしまうのです。

いろいろ調べた結果、回避は簡単でした。commandbuttonのimmediate属性をtrueにするのです。

   コントローラ

   Visual Force Page

これで、入力チェック抜きで希望のページに遷移することができました。

20分くらい悩んだかも...。

HTTP通信のサンプルが使えなくなっていた。

HTTP通信を試したくて、下記のページにを参考にテストを試みた。

AJAX ProxyでWebサービスマッシュアップ
ところが、サンプルコードで参照しているHotPepperのAPIの仕様が変わってしまったらしく、うまくいかない。
で、いろいろ試行錯誤して、やっとうまくいったのでコードを載せておきます。
実行するためには、リクルートWEBサービスにて、 APIキーを取得しなければなりません。下記のコードの****************の部分を取得したAPIキーで書き換えて下さい。

   Visual Force Page

3時間くらい格闘してしまいました...。

2012年3月18日日曜日

カスタム設定を使用したコード項目の使用-その4

4.カスタム設定項目の参照をテストする場合の注意点

カスタム設定項目の参照を含むコードのテストをする場合、テストコードのアノテーションに
SeeAllData=true
を付け加えなければなりません。

付け加えずにテストを実行すると、カスタム設定のオブジェクトがNullとなり、以下のようなエラーになります。
FATAL_ERROR|System.NullPointerException: Attempt to de-reference a null object

これだけのことで半日悩んでしまいました...。

カスタム設定を使用したコード項目の使用-その3

3.VFの画面上にカスタム設定の表示名を出力する。

コードの取り扱いには、もうひとつ解決しなければならない問題があります。
通常のデータ閲覧をする場合、そのまま画面上に表示しようとすると、性別の値に1または2という コードの値がそのまま表示されてしまいます。
そのため、別途関数を用意して表示名(男・女)を画面上に出力しなければなりません。

   コントローラ
※lstはコンストラクタで読み込んでいるデータリスト。
コードが設定されている項目は必ず画面上に読み込まれていなければなりません。

   Visual Force Page

このようにに表示されます。

2012年3月2日金曜日

カスタム設定を使用したコード項目の使用-その2

2.セレクトオプションに値を読み込ませる。

では、設定したカスタム設定の値を、実際にセレクトオプションの値として使ってみましょう。
今回参考にしたのはこちらのサイトです。
Using List Custom Settings in Salesforce.com
http://blog.jeffdouglas.com/2010/01/07/using-list-custom-settings-in-salesforce-com/

あと、オプションリストはソートが効かないので、下記のAPEXクラスを導入します。
abhinavguptas / Apex-Select-Option-Sorting -- SelectOptionSorter.cls
https://github.com/abhinavguptas/Apex-Select-Option-Sorting

   コントローラ

   Visual Force Page
コントローラでSelectOptionsが設定されれば、選択リスト、ラジオボタン、チェックボックスのどれでも使えるようになる。

選択リストの表示
ラジオボタンの表示 ラジオボタンを縦に並べる場合は、layoutにpageDirectionを設定します。
チェックボックスの表示
できあがりはこんな感じです。


データを1件作成してしまえば、データローダでダウンロードしてEXCEL等で追加データを作成、データローダでアップロード、という方法でコード類のメンテナンスが容易になります。

カスタム設定を使用したコード項目の使用-その1

カスタム設定は、項目数が少なく編集の頻度が低いコード類の管理用に使えます。 SalesForceでは、区分等を選択して入力する場合は第一に項目のデータ型に選択リストを使用するのがセオリーなのだと思いますが、 選択リストの選択肢のメンテナンスは、少々手間がかかります。
カスタム設定を使用する利点は、データのメンテナンスにデータローダが使えることです。初期設定やメンテナンスもぐんと楽になり、 使用するにあたってもSOQLを使うことなく簡単に値を呼び出すことができます。
※ カスタム設定を使用したページのソースを見ると、カスタム設定の値が丸ごと読み込まれていることが確認できます。
また、選択リストは設定した値がそのままオブジェクトに保存されてしまうのに対し、カスタム設定を使用すれば、画面に表示する値と実際にオブジェクトに格納する値を別けることができます。

1.カスタム設定の作成
コード項目ごとにカスタム設定を作成していきます。今回は例として性別コードを設定してみます。

性別コード(CSGender__c)を作成する。

設定種別
階層と、リストが選択できるが、今回は単純にリストを選択します。

項目
Name   ←名称固定。実際のコードを指定する。重複は不許可
DispName   コードに対応する表示名
Deleted   削除フラグ(trueの場合は選択肢として表示しない。)
カスタム設定の値を取得する関数getInstanceは、Nameがキーになります。

サンプル
Name  DispName  Deleted  
1false
2false

こんな感じです。

データを1件作成してしまえば、データローダでダウンロードしてEXCEL等で追加データを作成、データローダでアップロード、という方法でコード類のメンテナンスが容易になります。

VisualForcePageにおけるオブジェクトの項目の参照

ヘルプテキストを画面上に表示
「account」オブジエクトの、「type」項目に設定したヘルプを画面上に表示します。

項目の表示ラベルを画面上に表示
「account」オブジエクトの、「type」項目の表示ラベルを画面上に表示します。