Solved

Help using TObject to store integer values

Posted on 2001-08-22
11
488 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 100 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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…

691 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