範囲の指定

提供: RAD Studio
移動先: 案内検索

範囲でのレコードの制限 への移動


範囲を指定するには、互いに排他的な方法が 2 つあります。

  • SetRangeStart および SetRangeEnd を使用して、開始値と終了値を別々に指定する
  • SetRange を使用して両端を同時に指定する

範囲の開始値の設定

SetRangeStart 手続きを呼び出して、データセットを dsSetKey 状態にし、範囲の開始値リストの作成を開始します。SetRangeStart を呼び出すと、その後に続く Fields プロパティへの代入が、範囲の適用時に使用される開始インデックス値として扱われます。指定したフィールドを現在のインデックスに適用する必要があります。

たとえば、アプリケーションで Customers という名前の TSimpleDataSet コンポーネントを、CUSTOMER テーブルにリンクして使用していて、Customers データセットの各フィールドの永続フィールド コンポーネントを作成済みであるとします。CUSTOMER は、最初の列(CustNo)がインデックス付けされています。アプリケーションのフォームには、StartVal および EndVal という名前の 2 つの編集コンポーネントがあり、範囲の開始値と終了値を指定するのに使用します。次のコードが、範囲を作成して適用するのに使用できます。

with Customers do
begin
  SetRangeStart;
  FieldByName('CustNo').AsString := StartVal.Text;
  SetRangeEnd;
  if (Length(EndVal.Text) > 0) then
    FieldByName('CustNo').AsString := EndVal.Text;
  ApplyRange;
end;
Customers->SetRangeStart();
Customers->FieldValues["CustNo"] = StrToInt(StartVal->Text);
Customers->SetRangeEnd();
if (!EndVal->Text.IsEmpty())
  Customers->FieldValues["CustNo"] = StrToInt(EndVal->Text);
Customers->ApplyRange();

このコードでは、Fields に値を代入する前に、EndVal に入力されたテキストが null ではないかチェックしています。StartVal に入力されたテキストが null の場合、すべての値は null より大きいので、データセットの先頭からのすべてのレコードが含まれます。しかし、EndVal に入力されたテキストが null の場合は、null より小さい値はないので、どのレコードも含まれません。

複数列インデックスでは、インデックスのすべてのフィールドに開始値を指定することも、一部のフィールドに開始値を指定することもできます。インデックスで使用されるフィールドに値を設定しないと、範囲の適用時に null 値と見なされます。範囲の開始値(または終了値)を指定しないと、そのドメインの最小限(または最大限)が使用されます。インデックスに存在しないフィールドに値を設定しようとすると、データセットで例外が発生します。

ヒント: データセットの先頭から開始するには、SetRangeStart の呼び出しを省略します。

範囲の開始値の指定を終了するには、SetRangeEnd を呼び出すか、範囲を適用するか取り消します。

範囲の終了値の設定

SetRangeEnd 手続きを呼び出して、データセットを dsSetKey 状態にし、範囲の終了値リストの作成を開始します。SetRangeEnd を呼び出すと、その後に続く Data.DB.TDataSet.Fields プロパティへの代入が、範囲の適用時に使用される終了インデックス値として扱われます。指定したフィールドを現在のインデックスに適用する必要があります。

警告: データセットの最終レコードで範囲を終了させる場合でも、範囲の終了値は必ず指定します。終了値を設定しないと、Delphi は範囲の終了値を null 値と見なします。終了値が null の範囲は、常に空です。

Data.DB.TDataSet.FieldByName メソッドを呼び出すと、簡単に終了値を代入できます。以下に例を示します。

with Contacts do
begin
  SetRangeStart;
  FieldByName('LastName').AsString := Edit1.Text;
  SetRangeEnd;
  FieldByName('LastName').AsString := Edit2.Text;
  ApplyRange;
end;
Contacts->SetRangeStart();
Contacts->FieldByName("LastName")->Value = Edit1->Text;
Contacts->SetRangeEnd();
Contacts->FieldByName("LastName")->Value = Edit2->Text;
Contacts->ApplyRange();

範囲の開始値の指定と同様、インデックスに存在しないフィールドに値を設定しようとすると、データセットで例外が発生します。

範囲の終了値の指定を終了するには、範囲を適用するか取り消します。

範囲の開始値と終了値の設定

範囲の境界を指定するのに SetRangeStartSetRangeEnd を別々に呼び出す代わりに、SetRange 手続きを呼び出すと、一度の呼び出しで、データセットを dsSetKey 状態にして範囲の開始値と終了値を設定できます。

SetRange は、2 つの定数配列パラメータ(開始値のセットと終了値のセット)を取ります。たとえば次のステートメントでは、2 列インデックスに基づいて範囲を設定しています。

SetRange([Edit1.Text, Edit2.Text], [Edit3.Text, Edit4.Text]);
TVarRec StartVals[2];
TVarRec EndVals[2];
StartVals[0] = Edit1->Text;
StartVals[1] = Edit2->Text;
EndVals[0] = Edit3->Text;
EndVals[1] = Edit4->Text;
Table1->SetRange(StartVals, 1, EndVals, 1);

複数列インデックスでは、インデックスのすべてのフィールドに開始値と終了値を指定することも、一部のフィールドに開始値と終了値を指定することもできます。インデックスで使用されるフィールドに値を設定しないと、範囲の適用時に null 値と見なされます。インデックスの最初のフィールドの値を除外して、それに続くフィールドの値を指定するには、除外するフィールドに null 値を渡します。

データセットの最終レコードで範囲を終了させる場合でも、範囲の終了値は必ず指定します。終了値を設定しないと、データセットは範囲の終了値を null 値と見なします。開始範囲が終了範囲以上になるので、終了値が null の範囲は常に空です。

部分キーに基づいた範囲の指定

キーが 1 つ以上の文字列フィールドで構成されている場合、SetRange メソッドは部分キーをサポートします。たとえば、あるインデックスが LastName 列と FirstName 列に基づいている場合、次の範囲指定が有効です。

Contacts.SetRangeStart;
Contacts['LastName'] := 'Smith';
Contacts.SetRangeEnd;
Contacts['LastName'] := 'Zzzzzz';
Contacts.ApplyRange;
Contacts->SetRangeStart();
Contacts->FieldValues["LastName"] = "Smith";
Contacts->SetRangeEnd();
Contacts->FieldValues["LastName"] = "Zzzzzz";
Contacts->ApplyRange();

このコードでは、LastName が "Smith" 以上のすべてのレコードが範囲に含まれます。次のように値を指定することもできます。

Contacts['LastName'] := 'Sm';
Contacts->FieldValues["LastName"] = "Sm";

このステートメントでは、LastName が "Sm" 以上のレコードが含まれます。

境界値に一致するレコードの包含または除外

デフォルトでは、指定した範囲の開始値以上で、指定した範囲の終了値以下のすべてのレコードが範囲に含まれます。この動作は、KeyExclusive プロパティが制御します。KeyExclusive は、デフォルトでは False です。

必要な場合、データセットの KeyExclusive プロパティに True を設定すると、範囲の終了値に等しいレコードを除外できます。以下に例を示します。

Contacts.KeyExclusive := True;
Contacts.SetRangeStart;
Contacts['LastName'] := 'Smith';
Contacts.SetRangeEnd;
Contacts['LastName'] := 'Tyler';
Contacts.ApplyRange;
Contacts->SetRangeStart();
Contacts->KeyExclusive = true;
Contacts->FieldValues["LastName"] = "Smith";
Contacts->SetRangeEnd();
Contacts->FieldValues["LastName"] = "Tyler";
Contacts->ApplyRange();

このコードでは、LastName が "Smith" 以上で "Tyler" 未満のすべてのレコードが範囲に含まれます。

関連項目