Recent

Author Topic: [Solved]Using a description instead of an enumerated type  (Read 17089 times)

Knipfty

  • Full Member
  • ***
  • Posts: 232
Re: Using a description instead of an enumerated type
« Reply #15 on: August 27, 2012, 10:38:22 pm »
I've used them with DBComboLookup and DBRadioGroups where it was straight forward and natural (at least to me).  This is a bit more work on a DBGrid.

I actually have a similar requirement on creating a fee schedule in my application, but have to leave it to the user to define at a later date.  Not sure yet how I will implement it, but it could be via enumerate types if I get this working.  Or perhaps a simple DB look up.

Thanks again

Knipfty
64-bit Lazarus 2.2.0 FPC 3.2.2, 64-bit Win 11

Knipfty

  • Full Member
  • ***
  • Posts: 232
Re: [Solved]Using a description instead of an enumerated type
« Reply #16 on: August 28, 2012, 03:24:39 am »
OK, here is what I ended doing:

1.  I created two TField OnGetText event handlers (one for each column I wanted to affect)
Code: [Select]
procedure TTransRevenueBrowser.AdsRevenueTableBROnGetText(Sender: TField; var aText: string; DisplayText: boolean);
begin
  aText := BookReverseDesciption(TBookReverse(Sender.AsInteger))
end;

procedure TTransRevenueBrowser.AdsRevenueTableRTOnGetText(Sender: TField; var aText: string; DisplayText: boolean);
begin
  aText := RevenueDesciption(TRevenue(Sender.AsInteger))
end;

2.  Then in the table's data source DataChange event handler I added the following:
Code: [Select]
procedure TTransRevenueBrowser.DatasourceRevenueDataChange(Sender: TObject;
  Field: TField);
begin
  AdsRevenueTable.FieldByName('EntryType').OnGetText:=@AdsRevenueTableBROnGetText;
  AdsRevenueTable.FieldByName('RevenueType').OnGetText:=@AdsRevenueTableRTOnGetText
end;

I tried the above code in a number of event handlers, this one seems to work in all cases.  I am open to other suggestions.

In the TForm object definition I added:
Code: [Select]
    procedure AdsRevenueTableBROnGetText(Sender: TField; var aText: string; DisplayText: boolean);
    procedure AdsRevenueTableRTOnGetText(Sender: TField; var aText: string; DisplayText: boolean);

And that was it.  The code replaces the enumerated values with the desired strings.  I suspect, but can't figure out, that I should be able to use the Sender and/or the Field in step two rather than the code I used.  TField is always nil.  My guess is that its because But it is working.

Thanks everyone for your help!

Knipfty


64-bit Lazarus 2.2.0 FPC 3.2.2, 64-bit Win 11

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: [Solved]Using a description instead of an enumerated type
« Reply #17 on: August 28, 2012, 04:00:32 am »
I wouldn't use the datasource.datachange event for that what you can use depends heavily on how your application is designed.

Why you do not use the designer to select the events on the fields and you are assigning them through code?
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Knipfty

  • Full Member
  • ***
  • Posts: 232
Re: [Solved]Using a description instead of an enumerated type
« Reply #18 on: August 28, 2012, 10:54:04 am »
Where?  I couldn't find any other place that worked.  Certainly not on the field level.
64-bit Lazarus 2.2.0 FPC 3.2.2, 64-bit Win 11

avra

  • Hero Member
  • *****
  • Posts: 2579
    • Additional info
Re: [Solved]Using a description instead of an enumerated type
« Reply #19 on: August 28, 2012, 11:07:07 am »
Knipfty,

you do not need to assign OnGetText when ever data is changed. It is enough if you do it just once, like after creation. Just think about it - the same value is reassigned over and over again.

In this particular case using Form Designer and Object Inspector is more productive then assigning events programmaticaly as you do. Just click on your Dataset component, and in Object Inspector choose Events tab and find OnDataChange. Double clicking to it's dropdown box is a standard way to assign events in IDE.

Also, if you have zillion rows to show you will find that FieldByName() is very slow, and you use it twice for each row. If you want to speed it up then you can also do it just once and use the result where ever needed. For more info take a look at this thread: http://stackoverflow.com/questions/4765931/why-is-my-code-so-slow.
« Last Edit: August 28, 2012, 11:08:55 am by avra »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: [Solved]Using a description instead of an enumerated type
« Reply #20 on: August 28, 2012, 11:22:44 am »
In general if the dataset is on the form where the event is written and the fields are persistent then use the object inspector to select the events directly from the fields.
if the dataset is on the same form but with out persistent fields use the datasets afteropen event.
if the dataset is not on the same form and there are persistent fields then use the forms onCreate event making sure that the container that holds the dataset is created before the form.
if the dataset is not on the same form and there  are no persistent fields then things start to get interesting, there are a number of things here as well is the datasource (not dataset) on the form or not, what is the dataset's container?

Well as you can see there are to many variables for me to give a specific answer so it would be beneficial to both of us a small test project which duplicates your design as close as possible.

Regards
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Knipfty

  • Full Member
  • ***
  • Posts: 232
Re: [Solved]Using a description instead of an enumerated type
« Reply #21 on: August 28, 2012, 12:33:48 pm »
Hi taazz,

No need for a sample project.  The dataset is on the same form as the DBGrid AND the fields are not persistent.  I'll recode this evening and see what I end up with.  DO I use the same line I currently have?
Code: [Select]
procedure TTransRevenueBrowser.DatasourceRevenueDataChange(Sender: TObject;
  Field: TField);
begin
  AdsRevenueTable.FieldByName('EntryType').OnGetText:=@AdsRevenueTableBROnGetText;
  AdsRevenueTable.FieldByName('RevenueType').OnGetText:=@AdsRevenueTableRTOnGetText
end;
Just with the different procedure definition.

Or, do I somehow use TField and Sender?  I played with these in other event handlers, but could not get them to work.

Knipfty
64-bit Lazarus 2.2.0 FPC 3.2.2, 64-bit Win 11

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: [Solved]Using a description instead of an enumerated type
« Reply #22 on: August 28, 2012, 07:15:19 pm »
To be sure you need to double click the AfterOpen event editor on your object inspector but I think it should create the following procedure for you

Code: [Select]
procedure TForm1.AdsRevenueTableAfterOpen(DataSet: TDataSet);
begin
  AdsRevenueTable.FieldByName('EntryType').OnGetText:=@AdsRevenueTableBROnGetText;
  AdsRevenueTable.FieldByName('RevenueType').OnGetText:=@AdsRevenueTableRTOnGetText
end;

In the rare occasion where the dataset sql or underline table is changed you will get a sigsegv error if the fields are not found in the result set. I usually code it like this

Code: [Select]
procedure TForm1.AdsRevenueTableAfterOpen(DataSet: TDataSet);
var
  FldType1, fldType2 : TField;
begin
  FldType1 := AdsRevenueTable.FieldByName('EntryType');
  FldType2 := AdsRevenueTable.FieldByName('RevenueType');
  if assigned(FldType1) then  FldType1.OnGetText:=@AdsRevenueTableBROnGetText
  else Showmessage('Field < EntryType > Not found in the underline dataset');
  if Assigned(FldType2) then FldType2.OnGetText:=@AdsRevenueTableRTOnGetText
  else Showmessage('Field < RevenueType > Not found in the underline dataset');
end;

well not exactly the message is a resource string, I'm using format and I"m raising a exception instead of show message but you get the main point.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Knipfty

  • Full Member
  • ***
  • Posts: 232
Re: [Solved]Using a description instead of an enumerated type
« Reply #23 on: August 28, 2012, 07:24:03 pm »
Hi taazz,

Instead of hard coding the table name, could I use DataSet?  So something like this"
Code: [Select]
procedure TForm1.AdsRevenueTableAfterOpen(DataSet: TDataSet);
begin
  DataSet.FieldByName('EntryType').OnGetText:=@AdsRevenueTableBROnGetText;
  DataSet.FieldByName('RevenueType').OnGetText:=@AdsRevenueTableRTOnGetText
end;

I do like you second example and will probably follow it.

Thanks

Knipfty
64-bit Lazarus 2.2.0 FPC 3.2.2, 64-bit Win 11

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: [Solved]Using a description instead of an enumerated type
« Reply #24 on: August 28, 2012, 09:03:01 pm »
As long as you are sure that the dataset you attach this event has the required fields I see no problem to use the Dataset instead of the table it self.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Knipfty

  • Full Member
  • ***
  • Posts: 232
Re: [Solved]Using a description instead of an enumerated type
« Reply #25 on: August 28, 2012, 09:09:55 pm »
Cool.  I'll play with it this evening and see what happens.

Thanks, your help is greatly appreciated

Knipfty
64-bit Lazarus 2.2.0 FPC 3.2.2, 64-bit Win 11

Knipfty

  • Full Member
  • ***
  • Posts: 232
Re: [Solved]Using a description instead of an enumerated type
« Reply #26 on: August 29, 2012, 01:38:52 am »
Hi taazz,

worked like a charm!

Code: [Select]
procedure TTransRevenueBrowser.AdsRevenueTableAfterOpen(DataSet: TDataSet);
begin
  AdsRevenueTable.FieldByName('EntryType').OnGetText:=@AdsRevenueTableBROnGetText;
  AdsRevenueTable.FieldByName('RevenueType').OnGetText:=@AdsRevenueTableRTOnGetText
end;

Thanks!
64-bit Lazarus 2.2.0 FPC 3.2.2, 64-bit Win 11

Knipfty

  • Full Member
  • ***
  • Posts: 232
Re: [Solved]Using a description instead of an enumerated type
« Reply #27 on: August 30, 2012, 03:30:38 pm »
avra,

I finally had a chance to look at the link you provided.  THANKS!  Gave me something to think about.  It would appear that FieldByName loops thru the table structure until it finds the field I am looking for.  Using Field[some index value] would be more efficient program performance wise, but less efficient my time wise as my table structures are still changing.  Ugh!

I would agree though that FieldByName should be banished from loops.

Knipfty
64-bit Lazarus 2.2.0 FPC 3.2.2, 64-bit Win 11

 

TinyPortal © 2005-2018