How to declare a Constant array of array of Record in Delphi

fischermx
fischermx used Ask the Experts™
on
Hi,

Let's suppose the following code, which is used as sample, that is to declare a Constant array of record:

type
    TShopItem = record
      Name : string;
      Price : currency;
    end;

const
    Items : array[1..3] of TShopItem =
    (
      (Name : 'Clock'; Price : 20.99),
      (Name : 'Pencil'; Price : 15.75),
      (Name : 'Board'; Price : 42.96)
    ) ;


What if I want to declare a to declare a Constant array of array of record (array of array).
How do I declare that?

Taking the previous classes, now suppose that I have "groups" of TShopItem's, like :

Group 1
      (Name : 'Clock'; Price : 20.99)
      (Name : 'Pencil'; Price : 15.75)

Group 2
      (Name : 'Board'; Price : 42.96)
      (Name : 'Eraser'; Price : 2.96)

Group 3 (note different length)
      (Name : 'Paper'; Price : 5.96)
      (Name : 'Pen'; Price : 2.96)
      (Name : 'Postits'; Price : 2.96)

How do I put all that in a single constant array of array declaration?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Emmanuel PASQUIERFreelance Project Manager
Top Expert 2010
Commented:
you cannot because the groups 1 , 2 & 3 do not have the same size, so you cannot declare a single array.
Or you declare an array of 3x3 and there will be some holes (unused elements)
const
    Items : array[1..3, 1..3] of TShopItem =
   ( (
      (Name : 'Clock'; Price : 20.99),
      (Name : 'Pencil'; Price : 15.75),
      (Name : 'Board'; Price : 42.96)
     ),
     (
      (Name : 'Paper'; Price : 5.96),
      (Name : 'Pen'; Price : 2.96),
      (Name : 'Postits'; Price : 2.96)
     ),
     (
      (Name : 'Clock'; Price : 20.99),
      (Name : '-'; Price : 0),
      (Name : '-'; Price : 0)
     )
     );

Open in new window

Geert GOracle dba
Top Expert 2009
Commented:
a constant for a price ?
isn't that a completely wrong approach ?
i have never known a price to be constant (only for a day ... and then still ..)
i would come for Petrol at your place ... especially if your shop would have existed 50 years ago.

so far ... about the idea ...

why not use a TCollection to hold the items and a TCollectionItem to contain a specific item

type
  TShopItem = class(TCollection)
  private
    fPrice: Double;
    fName: string;
    fGroup: string; // single group or multiple group ??? you consider create a TCollection Group too :)
  public
    property Name: string read fName write SetName;
    property Price: Double read fPrice write SetPrice;
    property Group: string read fGroup write SetGroup;
  end;

  TShopItems = class(TCollection)
  end;

at the start of your program:

procedure InitTestData;
  procedure AddItem(aName: string; aPrice: double; aGroup: string);
  begin
    with ShopItems.Add do
    begin
      Name := aName;
      Price := aPrice;
      Group := aGroup;
    end;
  end;
begin
  AddItem('Clock', 20.99, 'Group 1');
  AddItem('Pencil', 15.75, 'Group 1');

  AddItem('Board', 42,96, 'Group 2');
end;
Freelance Project Manager
Top Expert 2010
Commented:
I'd rather setup a list of collections, to allow a better management of the item groups (that will strike out the idea that an item could be part of multiple groups, or it would be a little more complex to implement)

You use like this :

Var
 Inventory:TShopItemGroups;
begin
 Inventory:=TShopItemGroups;
 With Invenory['Group 1'] do
  begin
    AddItem('Clock', 20.99,);
    AddItem('Pencil', 15.75);
  end;
end;

and simply call Inventory.Free (or Clear) to free (clean) it all

If you need to know the group from a known item, you might consider adding a property in TShopItem that would not be a string name, but a reference on the TShopItemGroup (add Group:=Self in AddShopItem)
Interface

Type
  TShopItem = class(TCollectionItem)  // Not TCollection here
  private
    fPrice: Double;
    fName: string;
  public
    property Name: string read fName write SetName;
    property Price: Double read fPrice write SetPrice;
  end;

 TShopItemGroup = class(TCollection)
  private
    function GetShopItem(i:integer):TShopItem;
  public 
    procedure AddShopItem(aName: string; aPrice: double);  
  
    property ShopItems[i:integer]:TShopItem read GetShopItem;
  end;

 TShopItemGroups = class(TStringList)
  private
  public
   Constructor Create;
   
   function GetGroupByName(n:String):TShopItemGroup;

   property ItemGroup[name:String]:TShopItemGroup read GetGroupByName;
  end;
  
Implementation
  
Constructor TShopItemGroups.Create;
begin
 inherited;
 Duplicates:=dupIgnore;
 Sorted:=True;
 OwnsObjects:=True; // This is a rather new property, tell me if your Delphi version do not recognize it
end;

function TShopItemGroups.GetGroupByName(n:String):TShopItemGroup;
Var i:integer;
begin
 n:=UpperCase(n);
 i:=IndexOf(n);
 if i<0 // Group does not exist, create it
  Then i:=AddObject(n,TShopItemGroup.Create);
 Result:=TShopItemGroup(Objects[i]);
end;
 
function TShopItemGroup.GetShopItem(i:integer):TShopItem; 
begin
 Result:=TShopItem(Items[i]);
end;

procedure TShopItemGroup.AddShopItem(aName: string; aPrice: double);  
begin
 with TShopItem(Add) do 
  begin
   Name := aName;
   Price := aPrice;
  end;
end;

Open in new window

Become a Certified Penetration Testing Engineer

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

Author

Commented:
epasquier:

Thanks for your answer. But I think I can't do that. In the real application some groups have two or three elements, some others have 20 or 25, so there are a lot of gaps.
Geert GOracle dba
Top Expert 2009

Commented:
epasquier
>> why not TCollectionItem for group

You could set extra properties on a group:
Default_profit_Margin
Default_Stock_Location
Default_Supplier
etc etc

Author

Commented:
Geert_Gruwez:

That was, of course, sample data that I took from somewhere.
The real application will store REAL CONSTANT values that will never  ever change.

I like the TCollection idea, though this data has to be available at design time.... mmh..... I guess I can fill the collection at the initialization in the property editor unit (?).

Thanks for your answer.
Geert GOracle dba
Top Expert 2009

Commented:
why not use a database ?

much easier, you can copy a database, then mess with it ... :)
Geert GOracle dba
Top Expert 2009

Commented:
loading data in design time ???
wooo ... you're adding a complexity level, which you will not like

Author

Commented:
epasquier:

I like your idea of having a group, and a groups collection, besides the items.
I think I will use that.

My only concern is how to make all those available at design time for my property editors.

Author

Commented:
Geert_Gruwez:

>why not use a database ?
>much easier, you can copy a database, then mess with it ... :)

LOL, I want to do this to avoid the use of a database.
Yes, I know that's the proper place for so much data, but I can't.
It will be used at design time to fill some property editors.

I thought about to use a resource file, but not sure how if that will be even messier.



Emmanuel PASQUIERFreelance Project Manager
Top Expert 2010

Commented:
> My only concern is how to make all those available at design time for my property editors
I don't see why you couldn't create your own property editor based on this principle to make it easy for the programmer to fill that structure at design time. Just have to find  a persistent way of storing all that information (like exporting in a string). I'm not that used to make property editors, but if I remember, Geert have more experience about it and would be glad to learn also :o)

Or he is not listening, and I will have to dig tomorrow for a solution

Author

Commented:
epasquier:

That's fine. I think I will just have to create those objects in the initialization to have them loaded and ready for when the property designer is called.
It has to work, I guess.

Author

Commented:
Thank you!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial