Solved

Help using TObject to store integer values

Posted on 2001-08-22
11
483 Views
Last Modified: 2007-11-27
I am trying to change these 3 integers in the following object without having to create a bunch of if...then statements.  Hope you can tell what I am trying to do by the following code snipets.  I just want to be able to get and/or change the value of DTCurrentorder, DWCurrentOrder and MGSCurrentOrder by taking 'CurrentOrder' and putting 'MGS', 'DT', or 'DW' on the beginning.  Hope this makes sense.

Thanks

Rick


type
  TBranchOrder = class(TObject)
    DTCurrentOrder        : integer;
    DWCurrentOrder        : integer;
    MGSCurrentOrder       : integer;
  end;



procedure TfrmPurchaseOrderUpdate.BeginCreateOrders;
var
  BranchOrder: TBranchOrder;
  OrderQty, Avail: integer;
  PartType: String;
  CurrentBuyOutOrder, BuyOutItemNum, CurrentOrder, StockItemNum: ^Integer;
Begin
//intialize all to zero
  BranchOrder.DTCurrentOrder         := 0;
  BranchOrder.DWCurrentOrder         := 0;
  BranchOrder.MGSCurrentOrder        := 0;
  // GetPartType returns either ?MGS?, ?DW?, or ?DT?
  PartType := GetPartType;
  CurrentOrder      := BranchOrder.FieldAddress (PartType+'CurrentOrder');
  if CurrentOrder <> nil then
    CurrentOrder^ := 1;
End;
0
Comment
Question by:rwhitaker
  • 4
  • 2
  • 2
  • +3
11 Comments
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
??? this cannot work

too tired .. . listening . . .
0
 
LVL 6

Expert Comment

by:edey
Comment Utility
if you include typinfo in your uses clause i would think you'd be able to do something like this:

setInt64Prop(branchOrder,partType+'CurrentOrder',0);

Alt. you could use a a TStringList like so:

branchOrder := TStringList.create;
with branchOrder do
begin
 add('?MGS?');
 add('?DW?');
 add('?DT?');
end;

with branchOrder do
 Integer(objects[indexOf(partType)]) := 0;


Though both are a bit hackish.
GL
Mike
0
 

Author Comment

by:rwhitaker
Comment Utility
My bad, The GetPartType function should return either MGS, DW, or DT.  Ignore the question marks.  I don't know where they came from.

Ok, so Let's say GetParts returns the string 'MGS'.  In the object branchorder there is MGSCurrentOrder.   I just want to evaluate the value of BranchOrder.MGSCurrentOrder without having to write something like:

x:=GetPartType;
if x = 'MGS' then
  BranchOrder.MGSCurrentOrder := 1
else if x = 'DW' then
  BranchOrder.DWCurrentOrder := 1
else
  BranchOrder.DTCurrentOrder := 1;

3 items in my object wouldn't be that bad, but I actually have 12 items.  That if statement looks like crap.


0
 
LVL 9

Expert Comment

by:ITugay
Comment Utility
Hi rwhitaker,

may be something like this?

  X:=GetPartType;
  case StringCase(X, ['MGS', 'DW', 'DT']) of
    0: MSGCurrentOrder := 1;
    1: DWCurrentOrder := 1;
    2: DTCurrentOrder := 1;
  end;


here is StringCase implementation:

function StringCase(S: String; A: array of String): Integer;
var
  I: Integer;
begin
  I := -1;
  S := AnsiUppercase(S);
  for I := 0 to High(A) do
    if S = AnsiUppercase(A[I]) then
    begin
      Result := I;
      Break;
    end;
end;
0
 
LVL 9

Expert Comment

by:ITugay
Comment Utility
sorry, wrong implementation. Should be:

function StringCase(S: String; A: array of String): Integer;
var
  I: Integer;
begin
  Result := -1; //*****
  S := AnsiUppercase(S);
  for I := 0 to High(A) do
    if S = AnsiUppercase(A[I]) then
    begin
      Result := I;
      Break;
    end;
end;


0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 2

Expert Comment

by:FrodoBeggins
Comment Utility
Igor, better use Low(A) instead of 0 in the loop. Looks better :-)

Rgds,
Frodo
0
 
LVL 9

Expert Comment

by:ITugay
Comment Utility
Hi Frodo,
I will :-)
0
 
LVL 9

Expert Comment

by:ITugay
Comment Utility
Hi rwhitaker,

there is another way. You can declare published properties with the names "MGS", "DW", "DT" and then use procedure to set property value by it's name.

  X:=GetPartType;
  SetPropValue(BranchOrder, X, 1);

procedure located in TypInfo unit.

--------
Igor
0
 
LVL 5

Accepted Solution

by:
scrapdog earned 100 total points
Comment Utility
This, in my opinion, we would be the safest way to do it.  You will have to build the if-then construct, but you will only have to do it twice (once for get, once for set):

type
 TBranchOrder = class(TObject)
   DTCurrentOrder        : integer;
   DWCurrentOrder        : integer;
   MGSCurrentOrder       : integer;
 private
    function GetCurrentOrder(s: string): integer;
    procedure SetCurrentOrder(s: string; const Value: integer);
 public
    property CurrentOrder[s :string] :integer read GetCurrentOrder write SetCurrentOrder;
 end;



function TBranchOrder.GetCurrentOrder(s: string): integer;
begin
    if s = 'DT' then
        Result := DTCurrentOrder
    else if s = 'DW' then
        Result := DWCurrentOrder
    else
        Result := MGSCurrentOrder;
end;

procedure TBranchOrder.SetCurrentOrder(s: string; const Value: integer);
begin
    if s = 'DT' then
        DTCurrentOrder := Value
    else if s = 'DW' then
        DWCurrentOrder := Value
    else
        MGSCurrentOrder := Value;
end;


-----------------------------------

Now you can use CurrentOrder as an array that is indexed by strings.  Like this:


procedure TForm1.Button1Click(Sender: TObject);
var
    Test :TBranchOrder;
begin
    Test := TBranchOrder.Create;

    Test.CurrentOrder['DT'] := 10;
    ShowMessage(IntToStr(Test.CurrentOrder['DT']));

    Test.Free;
end;



You can substitute any string expression for the index (such as the result from GetPartType).
0
 
LVL 6

Expert Comment

by:edey
Comment Utility
In the end run, you have, I think, one of three choices:

1)use RTTI (see my first comment for typinfo.pas ex).
2)wrap the var's in a hash table like object (see the TStringList Example). There a large number of ways to do this.
3)use of some form of "sieve logic", ie the if .. else if or case of constructs.  Again, many similar ways to do this, as various posters to this question have shown.

Each of these have various strengths & weaknesses, ie:

1)RTTI is very flexible, the only requirement is that the data be ref'ed by an object property.  Can be used with any object, with little info needed at design time.  OTOH, it's not particularily fast, and you still have the overhead of a class/object wrapper.
2)Hash Tables, depending on implmentation, can be very fast, can hold any data type, can be very efficient, good for large amounts of data.  OTOH, takes the most work to implement well, requires a fair bit of 'hard coding' - there's a lot that needs to be known at deisgn time.
3)Sieve's are quick, simple, can be easy to read (for small numbers of conditions).  They also tend to produce fast code, esp. if your condition are ordered well (if 'DT' occurs most often, put it first to avoid the logic of the other two). OTOH, they require the most hard coding - you can't easily change the conditions, the number of conditions nor the number/source of the data.

In your particular case, though, I think I would still sugest 3) - the sieve.  However ugly, I just can't see how you'd be better served with the extra work for most iplementations of 1) or 2).

GL
Mike
0
 

Author Comment

by:rwhitaker
Comment Utility
Thanks for the multitude of viable solutions guys.  That was awesome.  In the end, I went with something similiar to what scrapdog suggested.

Again thanks for the help.
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now