gerardocrisci Posted September 2, 2021 Share Posted September 2, 2021 I have a problem using MyDAC (10.4.4) with UNIGUI. When using Locate before displaying the form, the record selected on the uniDBgrid is always the first, the cursor does not move. If the same operation is done at the click of a button ... the cursor moves ... and it works. procedure TMainForm.MySearch(V:string); begin if MyQuery1.Locate('ID',V,[]) then UniLabel1.Caption:='FOUND :'+V; end; procedure TMainForm.UniFormAfterShow(Sender: TObject); begin MySearch('12'); //Finds the record, but does not display it in the grid end; procedure TMainForm.UniButton2Click(Sender: TObject); begin MySearch('30'); //Find the recod and it is displayed in the grid. end; With this problem I cannot select the record before the unidbgrid is displayed. Do you have a solution? Link to comment Share on other sites More sharing options...
x11 Posted September 2, 2021 Share Posted September 2, 2021 Try to use OnCreate or OnShow Link to comment Share on other sites More sharing options...
Hayri ASLAN Posted September 2, 2021 Share Posted September 2, 2021 42 minutes ago, gerardocrisci said: I have a problem using MyDAC (10.4.4) with UNIGUI. When using Locate before displaying the form, the record selected on the uniDBgrid is always the first, the cursor does not move. If the same operation is done at the click of a button ... the cursor moves ... and it works. procedure TMainForm.MySearch(V:string); begin if MyQuery1.Locate('ID',V,[]) then UniLabel1.Caption:='FOUND :'+V; end; procedure TMainForm.UniFormAfterShow(Sender: TObject); begin MySearch('12'); //Finds the record, but does not display it in the grid end; procedure TMainForm.UniButton2Click(Sender: TObject); begin MySearch('30'); //Find the recod and it is displayed in the grid. end; With this problem I cannot select the record before the unidbgrid is displayed. Do you have a solution? You should locate onAfterLoad event to make sure data is ready. Link to comment Share on other sites More sharing options...
gerardocrisci Posted September 2, 2021 Author Share Posted September 2, 2021 But have you tried? However... in OnCreate or OnShow or OnAfterLoad .. it doesn't work for me Link to comment Share on other sites More sharing options...
Hayri ASLAN Posted September 2, 2021 Share Posted September 2, 2021 1 hour ago, gerardocrisci said: But have you tried? However... in OnCreate or OnShow or OnAfterLoad .. it doesn't work for me Can you please create a test case? Link to comment Share on other sites More sharing options...
gerardocrisci Posted September 2, 2021 Author Share Posted September 2, 2021 1 hour ago, Hayri ASLAN said: Can you please create a test case? simple example Mainform with MyConnection1, MyQuery1, MyDataSource1 Main.pas unit Main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, uniGUITypes, uniGUIAbstractClasses, uniGUIClasses, uniGUIRegClasses, uniGUIForm, uniLabel, uniButton, uniGUIBaseClasses, uniBasicGrid, uniDBGrid, Data.DB, DBAccess, MyAccess, MemDS; type TMainForm = class(TUniForm) MyConnection1: TMyConnection; MyQuery1: TMyQuery; MyDataSource1: TMyDataSource; UniDBGrid1: TUniDBGrid; UniButton1: TUniButton; UniLabel1: TUniLabel; procedure UniButton1Click(Sender: TObject); procedure UniFormAfterShow(Sender: TObject); private { Private declarations } public { Public declarations } procedure MySearch(V:string); end; function MainForm: TMainForm; implementation {$R *.dfm} uses uniGUIVars, MainModule, uniGUIApplication; function MainForm: TMainForm; begin Result := TMainForm(UniMainModule.GetFormInstance(TMainForm)); end; procedure TMainForm.MySearch(V:string); begin if MyQuery1.Locate('country_id',V,[]) then UniLabel1.Caption:='FOUND :'+V; end; procedure TMainForm.UniFormAfterShow(Sender: TObject); begin MySearch('4'); //Finds the record, but does not display it in the grid end; procedure TMainForm.UniButton1Click(Sender: TObject); begin MySearch('5'); //Find the recod and it is displayed in the grid. end; initialization RegisterAppFormClass(TMainForm); end. Main.dfm object MainForm: TMainForm Left = 0 Top = 0 ClientHeight = 299 ClientWidth = 635 Caption = 'MainForm' OldCreateOrder = False MonitoredKeys.Keys = <> OnAfterShow = UniFormAfterShow PixelsPerInch = 96 TextHeight = 13 object UniDBGrid1: TUniDBGrid Left = 20 Top = 25 Width = 386 Height = 246 Hint = '' DataSource = MyDataSource1 LoadMask.Message = 'Loading data...' TabOrder = 0 end object UniButton1: TUniButton Left = 435 Top = 90 Width = 75 Height = 25 Hint = '' Caption = 'UniButton1' TabOrder = 1 OnClick = UniButton1Click end object UniLabel1: TUniLabel Left = 440 Top = 130 Width = 46 Height = 13 Hint = '' Caption = 'UniLabel1' TabOrder = 2 end object MyConnection1: TMyConnection Database = 'sakila' Username = 'root' Server = 'localhost' Connected = True LoginPrompt = False Left = 440 Top = 20 EncryptedPassword = '' end object MyQuery1: TMyQuery Connection = MyConnection1 SQL.Strings = ( 'select * from country') Active = True Left = 180 Top = 125 end object MyDataSource1: TMyDataSource DataSet = MyQuery1 Left = 260 Top = 125 end end at startup it does not go to record # 4 this does not work with MyDAC Link to comment Share on other sites More sharing options...
Abaksoft Posted September 2, 2021 Share Posted September 2, 2021 5 hours ago, gerardocrisci said: simple example Mainform with MyConnection1, MyQuery1, MyDataSource1 Main.pas unit Main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, uniGUITypes, uniGUIAbstractClasses, uniGUIClasses, uniGUIRegClasses, uniGUIForm, uniLabel, uniButton, uniGUIBaseClasses, uniBasicGrid, uniDBGrid, Data.DB, DBAccess, MyAccess, MemDS; type TMainForm = class(TUniForm) MyConnection1: TMyConnection; MyQuery1: TMyQuery; MyDataSource1: TMyDataSource; UniDBGrid1: TUniDBGrid; UniButton1: TUniButton; UniLabel1: TUniLabel; procedure UniButton1Click(Sender: TObject); procedure UniFormAfterShow(Sender: TObject); private { Private declarations } public { Public declarations } procedure MySearch(V:string); end; function MainForm: TMainForm; implementation {$R *.dfm} uses uniGUIVars, MainModule, uniGUIApplication; function MainForm: TMainForm; begin Result := TMainForm(UniMainModule.GetFormInstance(TMainForm)); end; procedure TMainForm.MySearch(V:string); begin if MyQuery1.Locate('country_id',V,[]) then UniLabel1.Caption:='FOUND :'+V; end; procedure TMainForm.UniFormAfterShow(Sender: TObject); begin MySearch('4'); //Finds the record, but does not display it in the grid end; procedure TMainForm.UniButton1Click(Sender: TObject); begin MySearch('5'); //Find the recod and it is displayed in the grid. end; initialization RegisterAppFormClass(TMainForm); end. Main.dfm object MainForm: TMainForm Left = 0 Top = 0 ClientHeight = 299 ClientWidth = 635 Caption = 'MainForm' OldCreateOrder = False MonitoredKeys.Keys = <> OnAfterShow = UniFormAfterShow PixelsPerInch = 96 TextHeight = 13 object UniDBGrid1: TUniDBGrid Left = 20 Top = 25 Width = 386 Height = 246 Hint = '' DataSource = MyDataSource1 LoadMask.Message = 'Loading data...' TabOrder = 0 end object UniButton1: TUniButton Left = 435 Top = 90 Width = 75 Height = 25 Hint = '' Caption = 'UniButton1' TabOrder = 1 OnClick = UniButton1Click end object UniLabel1: TUniLabel Left = 440 Top = 130 Width = 46 Height = 13 Hint = '' Caption = 'UniLabel1' TabOrder = 2 end object MyConnection1: TMyConnection Database = 'sakila' Username = 'root' Server = 'localhost' Connected = True LoginPrompt = False Left = 440 Top = 20 EncryptedPassword = '' end object MyQuery1: TMyQuery Connection = MyConnection1 SQL.Strings = ( 'select * from country') Active = True Left = 180 Top = 125 end object MyDataSource1: TMyDataSource DataSet = MyQuery1 Left = 260 Top = 125 end end at startup it does not go to record # 4 this does not work with MyDAC I can't see MyQuery1.open Where do you open your DataSet ? OnCreate event ? Link to comment Share on other sites More sharing options...
gerardocrisci Posted September 3, 2021 Author Share Posted September 3, 2021 8 hours ago, Abaksoft said: I can't see MyQuery1.open Where do you open your DataSet ? OnCreate event ? DFM object MyQuery1: TMyQuery Connection = MyConnection1 SQL.Strings = ( 'select * from country') Active = True Left = 180 Top = 125 end This is in the example ... but you can open it wherever you want .. the problem is the positioning of the row in the grid after the initial locate. Link to comment Share on other sites More sharing options...
mierlp Posted September 3, 2021 Share Posted September 3, 2021 The Locate method is intended to search for a record; the IndexFieldNames property is intended to sort records on the client. These operations are only performed after fetching all data matching the query. Maybe the problem is that,- at the moment you execute the code, NOT ALL RECORDS are loaded because of TMyQuery.FetchAll = false. Then only the amount of records are loaded which is se by TMyQuery.FetchRows When you you execute code by button maybe all or more records are loaded on that point. So ....set the TMyQuery.FetchAll property to True; and see if it changes the behavior. Regards Link to comment Share on other sites More sharing options...
gerardocrisci Posted September 3, 2021 Author Share Posted September 3, 2021 2 hours ago, mierlp said: So ....set the TMyQuery.FetchAll property to True; and see if it changes the behavior. By default TMyQuery.FetchAll is true Link to comment Share on other sites More sharing options...
mierlp Posted September 3, 2021 Share Posted September 3, 2021 I did a simple test within my existing application which uses forms and frames. The frame contains the dbgrid so i tested is like this in the uniFrameCreate event i put this simple code: var P : Integer; begin if not dmType.TypeCountry.Active then dmType.TypeCountry.Active; dmtype.TypeCountry.Open; P := 5; dmType.TypeCountry.Locate('typeCountryID', P, []); Result is the record pointer is to the record with ID=5, see blue line in dbgrid...WORKS Make sure that the variable you use is of type integer! Link to comment Share on other sites More sharing options...
gerardocrisci Posted September 3, 2021 Author Share Posted September 3, 2021 13 minutes ago, mierlp said: Make sure that the variable you use is of type integer! Have you done the test with MyDAC?😱 With FireDAC or ODBC or whatever it works. From the example it is not a question of variable, the record finds it but does not display it. Link to comment Share on other sites More sharing options...
mierlp Posted September 3, 2021 Share Posted September 3, 2021 Test with MyDAC Link to comment Share on other sites More sharing options...
gerardocrisci Posted September 3, 2021 Author Share Posted September 3, 2021 1 minute ago, mierlp said: Test with MyDAC I don't use a Frame but a MainForm and the query is on the Form ... try my example .. i use the latest version of MyDAC and the problem is there! Please, create my example and try. Link to comment Share on other sites More sharing options...
mierlp Posted September 3, 2021 Share Posted September 3, 2021 See testcase in MainModule i put the MyConnection component and there you can use you're credentials to connect to you're mysql server mainform contains the query and dataset component form1 contains the dbgrid in the menu menu when you click the option 'Open form with dbgrid' there i open query in form1.Oncreate i set the parameters and it find record 5 testcae - dbgrid locate.zip Link to comment Share on other sites More sharing options...
gerardocrisci Posted September 3, 2021 Author Share Posted September 3, 2021 First I tell you Thanks for your answers Your example works ... but I haven't solved the problem😭 If you move Country: TMyQuery and dsCountry: TMyDataSource on Form1 ... the cursor after Locate stays on the first record. Try and let me know. if the Dataset and the Grid are on the same form .. the problem occurs. You want to check GRAZIE🙂 Link to comment Share on other sites More sharing options...
mierlp Posted September 3, 2021 Share Posted September 3, 2021 That's right .. that doesn't work, but that has to do with the fact that loading the database and executing the code may be too fast. In addition, it is never a good idea to put Queries and Datasets on the form, that's exactly what the DataModule are for. I would choose a different setup. Try it with a DataModule then I think you don't have the problem anymore or like in my example. When using DataModules all Querie and Dataset are everywhere available. Having Query and datasets available on a form has no added value, it's the wrong approach for database development. Regards Peter Link to comment Share on other sites More sharing options...
gerardocrisci Posted September 3, 2021 Author Share Posted September 3, 2021 6 minutes ago, mierlp said: Having Query and datasets available on a form has no added value, it's the wrong approach for database development. I do not agree! thanks Link to comment Share on other sites More sharing options...
mierlp Posted September 3, 2021 Share Posted September 3, 2021 haha...of course you don't have to agree with that 😉 My largest application is about 200 forms, 20 data modules and not a single query or dataset on the form. With a dataset you have everything neatly organized and you can address any query/dataset as long as you integrate the DataModule in your form. But also smaller applications are always developed with DataModules. You have to choose the approach that suits you and your application Link to comment Share on other sites More sharing options...
gerardocrisci Posted September 3, 2021 Author Share Posted September 3, 2021 8 minutes ago, mierlp said: You have to choose the approach that suits you and your application I only agree on this ... Link to comment Share on other sites More sharing options...
gerardocrisci Posted September 3, 2021 Author Share Posted September 3, 2021 Hi, trying I have this sequence: The database after locate is on the right record! the first "NotifyAjax" from the unidbgrid .. lead to the right position. .. I read the value 4 in Datasource.DataSet.RecNo the next "NotifyAjax" .. in unit uniDBGrid; procedure TUniCustomDBGrid.NotifyAjax; --> HookEvents(True); ---> HookFilter(true); does so to modify the DataSet.OnFilterRecord FFilterHooked := True; FSaveFilter := Ds.OnFilterRecord; Ds.OnFilterRecord := H_OnFilterRecord; ... and Datasource.DataSet.RecNo returns to the value 0 if i impose this fix .. i don't have the problem. // HookFilter(ASet); HookFilter(False); Not using filters on the grid ...can I apply this correction?? .. What happen? I know this is not the right solution .. ... but someone tells me if he has the same problem ..and if it has a solution. Thank you and I await a reply Link to comment Share on other sites More sharing options...
Abaksoft Posted September 3, 2021 Share Posted September 3, 2021 On 9/2/2021 at 2:02 PM, gerardocrisci said: I have a problem using MyDAC (10.4.4) with UNIGUI. When using Locate before displaying the form, the record selected on the uniDBgrid is always the first, the cursor does not move. Hello Gerardo, I have Devart ibdac_7.4.4_d27std (Last update). I Tested as the same protocol you did, with FireBird dataBase. Result You are right, in your test case, i get the same behavior : No row is detected after locate methode. Discussion it's not a good idea, to open the DataSet on DesignTime. When you do it on a conventional opening, as usually we do (Opening the DataSet on Activate Form, or OnCreate Frame) the locate methode find the correct row. Here is in attachment a testCase. Regards. Locate.7z Link to comment Share on other sites More sharing options...
gerardocrisci Posted September 3, 2021 Author Share Posted September 3, 2021 I found the problem procedure TUniCustomDBGrid.HookFilter(ASet: Boolean); ... begin if FDataLink <> nil then if (DataSource <> nil) and (DataSource.DataSet <> nil) then begin Ds := DataSource.DataSet; if ASet then begin ... if (...) then begin ... FSaveFilter := Ds.OnFilterRecord; Ds.OnFilterRecord := H_OnFilterRecord; end; end .... the change of OnFilterRecord notified after locate returns the cursor to the first record.. Just start "HookFilter" before "Locate" So it would be enough UniDBGrid1.HookFilter(True); MyQuery1.Locate('Country_ID', 5, []); but HookFilter is private and not directly accessible .. So to start it just confirm the Datasource SetDataSource(Value: TDataSource); --->HookEvents(True); ---> HookFilter(True); UniDBGrid1.DataSource := MyDataSource1; MyQuery1.Locate('Country_ID', 5, []); it is therefore easy to create an adjustment that functions any library to access the data. 😀😀😃 I am happy Link to comment Share on other sites More sharing options...
Tokay Posted February 10, 2022 Share Posted February 10, 2022 Hi! I also faced this problem. Maybe it could be fixed on the component side? This is a very used case: store last grid selection/position, but with current component behavior have no any solution except of such private call with unpredictable consequences. Link to comment Share on other sites More sharing options...
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now