執筆者:Salesforce 開発者
背景と応用シナリオ
Salesforce の世界に足を踏み入れた開発者であれば、必ず耳にする技術の一つが Visualforce (ビジュアルフォース) です。Visualforce は、Salesforce プラットフォーム、すなわち Force.com 上で、標準のユーザインターフェース (UI) では実現できない、高度にカスタマイズされたUIを構築するためのフレームワークです。これは、HTMLライクなタグベースのマークアップ言語と、サーバサイドのコントローラロジックを担う Apex (エイペックス) を組み合わせて使用します。
近年、Lightning Web Components (LWC) がUI開発の主流となりつつありますが、Visualforce がその価値を失ったわけではありません。現在でも、以下のような特定のシナリオにおいて、Visualforce は不可欠な技術として活用されています。
PDF帳票の生成
Visualforce の最も強力な機能の一つが、ページをPDFとしてレンダリングする機能です。見積書、請求書、契約書など、特定のフォーマットを持つドキュメントを動的に生成し、顧客に提供する場面で広く利用されています。LWC単体ではこの機能を実現することは難しく、依然としてVisualforce の独壇場と言える領域です。
カスタムロジックを伴うメールテンプレート
Visualforce を使用すると、複雑なビジネスロジックに基づいて動的に内容が変化するリッチなHTMLメールテンプレートを作成できます。例えば、関連する複数のオブジェクトから情報を集約し、条件に応じて表示内容を切り替えるといった高度な要求に応えることが可能です。
既存システムの保守・機能拡張
長年にわたり Salesforce を利用している多くの企業では、Visualforce で構築された既存のカスタムページが多数稼働しています。これらのシステムの保守や、部分的な機能拡張を行う際には、Visualforce の知識が必須となります。
Lightning Experience 内での利用
Visualforce ページは、Lightning アプリケーションビルダーを使用して Lightning Experience のページに直接埋め込むことができます。これにより、既存の Visualforce 資産を活かしつつ、最新のUI環境に統合することが可能です。
原理説明
Visualforce は、古典的かつ堅牢な Model-View-Controller (MVC) デザインパターンに基づいて設計されています。このアーキテクチャを理解することは、Visualforce を効果的に活用する上で非常に重要です。
Model (モデル)
モデルは、データの構造とロジックを表現します。Salesforce の文脈では、これは sObjects (標準オブジェクトやカスタムオブジェクト) に相当します。取引先 (Account)、商談 (Opportunity)、そして私たちが作成したカスタムオブジェクトなどがモデルの役割を担い、データベース内のデータを表現します。
View (ビュー)
ビューは、ユーザが見て操作するインターフェースの部分です。Visualforce では、<apex:page>
タグで始まるマークアップ言語がこれを担当します。HTMLタグに似た <apex:inputText>
や <apex:commandButton>
といったコンポーネントタグを使用して、データの表示やユーザからの入力を受け付ける画面を構築します。
Controller (コントローラ)
コントローラは、モデルとビューの間の橋渡し役です。ユーザがビューで行った操作 (ボタンのクリックなど) を受け取り、それに応じてモデル (データ) を操作し、最終的にビューの表示を更新する役割を担います。Visualforce で使用できるコントローラには、主に3つの種類があります。
1. Standard Controller (標準コントローラ): Salesforce が標準オブジェクト (Account, Contact など) およびすべてのカスタムオブジェクトに対して自動的に提供するコントローラです。レコードの保存、削除、編集といった基本的な機能をコーディングなしで利用でき、開発効率を大幅に向上させます。
2. Custom Controller (カスタムコントローラ): Apex クラスで記述する、完全にオリジナルのコントローラです。標準コントローラの機能では実現できない複雑なビジネスロジックや、複数のオブジェクトを横断する処理を実装する場合に使用します。開発の自由度が最も高い反面、すべてのロジックを自前で実装する必要があります。
3. Controller Extension (コントローラ拡張): 標準またはカスタムコントローラの機能を拡張するための Apex クラスです。既存のコントローラの機能を活用しつつ、独自のカスタムロジックを追加したい場合に使用します。例えば、標準の取引先ページに、特定の条件を満たす関連商談のリストを追加表示する、といったシナリオで役立ちます。
示例代码
ここでは、カスタムコントローラを使用して取引先 (Account) のリストを表示する簡単な Visualforce ページの作成方法を、Salesforce 公式ドキュメントに基づいたコードで示します。
ステップ1: Apex カスタムコントローラの作成
まず、取引先データを取得するためのロジックを持つ Apex クラスを作成します。
// accountListController.cls // このクラスは、取引先レコードのリストを取得し、Visualforceページで表示できるようにするカスタムコントローラです。 public class accountListController { // Visualforceページから {!accounts} として参照されるプロパティ。 // getAccountsメソッドが呼び出され、その戻り値がページに渡されます。 public List<Account> getAccounts() { // SOQL (Salesforce Object Query Language) を使用して、 // データベースから取引先 (Account) のIDと名前 (Name) を10件取得します。 // LIMIT 10 は、ガバナ制限を考慮し、一度に大量のデータを取得しないためのベストプラクティスです。 List<Account> results = [SELECT Id, Name FROM Account LIMIT 10]; return results; } }
ステップ2: Visualforce ページの作成
次に、上で作成した Apex コントローラを使用する Visualforce ページを作成します。
<!-- accountListPage.vfp --> <!-- controller属性で、このページが使用するApexクラスを指定します。 ここでは、先ほど作成した 'accountListController' を指定しています。 --> <apex:page controller="accountListController"> <!-- apex:pageBlockは、Salesforceの標準UIに似たスタイルのセクションを作成するためのコンポーネントです。 title属性でセクションのヘッダーテキストを設定します。 --> <apex:pageBlock title="Viewing Accounts"> <!-- apex:pageBlockTableは、データのリストを表形式で表示するためのコンポーネントです。 - value属性には、コントローラから受け取るデータのリストを指定します。ここでは {!accounts} を指定しており、 これはコントローラの getAccounts() メソッドを呼び出します。 - var属性には、リスト内の各レコードを指すための一時的な変数名を指定します。ここでは 'a' としています。 --> <apex:pageBlockTable value="{!accounts}" var="a"> <!-- apex:columnは、テーブル内の列を定義します。 value属性には、表示したいレコードの項目を指定します。 {!a.Name} は、現在処理中のレコード (変数 'a' に格納されている) の Name 項目を表示します。 --> <apex:column value="{!a.Name}"/> </apex:pageBlockTable> </apex:pageBlock> </apex:page>
この2つのファイルを作成・保存することで、組織内の最新10件の取引先名がリスト表示されるカスタムページが完成します。
注意事項
Visualforce 開発を行う際には、プラットフォーム特有の制約や考慮事項を理解しておく必要があります。
権限と共有設定
Apex コントローラは、デフォルトではシステムモードで実行されます。つまり、実行ユーザの権限設定 (オブジェクト権限や項目レベルセキュリティ) を無視してデータにアクセスします。ユーザの権限を尊重させたい場合は、クラス定義時に with sharing
キーワードを明示的に指定する必要があります。これにより、ユーザがアクセス権を持たないレコードや項目が意図せず表示・更新されることを防ぐことができます。
Governor Limits (ガバナ制限)
Salesforce はマルチテナント環境であるため、特定の組織がリソースを過剰に消費しないように、Governor Limits (ガバナ制限) と呼ばれる厳格な実行制限が設けられています。例えば、1回のトランザクション内で発行できる SOQL (Salesforce Object Query Language) クエリは100回まで、DML (Data Manipulation Language) ステートメント (insert, updateなど) は150回までといった制限があります。これらの制限を超えないように、コードの一括処理 (Bulkification) を常に意識する必要があります。
View State (ビューステート)
Visualforce ページは、ページの状態 (コントローラ内の変数データなど) を View State と呼ばれる暗号化された隠しフォーム項目に保持します。ユーザがボタンをクリックするなどの操作を行うと、この View State がサーバに送信され、状態が復元されます。しかし、View State のサイズには135KBという上限があり、これを超えるとエラーが発生します。コントローラ内で大量のデータを保持したり、複雑なコンポーネントを多用したりすると View State が肥大化しやすいため、transient
キーワードを使用して View State に含めない変数を宣言するなど、サイズを意識した設計が求められます。
エラー処理
Apex コントローラ内での DML 処理や SOQL クエリは、予期せぬエラー (必須項目がnull、検証ルール違反など) を引き起こす可能性があります。try-catch
ブロックを使用して例外を適切に捕捉し、ApexPages.addMessage()
メソッドを使ってユーザに分かりやすいエラーメッセージをフィードバックすることが重要です。Visualforce ページ側では <apex:pageMessages />
コンポーネントを配置することで、これらのメッセージを表示できます。
まとめとベストプラクティス
Visualforce は、Force.com プラットフォームにおけるカスタムUI開発の基盤を築いた、強力で柔軟なフレームワークです。LWC が登場した現在でも、PDF生成や既存システムの保守といった特定の領域でその重要性は揺るぎません。
Visualforce を用いた開発を成功させるためのベストプラクティスを以下にまとめます。
1. 適切なコントローラの選択: 可能な限り標準コントローラを活用し、コード量を削減します。標準機能にカスタムロジックを追加したい場合は、コントローラ拡張を選択します。完全に独自の複雑なロジックが必要な場合にのみ、カスタムコントローラを使用します。
2. ビジネスロジックの分離: コントローラクラスにすべてのロジックを詰め込むのではなく、ロジックを扱う専用のサービスクラスを作成し、コントローラはそれを呼び出すだけにします。これにより、コードの再利用性が高まり、テストも容易になります。
3. SOQLクエリとDML処理の一括処理 (Bulkification):
for
ループ内でSOQLクエリやDMLステートメントを実行することは、Governor Limits に抵触する最も一般的な原因です。必ずループの外でデータを一括処理するように設計してください。
4. View State の最小化:
ページの状態維持に不要な変数は transient
キーワードで宣言し、View State のサイズを小さく保ちます。これにより、ページのパフォーマンスが向上します。
5. 新規開発における技術選定: これから全く新しいUIを構築する場合、特に動的でインタラクティブなUIが求められる場合は、第一候補として LWC を検討すべきです。ただし、要件がPDF生成など Visualforce の得意分野に合致する場合は、迷わず Visualforce を選択するのが賢明です。
Visualforce の原理とベストプラクティスを深く理解することは、Salesforce 開発者としてのスキルセットを豊かにし、より複雑で多様なビジネス要件に対応する能力を高めることに繋がります。
コメント
コメントを投稿