Change the variable whose name is specified as input (Pascal)

I would like to know if there is a basic way to solve this problem. Also particularly interested in specific solutions for Pascal.

Let's say we have a form with two inputs: "InputVARIABLE" and "InputVALUE".

In the InputVARIABLE area, the user enters the name of the variable that he wants to change. In the InputVALUE area, the user enters the value of this variable.

So, for inputtexts "color" and "blue": how can I change the VAR_color variable without using IF statements, for example:

If InputVARIABLE.Text = 'color' Then VAR_color := InputVALUE.Text; 

Is there, for example, some function like:

 ChangeVariable(InputVARIABLE.Text, InputValue.Text) 

Hope you can help!

+3
source share
2 answers

In general, you cannot access characters in Pascal by using their name in a textual representation (string)

The Pascal / Delphi object has some extensions for this, but they are mainly intended for specific purposes (for example, allowing the framework to transfer data without knowing it), and less for regular code.

Therefore, you need to make changes to the plan. Usually you look at the names in an array of variablenames (or tstringlist if Object Pascal), and if a valid match is found, you use the index to set the result in the array.

+2
source

If you don't need to change the actual variables predefined in delphi, you can do something else.

All you really need is to save key-value pairs.

This in other languages ​​is called an associative array / dictionary / value key pairs

So you can say

 Arr['color'] := 'red'; 

or say

 Arr[edit1.Text] := edit2.Text; 

then in the opposite

 Caption := Arr['color']; 

sets the header to "red" or something else in edit2.text, you can add as many as you want.

If you have an older version of Delphi, you can do the same with the Tlist class, just not nested.

 arr:= TStringList.Create; arr.Add('color=red'); s := arr.Values['color']; arr.free; 

I also needed a nest, so I created an associative array class using the dictionary in delphi XE3, which may also help you in the future.

 unit assoc; interface uses System.Generics.Collections, System.SysUtils; type TAssoc = class private fVal: Variant; fStrict: Boolean; fDict: TDictionary<Variant,TAssoc>; function GetItem(Index: Variant): TAssoc; procedure SetVal(v: Variant); function GetVal:Variant; public /// <summary> /// Returns the TAssocnode by default allowing you to chain Nodes /// </summary> /// <param name="Index"> /// Search index, can be any primitive type. /// </param> property Items[Index: Variant]: TAssoc read GetItem; default; /// <summary> /// Use this to read and write a node value. /// </summary> /// <value> /// can be almost everything Try not to use objects in here. /// </value> property Val:Variant read GetVal write SetVal; /// <summary> /// Gives you a direct link to the tdictionary object alowing you to /// itterate /// </summary> property All:TDictionary<Variant,TAssoc> read fDict; /// <summary> /// <para> /// Usefull for creating keys in strict mode /// </para> /// <para> /// Array.add('key');<br />Array['key'].Val = 1; /// </para> /// <para> /// Wich would throw an error in strict mode as 'key' is not defined /// <br />In non strict mode it will just be created for you /// </para> /// </summary> function Add(Index: Variant):TAssoc; overload; /// <summary> /// <para> /// Usefull for creating keys in strict mode and setting its value at the same time /// </para> /// <para> /// Array.add('key',1);<br />Array['key'].Val = 1; /// </para> /// <para> /// Wich would throw an error in strict mode as 'key' is not defined /// <br />In non strict mode it will just be created for you /// </para> /// </summary> function Add(Index: Variant; Value: Variant):TAssoc; overload; /// <summary> /// Strictmode will raise an exception when you try to:<br />- set a nod /// that was already set instead of overwriting it.<br />- read a node /// that was nto set /// </summary> /// <param name="strictRules"> /// Strictmode on of off /// </param> constructor Create(strictRules:Boolean); destructor Free; /// <summary> /// Clears all underlying nodes /// </summary> procedure Clear; end; type TAssocEnum = TPair<Variant, TAssoc>; implementation { TAssoc } function TAssoc.Add(Index: Variant): TAssoc; begin Result := nil; if(fDict<>nil) then begin // see if dict is or can be made if(fDict.ContainsKey(Index)) then begin // see if the key is in there if(fStrict = true) then begin // duplicate keys not strict raise Exception.Create('Dictionary is in strict mode, the key "'+Index+'" was already set.'); end; end else begin // dict made, just not the key Result := TAssoc.Create(fStrict); fDict.Add(Index,Result); end; end else begin // dict not found begin // make dict and key fDict := TDictionary<Variant,TAssoc>.Create(1); Result := TAssoc.Create(fStrict); fDict.Add(Index,Result); end; end; end; function TAssoc.Add(Index, Value: Variant): TAssoc; begin Result := Add(Index); Result.Val := Value; end; procedure TAssoc.Clear; var Enum: TPair<Variant, TAssoc>; begin if(fDict<>nil) then begin for Enum in fDict do begin Enum.Value.Free; end; end; fDict.Clear; end; constructor TAssoc.Create(strictRules:Boolean); begin fStrict := strictRules; fDict := nil; TVarData(fVal).VType := varEmpty; end; destructor TAssoc.Free; var Enum: TPair<Variant, TAssoc>; begin if(fDict<>nil) then begin for Enum in fDict do begin Enum.Value.Free; end; end; end; function TAssoc.GetItem(Index: Variant): TAssoc; var v: Variant; begin Result := nil; if(fdict<>nil) then begin // see if dict is or can be made if(fDict.ContainsKey(Index)) then begin // see if the key is in there Result := fDict.Items[Index]; end else begin // dict made, just not the key if (fStrict) then begin raise Exception.Create('Dictionary is in strict mode, the key "'+Index+'" was not set.'); end else begin // if not set, create the index and make it into a assocnode Result := TAssoc.Create(fStrict); fDict.Add(Index,Result); end; end; end else begin // if the key is not in there see if strict or not if(fStrict) then begin // if strict then error index not set raise Exception.Create('Dictionary is in strict mode, the key "'+Index+'" was not set.'); end else begin // if not set, create the index and make it into a assocnode fDict := TDictionary<Variant,TAssoc>.Create(1); Result := TAssoc.Create(fStrict); fDict.Add(Index,Result); end; end; end; function TAssoc.GetVal: Variant; begin Result := fVal; end; procedure TAssoc.SetVal(v: Variant); begin fVal := v; end; // todo: // make a kickass helper class // output xml/json // walk through tree // parentnode property? // make a delphi7 version using stringlist? (not worth it) // have fun end. 

Simple use

 Arr := TAssoc.Create(False); Arr['color'].Val := 'red'; Arr[edit1.text].Val := edit2.text; Arr.Free; 

Extended use

 Arr := TAssoc.Create(False); Arr['cuzz']['cdcollection'][1]['name'].Val := 'Mika Album'; // set cd Arr['cuzz']['cdcollection'][2]['name'].Val := 1; // set cd Arr['cuzz']['cdcollection'][1]['name'].Val := 'Delphi 5'; // overwrite cd Arr['cuzz']['cdcollection']['last']['name'].Val := 'Delphi xe3'; // overwrite cd // list all cd's for Enum in Arr['cuzz']['cdcollection'].All do begin Memo1.Lines.Append('Property "'+String(Enum.Key)+'" holds "'+String(Enum.Value['name'].Val)); end; Arr.Free; 

Delphi rocks! Enjoy it.

+8
source

All Articles