?
Solved

Help using TObject to store integer values

Posted on 2001-08-22
11
Medium Priority
?
493 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
  • 2
  • +3
11 Comments
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6415246
??? this cannot work

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

Expert Comment

by:edey
ID: 6415283
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
ID: 6415338
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 9

Expert Comment

by:ITugay
ID: 6416775
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
ID: 6416781
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
 
LVL 2

Expert Comment

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

Rgds,
Frodo
0
 
LVL 9

Expert Comment

by:ITugay
ID: 6416813
Hi Frodo,
I will :-)
0
 
LVL 9

Expert Comment

by:ITugay
ID: 6416891
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 300 total points
ID: 6417043
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
ID: 6417628
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
ID: 6418396
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

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
Suggested Courses
Course of the Month10 days, 10 hours left to enroll

764 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