Link to home
Start Free TrialLog in
Avatar of ZifNab
ZifNab

asked on

Knowing when range of data has changed (not OnDataChange event)

I need to do some calculations on a range of data in a table or Query. e.g. Variations, Sum, Average, ... I already made a component for this. Now, I want to make this component aware when the range of this table or Query changes. I know that you can be notified with the OnDataChange event. But I use First, Next for browsing through the range and make the calculations. So this isn't possible to use. Is there a way to be only notified when the range of the table or query changes? Or are there other functions like First and Next which don't notify the OnDataChange event?
Avatar of millerw
millerw

Try looking at the events of the TTable/TQuery themselves.  The event you are referring to is for a TDataSource.  The TTable and TQuery have events called AfterPost, AfterInsert, etc.  These are called when a new record is added to the dataset and thus, the range changes.  There are events for before and after these events.  Try the After/BeforeInsert one.  That is the one I use to prevent a record from being added to the dataset and will tell you when a new record has been added by either an Insert or Append.  These events are only called when you add records so your next/first/prior methods won't call it.  

If you need example code or more help, let me know.
Scott
Avatar of ZifNab

ASKER

My tables and queries are read-only. I don't give the user the oppertunity to add/insert a record. The user is only capable of setting a range. e.g. StartDate...EndDate. The range is set with the SetRange function. I just checked but non of the events are called when you use this function (or am I incorrect?).
{I'd like to have an event which I can give to my component. So that the user doesn't has to fill in an event of, for example a table or query, to change my components behavior.}
Although thanks for you answer, but it doesn't help me for the moment.
ASKER CERTIFIED SOLUTION
Avatar of icampbe1
icampbe1

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ZifNab

ASKER

Hi Ian,

First, thanks for the info.

Second, I suppose : Expose =

published
 property SetRange;
 ...

procedure TTable2.SetRange(const StartValues, EndValues: array of const);
begin
 {my OnRangeChange event}
 inherited; // Is there a difference to call this before or after
               my own event?
end;

I already thought about that and it will work fine, but then I have to make a special TTable/TQuery component. And if my range changes, I have to call all my TDBCalc (my calculation component = TCustomLabel made dataaware) on the form. Don't like this way, but if there isn't another one, I suppose I have to use this.

But if I can make my TDBCalc aware for a RangeChange then I can use the old TTable and TQuery and the TDBCalc will change his result automatically. Is there such a solution?
I was thinking that you could make your own "event" by posting a new record and then cancelling.  It is a long way round but it will work.  All you have to do is call:

MyTable.Insert (or append or edit even);
MyTable.Cancel;

Everytime they change the range, call these two functions.  This will fire the After and Before Cancel and Insert events and then you can do your processing there.  This way doesn't require a new component and will work because you are FORCING an event to fire at a specific time.  This will expecially work if you never allow insertions and cancels other than for this case.  

The only question now, is can you track a range change by the user?  If you are allowing the user to change the range, then you can use the OnChange event of the form control that you are using to allow them to change the range.  Matter of fact, you can use that to track a range change in the first place because if the control changes, the range changes.  Now if they change the range to the same thing they had last time, you may process needlessly but that is the approach I would use if you don't want a new component.

How are you allowing the user the change the range?

Good luck,
Scott
Avatar of ZifNab

ASKER

Hi Scott,

Insert/Cancel that's a way, yess. If you're using this Table/Query only for this purpose. But if you use this Table/Query also on another form and there you want to Insert a record, then you've got a problem. Or am I looking something over my head?

How am I allowing the user to change the range?

I've got two forms next to each other. In the first form I let the user choose for a starting and an ending date. Also on this form you can choose (if you want) one date which will become the reference for the dates in the range. The other form responds by displaying the information, (graphically and analaticaly). You can always switch between these forms, so the user can always change the range if he wants to.

Now, if I can make my component TDBCalc automatically aware for a rangechange, I never have to call these components to change their result. Themself will look if the range of their table/query given by a datasource is changed. Is there a change then they will automatically change their result. You just have to put this component on the form and he'll do the rest. Offcourse, to many of such components will really slow down the program. Also big tables will slow down. But that's another problem. I think this you can solve by making another component, which looks for all the DBCalcs on the form. And this component can then sort all these DBCalcs and all the operations will be calculated in one single iteration. If you think I'm looking in a wrong direction, please give a sign!


I ran into a similar problem with a program I am writing now.  I made it so the user couldn't add a record on the DBGrids.  Come to find out, this also prevented me from inserting a new one programmically later on.  Here is what i did.  If the user was on pages 1 or 4 of a TPageControl, I set the Event pointer to nil.  If it was on pages 2-3, I set the event pointer to the event procedure I wrote.  Thus, on pages 1 and 4 I can add new records but on pages 2-3, any user adds are aborted.  You can use the forms OnActivate event to set the appropriate function depending on which form the user is on.  So that problem is not a problem anymore, just have the forms change it when they are active.

Now for your second problem.  
I think your going in the right direction but that direction requires that a new component to be written like Ian C. said.  If you don't want to write a new component, then you will have to use the Cancel method to fire it when appropriate.  Unfortunately, you will have to write some code either way.  You will be writing the code for the cancel method or writing the code for a new component.  Just remember, if you write the code for a new component now, you will most definitely find it useful in the future---and won't have to write it again or cut and paste code into a new program.  Once you write a component it can always be modified to suit future needs and will always be with you as long as you code.  

Think about the LONGTERM advantages instead of the short term time problems.

Good Luck,
Scott
I'll give you a code example (if not the whole thing) later tonight.  It isn't really much of a task.  

Ian C.

OKee Dokee...  I just put this together so you'll have to decide how to change it if you want to, but it should be OK.  Let me know if you need more help.

In the following code, it is up to you if you want to call the inherited methods before or after you trigger the event.  Usually an event signifies what has happened so this code triggers the events after the action to signify that a range has changed (not changing).  You can just as easily trigger the events first to signify that something is going to happen.  This is usefull if you pass another parameter like VAR ChangeOK: BOOLEAN  and stop the operation if you choose to.

Remember, other things can indirectly change a range (like filter) so trap those as well if you feel you must.


TYPE
  TNiftyTable = CLASS( TTable )
  PRIVATE
    FOnRangeChange: TDatasetNotifyEvent;
  PUBLIC
    {These methods will mask or hide the actual ones in TTable}
    PROCEDURE ApplyRange;
    PROCEDURE CancelRange;
    PROCEDURE SetRangeStart;
    PROCEDURE SetRangeEnd;
    PROCEDURE EditRangeStart;
    PROCEDURE EditRangeEnd;
    PROCEDURE SetRange( CONST StartVals, EndVals: ARRAY OF CONST );
  PUBLISHED
    OnRangeChange: TDatasetNotifyEvent  Read FOnRangeChange Write FOnRangeChange;
  END;

PROCEDURE Register;


IMPLEMENTATION

PROCEDURE TNiftyTable.ApplyRange;
BEGIN
  Inherited ApplyRange;               {Apply the new range first}
  IF Assigned( FOnRangeChage ) THEN
     FOnRangeChange( Self );          {Now, inform whoever}
END;

PROCEDURE TNiftyTable.CancelRange;
BEGIN
  Inherited CancelRange;              {Cancel the range}
  IF Assigned( FOnRangeChange ) THEN  
     FOnRangeChange( Self );          {Trigger the event}
END;

PROCEDURE TNiftyTable.SetRangeStart;
BEGIN
  Inherited SetRangeStart;
  IF Assigned( FOnRangeChange ) THEN
     FOnRangeChange( Self );
END;

PROCEDURE TNiftyTable.SetRangeEnd;
BEGIN
  Inherited SetRangeEnd;
  IF Assigned( FOnRangeChange ) THEN
     FOnRangeChange( Self );
END;

PROCEDURE TNiftyTable.EditRangeStart;
BEGIN
  Inherited SetRangeStart;
  IF Assigned( FOnRangeChange ) THEN
     FOnRangeChange( Self );
END;

PROCEDURE TNiftyTable.EditRangeEnd;
BEGIN
  Inherited SetRangeEnd;
  IF Assigned( FOnRangeChange ) THEN
     FOnRangeChange( Self );
END;

PROCEDURE TNiftyTable.SetRange( CONST StartVals, EndVals: ARRAY OF CONST );
BEGIN
  Inherited SetRange( StartVals, EndVals );
  IF Assigned( FOnRangeChange ) THEN
     FOnRangeChange( Self );
END;


PROCEDURE Register;   {Put it on the same palette tab as TTable}
BEGIN
  RegisterComponents( 'Data Access', [TNiftyTable] );
END;


I haven't tested this code so you'll have to weed out any typos etc yourself.

BOTTOM LINE:  This is the very same as a TTable but with a new event type. You can use it instead of TTable.

I hope that this helps you with your problem.  

Cheers,
Ian C.

Dear Ian C,

I didn't realize writing components was so easy.  I definitely recommend that ZifNab use your code for his purpose, the Cancel way would definitely be more code and more confusing.  

Anyway, here is why I'm writing.  I am new to the component realm of programming for Delphi.  I have been writing in Delphi for about 3-4 years and have never had the need for writing new components till now.  (College wasn't as demanding as the "real world" :-)  I have been trying to find some really good source for learning how to write new components.  I have written about 2 components already (mainly it was just making a protected property published), really easy to do.  But I feel as though I'm not ready for "big components" and the such.  I have the code for a really good parser that I wrote (2500 lines of code) and was thinking of making a component out of it since it is large and is already written.  Is there any good books out there for component writing?  So far, I've looked at quite a few and been really disappointed in their coverage.  Borland's books are OK, but as with most company manuals, they seem to be leaving out some stuff--it feels that way anyway.  What process did you go though to learn how to write components?  

If you want points for any of these questions, I can make a separate question for you to respond to.  I was just hoping you could help me out since you seem to know what your doing (I've been reading quite a few of your answers and see that you are one of the top 10 experts).  

Thanks for your time,
Scott
There is a really good book that I use as a reference all the time and have recommended it before.  It is the Delphi 2 Developer's Guide by Sams Publishing,  ISBN 0-672-30914-9.  It's not just component writing, but lots more stuff that you need to know (like message handling).  I don't know about a D3 book yet, but this one will do for your purposes.

There is another I'll but I don't have it here with me now, I'll get it later.

And finally, there's always Ray Kanopka's book.  Check out Raize Components.  Ray is a well known component writter.

Cheers,
Ian C.
Avatar of ZifNab

ASKER

Ian & Scott,

I'm sorry that I couldn't answer you earlier but I was in another hospital yesterday.

Ok, I see this is a way. And you get my points for this. But isn't there another way around. Where you don't have to change two or three components (e.g. TTable, TQuery, ...). So if you give the calculation component to someone else, he doesn't has to install the other TTable, TQuery. I, for myself, don't like to have lot's of different components which only do some few things else than the other ones, or which you have to use just for one special component.
I thought already to change my TDBCalc component. For instance to  descent it from TDatasource not from TCustomLabel. Then I wanted to make a sort of a fieldeditor (like in the TDataSet descendants, where you can make calculated fields, etc), where you could make all your calculation fields. But then I've got other BIG problems.

1) With TCustomlabel (data-aware) I had a caption which the user could place on the form. If I use a descendant of TDatasource I don't have it, but is there a way to do it?

2) I really don't know, how the TDataSet descendants can make new calculation fields and make them available on the form.

- Another way around is just to keep my TDBCalc components (TCustomlabel). I used this the first time because then you only have to couple TDBCalc to a Datasource and you don't have to look if the table is a TTable or a TQuery. TDatasource will do that for you. But then I've to find a way to make him only sensible for an change in range. But I've asked this already, so I supose there isn't a way around for this. But maybe there is? That's the last time I ask it to do it this way... sorry, can't help it.

- Another way is to use my TDBCalc, don't make him aware for range changes but make another, totally new component which is aware for rangechanges! This component will look for all the TDBCalcs on the form and will sort them out (e.g. their datasource, field). If a range changes he'll be the one, which will notify the TDBCalcs automatically. So their is almost no programming anymore. This will also reduce the time for calculating all the fields, because with one iteration through the table all TDBCalc opertations will be done. Just put one totally new component on the form and then the other TDBCalcs. That's all!

3) Which one of these 3 proposals is the best? Or is there still a better way to do it? Or maybe it's just too difficult to make it, and should I stay with changing the TTables and TQuery's.
Do you still want to help me? If you want, I'll increase the points for this. This is the first time I'm in experts-exchange, so I don't know yet, what a difficult question is. I suppose this is one is difficult but how much difficult???

Already thanks a lot, both of you!

Avatar of ZifNab

ASKER

Just a simple mind-spindle :

If you make a TDataSet descendant component, you'll always will have the field editor with you. Is there a way to disable this feature for the new component?
Avatar of ZifNab

ASKER

Just for the conveniece I'll give you the code of my TDBCalc component (if you need it to understand my questions from above, I know my english isn't so good). Please, look at it! And can you say if it's good or not? Can I improve my code writing? I've everything learned by myself so I'm not so selfsure.

{ DBCalc v. 1.0                                                                
{ (p) Tom Deprez                                                                            
{  select a datasource                                                        
{  select a field                                                              
{  select the operation                                                        
{                                                                            

unit DBCalc;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, DB, DBTables, dBCtrls;

type
  tOperation = (cAverage, cCount, cMax, cMin, cSum, cVariation);

  TDBCalc = class(TCustomLabel)
  private
    { Private declarations }
    FReadOnly: Boolean;
    FDataLink: TFieldDataLink;
    FOperation: tOperation;
    FCurrency: Boolean;
    FPrecision: Integer;
    FDisplayFormat: string;
    function GetDataField: string;
    function GetDataSource: TDataSource;
    procedure SetDataField(const Value: string);
    procedure SetDataSource(Value: TDataSource);
    procedure SetOperation(Value: tOperation);
    procedure SetCurrency(Value: Boolean);
    procedure SetPrecision(Value: Integer);
    procedure SetDisplayFormat(const Value: string);
    procedure DataChange(Sender: TObject);
  protected
    { Protected declarations }
    function Calculation:double; virtual;
    function GetLabelText:string; override;
  public
    { Public declarations }
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
    procedure Calculate;
  published
    { Published declarations }
    property Align;
    property Alignment;
    property AutoSize;
    property Color;
    property DragCursor;
    property DragMode;
    property Enabled;
    property FocusControl;
    property Font;
    property ParentColor;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ShowAccelChar;
    property ShowHint;
    property Transparent;
    property Visible;
    property WordWrap;
    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDrag;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDrag;
    property DataField: string read GetDataField write SetDataField;
    property DataSource: TDataSource read GetDataSource write SetDataSource;
    property Operation: tOperation read FOperation write SetOperation;
    property Currency: Boolean read FCurrency write SetCurrency default False;
    property Precision: Integer read FPrecision write SetPrecision default 15;
    property DisplayFormat: string read FDisplayFormat write SetDisplayFormat;
  end;

procedure Register;

implementation

procedure Register;
begin
 RegisterComponents('Samples', [TDBCalc]);
end;

constructor TDBCalc.Create(AOwner : TComponent);
begin
 inherited Create(AOwner);
 FReadOnly := True;
 FDataLink := TFieldDataLink.Create;
 FDataLink.OnDataChange := DataChange;
end;

destructor TDBCalc.Destroy;
begin
 FDataLink.OnDataChange := nil;
 FDataLink.Free;
 inherited Destroy;
end;

function TDBCalc.GetDataField: string;
begin
 Result := FDataLink.FieldName;
end;

function TDBCalc.GetDataSource: TDataSource;
begin
 Result := FDataLink.DataSource;
end;

procedure TDBCalc.SetDataField(const Value: string);
begin
 if Value <> FDataLink.FieldName then begin
  FDataLink.FieldName := Value;
  Invalidate;
 end;
end;

procedure TDBCalc.SetDataSource(Value: TDataSource);
begin
 if Value <> FDataLink.DataSource then begin
  FDataLink.DataSource := Value;
  Invalidate;
 end;
end;

procedure TDBCalc.SetOperation(Value: tOperation);
begin
 FOperation := Value;
 Invalidate;
end;

function TDBCalc.Calculation:Double;
var MyBookMark : TBookMark;
    CalcField, c1, c2 : double;
    init       : Boolean;
    DataChangeProc : TDataChangeEvent;
    DataChangeLink : TNotifyEvent;

begin
 if FDataLink.Field <> nil then begin
  {DataChangeLink := FDataLink.OnDataChange;
   FDataLink.OnDataChange := nil;
   DataChangeProc := FDataLink.DataSource.OnDataChange;
   FDataLink.DataSource.OnDataChange := nil;

   This works if you only have one TDBCalc on the form, otherwise
   you'll come in a never ending loop. Dum of me, that I didn't saw it
   the first time I wrote this! But offcourse, nobody is perfect and we all
   learn by making mistakes}

   with FDataLink.DataSource.DataSet do begin
   MyBookMark := GetBookMark;
   c1         := 0;
   c2         := 0;
   CalcField  := 0;
   init       := true;
   First;
   While not EOF do begin
   Case FOperation of
     cAverage   : begin
                   c1 := c1 + FDataLink.Field.AsVariant;
                   c2 := c2 + 1;
                  end;
     cCount     : CalcField := CalcField + 1;
     cMax       : if init then begin
                   CalcField := FDataLink.Field.AsVariant;
                   init      := False;
                  end
                   else if FDataLink.Field.AsVariant > CalcField then
                         CalcField := FDataLink.Field.AsVariant;
     cMin       : if init then begin
                   CalcField := FDataLink.Field.AsVariant;
                   init      := False;
                  end
                   else if FDataLink.Field.AsVariant < CalcField then
                         CalcField := FDataLink.Field.AsVariant;
     cSum       : CalcField  := CalcField + FDataLink.Field.AsVariant;
     cVariation : begin
                   if init then begin
                    c1   := FDataLink.Field.AsVariant;
                    c2   := FDataLink.Field.AsVariant;
                    init := false;
                   end
                    else begin
                     if FDataLink.Field.AsVariant > c1 then
                      c1 := FDataLink.Field.AsVariant;
                     if FDataLink.Field.AsVariant < c2 then
                      c2 := FDataLink.Field.AsVariant;
                    end;
                  end;
    end;
    Next;
   end;
   GotoBookMark(MyBookMark);
   FreeBookMark(MyBookMark);
   Case FOperation of
    cAverage   : CalcField := c1 / c2;
    cVariation : CalcField := c1 - c2;
   end;
   EnableControls;
  end;
{  FDataLink.OnDataChange := DataChangeLink;
  FDataLink.DataSource.OnDataChange := DataChangeProc;}
 end;
 Result := CalcField;
end;

procedure TDBCalc.SetCurrency(Value: Boolean);
begin
 if FCurrency <> Value then begin
  FCurrency := Value;
  Invalidate;
 end;
end;

procedure TDBCalc.SetPrecision(Value: Integer);
begin
 if Value < 2 then Value := 2;
 if Value > 15 then Value := 15;
 if FPrecision <> Value then begin
  FPrecision := Value;
  Invalidate;
 end;
end;

procedure TDBCalc.SetDisplayFormat(const Value: string);
begin
 if FDisplayFormat <> Value then begin
  FDisplayFormat := Value;
  Invalidate;
 end;
end;

function TDBCalc.GetLabelText: string;
var Format: TFloatFormat;
    Digits: Integer;

begin
 if FDisplayFormat = '' then begin
  if FCurrency then begin
   Format := ffCurrency;
   Digits := CurrencyDecimals;
  end else begin
       Format := ffGeneral;
       Digits := 0;
      end;
  GetLabelText := FloatToStrF(Calculation, Format, FPrecision, Digits);
 end
  else GetLabelText := FormatFloat(FDisplayFormat, Calculation);
end;

procedure TDBCalc.Calculate;
begin
 Invalidate;
end;

procedure TDBCalc.DataChange(Sender: TObject);
begin
 if (FDataLink.Field <> nil) and not(csDesigning in ComponentState) then Invalidate;
end;


end.
Sorry to hear about the hospital visit.  Hope it wasn't serious and you're ok.

After reading through your code, I did notice that you use VARIANT a lot.  If you read about the type VARIANT in the help file, you will find this statement:
-----------------
Note that while variants offer great flexibility, they also consume more memory than regular variables, and operations on variants are substantially slower than operations on statically typed values.
-----------------
I don't know if changing to ASFLOAT will speed up your calculation or not.  It would appear to since the TFloatField stores if value as a Double and that requires no conversion when you grab it out for calculations.  I would assume that a comparable speed to the present one would be seen for any other type of data it would operate on.  Your procedure is looking for doubles though and this will most likely improve speed in the long run since that seems to be a concern of yours.

Additionally, a speed increase will be noticed if you have one case statement and multiple loops instead of one each.  Here is why:  For each iteration of the While loop, you must run the conditional for the case statement and then the conditional for the While statement.  If you were to do it the opposite way, you will only be running the conditional for the case statement once and then the While conditional for each iteration.  Half the number of conditional statements that you must process.  The speed will only help for rather large datasets and will probably not be noticed otherwise.  Your code will look more repititious but it will run faster.

One more speed increase:  Get rid of the init variable and corresponding "if" statements.  When you case, run the init statement and then enter the loop.  No "if" statement is required.  (This will work if you do the speed increase above and then follow up with this suggestion).

Need for speed:  
1.  Loops are the most time consuming operations in programs.  Always move all information that you can outside of the loop.  If you can, run a conditional first and have two loops instead of having one loop with a conditional inside it.  

2.  If you are doing a calculation (large one) move the part of the calculation that is constant throughout the loop to be calculated to a temporary variable before entering the loop (this one is most likely handled by the optimizer.  This is a compiler technique that the computer should perform automatically.  Sometimes the optimizer doesn't catch it and doing it yourself ensures you get the best performance.)

3.  My suggestion for you, if you are interested in speed, is to learn about compilers.  There are many books out there, I can recommend a few if you want.  Get one and research on OPTIMIZATION.  Borland has a great optimizer but even the best optimizers can only do so much.  Sometimes knowing the techniques help in making sure your programs run the most efficiently.  Sometime just knowing what the OPTIMIZER will do with a sequence of statements can alert you to write it that way so the optimizer will catch it and make it more efficient.

Remember, Loops are great programming techniques but they need to be handled with care if you have speed as one of your major concerns.

Good Luck,
Scott
Avatar of ZifNab

ASKER

Hi Scott,

First of all, thanks for your sympathy about my hospital visit, but there isn't anything wrong with me. At the moment I work at a hospital and sometimes I have to visit others, so ...

Second, thanks a lot for looking at my code and giving me hints! I really appreciate that, if I can help you with something, just ask! And I'll try to help you at my best. Well I always thought that the code had to be the easiest readable and the least possible lines of code. Well, one person once said this to me.  Thanks for remembering me that this isn't always true.

Yes, please if you want, recommend me some books!

c.u.

Tom

I believe you all live in America? Because when my day is almost finished, you all start to send comments and answers. Well, I live in Belgium, you see. Bye!

Glad to hear your not sick or something.

I was wondering where you were from.  Your English is pretty good but every once in a while you put words in the wrong place.  I therefore knew you lived some where else but didn't know where.  Yes, I do live in the USA.  I am in Virginia on the East Coast.  

Yeah, many people don't realize that sometimes writing more code can make code faster in the long run--even though it takes a little more space in your EXE.  It is kind of a tradeoff between space and speed that you have to juggle.  "Which one if more important?" is the main question (even though now-a-days space doesn't seem to be that much of a consideration anymore).  

Glad I could help.  I am very used to looking at code and finding where it can be optimized---my professor in college would give us code and tell us to make it faster where we could.  It really helped me get to know how to make the most efficient code when speed is a consideration.  I have the book we used in the class and it has about 12 suggestions for optimization.  Most are only for programmers of compilers but they do help when your programming code to be compiled into an app.  I'll have to find it at home and send you all the information about it later on tonight.  (I'll warn you the book is like $50-$70.  And it doesn't have that many pages either.  Educational books like that are always very expensive.)  I can probably read up on it and paraphrase all the suggestions for you if you want.  That will be the cheapest way of doing it--and the best since I don't even know how easy it is to find this book on the market.  I'll send you a message on here tonight and tell you about the suggestions.

I can also write to my old professor and get some more suggestions from him.  He is really good with code and getting it to fly.

Talk to you later,
Scott
Ian,

Thanks for the suggestions.  I'll look into the books.  

I have heard of the Raise components and even have them here and at home.  They are really good ones.  I didn't realize that the guy the wrote them also wrote a book.  

Thanks again,
Scott
Avatar of ZifNab

ASKER

Scott,

Thanks, I'm looking forward on your message.

I've got a suggestion if you want some points for the information you gave me. You earn some, because you put a lot of time in it. If you want I can ask a question about compilers and optimizing speed. It's up to you!

c.u.

Tom
If you want to give me points for it then thats ok.  I believe in freedom of information, personally.  Actually, I was thinking of making a 0 point question and posting all my suggestions for others to have for free.  Additionally, anyone who had other suggestions could post them and it could be a speed posting area for all to participate in.  I don't know if it will work but I think there is enough interest in it that it may work quite well.  That gives me another idea too.  I have been searching for a subject of my web page.  I just may have found one :-)

What do you think?


Scott
Avatar of ZifNab

ASKER

Scott,

freedom of information! That's my kind of idea, too.

GREAT idea ;-) I think you found a hole in the market. But look out maybe you'll be overloaded too fast!

What do I have to do? Ask a zero question or recommend your site?
I believe the webmasters won't be happy with a zero question, I think it will take too much space in a little while.

c.u.

Tom

Tom.Deprez@uz.kuleuven.ac.be
Avatar of ZifNab

ASKER

Scott,

freedom of information! That's my kind of idea, too.

GREAT idea ;-) I think you found a hole in the market. But look out maybe you'll be overloaded too fast!

What do I have to do? Ask a zero question or recommend your site?
I believe the webmasters won't be happy with a zero question, I think it will take too much space in a little while.

c.u.

Tom

Tom.Deprez@uz.kuleuven.ac.be
Well, I can set up the 0 point question.  I'm just not sure whether to do that or just create the site.  I'm going to have to think about how I want the site to look and then maybe you can recommend it to someone.  Let me see what I can do tonight and then I'll tell you what I'm going to do tomorrow.

There are some 0 point questions on here if you will look around.  They are old ones so they don't show up on the awaiting answer questions till you goto the next set of them.  I think they are still there unless the webmasters erased them.

I'll send you an e-mail so you know mine.  I don't really want to post it here.  I also STONGLY believe in privacy of the individual.  

Talk to you later,
Scott
Hi Tom,

You might have forgotten to assess my answer.  I am also interested to find out if it worked for you.

Cheers,
Ian C.

Avatar of ZifNab

ASKER

Hi Ian,

Sorry, that I haven't assessed your answer yet, but I was still waiting for a respond of you on a comment. Like I said there, I will grade you for your answer, but I also like to have your opinion on that comment. I didn't wanted to grade this answer already because otherwise I would loose this thread, and I didn't wanted to make you upset by asking why you didn't responded on that comment.

I believe it's 12 or 13 comments earlier  :-). Hope you don't mind reading that and giving a comment on that. Or do I just have to ask a new question for that? That's going to be difficult, because I've not much points anymore.

About my component. It's for my own use, so it has to wait until all other work is finished, but now and than I find some time (most of the time at night) and offcourse, also the problems. My other question BDE : DbiGetNextRecord is one of these.

Already thanks a lot for answering me, can you also look at that comment (12 or 13 earlier)?

Have fun,
c.u. ZifNab;
Avatar of ZifNab

ASKER

Hi Ian,

I supose there is no other way than doing it your way.

Why haven't you replied to my last comment?

Have fun,
c.u. ZifNab;
Thanks.