メインコンテンツまでスキップ
バージョン: v20 R4 BETA

変数

4D のデータは、根本的に異なっている 2つの方法で保持されます。 フィールド はディスクに永続的にデータを保存するのに対し、変数 はメモリ上に一時的にデータを格納します。

データベースを作成する際には、フィールドに名前とデータタイプを指定します。 同様に、変数にも名前と データタイプ を指定します。

いったん作成された変数は、アプリケーションで必要とされる場所に使用できます。 たとえば、テキスト変数を同じタイプのフィールドに格納するには次のように書きます:

 [MyTable]MyField:=MyText

変数はランゲージの要素です。画面上に表示されることのない、裏方に徹した変数を作成・利用することができます。 もちろん、フォーム上に変数の値を表示することもできます (ポインターやBLOBを除く)。また、変数に値を入力したり、変数の値をレポートに印刷したりすることも可能です。 このとき、入力可や入力不可の変数オブジェクトはフィールドオブジェクトと同様に振舞い、提供されるコントロールも類似しています。 フォーム上のボタン、リストボックス、スクロールエリア、ピクチャーボタンなどのオブジェクトも変数を使って制御することができるほか、保存不要な計算結果を表示させることもできます。

変数の宣言

変数の作成は通常、宣言によっておこないます。 4D ランゲージでは、変数の宣言方法は2つあります:

  • var キーワードを使った宣言 (推奨、とくにオブジェクトやクラスをコードで使用する場合、このシンタックスによりコードエディターの提案や自動補完機能が強化されます)
  • "コンパイラー" や "配列" テーマの 4D ランゲージコマンドを使った宣言 (旧シンタックス)。

変数は宣言されると、その型に対応するデフォルト値 に初期化されます。別の値が 代入 されない限り、セッション中はこの値が保持されます。 あるいは、変数を宣言するときに、データ型と値を1行で 初期化 することもできます。

この方法は推奨されませんが、ただ "使用する" ことによって変数を宣言することもできます。 正式にそれらを宣言することは必須ではありません。 たとえば、今日の日付に30日足した値を格納した変数を作成するには、次のように書くことができます:

 MyDate:=Current date+30 //  MyDateを作成します
// これは日付型の変数であると 4D は推測します
// 30日後の日付が代入されます

宣言前に変数が作成された場合、宣言による初期化はおこなわれません。

変数を宣言するには、次のシンタックスを用います:

var <varName>{; <varName2>;...}{ : <varType>}

例:

var $myText : Text  // テキスト変数
var myDate1; myDate2 : Date // 複数の日付変数
var $myFile : 4D.File // File クラスオブジェクト変数
var $myVar // バリアント型変数

varName に指定する変数名は 4Dの 識別子の命名規則 に従う必要があります。 このシンタックスは ローカル変数とプロセス変数 の宣言のみサポートしています。インタープロセス変数 および 配列 には使用できません。

varType には次が指定できます:

  • 基本のデータ型: 変数には、宣言された型の値が格納されます
  • クラス参照 (4Dクラスまたはユーザークラス): 変数には、定義されたクラスのオブジェクトへの参照が格納されます

varType を省略すると、variant 型の変数が作成されます。

サポートされている varType 値の一覧です:

varType内容
Textテキスト値
Date日付値
Time時間値
Booleanブール値
Integer倍長整数値
Real実数値
Pointerポインター値
Pictureピクチャー値
BlobスカラーBLOB値
Collectionコレクション値
Variantバリアント値
Objectデフォルトクラス (4D.Object) のオブジェクト
4D.<className>4Dクラス名のオブジェクト
cs.<className>ユーザークラス名のオブジェクト
cs.<namespace><className><namespace> コンポーネントクラス名のオブジェクト

例題

  • 基本のデータ型の、ローカル変数およびプロセス変数の宣言:
var $myText; myText; $vt : Text
var myVar //variant

var $o : Object
// 次と同義です:
var $o : 4D.Object
// C_OBJECT($o) とも同義です
  • 4Dクラス型のオブジェクト変数の宣言:
var $myFolder : 4D.Folder
var $myFile : 4D.File
  • ユーザークラス型のオブジェクト変数の宣言:
var $myClass : cs.MyClass
var $dataclass : cs.Employee
var $entity : cs.EmployeeEntity

宣言と同時に変数を初期化する

変数を宣言する際には、1つのステートメントでデータ型と初期値の両方を指定することができます。 次に例を示します:

var $a : Text:="hello"
var $b : Date:=!2023-09-12!
var $c : Object:=New object()
var $d : cs.Customer:=cs.Customer.new()

変数は、データ型を明示的に指定せずに宣言および初期化することもできます。その場合、変数の型は 4D によって推論されます。 次に例を示します:

var $text:="hello"  // テキストと推論されます
var $number:=20 // 実数と推論されます
var $obj:={} // オブジェクトと推論されます
var $mycol:=[] // コレクションと推論されます

値の評価があいまいである場合、推論される型は インタープリターモードとコンパイル済みモード で異なる可能性があります。 この場合、コンパイラーによって警告が生成され、バリアント型が使用されます。 たとえば、次の $a の型はインタープリターモードでは正しくテキスト型と推論されますが、シンタックスチェックを実行すると警告が生成され、$a はコンパイル済みモードでバリアントとして型付けされます。

var $class:={test: "a"}
var $a:=$class.test

4D は最も一般的なタイプを推論しようとします。 たとえば、変数が整数値で初期化される場合、整数型ではなく実数型が使用されます (例: var $a:=10 //実数型が推論されます)。 このような場合や、クラスのインスタンス化など複雑な型を持つ変数を初期化する場合は、明示的に型を指定することが推奨されます。

ほとんどの場合、変数の型は自動的に決まります。 例外は、プロセス変数やインタープロセス変数に値を代入した場合で、その場合は警告メッセージが表示されます。

複数同時の代入はサポートされていません:

var $a; $b : Integer:=15 //エラー

変数への代入

変数を対象に、データを格納したり、格納したデータを別の対象にコピーしたりすることができます。 変数にデータを格納することを、変数にデータを代入する と言い、代入演算子 (:=) を使っておこないます。 代入演算子はフィールドに対してデータを代入する場合にも使います。

代入演算子は、変数を作成し、変数にデータを代入するために使用します。 作成する変数名を代入演算子の左側に書きます。 例:

MyNumber:=3

は変数 MyNumber を作成し、数値 3を代入します。 MyNumber が既に存在していれば、そこに数値 3が代入されます。

データ型の宣言 をせずに変数を作成することは通常推奨されません。

もちろん、変数からデータを取り出すことができなければ、便利とはいえません。 再度代入演算子を使用します。 [Products]Size というフィールドに MyNumber 変数の値を代入するには、代入演算子の右側に MyNumber を書きます:

[Products]Size:=MyNumber

これで、[Products]Size の値は 3 になります。 この例はとても単純ですが、ある場所から別の場所へランゲージによってデータを転送させる基本的な手順を表しています。

配列要素にデータを代入するには中カッコ ({...}) を使用します:

atNames{1}:="Richard"

ローカル、プロセス、およびインタープロセス変数

ローカルプロセス、および インタープロセス という、3種類の変数の変数を作成することができます。 これらの変数の違いは使用できるスコープにあります。また、それらを使用することのできるオブジェクトも異なります。

ローカル変数

ローカル変数はその名のとおりメソッド内でローカルであり、変数が作成されたメソッドの範囲内でのみ使用可能で、その他のメソッドからはアクセスできません。 メソッド内でローカルであるというのは、正式には「スコープがローカルである」といいます。 ローカル変数は、その使用範囲をメソッド内に限定するために用います。

ローカル変数は、以下のような目的のために使用されます:

  • 他の変数名との重複を避ける。
  • データを一時的に使用する。
  • プロセス変数の数を減らす。

ローカル変数の名前は必ずドル記号 ($) で始め、この記号を除く31文字までの文字を指定できます。 これより長い名前を指定すると、4D は余分の32文字以降を切り捨てます。

多くのメソッドや変数を持つアプリケーションプロジェクトで作業する場合、現在作業しているメソッドの範囲内で一時的に変数が必要となる場合がよくあります。 この場合、同じ変数名が他で使用されていないかどうかを気にすることなくローカル変数を作成することができます。

アプリケーションではしばしば、ユーザーによる少量のデータ入力を必要とする場合があります。 Request コマンドを使って、この情報を取得することができます。 このコマンドはデータ入力を求めるダイアログボックスを表示し、 ユーザーがデータを入力すると、その情報を戻り値として返します。 このようなデータは通常、メソッド内で長時間維持する必要はありません。 これは、ローカル変数を使用する典型的な例といえます。 次に例を示します:

 $vsID:=Request("ID を入力してください:")
If(OK=1)
QUERY([People];[People]ID =$vsID)
End if

このメソッドは、ユーザーに ID を入力するように要求します。 ローカル変数 $vsID にレスポンスが代入され、ユーザーが入力した ID に基づいた検索がおこなわれます。 このメソッドが終了した時点で、$vsID ローカル変数はメモリから消去されます。 この変数は 1回のみ、このメソッド内でしか使われないため、これ以上維持する必要はありません。

注: メソッドに渡される $1, $2...等の引数は ローカル変数です。 詳細については パラメーター を参照ください。

プロセス変数

プロセス変数は、同じプロセスの範囲内に限り使用可能です。 この変数はプロセスメソッドと、そのプロセス内で呼び出された他のメソッドで使用することができます。

プロセス変数には名前に付ける接頭辞がありません。 プロセス変数の名前は、最大31文字までの長さで指定できます。

インタープリターモードでは、変数は動的にメモリ上に作成・消去されます。 これに対してコンパイルモードでは、作成したすべてのプロセス (ユーザープロセス) で同じプロセス変数定義が共有されますが、変数のインスタンスはプロセス毎に異なるものとなります。 たとえば、プロセスP_1 とプロセスP_2 の両方においてプロセス変数 myVar が存在していても、それらはそれぞれ別のインスタンスです。

GET PROCESS VARIABLESET PROCESS VARIABLE を使用して、あるプロセスから他のプロセスのプロセス変数の値を取得したり、設定したりできます。 これらのコマンドの利用は、以下のような状況に限定することが、良いプログラミングの作法です:

  • コード内の特定の箇所におけるプロセス間通信
  • プロセス間のドラッグ&ドロップ処理
  • クライアント/サーバーにおいて、クライアントマシン上のプロセスとサーバーマシン上のストアドプロシージャー間の通信

詳細については プロセス の章と、各コマンドの説明を参照ください。

インタープロセス変数

インタープロセス変数はプロジェクト全体で使用することができ、すべてのコオペラティブプロセスで共有されます。 これらは主としてプロセス間で情報を共有するために使われます。

プリエンプティブプロセスにおいては使用できないことと、コードの保守管理を煩雑にすることから、インタープロセス変数の使用は推奨されません。

インタープロセス変数の名前は、必ずインタープロセス記号 (<>) で始めます。記号の後に31バイトまでの名前を指定できます。

クライアント/サーバーでは、各マシン (クライアントマシンとサーバーマシン) で同じインタープロセス変数定義を共有しますが、マシンごとに各変数のインスタンスが存在します。