Using ProgressBar for Table opening

Discussion of open issues, suggestions and bugs regarding MyDAC (Data Access Components for MySQL) for Delphi, C++Builder, Lazarus (and FPC)
naumov13
Posts: 9
Joined: Wed 02 Jan 2008 22:44

Using ProgressBar for Table opening

Post by naumov13 » Sun 05 Jul 2009 07:11

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.

Plash
Devart Team
Posts: 2844
Joined: Wed 10 May 2006 07:09

Post by Plash » Mon 06 Jul 2009 13:37

You can use the AfterFetch event to increment the progress bar.

naumov13
Posts: 9
Joined: Wed 02 Jan 2008 22:44

Post by naumov13 » Mon 06 Jul 2009 20:48

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?

Plash
Devart Team
Posts: 2844
Joined: Wed 10 May 2006 07:09

Post by Plash » Tue 07 Jul 2009 11:34

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;

naumov13
Posts: 9
Joined: Wed 02 Jan 2008 22:44

Post by naumov13 » Tue 07 Jul 2009 13:23

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.

eduardosic
Posts: 387
Joined: Fri 18 Nov 2005 00:26
Location: Brazil

Post by eduardosic » Tue 07 Jul 2009 22:51

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;

naumov13
Posts: 9
Joined: Wed 02 Jan 2008 22:44

Post by naumov13 » Wed 08 Jul 2009 09:47

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.

eduardosic
Posts: 387
Joined: Fri 18 Nov 2005 00:26
Location: Brazil

Post by eduardosic » Wed 08 Jul 2009 23:48

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..

naumov13
Posts: 9
Joined: Wed 02 Jan 2008 22:44

Post by naumov13 » Thu 09 Jul 2009 08:29

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?

eduardosic
Posts: 387
Joined: Fri 18 Nov 2005 00:26
Location: Brazil

Post by eduardosic » Thu 09 Jul 2009 13:36

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.

naumov13
Posts: 9
Joined: Wed 02 Jan 2008 22:44

Post by naumov13 » Fri 10 Jul 2009 08:04

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?

Dimon
Devart Team
Posts: 2910
Joined: Mon 05 Mar 2007 16:32

Post by Dimon » Mon 20 Jul 2009 08:55

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; 

graendael
Posts: 3
Joined: Sat 05 Sep 2009 13:48

Post by graendael » Sat 05 Sep 2009 13:53

Has anyone solved this???

graendael
Posts: 3
Joined: Sat 05 Sep 2009 13:48

Post by graendael » Sun 06 Sep 2009 21:23

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

Dimon
Devart Team
Posts: 2910
Joined: Mon 05 Mar 2007 16:32

Post by Dimon » Mon 07 Sep 2009 06:52

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.

Post Reply