Solved

Help using TObject to store integer values

Posted on 2001-08-22
11
485 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
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
Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

 
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

ScreenConnect 6.0 Free Trial

Want empowering updates? You're in the right place! Discover new features in ScreenConnect 6.0, based on partner feedback, to keep you business operating smoothly and optimally (the way it should be). Explore all of the extras and enhancements for yourself!

Question has a verified solution.

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

Suggested Solutions

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

810 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