Lazarus

Free Pascal => Beginners => Topic started by: JLWest on November 29, 2020, 01:27:02 am

Title: (Solved)Listbox to array error
Post by: JLWest 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
Title: Re: Listbox to array error
Post by: trev on November 29, 2020, 01:28:51 am

See Parser Messages (https://www.freepascal.org/docs-html/user/userse62.html) 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."
Title: Re: Listbox to array error
Post by: JLWest 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
Title: Re: Listbox to array error
Post by: lucamar 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
Title: Re: Listbox to array error
Post by: JLWest 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.                          

 
Title: Re: Listbox to array error
Post by: Handoko 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.
Title: Re: Listbox to array error
Post by: JLWest 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.

Title: Re: Listbox to array error
Post by: howardpc 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?
Title: Re: Listbox to array error
Post by: Thaddy 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:-)
Title: Re: Listbox to array error
Post by: Thaddy 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.
Title: Re: Listbox to array error
Post by: Handoko 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.
Title: Re: Listbox to array error
Post by: lucamar 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;
Title: Re: Listbox to array error
Post by: Handoko 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.
Title: Re: Listbox to array error
Post by: JLWest 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" 

Title: Re: Listbox to array error
Post by: lucamar 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.
Title: Re: Listbox to array error
Post by: JLWest on November 29, 2020, 07:21:13 pm
I already have Types in my use clause. I'm doing some graphics.This is copied out of the program.

Code: Pascal  [Select][+][-]
  1.  
  2.   Type
  3.  
  4.  TStringDynArray = array of string;
  5.  
  6. procedure TForm1.GenericArrayLoad(out theArray: TStringdynArray; const aBox: TListBox);
  7.  begin
  8.    theArray := aBox.Items.ToStringArray;
  9.  end;          
  10.  
Title: Re: Listbox to array error
Post by: lucamar on November 29, 2020, 07:25:06 pm
I already have Types in my use clause [...]

Then you don't need to declare TStringDynArray again; it's already declared inside the Types unit.
Title: Re: Listbox to array error
Post by: JLWest on November 29, 2020, 07:29:48 pm
took out the declaration and I still get the error:

unit1.pas(1678,27) Error: identifier idents no member "ToStringArray"
Title: Re: Listbox to array error
Post by: JLWest on November 29, 2020, 07:40:17 pm
 AS I understand it theArray := aBox.Items.ToStringArray;    is assigning the tstringlist of the listbox ABOX to a dynamic array. That is if it worked.

Therefore, I should be able to go the other way with something like this:

    Listbox1.items := ToStringArray; ?   
Title: Re: Listbox to array error
Post by: lucamar on November 29, 2020, 07:45:29 pm
took out the declaration and I still get the error:

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

Strange. Please, test the attached project and see if it also fails; it doesn't here.

AS I understand it the
Code: Pascal  [Select][+][-]
  1. Array := aBox.Items.ToStringArray;
is assigning the tstringlist of the listbox ABOX to a dynamic array. That is if it worked.

Therefore, I should be able to go the other way with something like this:
Code: Pascal  [Select][+][-]
  1. Listbox1.items := ToStringArray;

No, because ToStringArray is a method of the TStrings class. Besides, think of what that would do: it would destroy the current Items and replace them with ... what? :o

And what TStrings.ToStringArray does is to get the TStrings strings and copy them over to a dynamic array, a string at a time. That's it.

ETA: This is how it's done, in fact (taken from stringl.inc):
Code: Pascal  [Select][+][-]
  1. function TStrings.ToStringArray(aStart,aEnd : Integer): TStringDynArray;
  2. Var
  3.   I : Integer;
  4. begin
  5.   Result:=Nil;
  6.   if aStart>aEnd then exit;
  7.   SetLength(Result,aEnd-aStart+1);
  8.   For I:=aStart to aEnd do
  9.     Result[i-aStart]:=Strings[i];
  10. end;
Title: Re: Listbox to array error
Post by: JLWest on November 29, 2020, 08:19:43 pm
ok I will will take a few.
Title: Re: Listbox to array error
Post by: JLWest on November 29, 2020, 08:27:16 pm
Same error: unit1.pas(55,26) Error: identifier idents no member "ToStringArray"

I think there is a difference between windows and UNIX.
Title: Re: Listbox to array error
Post by: Thaddy on November 29, 2020, 08:29:32 pm
Same error: unit1.pas(55,26) Error: identifier idents no member "ToStringArray"
You need:
1) fpc 3.2.0. Not any older version, in that case YOU made the mistake. Old crap is nice for old people like me, not for starters.
2) include sysutils and types in the uses clause.
3) No, there is no difference between Windows and Linux in this case....
The documentation link assumes 3.2.0 since that is the current release.
Title: Re: Listbox to array error
Post by: JLWest on November 29, 2020, 08:35:18 pm
@Thaddy

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

This is my use clause:

uses
  Buttons,  clipbrd,  Classes,   Controls,
  Dialogs,  ExtCtrls, FileUtil,  Forms,
  Graphics, SysUtils, StrUtils,  StdCtrls, Menus,
  Types, LazFileUtils;           

Willing to post the code.               

Title: Re: Listbox to array error
Post by: Thaddy on November 29, 2020, 08:39:26 pm
No idea why it does not work for you. I tested it.
But code is always welcome because it makes it a lot easier to help you.
(not only me but also others like Lucamar)
Title: Re: Listbox to array error
Post by: JLWest on November 29, 2020, 08:42:50 pm
Ok Thaddy I'lll post. take a bit
Title: Re: Listbox to array error
Post by: lucamar on November 29, 2020, 08:43:59 pm
Willing to post the code.               

Yes, please, do it. It should be working, so there must be something else preventing it.

Though for my test project failing for you there must be something very wrong in your installation and that is more difficult to "debug" through forum posts %)
Title: Re: Listbox to array error
Post by: JLWest on November 29, 2020, 08:53:34 pm
You need a sub-dir under the installation dir with two small text files. there are really config files for the program.

It will compile I think but you need the Dataset to run. Willing to post the Dataset. The Dataset is just a bunch of text files, zipped 150KB



Title: Re: Listbox to array error
Post by: lucamar on November 29, 2020, 09:00:30 pm
Did you forget to post the code or is it "coming soon"(tm)? :)
Title: Re: Listbox to array error
Post by: JLWest on November 29, 2020, 09:05:12 pm
oh I thought I did. Sorry.
Title: Re: Listbox to array error
Post by: lucamar on November 29, 2020, 09:25:39 pm
It compiles OK here. Some normal hints and warnings but compilation ends as it should. Something wrong in your install, then?
Title: Re: Listbox to array error
Post by: JLWest on November 29, 2020, 09:32:34 pm
My install of what FPC, Lazarus?
Title: Re: Listbox to array error
Post by: lucamar on November 29, 2020, 09:39:16 pm
My install of what FPC, Lazarus?

Either or both, though I'd suspect FPC; after all, Classes ( from which comes TStrings) is part of the RTL.

Where does it go (if anywhere) if you Ctrl-click "ToStringArray" in the IDE?

Not that it should matter much: if it's capable of dealing with TListBox.Items it should be able to access its methods too. It's profoundly baffling...
Title: Re: Listbox to array error
Post by: JLWest on November 29, 2020, 09:53:45 pm
I go over to sourceforge and try to download FPC but the only thing I get is the 32 bit compiler and I have the 64 bit.

Title: Re: Listbox to array error
Post by: lucamar on November 29, 2020, 10:09:20 pm
It's best if you just uninstall and reinstall the whole Lazarus; that will get you a "refreshed" install of both, Lazarus and FPC.

While you're at it make sure to get the latest Lazarus 2.0.10. It might be that there was some bug in the version you're using which was corrected later. Or maybe ToStringArray() is new in 3.2.0, I don't know ...
Title: Re: Listbox to array error
Post by: JLWest on November 29, 2020, 10:22:01 pm
I Deleted the FPC dir on the C: drive downloaded and installed FPC 3.2.0. Same error.

I really hate to reinstall Lazerur as I have several packages added to the base.

When you compiled did the UI look alright?
Title: Re: Listbox to array error
Post by: lucamar on November 29, 2020, 10:27:32 pm
When you compiled did the UI look alright?

A little huge, with very big fonts, and severely displaced for my screen, but yes, it did look alright.
Title: Re: Listbox to array error
Post by: jamie on November 29, 2020, 10:28:38 pm
I suspect you are actually using 3.0.4 compiler some how, maybe your lazaus 2.0.4 which comes with the 3.0.4 and is installed within Lazarus.

this is what you should try...

 install the 2.0.10 version of Lazarus IDE side by side as a secondary IDE. that will install the 3.2.x compiler within that IDE.

 Start it and do a test run of that TostringArray.

Also, you could delete the FPC 3.2.0 you have and just leave alone the IDE install you have and I bet it will still find a compiler, but it will be 3.0.4 instead.

 In Lazarus you can direct the path to use a different compiler instead of the one that comes with it the older 2.0.4 IDE.

 Have you looked at that to see if it is looking at the 3.2.x install ?
Title: Re: Listbox to array error
Post by: JLWest on November 29, 2020, 10:45:38 pm
Yea it did still find a compiler. It located at C:\lazarus\fpc\3.2.0\bin\x86_64-win64.

Which says it's 3.2.0 but I will try and install another Lazarus install.
Title: Re: Listbox to array error
Post by: JLWest on November 29, 2020, 11:14:31 pm
Deleted everything but the project. Installed Lazarus. It worked. Using the compiler under the Lazarus install.

Thanks One and all.
TinyPortal © 2005-2018