### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Array of Record as Property  (Read 704 times)

#### Weitentaaal

• Sr. Member
• Posts: 392
• Weitental is a very beautiful garbage depot.
##### Array of Record as Property
« on: June 28, 2022, 03:25:05 pm »
Hello,

how do i get this to work:

Code: Pascal  [Select][+][-]
1. TSomeRecord = record
2.    S1: String;
3.    S2: String;
4.    S3: String;
5. end;
6.
7. { TAClass }
8. TAClass = class
9.
10. private
11.    fSomeArr: Array[0..1] of TSomeRecord;
12.
13. private
14.    procedure SetSomeArr(index: Integer; AValue: TSomeRecord );
15.    function GetSomeArr(index: Integer): TSomeRecord ;
16.
17. public
18.    property SomeArr [index: Integer]: TSomeRecord read GetSomeArr write SetSomeArr;
19.    procedure InitData;
20.
21. end;
22. implementation
23.
24. procedure TAClass.InitData;
25. begin
26.    SomeArr[0].S1:= 'test';
27.    SomeArr[0].S2:= 'test';
28.    SomeArr[0].S3:= 'test';
29. end;
30.
31. function TAClass.GetSomeArr(index: Integer): TSomeRecord;
32. begin
33.    if (index < Length(fSomeArr)) and (index >= 0) then begin
34.       Result:= fSomeArr[index];
35.    end;
36. end;
37.
38. procedure TAClass.SetSomeArr(index: Integer; AValue: TSomeRecord);
39. begin
40.    if (index < Length(fSomeArr)) and (index >= 0) then begin
41.       fSomeArr[index].S1:= AValue.S1;
42.       fSomeArr[index].S2:= AValue.S2;
43.       fSomeArr[index].S3:= AValue.S3;
44.    end;
45.
46.    Case index of
47.       0: ShowMessage('Array Field 1 Changed');
48.       1: ShowMessage('Array Field 2 Changed')
49.    end;
50. end;
51.

This Code provides the following Error: "Argument cannot be assigned to"

Quote
SomeArr[0].S1:= 'test';
SomeArr[0].S2:= 'test';
SomeArr[0].S3:= 'test';

how do I change the code to make this work ?

« Last Edit: June 29, 2022, 07:47:09 am by Weitentaaal »
Lazarus: 2.0.12 x86_64-win64-win32/win64
Compiler Version: 3.2.0

#### Weitentaaal

• Sr. Member
• Posts: 392
• Weitental is a very beautiful garbage depot.
##### Re: Array of Record as Property
« Reply #1 on: June 28, 2022, 04:04:09 pm »
I solved it in a dirty way:

Code: Pascal  [Select][+][-]
1.       property SomeArrS1 [index: Integer]: String read GetSomeArrS1 write SetSomeArrS1;
2.       property SomeArrS2 [index: Integer]: String read GetSomeArrS2 write SetSomeArrS2;
3.       property SomeArrS3 [index: Integer]: String read GetSomeArrS3 write SetSomeArrS3;
4.

any other Solution?, because the number of getter and setter would explode
Lazarus: 2.0.12 x86_64-win64-win32/win64
Compiler Version: 3.2.0

#### jcmontherock

• Full Member
• Posts: 137
##### Re: Array of Record as Property
« Reply #2 on: June 28, 2022, 04:28:36 pm »
Two suggestions:
1) Use dynamic arrays. It works with records.
2) Set the length of your strings (ex: string[255]).

#### Zvoni

• Hero Member
• Posts: 1274
##### Re: Array of Record as Property
« Reply #3 on: June 28, 2022, 04:37:37 pm »
This works
Code: Pascal  [Select][+][-]
1. program Project1;
2. Uses SysUtils, Classes;
3.
4. Type
5.   TSomeRecord=Record
6.     s1:String;
7.     s2:String;
8.     s3:String;
9.   end;
10.
11.   { TAClass }
12.
13.   TAClass = Class
14.     Private
15.       fSomeArr:Array[0..1] Of TSomeRecord;
16.     Protected
17.       Procedure SetSomeArr(AIndex:Integer;AValue:TSomeRecord);
18.       Function GetSomeArr(AIndex:Integer):TSomeRecord;
19.     Public
20.       Property SomeArr[AIndex:Integer]:TSomeRecord Read GetSomeArr Write SetSomeArr;
21.       Procedure InitData;
22.   end;
23.
24. { TAClass }
25.
26. procedure TAClass.SetSomeArr(AIndex: Integer; AValue: TSomeRecord);
27. begin
28.   fSomeArr[AIndex].s1:=AValue.s1;
29.   fSomeArr[AIndex].s2:=AValue.s2;
30.   fSomeArr[AIndex].s3:=AValue.s3;
31. end;
32.
33. function TAClass.GetSomeArr(AIndex: Integer): TSomeRecord;
34. begin
35.   Result:=fSomeArr[AIndex];
36. end;
37.
38. procedure TAClass.InitData;
39. begin
40.   fSomeArr[0].s1:='Test 1';
41.   fSomeArr[0].s2:='Test 2';
42.   fSomeArr[0].s3:='Test 3';
43.   fSomeArr[1].s1:='empty 1';
44.   fSomeArr[1].s2:='empty 2';
45.   fSomeArr[1].s3:='empty 3';
46. end;
47.
48. Var
49.   MyClass:TAClass;
50.   MyArr:TSomeRecord;
51.   i:Integer;
52.
53. begin
54.   MyClass:=TAClass.Create;
55.   MyClass.InitData;
56.   For i:=0 To 1 Do
57.     Begin
58.       Writeln(MyClass.SomeArr[i].s1);
59.       Writeln(MyClass.SomeArr[i].s2);
60.       Writeln(MyClass.SomeArr[i].s3);
61.     End;
62.   MyArr.s1:='test 11';
63.   MyArr.s2:='test 12';
64.   MyArr.s3:='test 13';
65.   MyClass.SomeArr[1]:=MyArr;
66.   For i:=0 To 1 Do
67.     Begin
68.       Writeln(MyClass.SomeArr[i].s1);
69.       Writeln(MyClass.SomeArr[i].s2);
70.       Writeln(MyClass.SomeArr[i].s3);
71.     End;
72. end.

Returns
Test 1
Test 2
Test 3
empty 1
empty 2
empty 3
Test 1
Test 2
Test 3
test 11
test 12
test 13
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

#### Weitentaaal

• Sr. Member
• Posts: 392
• Weitental is a very beautiful garbage depot.
##### Re: Array of Record as Property
« Reply #4 on: June 28, 2022, 05:18:53 pm »
Two suggestions:
1) Use dynamic arrays. It works with records.
2) Set the length of your strings (ex: string[255]).

tried both, but i couldn't get it to work

This works
Code: Pascal  [Select][+][-]
1. program Project1;
2. Uses SysUtils, Classes;
3.
4. Type
5.   TSomeRecord=Record
6.     s1:String;
7.     s2:String;
8.     s3:String;
9.   end;
10.
11.   { TAClass }
12.
13.   TAClass = Class
14.     Private
15.       fSomeArr:Array[0..1] Of TSomeRecord;
16.     Protected
17.       Procedure SetSomeArr(AIndex:Integer;AValue:TSomeRecord);
18.       Function GetSomeArr(AIndex:Integer):TSomeRecord;
19.     Public
20.       Property SomeArr[AIndex:Integer]:TSomeRecord Read GetSomeArr Write SetSomeArr;
21.       Procedure InitData;
22.   end;
23.
24. { TAClass }
25.
26. procedure TAClass.SetSomeArr(AIndex: Integer; AValue: TSomeRecord);
27. begin
28.   fSomeArr[AIndex].s1:=AValue.s1;
29.   fSomeArr[AIndex].s2:=AValue.s2;
30.   fSomeArr[AIndex].s3:=AValue.s3;
31. end;
32.
33. function TAClass.GetSomeArr(AIndex: Integer): TSomeRecord;
34. begin
35.   Result:=fSomeArr[AIndex];
36. end;
37.
38. procedure TAClass.InitData;
39. begin
40.   fSomeArr[0].s1:='Test 1';
41.   fSomeArr[0].s2:='Test 2';
42.   fSomeArr[0].s3:='Test 3';
43.   fSomeArr[1].s1:='empty 1';
44.   fSomeArr[1].s2:='empty 2';
45.   fSomeArr[1].s3:='empty 3';
46. end;
47.
48. Var
49.   MyClass:TAClass;
50.   MyArr:TSomeRecord;
51.   i:Integer;
52.
53. begin
54.   MyClass:=TAClass.Create;
55.   MyClass.InitData;
56.   For i:=0 To 1 Do
57.     Begin
58.       Writeln(MyClass.SomeArr[i].s1);
59.       Writeln(MyClass.SomeArr[i].s2);
60.       Writeln(MyClass.SomeArr[i].s3);
61.     End;
62.   MyArr.s1:='test 11';
63.   MyArr.s2:='test 12';
64.   MyArr.s3:='test 13';
65.   MyClass.SomeArr[1]:=MyArr;
66.   For i:=0 To 1 Do
67.     Begin
68.       Writeln(MyClass.SomeArr[i].s1);
69.       Writeln(MyClass.SomeArr[i].s2);
70.       Writeln(MyClass.SomeArr[i].s3);
71.     End;
72. end.

Returns
Test 1
Test 2
Test 3
empty 1
empty 2
empty 3
Test 1
Test 2
Test 3
test 11
test 12
test 13

guess i will have to do it this way, just tried to avoid creating a temporery record. Thanks !
Lazarus: 2.0.12 x86_64-win64-win32/win64
Compiler Version: 3.2.0

#### MarkMLl

• Hero Member
• Posts: 4763
##### Re: Array of Record as Property
« Reply #5 on: June 28, 2022, 06:19:36 pm »
how do I change the code to make this work ?

By giving us a complete program to play with, including the bit where you set the compiler mode etc. and telling us what version of FPC you're using.

Sorry to nitpick, but what you're doing /shouldn't/ be a problem...

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

#### Warfley

• Hero Member
• Posts: 910
##### Re: Array of Record as Property
« Reply #6 on: June 28, 2022, 07:36:30 pm »
There is an easy but ugly way and a complicated way, which at the point of usage looks like direct access to the array.

First the easy way, just access it via pointer:
Code: Pascal  [Select][+][-]
1. type
2.   PTestRec = ^TTestRec;
3.   TTestRec = record
4.     A, B, C: Integer;
5.   end;
6.
7.   { TTest }
8.
9.   TTest = class
10.   private
11.     FData: array of TTestRec;
12.
13.     constructor Create;
14.     function GetItemPtr(AIndex: Integer): PTestRec;
15.   public
16.
17.     property ItemPtr[AIndex: Integer]: PTestRec read GetItemPtr;
18.   end;
19.
20. { TTest }
21.
22. constructor TTest.Create;
23. begin
24.   SetLength(FData, 1);
25.   FillChar(FData[0], SizeOf(TTestRec), #0);
26. end;
27.
28. function TTest.GetItemPtr(AIndex: Integer): PTestRec;
29. begin
30.   Result := @FData[AIndex];
31. end;
32.
33. var
34.   Test: TTest;
35. begin
36.   Test := TTest.Create;
37.   Test.ItemPtr[0]^.A := 42;
38.   Test.ItemPtr[0]^.B := 42;
39.   Test.ItemPtr[0]^.C := 42;
40.   WriteLn(Test.FData[0].A);
42. end.

This circumvents all access control (as you can see no setter), and you need to use the pointer notation ^ (which could be circumvented by using AutoDeref).

The complicated way is to create a temporary reference object:
Code: Pascal  [Select][+][-]
1. program Project1;
2.
3. {\$mode objfpc}{\$H+}
5.
6. type
7.   PTestRec = ^TTestRec;
8.   TTestRec = record
9.     A, B, C: Integer;
10.   end;
11.
12.   { TTestRecRef }
13.
14.   TTestRecRef = record
15.   private
16.     function GetA: Integer;
17.     function GetB: Integer;
18.     function GetC: Integer;
19.     procedure SetA(AValue: Integer);
20.     procedure SetB(AValue: Integer);
21.     procedure SetC(AValue: Integer);
22.   public
23.     Ref: PTestRec;
24.
25.     property A: Integer read GetA write SetA;
26.     property B: Integer read GetB write SetB;
27.     property C: Integer read GetC write SetC;
28.
29.     class operator:=(var AData: TTestRec): TTestRecRef;
31.   end;
32.
33.   { TTest }
34.
35.   TTest = class
36.   private
37.     FData: array of TTestRec;
38.
39.     constructor Create;
40.     function GetItem(AIndex: Integer): TTestRecRef;
41.     procedure SetItem(AIndex: Integer; AValue: TTestRecRef);
42.   public
43.
44.     property Item[AIndex: Integer]: TTestRecRef read GetItem write SetItem;
45.   end;
46.
47. constructor TTest.Create;
48. begin
49.   SetLength(FData, 1);
50.   FillChar(FData[0], SizeOf(TTestRec), #0);
51. end;
52.
53. function TTest.GetItem(AIndex: Integer): TTestRecRef;
54. begin
55.   Result := FData[AIndex];
56. end;
57.
58. procedure TTest.SetItem(AIndex: Integer; AValue: TTestRecRef);
59. begin
60.   FData[AIndex] := AValue;
61. end;
62.
63. { TTestRecRef }
64.
65. function TTestRecRef.GetA: Integer;
66. begin
67.   Result := Ref^.A;
68. end;
69.
70. function TTestRecRef.GetB: Integer;
71. begin
72.   Result := Ref^.B;
73. end;
74.
75. function TTestRecRef.GetC: Integer;
76. begin
77.   Result := Ref^.C;
78. end;
79.
80. procedure TTestRecRef.SetA(AValue: Integer);
81. begin
82.   Ref^.A := AValue;
83. end;
84.
85. procedure TTestRecRef.SetB(AValue: Integer);
86. begin
87.   Ref^.B := AValue;
88. end;
89.
90. procedure TTestRecRef.SetC(AValue: Integer);
91. begin
92.   Ref^.C := AValue;
93. end;
94.
95. class operator TTestRecRef.:=(var AData: TTestRec): TTestRecRef;
96. begin
98. end;
99.
100. class operator TTestRecRef.:=(AData: TTestRecRef): TTestRec;
101. begin
103. end;
104.
105.
106. var
107.   Test: TTest;
108. begin
109.   Test := TTest.Create;
110.   Test.Item[0].A:=42;
111.   Test.Item[0].B:=42;
112.   Test.Item[0].C:=42;
113.   WriteLn(Test.FData[0].A);
115. end.
116.
This also gives you fine grained access control to every bit of the record

#### Weitentaaal

• Sr. Member
• Posts: 392
• Weitental is a very beautiful garbage depot.
##### Re: Array of Record as Property
« Reply #7 on: June 29, 2022, 07:39:25 am »
how do I change the code to make this work ?

By giving us a complete program to play with, including the bit where you set the compiler mode etc. and telling us what version of FPC you're using.

Sorry to nitpick, but what you're doing /shouldn't/ be a problem...

MarkMLl

Attached a small example

Lazarus: 2.0.12 x86_64-win64-win32/win64
Compiler Version: 3.2.0

#### Weitentaaal

• Sr. Member
• Posts: 392
• Weitental is a very beautiful garbage depot.
##### Re: Array of Record as Property
« Reply #8 on: June 29, 2022, 07:46:11 am »
There is an easy but ugly way and a complicated way, which at the point of usage looks like direct access to the array.

First the easy way, just access it via pointer:
Code: Pascal  [Select][+][-]
1. type
2.   PTestRec = ^TTestRec;
3.   TTestRec = record
4.     A, B, C: Integer;
5.   end;
6.
7.   { TTest }
8.
9.   TTest = class
10.   private
11.     FData: array of TTestRec;
12.
13.     constructor Create;
14.     function GetItemPtr(AIndex: Integer): PTestRec;
15.   public
16.
17.     property ItemPtr[AIndex: Integer]: PTestRec read GetItemPtr;
18.   end;
19.
20. { TTest }
21.
22. constructor TTest.Create;
23. begin
24.   SetLength(FData, 1);
25.   FillChar(FData[0], SizeOf(TTestRec), #0);
26. end;
27.
28. function TTest.GetItemPtr(AIndex: Integer): PTestRec;
29. begin
30.   Result := @FData[AIndex];
31. end;
32.
33. var
34.   Test: TTest;
35. begin
36.   Test := TTest.Create;
37.   Test.ItemPtr[0]^.A := 42;
38.   Test.ItemPtr[0]^.B := 42;
39.   Test.ItemPtr[0]^.C := 42;
40.   WriteLn(Test.FData[0].A);
42. end.

This circumvents all access control (as you can see no setter), and you need to use the pointer notation ^ (which could be circumvented by using AutoDeref).

The complicated way is to create a temporary reference object:
Code: Pascal  [Select][+][-]
1. program Project1;
2.
3. {\$mode objfpc}{\$H+}
5.
6. type
7.   PTestRec = ^TTestRec;
8.   TTestRec = record
9.     A, B, C: Integer;
10.   end;
11.
12.   { TTestRecRef }
13.
14.   TTestRecRef = record
15.   private
16.     function GetA: Integer;
17.     function GetB: Integer;
18.     function GetC: Integer;
19.     procedure SetA(AValue: Integer);
20.     procedure SetB(AValue: Integer);
21.     procedure SetC(AValue: Integer);
22.   public
23.     Ref: PTestRec;
24.
25.     property A: Integer read GetA write SetA;
26.     property B: Integer read GetB write SetB;
27.     property C: Integer read GetC write SetC;
28.
29.     class operator:=(var AData: TTestRec): TTestRecRef;
31.   end;
32.
33.   { TTest }
34.
35.   TTest = class
36.   private
37.     FData: array of TTestRec;
38.
39.     constructor Create;
40.     function GetItem(AIndex: Integer): TTestRecRef;
41.     procedure SetItem(AIndex: Integer; AValue: TTestRecRef);
42.   public
43.
44.     property Item[AIndex: Integer]: TTestRecRef read GetItem write SetItem;
45.   end;
46.
47. constructor TTest.Create;
48. begin
49.   SetLength(FData, 1);
50.   FillChar(FData[0], SizeOf(TTestRec), #0);
51. end;
52.
53. function TTest.GetItem(AIndex: Integer): TTestRecRef;
54. begin
55.   Result := FData[AIndex];
56. end;
57.
58. procedure TTest.SetItem(AIndex: Integer; AValue: TTestRecRef);
59. begin
60.   FData[AIndex] := AValue;
61. end;
62.
63. { TTestRecRef }
64.
65. function TTestRecRef.GetA: Integer;
66. begin
67.   Result := Ref^.A;
68. end;
69.
70. function TTestRecRef.GetB: Integer;
71. begin
72.   Result := Ref^.B;
73. end;
74.
75. function TTestRecRef.GetC: Integer;
76. begin
77.   Result := Ref^.C;
78. end;
79.
80. procedure TTestRecRef.SetA(AValue: Integer);
81. begin
82.   Ref^.A := AValue;
83. end;
84.
85. procedure TTestRecRef.SetB(AValue: Integer);
86. begin
87.   Ref^.B := AValue;
88. end;
89.
90. procedure TTestRecRef.SetC(AValue: Integer);
91. begin
92.   Ref^.C := AValue;
93. end;
94.
95. class operator TTestRecRef.:=(var AData: TTestRec): TTestRecRef;
96. begin
98. end;
99.
100. class operator TTestRecRef.:=(AData: TTestRecRef): TTestRec;
101. begin
103. end;
104.
105.
106. var
107.   Test: TTest;
108. begin
109.   Test := TTest.Create;
110.   Test.Item[0].A:=42;
111.   Test.Item[0].B:=42;
112.   Test.Item[0].C:=42;
113.   WriteLn(Test.FData[0].A);
115. end.
116.
This also gives you fine grained access control to every bit of the record

Thank you, for those examples !

i do like your first Example. i will give t a try !

your second example does look good but how i said earlier, the number of getter and setter will explode.
Lazarus: 2.0.12 x86_64-win64-win32/win64
Compiler Version: 3.2.0

#### MarkMLl

• Hero Member
• Posts: 4763
##### Re: Array of Record as Property
« Reply #9 on: June 29, 2022, 10:23:58 am »
Attached a small example

OK, so the missing link is that it's mode objfpc and you've got H+.

Zvoni's obviously got a neat solution, but TBH I think I'd go for the verbose solution even if it required a great deal of boilerplate code, since that unambiguously avoids shuffling fields around when they're not going to be changed.

In the general case and noting that in your example the elements are of the same type, do you really need to have a record with (named) fields or could this be done with an array with indexed elements?

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

#### Weitentaaal

• Sr. Member
• Posts: 392
• Weitental is a very beautiful garbage depot.
##### Re: Array of Record as Property
« Reply #10 on: June 29, 2022, 10:41:38 am »
Attached a small example

OK, so the missing link is that it's mode objfpc and you've got H+.

Zvoni's obviously got a neat solution, but TBH I think I'd go for the verbose solution even if it required a great deal of boilerplate code, since that unambiguously avoids shuffling fields around when they're not going to be changed.

In the general case and noting that in your example the elements are of the same type, do you really need to have a record with (named) fields or could this be done with an array with indexed elements?

MarkMLl

yes i need  a record with (named) fields because in my Code its a rcord of Double, String and integer. Didn't thought about this when writing the example code, just wanted to try this.

Thank you i will take one of the various Solution you guys presented me

Lazarus: 2.0.12 x86_64-win64-win32/win64
Compiler Version: 3.2.0

#### Paolo

• Sr. Member
• Posts: 321
##### Re: Array of Record as Property
« Reply #11 on: June 29, 2022, 11:10:22 am »
this can help ?

see attached file

Code: Pascal  [Select][+][-]
1.   StrNum = (S1, S2, S3);    //-- her you can add/remove other elements without change next code
2.
3.   TStrArr = array [StrNum] of string;
4.
5.   TSomeRecord2 = record
6.     String_ : TStrArr;
7.   end;
8.
9.
10.   { TAClass2 }
11.
12.   TAClass2 = class
13.   private
14.     fSomeArr: Array[0..1] of TSomeRecord2;
15.   private
16.     function GetSomeArrStr(index: integer; SNum: StrNum): string;
17.     procedure SetSomeArrStr(index: integer; Snum: StrNum; AValue: string);
18.     procedure SetSomeArr(index: Integer; AValue: TSomeRecord2);
19.     function GetSomeArr(index: Integer): TSomeRecord2;
20.   public
21.     property SomeArr [index: Integer]: TSomeRecord2 read GetSomeArr write SetSomeArr;
22.     property SomeArrStr [index1: integer; SNum: StrNum]: string read GetSomeArrStr write SetSomeArrStr; default;
23.     procedure InitData;
24.   end;
25.
26. var
27.   Form1: TForm1;
28.
29. implementation
30.
31. {\$R *.lfm}
32.
33. var
34.   TmpRec : TAClass2;
35.
36. { TForm1 }
37.
38. procedure TForm1.Button1Click(Sender: TObject);
39. begin
40.   TmpRec[0,S1]:=Edit1.Text;  //example usage in assignement
41.   TmpRec[0,S2]:=Edit2.Text;
42.   TmpRec[0,S3]:=Edit3.Text;
43. end;
44.
45. procedure TForm1.Button2Click(Sender: TObject);
46. begin
47.   Edit4.Text:=TmpRec[0,S1];  //example usage in reading
48.   Edit5.Text:=TmpRec[0,S2];
49.   Edit6.Text:=TmpRec[0,S3];
50. end;
51.
52. { TAClass2 }
53.
54. function TAClass2.GetSomeArrStr(index: integer; SNum: StrNum): string;
55. begin
56.   result:=fSomeArr[index].String_[SNum];
57. end;
58.
59. procedure TAClass2.SetSomeArrStr(index: integer; Snum: StrNum; AValue: string);
60. begin
61.   fSomeArr[index].String_[SNum]:=AValue;
62. end;
63.
64. procedure TAClass2.SetSomeArr(index: Integer; AValue: TSomeRecord2);
65. begin
66.   fSomeArr[index]:=AValue;
67. end;
68.
69. function TAClass2.GetSomeArr(index: Integer): TSomeRecord2;
70. begin
71.   Result:=fSomeArr[index];
72. end;
73.
74. procedure TAClass2.InitData;
75. begin
76.   fSomeArr[0].String_[S1]:='test1';
77.   fSomeArr[0].String_[S2]:='test2';
78.   fSomeArr[0].String_[S3]:='test3';
79. end;
80.

#### Weitentaaal

• Sr. Member
• Posts: 392
• Weitental is a very beautiful garbage depot.
##### Re: Array of Record as Property
« Reply #12 on: June 29, 2022, 11:29:00 am »
this can help ?

see attached file

Code: Pascal  [Select][+][-]
1.   StrNum = (S1, S2, S3);    //-- her you can add/remove other elements without change next code
2.
3.   TStrArr = array [StrNum] of string;
4.
5.   TSomeRecord2 = record
6.     String_ : TStrArr;
7.   end;
8.
9.
10.   { TAClass2 }
11.
12.   TAClass2 = class
13.   private
14.     fSomeArr: Array[0..1] of TSomeRecord2;
15.   private
16.     function GetSomeArrStr(index: integer; SNum: StrNum): string;
17.     procedure SetSomeArrStr(index: integer; Snum: StrNum; AValue: string);
18.     procedure SetSomeArr(index: Integer; AValue: TSomeRecord2);
19.     function GetSomeArr(index: Integer): TSomeRecord2;
20.   public
21.     property SomeArr [index: Integer]: TSomeRecord2 read GetSomeArr write SetSomeArr;
22.     property SomeArrStr [index1: integer; SNum: StrNum]: string read GetSomeArrStr write SetSomeArrStr; default;
23.     procedure InitData;
24.   end;
25.
26. var
27.   Form1: TForm1;
28.
29. implementation
30.
31. {\$R *.lfm}
32.
33. var
34.   TmpRec : TAClass2;
35.
36. { TForm1 }
37.
38. procedure TForm1.Button1Click(Sender: TObject);
39. begin
40.   TmpRec[0,S1]:=Edit1.Text;  //example usage in assignement
41.   TmpRec[0,S2]:=Edit2.Text;
42.   TmpRec[0,S3]:=Edit3.Text;
43. end;
44.
45. procedure TForm1.Button2Click(Sender: TObject);
46. begin
47.   Edit4.Text:=TmpRec[0,S1];  //example usage in reading
48.   Edit5.Text:=TmpRec[0,S2];
49.   Edit6.Text:=TmpRec[0,S3];
50. end;
51.
52. { TAClass2 }
53.
54. function TAClass2.GetSomeArrStr(index: integer; SNum: StrNum): string;
55. begin
56.   result:=fSomeArr[index].String_[SNum];
57. end;
58.
59. procedure TAClass2.SetSomeArrStr(index: integer; Snum: StrNum; AValue: string);
60. begin
61.   fSomeArr[index].String_[SNum]:=AValue;
62. end;
63.
64. procedure TAClass2.SetSomeArr(index: Integer; AValue: TSomeRecord2);
65. begin
66.   fSomeArr[index]:=AValue;
67. end;
68.
69. function TAClass2.GetSomeArr(index: Integer): TSomeRecord2;
70. begin
71.   Result:=fSomeArr[index];
72. end;
73.
74. procedure TAClass2.InitData;
75. begin
76.   fSomeArr[0].String_[S1]:='test1';
77.   fSomeArr[0].String_[S2]:='test2';
78.   fSomeArr[0].String_[S3]:='test3';
79. end;
80.

very creative solution !

Thank you ! i will try this one too.
Lazarus: 2.0.12 x86_64-win64-win32/win64
Compiler Version: 3.2.0

#### Paolo

• Sr. Member
• Posts: 321
##### Re: Array of Record as Property
« Reply #13 on: June 29, 2022, 02:39:38 pm »
this also should work (not in deep tested), see attached code.

Code: Pascal  [Select][+][-]
1.
2.   TSomeRecord = record
3.     S1, S2, S3 : string;
4.   end;
5.
6.   { TIntClass }
7.
8.   TIntClass = class
9.   private
10.     fSomeRec: TSomeRecord;
11.     function GetStr(index: integer): string;
12.     procedure SetStr(index: integer; AValue: string);
13.   public
14.     property S1: string Index 1 read GetStr write SetStr;  //<-- property indexing technique, just one get and set for all Sj
15.     property S2: string Index 2 read GetStr write SetStr;
16.     property S3: string Index 3 read GetStr write SetStr;
17.   end;
18.
19.   { TAClass3 }
20.
21.   TAClass3 = class
22.   private
23.     fSomeArr: array [0..1] of TIntClass;
24.   private
25.     procedure SetSomeArr(index: Integer; AValue: TIntClass);
26.     function GetSomeArr(index: Integer): TIntClass;
27.   public
28.     property SomeArr [index: Integer]: TIntClass read GetSomeArr write SetSomeArr; default;
29.     procedure InitData;
30.     constructor Create;
31.     destructor Destroy; override;
32.   end;
33.
34. var
35.   Form1: TForm1;
36.
37. implementation
38.
39. {\$R *.lfm}
40.
41. var
42.   TmpRec : TAClass3;
43.
44. { TIntClass }
45.
46. function TIntClass.GetStr(index: integer): string;
47. begin
48.   case index of
49.     1:result:=fSomeRec.S1;
50.     2:result:=fSomeRec.S2;
51.     3:result:=fSomeRec.S3
52.   end;
53. end;
54.
55. procedure TIntClass.SetStr(index: integer; AValue: string);
56. begin
57.   case index of
58.     1:fSomeRec.S1:=AValue;
59.     2:fSomeRec.S2:=AValue;
60.     3:fSomeRec.S3:=AValue
61.   end;
62. end;
63.
64. { TForm1 }
65.
66. procedure TForm1.Button1Click(Sender: TObject);
67. begin
68.   case CheckBox1.checked of
69.     true:begin
70.       TmpRec[0].S1:=Edit1.Text;
71.       TmpRec[0].S2:=Edit2.Text;
72.       TmpRec[0].S3:=Edit3.Text;
73.     end;
74.     false:begin
75.       TmpRec[1].S1:=Edit1.Text+'2';
76.       TmpRec[1].S2:=Edit2.Text+'2';
77.       TmpRec[1].S3:=Edit3.Text+'2';
78.     end;
79.   end;
80. end;
81.
82. procedure TForm1.Button2Click(Sender: TObject);
83. begin
84.   case CheckBox1.checked of
85.     true:begin
86.       Edit4.Text:=TmpRec[0].S1;
87.       Edit5.Text:=TmpRec[0].S2;
88.       Edit6.Text:=TmpRec[0].S3;
89.     end;
90.     false:begin
91.       Edit4.Text:=TmpRec[1].S1;
92.       Edit5.Text:=TmpRec[1].S2;
93.       Edit6.Text:=TmpRec[1].S3;
94.     end;
95.   end;
96. end;
97.
98. { TAClass3 }
99.
100. procedure TAClass3.SetSomeArr(index: Integer; AValue: TIntClass);
101. begin
102.   fSomeArr[index].fSomeRec:=AValue.fSomeRec; //caution here... copy only data
103. end;
104.
105. function TAClass3.GetSomeArr(index: Integer): TIntClass;
106. begin
107.   Result:=fSomeArr[index];
108. end;
109.
110. procedure TAClass3.InitData;
111. begin
112.   fSomeArr[0].S1:='test1';
113.   fSomeArr[0].S2:='test2';
114.   fSomeArr[0].S3:='test3';
115. end;
116.
117. constructor TAClass3.Create;
118. begin
119.   inherited Create;
120.   fSomeArr[0]:=TIntClass.Create;
121.   fSomeArr[1]:=TIntClass.Create;
122. end;
123.
124. destructor TAClass3.Destroy;
125. begin
126.   fSomeArr[1].Free;
127.   fSomeArr[0].Free;
128.   inherited Destroy;
129. end;
130.
131. initialization
132.   TmpRec:=TAClass3.Create;
133. end.
134.
135.

Here it is allowed to write what (as I understood) you want
Code: Pascal  [Select][+][-]
1. TmpRec[0].S1:=Edit1.Text;
2. Edit4.Text:=TmpRec[0].S1;
3.

let me know if you will find bugs.