6
votes

Obtenez le décalage d'un champ dans un enregistrement DELPHI au moment de l'exécution

donné un type d'enregistrement: xxx

et le nom d'un champ comme une chaîne , comment puis-je obtenir le décalage de ce champ dans l'enregistrement? J'ai besoin de le faire au moment de l'exécution - le nom du champ à accéder est décidé au moment de l'exécution.

exemple: xxx

J'utilise DELPHI 7 .


2 commentaires

@joe ouais, je sais comment ça sent ça. Je ne lie pas réellement une zone de texte à cela; Ce n'était que l'exemple le plus simple que je puisse penser à illustrer le problème. Il fait réellement partie d'une sorte de moteur de règles, qui exécute des commandes pouvant se référer aux champs de base de données par son nom. Le problème est que les champs en question ont déjà été chargés dans un enregistrement lorsque ce code s'exécute.


Je suis allé avec une maintenue manuellement si-d'autre à la fin, coupez la chose de pointeur entièrement et juste mappage nom: chaîne à valeur: devise .


4 Réponses :


1
votes

Est-ce ce que vous recherchez

 type
   TItem = record
     UPC : string[20];
     Price : Currency;
     Cost : Currency;
     ...
   end; 

 var
   myRecord    : TItem ;
   myRecordPtr : ^TItem ;

 begin
   myRecord.price:= 100;
   myRecord.UPC := '111';
   myRecordPtr := @myRecord;
   if edit1.text = 'UPC' then   
     ShowMessage(myRecordptr.UPC);  // Displays '111'
   else if edit1.text = 'price' then   
     ShowMessage(myRecordptr.Price);  // Displays '100'
 end;


9 commentaires

Nope, j'ai une corde comme "UPC". Je souhaite utiliser la réflexion ou l'équivalent Delphi pour obtenir la valeur du champ que les noms de chaîne.


La chaîne pourrait être «UPC», ou cela pourrait être «prix» ou autre chose - je ne saurai pas avant l'heure d'exécution.


J'espère que j'ai mal compris. Mais showMessage (myRecordptr.price) affichera 100. Donc, ce dont vous avez besoin, c'est simplement remplacer UPC avec le prix.


Je ne peux pas faire ça à Runtime . J'ai une situation dans laquelle l'utilisateur saisira une zone de texte "Price" ou "UPC" ou autre, puis je dois afficher la valeur de ce champ (scénario simplifié).


Mais dans cette ligne Inc (PC, GetItemfieldOffset ('coût')); vous spécifiez cost.di vous voulez dire que vous ne savez pas si vous souhaitez spécifier le coût ou le prix ici jusqu'à ce que le temps d'exécution


Est-ce que la condition si résout votre problème? Vérifiez le message édité


Oui, cela fonctionnera - mais pour diverses raisons, je ne veux pas utiliser un bloc IF-elsesif. Il existe de nombreux champs dans le vrai disque et je ne veux pas avoir à mettre à jour mon code s'il change.


Re: Ne pas mettre à jour - j'ai bien peur que vous ne puissiez éviter cela dans D7.


Vous pouvez éviter l'IF-else Cascade si vous utilisez une sorte de registre (E.G. Procédure Addfield (Const Aname String; Aoffset: Integer); qui pourrait écrire sur une limite de filiste).



4
votes

après fonctionnerait pour votre scénario simplifié, mais je doute qu'il soit possible de faire une fonction générique pour ce genre de chose.

Le meilleur que je puisse penser si c'est ajouter une sorte de Objet d'enregistrement, mais il vous obligerait toujours à enregistrer tous les enregistrements dont vous avez besoin d'un décalage de. xxx


0 commentaires

8
votes

Vous ne pouvez pas. Delphi 7 n'émet pas de RTTI pour les enregistrements. Il existe d'autres options (comme les réponses précédentes), mais celles-ci nécessitent une cartographie manuelle du "nom du champ" -> "offset".


0 commentaires

4
votes

Comme Alex a dit, Delphi 7 n'émet pas RTTI pour les enregistrements. Vous ne pouvez donc pas récupérer les informations requises au moment de l'exécution. Toutefois, dans les versions ultérieures (Delphi 2010+), et le code suivant: xxx pré>

produira 'tiem {{nom = uppc, offset = 0} {nom = prix, offset = 24} {nom = coût, décalage = 32}} ' p>

Vous pouvez également définir la valeur de champ dans une instance particulière (bien que vous puissiez vraiment vérifier le type) en utilisant: p>

if fields[i].Name = 'Price' then
  fields[i].SetValue(@item, 10);


1 commentaires

À droite. Mettez un autre moyen, RTTI fait pour vous automatiquement et génériquement pour tous les types de ce que vous pouvez faire pour vous-même spécifiquement et le plus efficacement que seuls les types qui en ont besoin.