IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Conversions de mesures


précédentsommairesuivant

I. Généralités

I-A. Familles de conversions

Les familles de conversion prises en charge en standard par Delphi 6 sont les suivantes :

  • les distances (ex. : micromicron, mètre, mille nautique, pica, inch, etc.) ;
  • les aires (ex. : are, hectare, mètre carré, yard carré, inch carré, etc.) ;
  • les volumes (ex. : décimètre cube, hectomètre cubes, millilitre, décilitre, gallon, etc.) ;
  • les masses (ex. : nanogramme, hectogramme, grain, pound, etc.) ;
  • les températures (ex. : Celsius, kelvin, Fahrenheit, Réaumur, etc.) ;
  • le temps (ex. : milliseconde, minute, semaine, décades, date julienne, etc.).

Le nombre d'unités de mesure déclaré par famille est non négligeable, il y a de fortes chances que vous découvriez pour la première fois un bon nombre de termes scientifiques…

I-B. Types de conversions

Un type de conversion est un sous-élément d'une famille de conversion.

Le micromicron, le mètre sont des types de conversion de la famille des distances.

Le nanogramme et le grain le sont aussi pour la famille des masses.

I-C. Modes de conversions

On distingue deux modes de conversion :

I-C-1. La conversion simple

La conversion simple s'appuie sur un facteur numérique. Exemple 1 miles = 1609,344 mètres donc la conversion s'effectue avec un facteur multiplicateur de 1,609344.

Nous allons créer une application permettant de convertir des mètres en miles et inversement.

Posez sur une form deux champs TLabeledEdit (onglet Supplément) qui nous permettront de saisir les valeurs, un pour les mètres et un pour les miles (fig. 1).

Image non disponible
Figure 1

Dans la clause uses section implémentation de votre fiche, indiquez que vous utiliserez l'unité unités ConvUtils et StdConvs.

 
Sélectionnez
implementation

uses ConvUtils, StdConvs;

ConvUtils implémente les routines utilitaires de conversion, et StdConvs déclare les familles et types de mesures les plus courants (distances, températures, aires, volumes, etc.) accompagnés des facteurs multiplicateurs de conversion respectifs.

Nous allons implémenter les conversions Mètres <-> Miles dans les gestionnaires d'événement OnKeyDown des TLabeledEdit en interceptant la touche [Entrée].

 
Sélectionnez
procedure TfrmMetresMiles.edMetresKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  metres, miles: Double;
begin
  if Key = VK_RETURN then
  begin
    metres := StrToFloat(edMetres.Text);
    // Exécution de la conversion
    miles := Convert(metres, duMeters, duMiles);
    edMiles.Text := FloatToStr(miles);
  end;
end;

La fonction globale Convert se charge de la conversion en spécifiant la valeur à convertir suivie des unités de mesure source et destination. Elle est déclarée dans l'unité ConvUtils comme suit :

 
Sélectionnez
function Convert(const AValue: Double; const AFrom, ATo: TConvType): Double;

Le résultat est de type Double. Elle attend en paramètre :

  • la valeur à convertir (de type Double) ;
  • le type de l'unité de mesure de la valeur à convertir (exemple : duMeters pour Mètres) ;
  • le type de l'unité de mesure résultat (exemple : duMiles pour Miles).

Pour réaliser la conversion inverse, implémentez le gestionnaire OnKeyDown du TLabeledEdit respectif aux Miles, et appelez la routine de conversion Convert en inversant les types d'unités de mesure pour les paramètres AFrom et ATo :

Pour convertir des mètres en miles, nous avions la ligne de code suivante :

 
Sélectionnez
miles := Convert(metres, duMeters, duMiles);

On implémente l'opération inverse dans le gestionnaire OnKeyDown du TLabeledEdit respectif à la saisie des miles :

 
Sélectionnez
metres := Convert(miles, duMiles, duMeters);

Avantage de l'opération : nous avons réalisé une conversion de valeur entre deux unités de mesure à l'aide d'une seule ligne de code sans se soucier des unités ni des facteurs de conversion.

Jusqu'à présent, nous avons vu des conversions mettant en jeu une seule famille de conversions, les distances. Mais plusieurs cas existent où deux familles interviennent dans la mesure. Par exemple, les kilomètres/heure, les litres/minute, etc.

Nous allons ajouter des éléments à notre application (fig. 2) de façon à calculer une conversion d'un temps exprimé en secondes pour parcourir une distance en mètres, et obtenir la vitesse correspondante en kilomètres par heure :

Image non disponible
Figure 2

43"18 est le record du monde du 400 m plat détenu par Michaël Johnson (1999 - Séville).

Dans le code, nous allons intercepter la touche Entrée sur le TLabeledEdit de saisie du temps, et implémenter la conversion :

 
Sélectionnez
procedure TfrmMetresMiles.edTempsKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  distance, temps, vitesse: double;
begin
  if Key <> VK_RETURN then exit;
  distance := StrToFloat(edDistance.Text);
  temps := StrToFloat(edTemps.Text);
  // La vitesse est exprimée en m/s et convertie en km/h
  vitesse := Convert(distance/temps, duMeters, tuSeconds, duKilometers, tuHours);
  edVitesse.Text := FloatToStr(vitesse);
end;

Nous avons encore fait appel à la fonction Convert, mais cette fois avec des paramètres différents. Convert est en effet redéfini deux fois dans l'unité ConvUtils.

Voyons maintenant le deuxième mode de conversion…

I-C-2. La conversion procédurale

La conversion procédurale recherche un résultat qui n'est plus lié à un simple facteur de conversion, mais qui est pris en charge par une fonction de conversion implémentée par le développeur (exécution de méthodes d'un objet, récupération de données dans un SGBD, etc.).

Dans une application se chargeant d'effectuer une conversion francs/euros, nous aimerions que la routine de conversion se charge en plus d'appliquer l'arrondi bancaire.

Nous allons créer une application base de données locale de 1er niveau, utilisant un ClientDataSet qui servira de table locale pour stocker des enregistrements. Chaque enregistrement stockera un tarif en euros pour un article donné. Nous saisirons les montants en euros, mais pour un temps indéterminé nous souhaitons pouvoir afficher le montant respectif en francs. À cet effet, nous utiliserons un champ calculé pour l'affichage des montants en francs. De fait, lorsque nous n'aurons plus besoin de visualiser les prix en francs, il sera aisé de supprimer le champ calculé, sans pour autant modifier la structure de la table.

La conversion en elle-même est aussi simple que pour le premier exemple, puisque la conversion francs/euros ne tient qu'à une simple opération de multiplication ou de division réalisée par la fonction Convert (facteur multiplicateur de 6.55957).

Mais cela ne nous suffit pas, nous aimerions effectuer un arrondi bancaire sur le résultat, et surtout que le calcul de cet arrondi soit pris en charge par la routine de conversion elle-même.

L'unité EuroConv livrée dans les démos effectue cette opération en surchargeant certaines routines de ConvUtils de façon à personnaliser la conversion. En l'occurrence, après conversion classique d'une monnaie vers l'autre, le résultat est passé à la fonction SimpleRound qui effectue l'arrondi bancaire. On a bien ici une spécialisation de la conversion de base :

 
Sélectionnez
Result := AValue / Factor;

Revenons à notre application et dans la clause uses section implémentation de votre fiche, ajoutez une référence à l'unité EuroConv.

 
Sélectionnez
var
  frmEuroFranc: TfrmEuroFranc;

implementation

uses ConvUtils, EuroConv;

Attention l'unité EuroConv est située dans le dossier $DELPHI\Demos\ConvertIt, ce chemin doit être connu dans les options du projet (Répertoires/Chemin de Recherche) ou bien copiez-le dans le même dossier que votre application. L'unité EuroConv est un ajout de Borland au framework de conversion initial, en guise d'exemple de personnalisation. Elle recense toutes les monnaies liées à l'euro et permet donc de réaliser les conversions dans tous les sens de monnaie possibles.

I-C-2-a. Création de l'ensemble de données

Ensuite, disposez un TClientDataSet sur la fiche, double-cliquez dessus pour ouvrir l'éditeur de champs, ensuite un clic droit sur l'éditeur donne accès au menu [Nouveau Champ] (fig. 3).

Image non disponible
Figure 3

Ajoutez les champs suivants :

Nom du champ

Type de champ

Type de donnée

Valeur

IDTarif

Données

AutoInc

 

LibelleTarif

Données

String

100

TarifsEuro

Données

Float

 

TarifsFrancs

Calculé

Float

 

Ensuite, à l'aide du menu contextuel sur le ClientDataSet, sélectionnez [Créez un ensemble de données].

I-C-2-b. Connexions aux contrôles visuels

Disposez un DBGrid, un DBNavigator et des champs DB d'édition, tous reliés via un Datasource à l'ensemble de données client ci-dessus (fig. 4).

Image non disponible
Figure 4

À l'ouverture de l'application, nous activerons le ClientDataSet et le désactiverons à la fermeture.

 
Sélectionnez
procedure TfrmEuroFranc.FormCreate(Sender: TObject);
begin
  cdsTarif.Active := True;
end;
 
procedure TfrmEuroFranc.FormDestroy(Sender: TObject);
begin
  cdsTarif.Active := False;
end;
I-C-2-c. Réalisation de la conversion

Puisque c'est un champ calculé qui affichera le montant en francs respectif au montant saisi en euros, nous implémenterons la conversion en gérant l'événement OnCalcField du ClientDataSet :

 
Sélectionnez
procedure TfrmEuroFranc.cdsTarifCalcFields(DataSet: TDataSet);
begin
  TarifFrancs.Value := Convert(TarifEuros.Value, euEUR, euFFR);
end;

euEUR et euFFR sont des types d'unités de mesure déclarés dans l'unité EuroConv, et représentent respectivement les unités de mesure source et destination nécessaires à la conversion.

Avantage de l'opération : comme pour le premier exemple, un appel à la fonction Convert a suffi pour obtenir une conversion de données. Cependant cette dernière ici élargissait l'opération de base en ajoutant le calcul de l'arrondi bancaire.

On peut en conclure que nous bénéficions d'un ensemble cohérent et générique, quelle que soit la complexité de l'opération de conversion. Nous allons à présent étudier comment fonctionne ce framework de conversion et comment implémenter des conversions personnalisées non disponibles dans l'unité StdConvs et EuroConv.

Nous allons à présent découvrir le fonctionnement interne, à savoir comment les conversions sont réalisées par Delphi (et Kylix).


précédentsommairesuivant

Copyright © 2002 Sylvain James. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.