Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 9 of 9 total
Thread Cosmetic Data Conversions
Tue, Sep 19 2006 12:56 AMPermanent Link

"Adam H."
Hi,

I have an application that deals with weights. Throughout the database, I
would prefer to keep all my fields consistant (ie, record everything in
metric tonnes). However, depending on the form (or the user), they may
prefer to work with certain parts of the data (at particular times) in
different scales (ie, grams, kilograms, lbs, etc). In the end, calculations
will need to be done across the whole data (which is another reason why I
prefer to keep all my fields storing data in a constant/standard way).

In the past, I have seen only three options to this:

1) Force the user to use the same standard of measurement (doesn't get me
far Smiley

2) Have different forms store values as different measurements, and take
this into consideration everytime I write a report or do a calculation, or

3) When displaying data, create a memory table - do a conversion from the
underlying value to the measurement the user wants to see, and convert back
when closing.

I was wondering if anyone has another idea, or has come across a cheat
component. Smiley (One thought I had was to write a visual data component that
did the conversion automatically (embedded), and converted back. I don't
know how difficult this would be to do - or whether one already exists, or
is option #3 the best to go with?

Thanks & Regards

Adam.

Tue, Sep 19 2006 10:00 AMPermanent Link

"Johnnie Norsworthy"
"Adam H." <ahairsub4@rREMOVEMEspamSTOPPER.jvxp.com> wrote in message
news:F6007736-E25C-45C4-AAA8-76EC10D27EEC@news.elevatesoft.com...
> Hi,
>
> I have an application that deals with weights. Throughout the database, I
> would prefer to keep all my fields consistant (ie, record everything in
> metric tonnes). However, depending on the form (or the user), they may
> prefer to work with certain parts of the data (at particular times) in
> different scales (ie, grams, kilograms, lbs, etc). In the end,
> calculations will need to be done across the whole data (which is another
> reason why I prefer to keep all my fields storing data in a
> constant/standard way).

I would standardize the stored units across the whole database.

Then for display, you could use calculated fields for the conversion to the
user's preferred units. That would be as easy as a configuration option if
it is consistent for all fields, but more difficult if individual fields
would be entered using differing units. That would mean retaining the last
unit used for each field.

Another option would be to have three fields for each value:
ValueInStandardUnits
ValueEntered (can use data-aware control)
UnitUsed (can use data-aware control, lookup list)

Then OnPost, use the value from the two data-aware control fields to
calculate and set the third field. I'm partial to this method since it gives
the user the most freedom and remembers what they chose to enter for the
units. Of course for the best user-interface, you should always remember the
unit the user LAST used for those fields (I'd use the registry) and preset
the units when entering new records.

-Johnnie

Tue, Sep 19 2006 5:01 PMPermanent Link

"Adam H."
Hi Jonnie,

Thanks for your reply...

> I would standardize the stored units across the whole database.

Great. I'm on the right path.  Smile

> Then for display, you could use calculated fields for the conversion to
> the user's preferred units.

The problem with calculated fields is that the user needs to be able to edit
the values they see (like in a TDBEdit box) - otherwise, I would agree, it
would be my prime choice.
..
> Another option would be to have three fields for each value:
> ValueInStandardUnits
> ValueEntered (can use data-aware control)
> UnitUsed (can use data-aware control, lookup list)

Thanks for that. I didn't really think of that as an option. I'll add that
to my list of things to consider.

Another option I came up with, that I've tried playing around with was to
modify something higher up in the hirachy to give me what I desire. I've
tried fiddlying around in db.pas (made a copy of course Smiley and adding a
new property called multiplyvalue. (Float value). I then played with a few
procedures in db.pas (such as TFloatfield.GetAsVariant, and
TFloatField.SetasFloat to intercept the value between the data control, and
the database.

This worked well in some instances, as it allowed me to specify a different
multiply value per TField, however I don't like the idea of playing around
with db.pas. It will affect ALL applications (and data components), instead
of just the ones I want on my forms.

Another thought I had was to create a TDatasource of my own (TMyDatasource),
and create a property multiplyvalue, and intercept any communication between
the dataset and the data controls there, but unlike with TFields, I could
not find a way to do this with the TDatasource component. (If anyone knows
if this is possible, please speak up Smiley

Another thought was to create a descendant of TDBEdit to do what I want, but
then I also realised I may hit trouble, as I use TcxDBTextEdits - which
again I could change, but I think the problem would come further down the
track when I also use it in TcxGrids, etc. Then I would have to maintain my
own copy of all these additional files, and modify them every time their's
an upgrade.

My optimum solution would be to create a component that works between the
dataset and the data aware control (like a TDatasource) where no
modifications to existing components are required, and no extra coding in
applications down the track are also required, except for setting a value.

Not sure if I can pull it off though.  Smiley

Cheers

Adam.

Tue, Sep 19 2006 5:12 PMPermanent Link

"Robert"

"Adam H." <ahairsub4@rREMOVEMEspamSTOPPER.jvxp.com> wrote in message
news:025B8710-DC65-4652-8025-6908AA0E33A8@news.elevatesoft.com...
>
> Thanks for that. I didn't really think of that as an option. I'll add that
> to my list of things to consider.
>

If you know which unit the user was last using (which you probably do) make
it a global, and then beforepost, do the conversions as required

Case UnitsInUse of
grams:  begin
              tonnes := grams * 10000;
             oz := grams * 20;
         end;
tonnes: begin
               grams := tonnes div 10000;
              oz : grams div 20;
         end;
etc.

If you allow changes on the fly (ie, he started using grams, made a change,
then decides to switch to oz) it gets a bit more complicated, but not much.

How are you going to handle the display? It seems that when they switch form
one unit to another, you would want to display the number in the same place.
I guess you could set up three database fields on the same screen
coordinates, one using grams, the other oz, the other tonnes, and use a case
procedure as per above to set one to active and visible, the other two to
inactive and not visible.

Robert


Tue, Sep 19 2006 5:13 PMPermanent Link

"Johnnie Norsworthy"
"Adam H." <ahairsub4@rREMOVEMEspamSTOPPER.jvxp.com> wrote in message
news:025B8710-DC65-4652-8025-6908AA0E33A8@news.elevatesoft.com...
> Hi Jonnie,
>
> Thanks for your reply...
>
>> I would standardize the stored units across the whole database.
>
> Great. I'm on the right path.  Smile
>
>> Then for display, you could use calculated fields for the conversion to
>> the user's preferred units.
>
> The problem with calculated fields is that the user needs to be able to
> edit the values they see (like in a TDBEdit box) - otherwise, I would
> agree, it would be my prime choice.
> .
>> Another option would be to have three fields for each value:
>> ValueInStandardUnits
>> ValueEntered (can use data-aware control)
>> UnitUsed (can use data-aware control, lookup list)
>
> Thanks for that. I didn't really think of that as an option. I'll add that
> to my list of things to consider.

I'd still go this route. You don't have to modify anything or write any new
component or library descendants and you can use any data-aware library you
want and change any time you want.

I think this is the least work and best solution for later upgrades. If you
use the same table when saving data in multiple locations you can use the
same OnPost event code, so that is just in one place too.

If you have existing data, you would need to change the schema and perform
an initial conversion for each existing record.

-Johnnie

Wed, Sep 20 2006 11:13 AMPermanent Link

Sean McCall
Have you looked at TField.OnGetText and TField.OnSetText?

You can also extend TFields by creating an object and using the .Tag
property.

AField.Tag := Integer(TMyObject.Create);

Just don't forget to destroy the objects before you release the table.
You could do this automatically by

TMyTable = class(TDBISAMTable) and
putting code to do this in the destructor.

HTH,

Sean

Adam H. wrote:
> Hi Jonnie,
>
> Thanks for your reply...
>
>> I would standardize the stored units across the whole database.
>
> Great. I'm on the right path.  Smile
>
>> Then for display, you could use calculated fields for the conversion to
>> the user's preferred units.
>
> The problem with calculated fields is that the user needs to be able to edit
> the values they see (like in a TDBEdit box) - otherwise, I would agree, it
> would be my prime choice.
> .
>> Another option would be to have three fields for each value:
>> ValueInStandardUnits
>> ValueEntered (can use data-aware control)
>> UnitUsed (can use data-aware control, lookup list)
>
> Thanks for that. I didn't really think of that as an option. I'll add that
> to my list of things to consider.
>
> Another option I came up with, that I've tried playing around with was to
> modify something higher up in the hirachy to give me what I desire. I've
> tried fiddlying around in db.pas (made a copy of course Smiley and adding a
> new property called multiplyvalue. (Float value). I then played with a few
> procedures in db.pas (such as TFloatfield.GetAsVariant, and
> TFloatField.SetasFloat to intercept the value between the data control, and
> the database.
>
> This worked well in some instances, as it allowed me to specify a different
> multiply value per TField, however I don't like the idea of playing around
> with db.pas. It will affect ALL applications (and data components), instead
> of just the ones I want on my forms.
>
> Another thought I had was to create a TDatasource of my own (TMyDatasource),
> and create a property multiplyvalue, and intercept any communication between
> the dataset and the data controls there, but unlike with TFields, I could
> not find a way to do this with the TDatasource component. (If anyone knows
> if this is possible, please speak up Smiley
>
> Another thought was to create a descendant of TDBEdit to do what I want, but
> then I also realised I may hit trouble, as I use TcxDBTextEdits - which
> again I could change, but I think the problem would come further down the
> track when I also use it in TcxGrids, etc. Then I would have to maintain my
> own copy of all these additional files, and modify them every time their's
> an upgrade.
>
> My optimum solution would be to create a component that works between the
> dataset and the data aware control (like a TDatasource) where no
> modifications to existing components are required, and no extra coding in
> applications down the track are also required, except for setting a value.
>
> Not sure if I can pull it off though.  Smiley
>
> Cheers
>
> Adam.
>
>
Wed, Sep 20 2006 11:23 AMPermanent Link

Chris Erdal
"Adam H." <ahairsub4@rREMOVEMEspamSTOPPER.jvxp.com> wrote in
news:F6007736-E25C-45C4-AAA8-76EC10D27EEC@news.elevatesoft.com:


> In the past, I have seen only three options to this:
>

Here's another one:

http://delphi.newswhat.com/geoxml/forumhistorythread?
groupname=borland.public.delphi.database.multi-tier&messageid=42e653af$1
@newsgroups.borland.com

(stick the URL back together first Wink

--
Chris
(XP-Pro + Delphi 7 Architect + DBISAM 4.24 Build 1)
Wed, Sep 20 2006 9:33 PMPermanent Link

"Adam H."
Hi Sean,

> Have you looked at TField.OnGetText and TField.OnSetText?

No - I hadn't. I just played with it then, and it looks as though this could
certainly meet my requirements without too much trouble whatsoever!

> You can also extend TFields by creating an object and using the .Tag
> property.
>
> AField.Tag := Integer(TMyObject.Create);
<snip>

Amaizing! I have never come across this before. I thought tag's simply were
a way of assigning an integer to a property, and not for anything else!
Learn something new every day. Smile

Thanks!

Adam.

Wed, Sep 20 2006 9:34 PMPermanent Link

"Adam H."
Hi Chris,

Thanks for the link. Worth the read, but at this stage, I'm excited about
the OnGetText and OnSetText properties. Smile

Cheers

Adam.

Image