Recent

Author Topic: (Solved)Listbox to array error  (Read 3836 times)

JLWest

  • Hero Member
  • *****
  • Posts: 1293
(Solved)Listbox to array error
« on: November 29, 2020, 01:27:02 am »
I don't know what this means.

unit1.pas(1639,22) Error: No default property available

Code: Pascal  [Select][+][-]
  1. procedure TForm1.GenericArrayLoad( TheARRAY : Array of String; ABox : Tlistbox; ASort : Boolean);
  2.  var i  : Integer;
  3.    Item : String;
  4.  begin
  5.   ABOX.Sorted := ASORT;
  6.   if ABox.Items.Count = 0 then begin exit; end;
  7.      for i := 0 to ABOX.Items.Count -1 do begin
  8.          Item := ABOX[i];                                            {Error line 8}
  9.          THEARRAY[i] := Item;
  10.      end;
  11.  end;  

Thanks
« Last Edit: November 30, 2020, 12:55:45 am by JLWest »
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: Listbox to array error
« Reply #1 on: November 29, 2020, 01:28:51 am »

See Parser Messages where you'll find:

"You are trying to access a default property of a class, but this class (or one of its ancestors) doesn’t have a default property."

JLWest

  • Hero Member
  • *****
  • Posts: 1293
Re: Listbox to array error
« Reply #2 on: November 29, 2020, 01:47:10 am »
Thanks, I guess I can't write a generic like this.

 Item := ABOX.Items;   and it works
« Last Edit: November 29, 2020, 01:50:27 am by JLWest »
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Listbox to array error
« Reply #3 on: November 29, 2020, 04:00:08 am »
I guess you meant:
Code: Pascal  [Select][+][-]
  1.  Item := ABOX.Items[i];

The forum software is a little tricky with bracketed things ;D
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

JLWest

  • Hero Member
  • *****
  • Posts: 1293
Re: Listbox to array error
« Reply #4 on: November 29, 2020, 05:43:52 am »
No not really.  I load 4 or 5 arrays in a program and was trying to write a generic load.

Pass a procedure a dynamic array, listbox  and true or false for the sorted option on the list box. Thinking one procedure could load all the arrays.

I got past the problem of Item := ABOX; with Item := ABOX.Items;

bur I now have a error of trying to setlength of the array passed as a parm.

  SetLength(THEARRAY,0);
  SetLength( THEARRAY, i); 

error of type mismatch. So maybe i can't do this.

   

Code: Pascal  [Select][+][-]
  1. procedure TForm1.GenericArrayLoad( TheARRAY : Array of String; ABox : Tlistbox; ASort : Boolean);
  2.  var i  : Integer;
  3.    Item : String;
  4.  begin
  5.   ABOX.Sorted := ASORT;
  6.   i := ABOX.Items.Count;
  7.   Application.ProcessMessages;
  8.   SetLength(THEARRAY,0);                                     {error}
  9.   SetLength( THEARRAY, i);                                     {error}
  10.   if ABox.Items.Count = 0 then begin exit; end;
  11.   for i := 0 to ABOX.Items.Count -1 do begin
  12.       Item := ABOX.Items[i];
  13.       THEARRAY[i] := Item;
  14.   end;
  15.  end;
  16.                          

 
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: Listbox to array error
« Reply #5 on: November 29, 2020, 07:04:02 am »
Pascal is strict. In your case, you have to declare a type for the "array of string" to use it in the parameter list before you can use SetLength.

Code: Pascal  [Select][+][-]
  1. type
  2.   TStringOfArray = array of string;
  3.  
  4. procedure TForm1.GenericArrayLoad(TheARRAY: TStringOfArray; ABox : Tlistbox; ASort : Boolean);
  5. begin
  6.    // ...
  7.   SetLength(TheArray, i);
  8.    // ...
  9. end;

Alternatively you can use the ready define type TStringArray.

JLWest

  • Hero Member
  • *****
  • Posts: 1293
Re: Listbox to array error
« Reply #6 on: November 29, 2020, 07:34:03 am »
It lets me declare the type but still gives me the error. Type mismatch on the setlength statement.

FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Listbox to array error
« Reply #7 on: November 29, 2020, 10:26:54 am »
Your procedure would be better written like this:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.GenericArrayLoad(out theArray: TStringArray; aBox: TListBox; aSort: Boolean);
  2. var
  3.   i: Integer;
  4. begin
  5.  theArray := Nil;
  6.  if aBox.Items.Count = 0 then    
  7.     Exit;
  8.   aBox.Sorted := aSort;
  9.   SetLength(theArray, aBox.Items.Count);
  10.   for i := 0 to aBox.Items.Count-1 do
  11.     theArray[i] := aBox.Items[i];
  12. end;
If that give a type mismatch error, something else is wrong. Is SysUtils in your uses clause?

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: Listbox to array error
« Reply #8 on: November 29, 2020, 11:16:57 am »
Listbox.Items is derived from Tstrings, so you can simply do TStrings.ToStringArray (returns TStringDynArray a.k.a. array of string, declared in types)
Why take the long road or the hard way? One call... No loops.
Code: Pascal  [Select][+][-]
  1. procedure TForm1.GenericArrayLoad(out theArray: TStringdynArray; const aBox: TListBox;);
  2. begin
  3.   theArray := aBox.Items.ToStringArray; // that is really all there is to it!!!!
  4. end;
I left out the sort here, but that is easy to add again to aBox.Items..
https://www.freepascal.org/docs-html/rtl/classes/tstrings.tostringarray.html

And again I wonder why people seem to be unable to read documentation......

A fair question but silly answers.. :D ;) 8-) O:-)
« Last Edit: November 29, 2020, 11:45:49 am by Thaddy »
Specialize a type, not a var.

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: Listbox to array error
« Reply #9 on: November 29, 2020, 04:30:01 pm »
Alternatively you can use the ready define type TStringArray.
No you can't because that is a fixed array and not a dynamic array
Simply use my example above.
TStringDynArray is a dynamic array of string, and declared in types.
« Last Edit: November 29, 2020, 04:56:37 pm by Thaddy »
Specialize a type, not a var.

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: Listbox to array error
« Reply #10 on: November 29, 2020, 06:25:44 pm »
Alternatively you can use the ready define type TStringArray.
No you can't because that is a fixed array and not a dynamic array

But why this code below works?

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Dialogs, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     procedure Button1Click(Sender: TObject);
  17.   end;
  18.  
  19. var
  20.   Form1: TForm1;
  21.  
  22. implementation
  23.  
  24. procedure SetData(var TheArray: TStringArray; Count: Integer);
  25. var
  26.   i: Integer;
  27. begin
  28.   if (Count < 0) or (Count > 10) then Exit;
  29.   SetLength(TheArray, Count);
  30.   for i := 1 to Count do
  31.     TheArray[i-1] := i.ToString;
  32. end;
  33.  
  34. {$R *.lfm}
  35.  
  36. { TForm1 }
  37.  
  38. procedure TForm1.Button1Click(Sender: TObject);
  39. var
  40.   AList: TStringArray;
  41.   S:     string;
  42.   i:     Integer;
  43. begin
  44.   AList := nil;
  45.   SetData(AList, 8);
  46.   S := '';
  47.   for i := 0 to Length(AList)-1 do
  48.     S := S + AList[i] + LineEnding;
  49.   ShowMessage(S);
  50. end;
  51.  
  52. end.

Note:
Previously, my code did not work correctly (post #5) because I forgot it requires a var or out parameter. I prefer var because you'll get a hint if you use out.
« Last Edit: November 29, 2020, 07:01:57 pm by Handoko »

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Listbox to array error
« Reply #11 on: November 29, 2020, 06:47:01 pm »
Alternatively you can use the ready define type TStringArray.
No you can't because that is a fixed array and not a dynamic array

But why this code below works?

[...etc ...]

It works because, despite what Thaddy says, TStringArray is  a dynamic array type (at least the normal sysutils version); it's declared (in syshelph.inc) as:

Code: Pascal  [Select][+][-]
  1. {Type}
  2.   TStringArray = Array of string;

Of course, if one wants to be sure that it's a long-string array no matter the state of $H, then one should use TStringDynArray, which is explicitely declared as:

Code: Pascal  [Select][+][-]
  1.   TStringDynArray = array of AnsiString;
« Last Edit: November 29, 2020, 06:51:15 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: Listbox to array error
« Reply #12 on: November 29, 2020, 06:54:13 pm »
The name is confusing. I think it would be better to be called as TAnsiStringArray.

When I saw Thaddy mentioned TStringDynArray, I thought I was wrong. What he said is correct: I didn't check the documentation:-[

But I believed it should work because I remember I ever used such code at least once.
« Last Edit: November 29, 2020, 07:02:49 pm by Handoko »

JLWest

  • Hero Member
  • *****
  • Posts: 1293
Re: Listbox to array error
« Reply #13 on: November 29, 2020, 07:03:37 pm »
@howardpc

your code compiled just fine, haven't tested the results yet

I can't get Thaddy's code to compile. There was an error in the headder I fixed. Under types  Declared TStringDynArray = array of string;   

unit1.pas(1678,27) Error: identifier idents no member "ToStringArray" 

FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Listbox to array error
« Reply #14 on: November 29, 2020, 07:13:39 pm »
I can't get Thaddy's code to compile. There was an error in the headder I fixed. Under types  Declared TStringDynArray = array of string;   

unit1.pas(1678,27) Error: identifier idents no member "ToStringArray"

That's not what Thaddy meant: what you shoudl do is add the unit Types to your uses clause, since there's where TStringDynArray is declared.

As for ToStringArray not being declared ... that is strange. It's declared for class TStrings (the base class) in unit Classes and you should already have that in your uses clause; the very first, in fact, for default form units. Are you sure you're using:
Code: Pascal  [Select][+][-]
  1. AStringArray := AListBox.Items.ToStringArray;
or similar? Note that it's Items which is an instance of a TStrings decendant, so it should have a valid (or at least declared, if from the base class) ToStringArray method.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

 

TinyPortal © 2005-2018