Spécification de portées

De RAD Studio
Aller à : navigation, rechercher

Remonter à Limitation des enregistrements avec des portées


Deux moyens s'excluant mutuellement permettent de spécifier une portée :

  • Spécifier le début et la fin séparément en utilisant SetRangeStart et SetRangeEnd.
  • Spécifier les valeurs des deux extrémités simultanément en utilisant SetRange.

Définition du début d'une portée

Appelez la procédure SetRangeStart pour placer l'ensemble de données à l'état dsSetKey et commencez à créer une liste de valeurs de début pour la portée. Après l'appel à SetRangeStart, les affectations suivantes de la propriété Fields sont traitées comme des valeurs d'index de début à utiliser lorsque la portée est appliquée. Les champs spécifiés doivent s'appliquer à l'index en cours.

Supposons, par exemple, que votre application utilise un composant TSimpleDataSet appelé Customers, lié à la table CUSTOMER, et que vous ayez créé des composants champ persistants pour chaque champ de l'ensemble de données Customers. La table CUSTOMER est indexée sur la première colonne (CustNo). Dans une fiche de l'application, deux composants d'édition appelés StartVal et EndVal permettent d’indiquer les valeurs de début et de fin d'une portée. Le code ci-dessous peut être utilisé pour créer une portée et l'appliquer :

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();

Ce code vérifie que le texte entré dans EndVal n’est pas null avant d'assigner des valeurs à Fields. Si le texte entré pour StartVal vaut NULL, tous les enregistrements à partir du début de l'ensemble de données sont alors inclus, puisque toutes les valeurs sont supérieures à null. Néanmoins, si le texte entré pour EndVal est null, aucun enregistrement n'est alors inclus, puisqu'aucun ne peut être inférieur à null.

Pour un index multicolonne, vous pouvez spécifier une valeur de début pour tous les champs de l'index ou pour certains des champs. Si aucune valeur n'est fournie pour l'un des champs utilisé dans l'index, une valeur null est affectée au champ lors de l'application de la portée. Si le début (ou la fin) de la portée n'est pas spécifié, la limite inférieure (ou supérieure) du domaine est alors utilisée. Si vous essayez de définir une valeur pour un champ ne figurant pas dans l’index, l'ensemble de données déclenche une exception.

Conseil : Pour commencer au début de l'ensemble de données, n'appelez pas SetRangeStart.

Pour terminer la spécification du début d'une portée, appelez SetRangeEnd ou appliquez ou annulez la portée.

Définition de la fin d'une portée

Appelez la procédure SetRangeEnd pour placer l'ensemble de données à l'état dsSetKey et commencez à créer une liste de valeurs de fin pour la portée. Après l'appel à SetRangeEnd, les affectations suivantes de la propriété Data.DB.TDataSet.Fields sont traitées comme des valeurs d'index de fin à utiliser lorsque la portée est appliquée. Les champs spécifiés doivent s'appliquer à l'index en cours.

Avertissement : Spécifiez toujours les valeurs de fin pour une portée, même si vous voulez qu'une portée se termine sur le dernier enregistrement de l'ensemble de données. Si vous ne fournissez pas de valeurs de fin, Delphi suppose que la valeur de fin de la portée est une valeur null. Une portée avec des valeurs de fin null est toujours vide.

La façon la plus simple d'assigner des valeurs de fin consiste à appeler la méthode Data.DB.TDataSet.FieldByName. Par exemple,

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();

Comme avec la spécification des valeurs de début de portée, si vous essayez de définir une valeur pour un champ ne figurant pas dans l'index, l'ensemble de données déclenche une exception.

Pour terminer la spécification de la fin d'une portée, appliquez ou annulez la portée.

Définition des valeurs de début et de fin de portée

Plutôt que d'utiliser des appels distincts à SetRangeStart et SetRangeEnd pour spécifier les limites de la portée, vous pouvez appeler la procédure SetRange pour placer l'ensemble de données à l'état dsSetKey et définir des valeurs de début et de fin pour une portée avec un simple appel.

SetRange prend deux paramètres tableau constants : un ensemble de valeurs de début et un ensemble de valeurs de fin. Par exemple, l'instruction suivante établit une portée basée sur un index de deux colonnes :

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);

Pour un index multicolonne, vous pouvez spécifier les valeurs de début et de fin pour tous les champs de l'index ou pour certains des champs. Si aucune valeur n'est fournie pour l'un des champs utilisé dans l'index, une valeur null est affectée au champ lors de l'application de la portée. Pour omettre une valeur pour le premier champ d'un index et spécifier des valeurs pour les champs suivants, passez une valeur null pour le champ omis.

Spécifiez toujours les valeurs de fin pour une portée, même si vous voulez qu'une portée se termine sur le dernier enregistrement de l'ensemble de données. Si vous ne fournissez pas des valeurs de fin, l'ensemble de données suppose que la valeur de fin de la portée est une valeur null. Une portée avec des valeurs de fin null est toujours vide car la portée de début est supérieure ou égale à la portée de fin.

Spécification d'une portée basée sur des clés partielles

Si une clé est composée d’un ou de plusieurs champs chaîne, les méthodes SetRange supportent les clés partielles. Par exemple, si un index est basé sur les colonnes LastName et FirstName, les spécifications de portée suivantes sont valides :

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();

Ce code inclut tous les enregistrements dans une portée où LastName est supérieur ou égal à "Smith". La spécification des valeurs peut aussi se présenter ainsi :

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

Cette instruction inclut les enregistrements où LastName est supérieur ou égal à "Sm".

Inclusion ou exclusion d'enregistrements correspondant aux valeurs de limites

Par défaut, une portée inclut tous les enregistrements supérieurs ou égaux à la portée de début spécifiée et inférieurs ou égaux à la portée de fin spécifiée. Ce comportement est contrôlé par la propriété KeyExclusive. Par défaut, KeyExclusive est défini sur False.

Si vous préférez, vous pouvez définir la propriété KeyExclusive d'un ensemble de données sur True pour exclure les enregistrements égaux à la portée de fin. Par exemple,

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();

Ce code inclut tous les enregistrements d'une portée où LastName est supérieur ou égal à "Smith" et inférieur à "Tyler".

Voir aussi