Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Determining field in a record type

Status
Not open for further replies.

rogerte

Programmer
Nov 9, 2001
164
GB
This is probably a stupid question, but we have been asked about it, and no-one here has a clue!

Lets say a Record is set up:

NRec = record
A : integer;
B : Integer;
C : integer;
end;
NewRec := NRec;

Assuming there are 3 possible conditions that have the same name as the record type fields (ie conditions are A B and C), every time a condition and value is come across the value of the corresponding record field should change to reflect that value (ie. if value is 5 and condition is B then NewRec.B should be set to 5 etc.)

The question is: How can one identify which field in the record to change?

If it was a Paradox table then "fieldByName('B').asInteger := 5" could be used.



 
I'm not really sure I understand the question but you could define NRec as follows:-
Code:
type
  Nrec = record
    case x: boolean of
      True: ( A: integer;
              B: integer;
              C: integer;
            );
      False: ( Vector: array [ 'A'..'C' ] of integer; );
  end;
And then you can define a variable of type NRec.
Code:
var
  data: Nrec;
and then assign a valuable to the second element of the array either by
Code:
begin
  data.Vector['B'] := 123;
end;
or by
Code:
begin
  data.B := 456;
end;


Andrew
Hampshire, UK
 
Thanks for the reply - probably didn't make myself too clear.

Assume that there are 2 edits. One (Edit1) contains 'B' the other (Edit2) contains '5.01'.

What is needed is for the field NewRec.B to be set to 5.01

If, however, the Edit1 contained 'C' then it would be NewRec.C which would need to be set to 5.01.

What I was trying to ask was - in such a case could one dynamically determine which record field to use rather than something like:

If Edit1.text = 'A' then NewRec.A := Edit2.text
else If Edit1.text = 'B' then NewRec.B := Edit2.text
else........ etc. etc.

I should point out that the real problem involves a 20 field record type!

Roger
 
This is quite easy using the NewRec that I defined earlier.
Code:
type
  Nrec = record
    case x: boolean of
      True: ( A: integer;
              B: integer;
              C: integer;
            );
      False: ( Vector: array [ 'A'..'C' ] of integer; );
  end;

var
  NewRec: Nrec;
...
begin
  NewRec.Vector [ Edit1.Text[1] ] := Edit2.Text;
Of course, you would want to put some checks in to make sure that Edit1.Text contains one (or more?) valid letters by coding an OnKeyPress event handler.


In the real problem your Record would be defined as:
Code:
type
  Nrec = record
    case x: boolean of
      True: ( A: integer;
              B: integer;
              C: integer;
              ...
              T: integer;
            );
      False: ( Vector: array [ 'A'..'T' ] of integer; );
  end;


Andrew
Hampshire, UK
 
procedure TfMain.Button1Click(Sender: TObject);
var aChar: AnsiChar;
begin
aChar := AnsiUpperCase(edtFieldName.Text)[1];//First 'uppercase' of Text/String
(*** Not necessariy anymore ***
case aChar of
'A': data.vector['A'] := StrToInt(edtValue.Text);
'B': data.vector['A'] := StrToInt(edtValue.Text);
'C': data.vector['A'] := StrToInt(edtValue.Text);
else
//Error
end;//case
*)
if (aChar < Low(data.vector)) or (aChar > High(data.vector))then begin
MessageDlg('Invalid FieldName : &quot;'+aChar+'&quot;'+#13#10
+'Valid FieldName: '+Low(data.vector)+'..'+High(data.vector)
, mtWarning, [mbOK], 0);
end else begin
data.vector[aChar] := StrToInt(edtValue.Text)
end;//else
end;
 
Roger,

In your first posting you say that the field B is an integer but in the second posting you have an example where you want to assign 5.01 to the field.

Assuming that you want it to be an integer then my suggested coding should be amended to
Code:
  NewRec.Vector[Edit1.Text[1]] := StrToIntDef(Edit2.Text,Low(Integer));
In this code, if an invalid integer is in Edit2.Text the minimum value of an integer is placed in the selected integer. You may have a different requirement.

You would still need to check that Edit1.Text[1] contains a valid character in the range of your subscripts.


Note that nyff2's code does not meet your requirement as it uses a case statement (and there is a typo in that each subscript is set to 'A' when they should be 'A', 'B', 'C').

Andrew
Hampshire, UK
 
Hi

I got 10 variables type Tbitmap
they are named bitmap1, bitmap2 .. .. bitmap10

when I write a procedure I don't want to repeat myself 10 times, but I would like to have the names changed in a loop

something like

for ii:=1 to 10 do
begin
bitmapii.free
end;

this doesn't work of course, but i would like to know how it will work
 
There is a useful function in Delphi called FindComponent and it is ideal for your requirement.
Code:
[COLOR=blue]
var
  ii: integer;
  bmp: TBitMap;
for ii := 1 to 10 do begin
  bmp := FindComponent('BitMap'+IntToStr(ii)) as TBitMap;
  bmp.Free;
end;
[/color]

Andrew
Hampshire, UK
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top