1 (edited by kkalgidim 2018-05-04 21:49:33)

Topic: Slow Combobox Filter Problem

Hi,
i am using myvisualdatabase version v1.52

on my project i am using comcobox.
when type in combo box it filters by name

i am using this function to filter from db

procedure Form1_ComboBox1_OnKeyPress (Sender: string; var Key: Char);
var
    id: integer;
begin

    if ord(Key)= 13 then
    begin
        id := Form1.ComboBox1.dbItemID;
        Form1.ComboBox1.DroppedDown:=False;
        Form1.ComboBox1.dbItemID := id;
        Key := #0;
        Exit;
    end;

if ((ord(Key)= 8) OR (ord(Key)= VK_ESCAPE ))  then // for backspace button
    begin
        s_cbGroups := '';
        Form1.ComboBox1.Text := '';
        UpdateDatabase('kim');
        Key := #0;
        Form1.ComboBox1.DroppedDown:=False;
        Form1.ComboBox1.dbItemID := -1;
        Exit;
    end;

    s_cbGroups := s_cbGroups + Key;
    Key := #0;


    Form1.ComboBox1.dbFilter := '(isim LIKE ''%'+ s_cbGroups +'%'''+')';

    id := Form1.ComboBox2.dbItemID;
    UpdateDatabase('kim');
    Form1.ComboBox2.dbItemID := id;

    Form1.ComboBox1.DroppedDown:=True;

    Form1.ComboBox1.Text := s_cbGroups;
    Form1.ComboBox1.SelStart := Length(s_cbGroups);
end;



procedure Form1_ComboBox1_OnCloseUp (Sender: string);
var
    id,id2: integer;
begin

    id := Form1.ComboBox1.dbItemID;
    id2 := Form1.ComboBox2.dbItemID;
    Form1.ComboBox1.dbFilter := '';
    UpdateDatabase('kim');
    Form1.ComboBox1.dbItemID := id;
    Form1.ComboBox2.dbItemID := id2;
    s_cbGroups := '';
end;

For example when i try to find name "John"
i type jo
and normally it was finding john instantly.
But now the name number increased to 600 customer so it become slow
how can i make it fast?


Thanx

2 (edited by mathmathou 2018-05-05 08:39:11)

Re: Slow Combobox Filter Problem

Hello kkalgidim,


As I am the one usually finding complex solutions to simple problems, you might want to wait for others advises smile


I see two workarounds for your problem (not sure you can implement the second one in your MVD version though...).


The first solution (and the simplest) would be to (manually) create an index on your table containing the names. This usually speeds up searches quite a bit. I recommend you search for sqlite and indexes in google, you will see that this is pretty straightforward.


The second solution would be to implement a delay (timer) in your application. Like the user is typing letter in the search field but the search does not trigger before say 0,5 second. This way, the user has time to type in his search criteria without the query being triggered every time et types in a letter (which is the cause of your application slowing down).


First you have to declare a timer in you application. This is a global variable meaning you have to place it at the very beginning of your script, like this for example :

var
     TimerA : TTimer; //----->Timer for name search

Now that the timer is declared, you will need to create it. This is done on the OnShow event of the form where it will be used like this :

Formx_Onshow (Sender: string; Action: string);
begin
    TimerA := TTimer.Create(nil); // create timer
    TimerA.OnTimer := @OnTimerA;  // event procedure the timer points to
    TimerA.Interval := 500; // interval in milliseconds of your timer


....
end;

Do not declare it in the variable section of the form since you already declared it as a global variable


Now, what does the timer do ? Declare the procedure like this :

procedure OnTimerA (Sender: TObject);
var
    //any variable you need for your search query if any
begin
    // you code here with your own search logic
     TimerA.enabled := False;
end;

Don't forget to stop (enabled := false) your timer at the end of the logic, it is the typing of the user that will trigger it after each character type din.


Finally, in the OnChange event of your search field disable the timer and start it again to reset the interval in milliseconds you set up previously.

procedure edit1_OnChange(Sender: string);
     TimerA.Enabled := False; //stops the timer and reset the time interval
     TimerA.Enabled := True; //starts the timer again for the given time interval

Since MVD creates all forms at startup and not dynamically, do not forget to free the timer when the corresponding form is closed :

procedure FormX_OnClose (Sender: string; Action: string);
begin
     TimerA.Free;
end;

Now each time the user types in a character, the system will wait 0,5 seconds before firing the search query. each time the user type sin a new character, the timer is reset for another interval.


Hope this helps.

Cheers


Mathias

I'm a very good housekeeper !
Each time I get a divorce, I keep the house

Zaza Gabor

Re: Slow Combobox Filter Problem

In the latest version of MVD, combobox have property Searchable, so you can fast search without an additional script.

Dmitry.