Page 1 of 2

Using ProgressBar for Table opening

Posted: Sun 05 Jul 2009 07:11
by naumov13
Hello.
When I open a table (MyTable1.Open) containing a large number of records, my application freezes.
Is any way to use the progressbar on the procedure for opening the table?
Thank you.

Posted: Mon 06 Jul 2009 13:37
by Plash
You can use the AfterFetch event to increment the progress bar.

Posted: Mon 06 Jul 2009 20:48
by naumov13
Thank you for your reply.
However, I still do not understand what I need to do.
What values to use for Max and Min of ProgressBar and in which the structure execute increment of progress?
Could you give simple example?

Posted: Tue 07 Jul 2009 11:34
by Plash
You should set the QueryRecCount option of TMyTable to True. After you open the table assing a value of the RecordCount property to the Max property of the progress bar. Set the Min and Position properties to 0.
Use the following code in the AfterFetch event:

Code: Select all

  ProgressBar.Position := ProgressBar.Position + MyTable.FetchRows;

Posted: Tue 07 Jul 2009 13:23
by naumov13
Well, it's nice and easy.
But my application freezes during the opening table.
Plash wrote:After you open the table assing a value of the RecordCount property to the Max...
After that this is useless and has no meaning.

Posted: Tue 07 Jul 2009 22:51
by eduardosic
naumov13 wrote:Well, it's nice and easy.
But my application freezes during the opening table.
Plash wrote:After you open the table assing a value of the RecordCount property to the Max...
After that this is useless and has no meaning.
you can try..

Code: Select all

ProgressBar.Position := ProgressBar.Position + MyTable.FetchRows;
Application.ProcessMessages;

Posted: Wed 08 Jul 2009 09:47
by naumov13
I am sorry but I think we don't understand each other correctly.
I'm experienced in working on ProgressBar and Application.ProccessMessages.
The fact of the matter is that the value Max should be pointed before the procedure TableOpen has been called, not after.

Posted: Wed 08 Jul 2009 23:48
by eduardosic
Plash, the solution don't work.. the Afterfetch is called one time with 25 rows in FetchRows propertie.

naumov13, want increment the progressbar while the TMyTable is Opening..

Posted: Thu 09 Jul 2009 08:29
by naumov13
eduardosic Yes, you're right. It is precisely what was meant.

I realize that it is impossible to get RecordsCount before MyTable.Open procedure would have been called.
So, I'm trying to find a way to do it between BeforeOpen and AfterOpen events.
Here are the results of my test log for events occured. My Table contains 20 fields (1 of them is calculated) and 300 records rows.
  • 10:00:05: MyTable Before Open (once)
    10:00:05: MyTable Before Fetch (13 times)
    10:00:05: MyTable After Fetch (once)
    10:00:05: MyTable Calc Fields (6675 times)
    10:00:14: MyTable After Open (once)
For example, I can use a number 6675 for MaxValue (it works correctly) and do increment Progress in OnCalcFields event handler.
How has it turned out that the number of OnCalcFields event occurence is 6675?
How can I calculate it for another quantity of fields and records of the Table?


Also I found information about the TDBProgress componen by RXLib (and TJvDBProgress by JVCL Team)

This component uses the Callback-function IDAPI for reporting on the implementation of long-term operations with the database and (in the 32-bit version) for tracking downloads BDE to SQL-servers.
Not all operations will provide information on the course of its implementation. When Query executes messages sent on the performed action. The percentage reported for indexing, batch operations, as well as several other actions.

Unfortunately, nothing is reported, for example, when opening the table.

Because nothing like this out, maybe it makes sense to make a new feature?

Posted: Thu 09 Jul 2009 13:36
by eduardosic
you can try this..

Code: Select all

Procedure XXXX.OpenTable;
begin
    with TblClient do begin
      Close;
      FetchAll     := False; //Speed Open Process..
      FetchRows := 50;
      Open;
      Progressbar.Max :=  Recordcount;
      DisableControls;   
      while not Eof do begin //fetch all rows and increment progressbar
        Progressbar.Position := Progressbar.Position + 1;
        Next;
        Application.ProcessMessages;
      end;
      First;
      EnableControls;   
    end;
end;
I Made a Generic Window with a animation of a Progressbar like Windows Vista... o show the windows while TMyQuery is Openning.

Posted: Fri 10 Jul 2009 08:04
by naumov13
Yeah, this code works correctly and fast...

Code: Select all

      ......
      while not Eof do begin //fetch all rows and increment progressbar

        // I want to display the actual progress not here...

        Progressbar.Position := Progressbar.Position + 1;
        Next;
        Application.ProcessMessages;
      end;
      .....

But here:

Code: Select all

    ...
    with TblClient do begin
      Close;
      FetchAll     := False; // Gives no effect
      FetchRows := 50;

     // This procedure is working increadebly slowly because of great number of OnCalcFields executions. 
     Open;
      ......
    end;
    ...
I still don't know how to define that number.
Do you have any ideas?

Posted: Mon 20 Jul 2009 08:55
by Dimon
To solve the problem you can use the following code in the OnCalcFields event handler:

Code: Select all

Progressbar.Max :=  MyTable.RecorCount; 
ProgressBar.Position := MyTable.RecNo; 

Posted: Sat 05 Sep 2009 13:53
by graendael
Has anyone solved this???

Posted: Sun 06 Sep 2009 21:23
by graendael
Well I have found a way to know the records in an easy way before opening the table

Myquery1.SQL.Text:='SELECT COUNT(*) FROM tbsolicitudes2';
Myquery1.execute;

progressbar1.Max:=MyQuery1.Fields[0].AsInteger;

mytable1.tablename:='tbsolicitudes2';
Mytable1.FetchAll:=true;

//up to here everything works fine
//from now on it "freezes" for 4 minutes


mytable1.Open;

Once it is open everything works fine. If a progressbar could be placed while opening the user wouldn't think the program is freezing.

The problem with:

procedure TForm1.MyTable1CalcFields(DataSet: TDataSet);
begin
progressbar1.Position:=mytable1.RecNo;
Application.Processmessages;
end;

is that the dataset calculates the fields when they are required,

//up to now everything works great; the problem is with Open. I think there should be an event "onfetch", "onfetchprogress" or sth like that because oncalculatefields only is executed when accessing to a certain record.

If we leave the TForm1.MyTable1CalcFields(DataSet: TDataSet) the way I have shown above and I link mytable1 to a dbgrid when I move the scroll of the dbgrid the progressbar progresses with it but when opening the table the progressbar does nothing.

¿Do we have any solution?



Mytable1

Posted: Mon 07 Sep 2009 06:52
by Dimon
This problem has arisen because you set the FetchAll property to False. You should set this property to True or call the TDataSet.Last method after caliing Open.