コンポーネントの開発
4D のコンポーネントとは、4Dアプリケーションにインストール可能 な、1つ以上の機能を持つ 4D関数やメソッド、フォームの一式です。 たとえば、メールの送受信をおこない、それらを 4D アプリケーションに格納するための機能を持ったコンポーネントを作成できます。
ニーズに合わせて独自の 4Dコンポーネントを開発し、それを非公開とすることができます。 また、作成した コンポーネントを4Dコミュニティで共有 することもできます。
定義
- マトリクスプロジェクト: コンポーネント開発に使用する4D プロジェクト。 マトリクスプロジェクトは特別な属性を持たない標準のプロジェクトです。 マトリクスプロジェクトはひとつのコンポーネントを構成します。
- ホストプロジェクト: コンポーネントがインストールされ、それを使用するアプリケーションプロジェクト。
- コンポーネント: ホストアプリケーションにインストール され、同アプリケーションによって使用されるマトリクスプロジェクトのこと。マトリクスプロジェクトはコンパイルし、ビルド することができます。
基本
4D コンポーネントの作成とインストールは直接 4D を使用しておこないます:
- コンポーネントを使用するには、アプリケーションにインストール するだけです。
- 言い換えれば、マトリクスプロジェクト自体も1 つ以上のコンポーネントを使用できます。 しかしコンポーネントが "サブコンポーネント" を使用することはできません。
- コンポーネントは次の 4D の要素を呼び出すことができます: クラス、関数、プロジェクトメソッド、プロジェクトフォーム、メニューバー、選択リストなど。 反面、コンポーネントが呼び出せないものは、データベースメソッドとトリガーです。
- コンポーネント内でデータストアや標準のテーブル、データファイルを使用することはできません。 しかし、外部データベースのメカニズムを使用すればテーブルやフィールドを作成し、そこにデータを格納したり読み出したりすることができます。 外部データベースは、メインの 4D データベースとは独立して存在し、SQLコマンドでアクセスします。
- インタープリターモードで動作するホストプロジェクトは、インタープリターまたはコンパイル済みどちらのコンポーネントも使用できます。 コンパイルモードで実行されるホストデータベースでは、インタープリターのコンポーネントを使用できません。 この場合、コンパイル済みコンポーネントのみが利用可能です。
ランゲージコマンドのスコープ
使用できないコマンド を除き、コンポーネントではすべての 4D ランゲージコマンドが使用できます。
コマンドがコンポーネントから呼ばれると、コマンドはコンポーネントのコンテキストで実行されます。 ただしEXECUTE FORMULA と EXECUTE METHOD コマンドは除きます。これらはコマンドで指定されたメソッドのコンテキストを使用します。 また、ユーザー&グループテーマの読み出しコマンドはコンポーネントで使用することができますが、読み出されるのはホストプロジェクトのユーザー&グループ情報であることに注意してください (コンポーネントに固有のユーザー&グループはありません)。
SET DATABASE PARAMETER および Get database parameter コマンドは例外となります: これらのコマンドのスコープはグローバルです。 これらのコマンドがコンポーネントから呼び出されると、結果はホストプロジェクトに適用されます。
さらに、Structure file と Get 4D folder コマンドは、コンポーネントで使用するための設定ができるようになっています。
COMPONENT LIST コマンドを使用して、ホストプロジェクトにロードされたコンポーネントのリストを取得できます。
使用できないコマンド
(読み取り専用モードで開かれるため) ストラクチャーファイルを更新する以下のコマンドは、コンポーネントで使用することができません。 コンポーネント中で以下のコマンドを実行すると、-10511, "CommandName コマンドをコンポーネントでコールすることはできません" のエラーが生成されます:
- ON EVENT CALL
- Method called on event
- SET PICTURE TO LIBRARY
- REMOVE PICTURE FROM LIBRARY
- SAVE LIST
- ARRAY TO LIST
- EDIT FORM
- CREATE USER FORM
- DELETE USER FORM
- CHANGE PASSWORD
- EDIT ACCESS
- Set group properties
- Set user properties
- DELETE USER
- CHANGE LICENSES
- BLOB TO USERS
- SET PLUGIN ACCESS
注:
- Current form tableコマンドは、プロジェクトフォームのコンテキストで呼び出されると- Nilを返します。 ゆえにこのコマンドをコンポーネントで使用することはできません。
- SQLデータ定義言語のコマンド (CREATE TABLE、DROP TABLE等) をコンポーネントのフレームワークで使用することはできません。 ただし、外部データベースの場合は使用することができます (CREATE DATABASESQL コマンド参照)。
プロジェクトメソッドの共有
マトリクスプロジェクトのすべてのプロジェクトメソッドは 、コンポーネントに含まれます。 つまり、マトリクスプロジェクトをコンポーネント化した後、これらのプロジェクトメソッドは同コンポーネント内で呼び出して実行することができます。
他方、デフォルトでは、これらのプロジェクトメソッドはホストプロジェクトに表示されず、呼び出すこともできません。 マトリクスプロジェクトで、メソッドプロパティダイアログボックスの コンポーネントとホストプロジェクト間で共有 ボックスをチェックすることで、ホストプロジェクトおよびそのコンポーネントと共有したいメソッドを明示的に設定することができます。
設定することで、共有されたプロジェクトメソッドはホストプロジェクトにおいて呼び出せるようになります (しかしホストプロジェクトのコードエディターで編集することはできません)。 これらのメソッドはコンポーネントの エントリーポイント となります。
セキュリティのため、デフォルトでは、コンポーネントはホストプロジェクトのプロジェクトメソッドを実行することはできません。 特定の場合に、ホストプロジェクトのプロジェクトメソッドにコンポーネントがアクセスできるようにする必要があるかもしれません。 そうするには、ホストプロジェクトのプロジェクトメソッド側で、コンポーネントからのアクセスを可能にするよう明示的に指定しなければなりません。これはメソッドプロパティダイアログボックスの、コンポーネントとホストプロジェクト間で共有 で設定します。

ホストプロジェクトのプロジェクトメソッドがコンポーネントから利用可能になっていれば、EXECUTE FORMULA または EXECUTE METHOD コマンドを使用して、コンポーネント側からホストのメソッドを実行することができます。 例:
// ホストメソッド
component_method("host_method_name")
// コンポーネントメソッド
#DECLARE ($param : Text)
EXECUTE METHOD($param)
インタープリターコンポーネントがインストールされたインタープリターホストデータベースは、それがインタープリターコンポーネントのメソッドを呼び出さなければ、コンパイル/シンタックスチェックができます。 そうでない場合、コンパイルまたはシンタックスチェックを実行しようとすると警告ダイアログが表示され、操作を実行することはできません。
一般的に、インタープリターメソッドはコンパイル済みメソッドを呼び出せますが、逆はできません。これをおこなうにはEXECUTE METHODやEXECUTE FORMULAコマンドを使用します。
クラスの共有
デフォルトでは、ホストプロジェクトの 4Dコードエディターからコンポーネントのクラスを呼び出すことはできません。 ホストプロジェクトおよび読み込まれているコンポーネントに対してコンポーネントのクラスを公開したい場合は、コンポーネント名前空間を宣言 する必要があります。 また、コンポーネントのクラスがホストコードエディターでどのように提案されるかをコントロールすることもできます。
コンポーネント名前空間の宣言
ホストプロジェクトおよび読み込まれているコンポーネントに対してコンポーネントのクラスを公開するには、マトリクスプロジェクトの設定の 一般ページにある クラスストア内でのコンポーネント名前空間 オプション に値を入力します。 デフォルトでは、このエリアは空です。つまり、コンポーネントのクラスはコンポーネント外で利用できません。
名前空間 は、同じ名前のクラスや関数を持つ異なるコンポーネントがホストプロジェクトで使用されている場合に、競合が発生しないようにします。 コンポーネント名前空間は、プロパティの命名規則 に準拠する必要があります。
値を入力すると、ホストプロジェクトおよび読み込まれているコンポーネントのコードにおいて、ユーザークラスストア (cs) ユーザークラスストア (cs) 内の cs.<value> 名前空間を介して、コンポーネントのクラスが利用可能になることを宣言することになります。 たとえば、getArea() 関数を持つ Rectangle クラスが存在する場合に、コンポーネント名前空間として "eGeometry" を入力すると、このプロジェクトがコンポーネントとしてインストールされると、ホストプロジェクトの開発者は次のように記述することができます:
// ホストプロジェクトまたは読み込まれているコンポーネントにて
var $rect: cs.eGeometry.Rectangle
$rect:=cs.eGeometry.Rectangle.new(10;20)
$area:=$rect.getArea()
コンパイルされた コンポーネントの名前空間は、ホストプロジェクトの コンポーネントメソッドページ にて、コンポーネント名の後に括弧で表示されます。
競合を避けるためには、優れた識別名の使用が推奨されます。 もし、コンポーネントの名前空間と同じ名前のユーザークラスがすでにプロジェクトに存在していた場合、そのユーザークラスが考慮され、コンポーネントクラスは無視されます。
コンポーネントの ORDAクラスは、ホストプロジェクトでは使用できません。 たとえば、コンポーネントに Employees というデータクラスがある場合、ホストプロジェクトで "cs.Mycomponent.Employee" クラスを使用することはできません。
非表示クラス
アンダースコア ("_") を名前の前に付けることで、コンポーネントのクラスや関数を非表示にすることができます。 コンポーネント名前空間が定義されている 場合、非表示のクラスや関数はコード補完の際に提案されません。
ただし、名前がわかっていれば使用することは可能です。 たとえば、_Rectangle クラスが非表示の場合でも、次のシンタックスは有効です:
$rect:=cs.eGeometry._Rectangle.new(10;20)
非表示のクラス内の、非表示でない関数は、そのクラスを 継承 するクラスでコード補完を使用すると提案されます。 たとえば、あるコンポーネントに
_Personクラスを継承したTeacherクラスがある場合、Teacherのコード補完では_Personの非表示でない関数が提案されます。
ホストからコンポーネントを編集する
ホストプロジェクトの実際のコンテキストからコンポーネントをチューニングするのを容易にするために、ロードしたコンポーネントをインタープリターモードのホストプロジェクトから直接編集してそのコードを保存することが可能です。 コンポーネントのコードは、以下の条件を満たしている場合に編集可能です:
- コンポーネントが インタープリタモードでロードされていること
- コンポーネントが依存関係マネージャーのローカルキャッシュ からロードされていないこと、つまりGitHub からダウンロードされた ものではないこと。
この場合、ホストプロジェクトのコードエディター内でコンポーネントのコードを開き、編集して、保存することができ、その変更は直ちに反映されます。
エクスプローラーでは、コンポーネントのコードが編集可能であることを表す特定のアイコンが表示されます:

コンパイル済みコンポーネントのコード補完
開発者に向けてコンポーネントを使いやすくするため、マトリクスプロジェクトの設定で、 一般ページの コンパイル時にコード補完用のシンタックスファイルを生成する オプション をチェックすることができます。
すると、コンパイル時にシンタックスファイル (JSON形式) が自動生成され、そこにコンポーネントのクラス、関数、および 公開メソッド のシンタックスを格納し、コンポーネントプロジェクトの \Resources\ja.lproj フォルダーに配置されます。 4D は、このシンタックスファイルをもとに、コード補完や関数シンタックスなどのコードエディター用のヘルプを生成します。

コンポーネント名前空間 を入力しない場合、シンタックスファイル生成のオプションがチェックされていても、クラスや公開メソッド用のリソースは生成されませ ん。
変数の渡し方
ローカル、プロセス、インタープロセス変数は、コンポーネントとホストプロジェクト間で共有されません。 ホストプロジェクトからコンポーネントの変数を編集、またはその逆をおこなう唯一の方法はポインターを使用することです。
配列を使用した例:
// ホストプロジェクト側:
     ARRAY INTEGER(MyArray;10)
     AMethod(->MyArray)
// コンポーネント側で AMethod プロジェクトメソッドは以下の通りです:
     APPEND TO ARRAY($1->;2)
変数を使用した例:
C_TEXT(myvariable)
component_method1(->myvariable)
C_POINTER($p)
$p:=component_method2(...)
ポインターを使用しない場合でも、コンポーネント側からホストデータベースの (変数そのものではなく) 変数の値にアクセスすること自体は可能ですし、その逆も可能です:
// ホストデータベース内
C_TEXT($input_t)
$input_t:="DoSomething"
component_method($input_t)
// component_method は $1 に "DoSomething" を受け取ります ($input_t 変数を受け取るわけではありません)
ホストプロジェクトとコンポーネント間でポインターを使用して通信をおこなうには、以下の点を考慮する必要があります:
- 
Get pointerをコンポーネント内で使用した場合、このコマンドはホストプロジェクトの変数へのポインターを返しません。また逆にこのコマンドをホストプロジェクトで使用した場合も同様です。
- 
コンパイル済みプロジェクトでは、コンパイルされたコンポーネントしか使用できませんが、インタープリタープロジェクトの場合には、インタープリターおよびコンパイル済みコンポーネントを同時に使用することができます。 この場合、ポインターの利用は以下の原則を守らなければなりません: インタープリターモードでは、コンパイルモードにおいて作成されたポインターを解釈できます。逆にコンパイルモードでは、インタープリターモードにて作成されたポインターを解釈することはできません。 以下の例でこの原則を説明します: 同じホストプロジェクトにインストールされた 2つのコンポーネント C ( コンパイル済) と I ( インタープリタ) があります: 
- 
コンポーネントC が定義する変数 myCvarがあるとき、コンポーネントI はポインター->myCvarを使用して変数の値にアクセスすることができます。
- 
コンポーネントI が定義する変数 myIvarがあるとき、コンポーネントC はポインター->myIvarを使用しても変数の値にアクセスすることはできません。 このシンタックスは実行エラーを起こします。
- 
RESOLVE POINTERを使用したポインターの比較はお勧めできません。変数の分離の原則により、ホストプロジェクトとコンポーネント (あるいは他のコンポーネント) で同じ名前の変数が存在することができますが、根本的にそれらは異なる内容を持ちます。 両コンテキストで、変数のタイプが違うことさえありえます。 ポインターmyptr1とmyptr2がそれぞれ変数を指すとき、以下の比較は正しくない結果となるかもしれません:
     RESOLVE POINTER(myptr1;vVarName1;vtablenum1;vfieldnum1)
     RESOLVE POINTER(myptr2;vVarName2;vtablenum2;vfieldnum2)
     If(vVarName1=vVarName2)
      // 変数が異なっているにもかかわらず、このテストはtrue を返します
このような場合には、ポインターを比較しなければなりません:
     If(myptr1=myptr2) // このテストはFalse を返します
エラー処理
ON ERR CALL コマンドによって実装された エラー処理メソッド は、実行中のプロジェクトに対してのみ適用されます。 コンポーネントによって生成されたエラーの場合、ホストプロジェクトの ON ERR CALL エラー処理メソッドは呼び出されず、その逆もまた然りです。
しかしながら、ホストアプリケーションにコンポーネントエラーハンドラーを実装する ことで、コンポーネントでキャッチされなかったエラーを管理することができます。
ホストプロジェクトのテーブルへのアクセス
コンポーネントでテーブルを使用することはできませんが、ホストプロジェクトとコンポーネントはポインターを使用して通信をおこなうことができます。 たとえば、以下はコンポーネントで実行可能なメソッドです:
// コンポーネントメソッドの呼び出し
methCreateRec(->[PEOPLE];->[PEOPLE]Name;"Julie Andrews")
コンポーネント内の methCreateRec メソッドのコード:
C_POINTER($1) // ホストプロジェクトのテーブルへのポインター
C_POINTER($2) // ホストプロジェクトのフィールドへのポインター
C_TEXT($3) // 代入する値
$tablepointer:=$1
$fieldpointer:=$2
CREATE RECORD($tablepointer->)
$fieldpointer->:=$3
SAVE RECORD($tablepointer->)
コンポーネントのコンテキストにおいて、テーブルフォームへの参照はすべてホスト側のテーブルフォームへの参照だと 4D はみなします (コンポーネントはテーブルを持つことができないからです)。
テーブルやフィールドの利用
コンポーネントは、マトリクスプロジェクトのストラクチャーで定義されたテーブルやフィールドを使用することはできません。 しかし外部データベースを作成し、そのテーブルやフィールドを必要に応じ利用することはできます。 外部データベースの作成と管理は SQL を用いておこないます。 外部データベースは、メインの4Dプロジェクトから独立している別の 4Dプロジェクトですが、メインプロジェクトから操作が可能です。 外部データベースの利用は、そのデータベースを一時的にカレントデータベースに指定することです。言い換えれば、4Dが実行する SQL クエリのターゲットデータベースとして外部データベースを指定します。 外部データベースの作成は SQL の CREATE DATABASE コマンドを使用します。
例題
以下のコードはコンポーネントに実装されており、外部データベースに対して3つの基本的なアクションをおこないます:
- 外部データベースを作成します (存在しない場合)
- 外部データベースにデータを追加します
- 外部データベースからデータを読み込みます
外部データベースの作成:
<>MyDatabase:=Get 4D folder+"\MyDB" // (Windows) データを許可されているディレクトリに保存します
 Begin SQL
        CREATE DATABASE IF NOT EXISTS DATAFILE :[<>MyDatabase];
        USE DATABASE DATAFILE :[<>MyDatabase];
        CREATE TABLE IF NOT EXISTS KEEPIT
        (
        ID INT32 PRIMARY KEY,
        kind VARCHAR,
        name VARCHAR,
        code TEXT,
        sort_order INT32
        );
        CREATE UNIQUE INDEX id_index ON KEEPIT (ID);
        USE DATABASE SQL_INTERNAL;
 End SQL
外部データベースへのデータ書き込み:
 $Ptr_1:=$2 // ポインターを介してホストプロジェクトからデータを取得します
 $Ptr_2:=$3
 $Ptr_3:=$4
 $Ptr_4:=$5
 $Ptr_5:=$6
 Begin SQL
        USE DATABASE DATAFILE :[<>MyDatabase];
        INSERT INTO KEEPIT
        (ID, kind, name, code, sort_order)
        VALUES
        (:[$Ptr_1], :[$Ptr_2], :[$Ptr_3], :[$Ptr_4], :[$Ptr_5]);
        USE DATABASE SQL_INTERNAL;
 End SQL
外部データベースからデータを読み込み:
 $Ptr_1:=$2 // ホストプロジェクトへのデータアクセスはポインターを通じておこないます
 $Ptr_2:=$3
 $Ptr_3:=$4
 $Ptr_4:=$5
 $Ptr_5:=$6
 Begin SQL
    USE DATABASE DATAFILE :[<>MyDatabase];
    SELECT ALL ID, kind, name, code, sort_order
    FROM KEEPIT
    INTO :$Ptr_1, :$Ptr_2, :$Ptr_3, :$Ptr_4, :$Ptr_5;
    USE DATABASE SQL_INTERNAL;
 End SQL
フォームの使用
- 特定のテーブルに属さない" プロジェクトフォーム" のみが、コンポーネント内で利用できます。 マトリクスプロジェクトのすべてのプロジェクトフォームをコンポーネントで使用することができます。
- コンポーネントはホストプロジェクトのテーブルフォームを使用できます。 この場合、コンポーネントのコードでフォームを指定するにあたっては、テーブル名ではなく、テーブルへのポインターを使用しなければならないことに注意してください。
コンポーネントが
ADD RECORDコマンドを使用すると、ホストプロジェクトのコンテキストで、ホストプロジェクトのカレントの入力フォームが表示されます。 したがって、その入力フォーム上に変数が含まれている場合、コンポーネントはその変数にアクセスできません。
- コンポーネントフォームをホストプロジェクト内で サブフォームとして公開 することができます。 これは具体的には、グラフィックオブジェクトを提供するコンポーネントを開発できることを意味します。 たとえば、4D社が提供するウィジェットはコンポーネントのサブフォーム利用に基づいています。
コンポーネントのコンテキストにおいては、参照されるプロジェクトフォームはすべてコンポーネント内に存在している必要があります。 たとえば、コンポーネント内において、
DIALOGまたはOpen form windowコマンドを使用してホスト側のプロジェクトフォームを参照しようとした場合にはエラーが生成されます。
リソースの使用
コンポーネントは、自身の Resourcesフォルダーにあるリソースを使用することができます。
これによって自動メカニズムが有効となり、コンポーネントの Resources フォルダー内で見つかった XLIFF ファイルは、 同コンポーネントによってロードされます。
1つ以上のコンポーネントを含むホストプロジェクトでは、ホストプロジェクトと同様にそれぞれのコンポーネントも固有のリソースチェーンを持っています。 リソースは異なるプロジェクト間で分離されます。コンポーネントA のリソースにコンポーネントB やホストプロジェクトからアクセスすることはできません。
初期化のコードの実行
コンポーネントは、ホストデータベースを開いたときまたは閉じたときに、自動的に 4Dコードを実行することができます。これによってたとえば、ホストデータベースに関連する設定やユーザーの状態などを読み込み・保存することができます。
初期化やデータベースを閉じるコードの実行は、 On Host Database Event データベースメソッド を使用しておこなわれます。
セキュリティ上の理由から、
On Host Database Eventデータベースメソッドを使用可能にするためには、その実行をホストデータベースで明示的に許可する必要があります。 このためには、ストラクチャー設定画面のセキュリティページ内の、コンポーネントの "On Host Database Event" メソッドを実行 オプションにチェックを入れます:
Info.plist
コンポーネントは、そのroot フォルダ にシステム(macOS のみ)と依存関係マネージャが読み取り可能な追加の情報を提供する、 Info.plist ファイルを持っています。
このファイルは必須ではありませんが、macOS 用の公証可能でステープル可能な コンポーネントをビルドするためには必要です。 そのため、これがまだ存在しない場合にはにビルド時に自動的に作成されます。 一部のキーはbuildApp XML キーを使用して設定可能である点に留意してください(コンポーネントのビルド を参照してください)。
コンポーネントのInfo.plist ファイル内でサポートされているキーは、大部分はApple bundle キー であり、Windows 上では無視されます。 しかしながら、これらは全てのプラットフォームにおいて依存関係マネージャ によって使用されます。
定義可能なキーは以下の通りです:
| key | description | 
|---|---|
| CFBundleName | コンポーネント名(内部) | 
| CFBundleDisplayName | 表示するコンポーネント名 | 
| NSHumanReadableCopyright | 表示する著作権 | 
| CFBundleVersion | コンポーネントのバージョン | 
| CFBundleShortVersionString | 表示するコンポーネントのバージョン | 
| com.4d.minSupportedVersion | サポートされる最低限の4D のバージョン。これは依存関係マネージャの4D のバージョンに従うコンポーネントにおいて使用されます。 | 
以下は、Info.plist ファイルの一例です:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<plist>
  <dict>
    <key>CFBundleName</key>
    <string>UI</string>
    <key>CFBundleDisplayName</key>
    <string>UI</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>NSHumanReadableCopyright</key>
    <string>©vdl 2025</string>
    <key>CFBundleVersion</key>
    <string></string>
    <key>com.4d.minSupportedVersion</key>
    <string>20R10</string>
  </dict>
</plist>
macOS 上では、Finder からこの情報を見ることができます:

コンポーネントの保護: コンパイル
コンポーネントとしてインストールされたマトリクスプロジェクトのコードは、ホストプロジェクトからデフォルトでアクセス可能です。 特に:
- エクスプローラーのメソッドページに存在する共有のプロジェクトメソッドは、ホストプロジェクトのメソッドから呼び出し可能です。 エクスプローラーのプレビューエリアでそれらの内容を選択してコピーすることが可能です。 また、その内容はデバッガーで見ることもできます。 しかし、それらをコードエディター上で開いたり編集したりすることはできません。
- マトリクスプロジェクトの他のプロジェクトメソッドはエクスプローラーに現れません。しかし、ホストプロジェクトのデバッガーには内容が表示されます。
- 名前空間が宣言されていれば、非表示でないクラスや関数はデバッガーで確認することができます。
コンポーネントのコードを効果的に保護するには、マトリクスプロジェクトを コンパイルしビルドして、.4dz ファイルとして提供します。 コンパイルされたマトリクスプロジェクトがコンポーネントとしてインストールされると:
- 共有のプロジェクトメソッド、クラス、および関数は、ホストプロジェクトのメソッドから呼び出し可能です。共有のプロジェクトメソッドは、エクスプローラーのメソッドページにも表示されます。 しかし、その内容はプレビューエリアにもデバッガーにも表示されません。
- マトリクスプロジェクトの他のプロジェクトメソッドは一切表示されません。
GitHub上でコンポーネントを共有する
開発したコンポーネントを GitHub で公開し、4D開発者のコミュニティをサポートすることをお勧めします。 正しく参照されるためには、4d-component トピックをご利用ください。