apex:pageBlockTableの幅を画面幅以上にする方法
apex:pageBlockTableを使うとTableの幅が画面幅に設定されてしまい、列の数が多い際には、一列あたりの表示幅が狭くなってしまいます。
apex:pageBlockTable を
<div style="width:140%"> <apex:pageBlockTable value="{!accs}" var="acc" > .... </apex:pageBlockTable> </div>
Apex Data Loaderで使用される文字コード
CSVファイルを利用してSalesforceへデータをアップロードする。もしくはSalesforceのデータをCSVファイルとしてダウンロードする際には、Apex Data Loaderが便利です。このApex Data Loaderで利用可能なCSVファイルの文字コード(エンコーディング)として、以下のものが利用可能です。
- UTF-8
Data Loaderのメニューから[setting] > [settings]と移動し、[Read all CSVs with UTF-8 encoding]を選択すると、ファイルがUTF-8であるものとしてCSVファイルが読み込まれます。 - MS932(Shift_JIS)
日本語Windows環境では、なにも設定を行わなければ、CSVファイルがMS932であるものとして読み込まれます。これは、DataLoaderが内部的にJavaの標準ライブラリのjava.io.FileReaderをつかっているからです。FileReaderは、JVMのデフォルト・エンコーディング(file.encoding)を利用してファイルを読み込みます。
もし、日本語OS以外でData Loaderを利用する場合は、Shift_JISのファイルを読み込めませんので注意が必要です。そのような場合は、CSVファイルをUTF-8で用意した上で、[Read all CSVs with UTF-8 encoding]にチェックをつけます。
[参考情報]
Apex Data Loaderのソースコード
http://sforce-app-dl.cvs.sourceforge.net/viewvc/sforce-app-dl/apexdataloader/src/com/salesforce/dataloader/dao/csv/CSVFileReader.java?revision=1.1&view=markup
152行目のopenというメソッドでファイルの読み取りをおこなっています。
XMLデータの処理
目的
Apexコードのなかで、XMLを処理する方法をとりあげます。
例として、前回取り上げた、Kakaku.comのAPIのデータ取得結果(XML)を処理してみます。
ポイント
XMLを扱うためのApex標準クラスとして、XMLStreamReader/XMLStreamWriterが用意されていますが、これらは比較的低レイヤのAPIのためこれらのクラスをそのまま利用するのは煩雑です。
オープンソースのライブラリとしてXML Dom parserというのがあり、これを使うとXMLのDOM APIを利用できますので、今回はこのXMLDomを使ってみましょう。
XML Dom parser
http://developer.force.com/codeshare/apex/ProjectPage?id=a0630000002ahp5AAA
以下のURLから、XMLDom.clsとXMLDomTest.clsをダウンロードし、各クラスを環境に作成しておきます(現時点でのDeveloper Editionでは、初期状態からXML Domがインストールされています)。
http://code.google.com/p/visualforce-components/source/browse/trunk/XmlDom/src/unpackaged/classes/
サンプルコード
以下のXMLを処理するコードを書いてみます。
<BBSInfo> <ProductID>01309511986</ProductID> <NumOfResult>5</NumOfResult> <Item> <ThreadTitle>バッテリー消費激しい</ThreadTitle> <ThreadId>9687067</ThreadId> <ThreadClass>0</ThreadClass> <ThreadUrl>http://bbs.kakaku.com/bbs/-/SortID=9687067/</ThreadUrl> <ThreadSummary>アプリ利用時のバッテリー消費が著しいように思います。バッテリログというアプリを入れて確認したところネット非接続・位置情報サービスオフでも20分程度の使用で残量が20〜30%程度減ります。…</ThreadSummary> <NickName>passatb5</NickName> <NumOfResponse>7</NumOfResponse> <WrittenDate>2009/06/12 9:16:43</WrittenDate> </Item> <Item> <ThreadTitle>Mac版ネットブック的な利用をしたいのですが…。</ThreadTitle> <ThreadId>9573279</ThreadId> <ThreadClass>0</ThreadClass> <ThreadUrl>http://bbs.kakaku.com/bbs/-/SortID=9573279/</ThreadUrl> <ThreadSummary>おはようございます。Mac版ネットブック的な利用をしようと考えて、購入しました。がしかし、自分の使用したい建物が無線LANスポットではないので、上手く活用できません…。ソフトバン…</ThreadSummary> <NickName>ぶっち624</NickName> <NumOfResponse>3</NumOfResponse> <WrittenDate>2009/05/20 7:09:16</WrittenDate> </Item> </BBSInfo>
このXMLが文字列変数contentに格納されている場合に、XMLから各要素の情報を取り出すコードです。
public void parseContent(String content){ // XMLをStringの変数に格納する // XMLの文字列を与えて、XMLDomを初期化する XMLDom dom = new XMLDom(content); // XMLの中から、Item要素を抽出する(複数返ってくる可能性あり) List<XMLDom.Element> items = dom.getElementsByTagName('Item'); for (XMLDom.Element item:items){ // item要素の子要素からThreadTitleとThreadIdを取得し、ノード値を取得 System.out(item.getElementByTagName('ThreadTitle').nodeValue); System.out(item.getElementByTagName('ThreadId').nodeValue); ....
HTTPで外部サイトから情報を取得する
ポイント
サンプルコードを実行する前に、実行する組織でリモート・サイトの登録を行っておく必要がある。
[設定] > [管理者設定] > [セキュリティのコントロール] > [リモートサイトの設定]
ここで、接続先のURLを設定する。今回は価格.comのAPIにアクセスするので、リモートサイトのURLとして
http://api.kakaku.com を登録する。
サンプルコード
public class ProductMessage { public String getMessageContent(){ // HTTP接続に必要名HTTP、HTTPRequestクラスを初期化する HTTP h = new HTTP(); HTTPRequest req = new HTTPRequest(); // 指定したURLにGETメソッドで接続する String url= 'http://api.kakaku.com/Ver1/BBSInfo.asp?ProductId=01309511986&SortOrder=Code&Filter=1'; req.setEndpoint(url); req.setMethod('GET'); // 実際に接続を行う HTTPResponse res = h.send(req); // HTTP Bodyを取得する return res.getBody(); } }
制限事項
接続先のポート番号には、以下の制限があります。
- 80: このポートは、HTTP 接続のみを受け付けます。
- 443: このポートは、HTTPS 接続のみを受け付けます。
-7000-10000 (7000 と 10000 も含む): これらのポートは、HTTP 接続または HTTPS 接続を受け付けます
参考資料
Force.com Apex Code Developer's Guide
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_restful_http_httprequest.htm#kanchor774
ポータルユーザとして登録されている取引先責任者のIDから、ユーザ情報を取得する
目的
ポータルユーザとして登録されている取引先責任者のIDがわかっている時に、対応するユーザ情報を取得するSOQLの書き方
サンプルコード
contId = [取引先責任者のID];
// ポータルユーザの場合、contactIdに対応する取引先責任者のIDが入っている
User u = [select id, name from User where cantactId = :contId];
ページ表示時にデータ更新を行いたい
目的
Visualforceのページが表示されたタイミングでデータの更新処理を行いたい
ポイント
一見、Controllerのコンストラクタに、更新(update/insert)処理をいれればよいように思われるが、Visualforceの制約で、コンストラクタに更新処理をいれても、正常に更新されない。
pageタグのaction属性で、更新処理を行うメソッドを指定すれば、ページ読み込み時に更新処理が実行される
サンプル・コード
ページが表示されたタイミングで、既読フラグをtrueに設定する
<apex:page showHeader="false" controller="TestController" action="{!setReadFlag}"> .... </apex:page>
public class TestController { ..... // pageタグのaction属性に指定したメソッドを実装 public PageReference setReadFlag(){ TestObject__c obj = [select id , ReadMessage__c from TestObject__c where Id = :testId]; if(obj != null){ //既読フラグをtrueに設定 obj.ReadMessage__c = true; update(obj); } return null; } ....
制限事項
参考資料
Triggerで添付ファイルを含めたメールを送信する
目的
オブジェクトが更新されたタイミングで、レコードに紐付いた添付ファイル(Attachment)をメールの添付ファイルとして送信したい。
ポイント
メールの送信は、ApexのMessagingクラスを利用します。添付ファイルの扱い方に関しては、サンプル・コードを参照してください。
サンプル・コード
trigger SendMailTrigger on TestObject__c (after insert, after update) { for (TestObject__c obj: Trigger.new){ if (/** メールが送信される条件 **/){ // メール送信のためのクラス SingleEmailMessage を初期化 Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); // 宛先を設定 String[] toAddress = new String[]{obj.email__c}; mail.setToAddresses(toAddress); // メールの件名を設定 mail.setSubject(obj.title__c); // メールで利用するエンコーディングを指定 mail.setCharset('ISO-2022-JP'); // 本文を設定 mail.setPlainTextBody(obj.comment__c); // レコードにひもずく添付ファイルを取得 List<Attachment> atts = [select name, body from attachment where parentId = :obj.id]; // メールの添付ファイルを設定 List<Messaging.Emailfileattachment> fas = new List<Messaging.Emailfileattachment>(); for (Attachment att : atts){ Messaging.Emailfileattachment fa = new Messaging.Emailfileattachment(); fa.setFileName(att.name); fa.setBody(att.body); fas.add(fa); } mail.setFileAttachments(fas); // ReplyToで設定するEmailアドレスの設定 mail.setReplyTo(REPLY_TO); // メールの送信 Messaging.sendEmail(new List<Messaging.Email>{mail}); } } }
制限事項
Apexコードからのメール送信は、一括メール送信扱いになりますので、一日1000通までという制限が課せられます。
参考資料
Force.com Apex Code Developer's Guide
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_email_outbound.htm