Is it possible to call the function locate of dataset, without freezing the main thread, and ask the user if he wants to stop the function?
best regards;
thanks
EDIT 1
First code example
EDIT 2
Add comment to source with information of function call
I use ORACLE 11g of database , the dataset is a VIEW that return many record
I use for connect to oracle the component TOraQuery of DevArt with FetchRows set to 50
The locate is slow if the user enter the ID more distance from current fetch
this is the code that use for locate
procedure TForm1.GoToID(Id: integer; silent: boolean = false);
var KeyField : string;
T0 : TDateTime;
begin
T0 := Now;
if Not FQueryGrid.Active then
begin
{ Function to write a log on file }
LogModule.WriteLog('TForm1.GoToID', 'Query not active', tpliv3);
Exit;
end;
if FQueryGrid.RecordCount = 0 then Exit;
{FQueryGrid.DisableControls; No effect on performance}
Try
{ GetKeyFieldForUpdateRecord Function with return the name of PRIMAY KEY
OF VIEW
CASE Type OF
1: RESULT := 'ID_DATA';
2: RESULT := 'ID_TRACK';
3: RESULT := 'ID_MACHINE';
END;
}
KeyField := GetKeyFieldForUpdateRecord;
try
if Id > 0 then
begin
{Check if ID request from user is egual at the current selected id}
if Id = FQueryGrid.FieldByName(KeyField).AsInteger then
begin
{Function that save some fields on Record variable of current ID}
SetBuild(True);
Exit;
end;
{ Freezing of main }
if FQueryGrid.Locate(KeyField, Id, []) then
begin
{Function that save some fields on Record variable of current ID}
SetBuild(True);
end
else
if not silent then
MessageBox(Handle, Pchar(STR_PROG_NOT_FOUND), 'Warning', MB_ICONWARNING or MB_OK or MODALITY);
end;
except
on e: Exception do
{ Function to write a log on file }
LogModule.WriteLog('TForm1.GoToID', e.Message, tpliv1);
end;
Finally
//FQueryGrid.EnabledControls;
{$REGION 'Log'}
{TSI:IGNORE ON}
{ Function to write a log on file with timing elpased for execute }
LogModule.WriteLog(Format('[%p]%s.GoToID',[pointer(Self),Self.Classname]),
Format('Execute in %s',[FormatDateTime(LOG_ID_343_2,Now-t0)]),tpliv5,True);
{TSI:IGNORE OFF}
{$ENDREGION}
end;
end;
EDIT 3
Test with function FindKey
This function searches for the parameter passed to the function by using indexes specificata on the property INDEXNAME or INDEXFIELDNAME, the problem is that it searches only within fetched records and does not move the dataset for fetch new record
procedure TForm1.GoToID(Id: integer; silent: boolean = false);
var KeyField : string;
T0 : TDateTime;
begin
T0 := Now;
if Not FQueryGrid.Active then
begin
{ Function to write a log on file }
LogModule.WriteLog('TForm1.GoToID', 'Query not active', tpliv3);
Exit;
end;
if FQueryGrid.RecordCount = 0 then Exit;
{FQueryGrid.DisableControls; No effect on performance}
Try
{ GetKeyFieldForUpdateRecord Function with return the name of PRIMAY KEY
OF VIEW
CASE Type OF
1: RESULT := 'ID_DATA';
2: RESULT := 'ID_TRACK';
3: RESULT := 'ID_MACHINE';
END;
}
KeyField := GetKeyFieldForUpdateRecord;
try
if Id > 0 then
begin
{Check if ID request from user is egual at the current selected id}
if Id = FQueryGrid.FieldByName(KeyField).AsInteger then
begin
{Function that save some fields on Record variable of current ID}
SetBuild(True);
Exit;
end;
{ Freezing of main }
if FQueryGrid.FindKey([id]) then
begin
{Function that save some fields on Record variable of current ID}
SetBuild(True);
end
else
if not silent then
MessageBox(Handle, Pchar(STR_PROG_NOT_FOUND), 'Warning', MB_ICONWARNING or MB_OK or MODALITY);
end;
except
on e: Exception do
{ Function to write a log on file }
LogModule.WriteLog('TForm1.GoToID', e.Message, tpliv1);
end;
Finally
//FQueryGrid.EnabledControls;
{$REGION 'Log'}
{TSI:IGNORE ON}
{ Function to write a log on file with timing elpased for execute }
LogModule.WriteLog(Format('[%p]%s.GoToID',[pointer(Self),Self.Classname]),
Format('Execute in %s',[FormatDateTime(LOG_ID_343_2,Now-t0)]),tpliv5,True);
{TSI:IGNORE OFF}
{$ENDREGION}
end;
end;
EDIT 4
Decreasing performance
procedure TForm1.GoToID(Id: integer; silent: boolean = false);
var KeyField : string;
T0 : TDateTime;
BFound : Boolean;
begin
T0 := Now;
BFound := False;
if Not FQueryGrid.Active then
begin
{ Function to write a log on file }
LogModule.WriteLog('TForm1.GoToID', 'Query not active', tpliv3);
Exit;
end;
if FQueryGrid.RecordCount = 0 then Exit;
{FQueryGrid.DisableControls; No effect on performance}
Try
{ GetKeyFieldForUpdateRecord Function with return the name of PRIMAY KEY
OF VIEW
CASE Type OF
1: RESULT := 'ID_DATA';
2: RESULT := 'ID_TRACK';
3: RESULT := 'ID_MACHINE';
END;
}
KeyField := GetKeyFieldForUpdateRecord;
try
if Id > 0 then
begin
{Check if ID request from user is egual at the current selected id}
if Id = FQueryGrid.FieldByName(KeyField).AsInteger then
begin
{Function that save some fields on Record variable of current ID}
SetBuild(True);
Exit;
end;
{ Freezing of main }
FQueryGrid.First;
while not FQueryGrid.Eof do
begin
if Id = FQueryGrid.FieldByName(KeyField).AsInteger then
begin
{Function that save some fields on Record variable of current ID}
BFound := True;
SetBuild(True);
Break;
end;
FQueryGrid.Next
end;
if not BFound then
if not silent then
MessageBox(Handle, Pchar(STR_PROG_NOT_FOUND), 'Warning', MB_ICONWARNING or MB_OK or MODALITY);
end;
except
on e: Exception do
{ Function to write a log on file }
LogModule.WriteLog('TForm1.GoToID', e.Message, tpliv1);
end;
Finally
//FQueryGrid.EnabledControls;
{$REGION 'Log'}
{TSI:IGNORE ON}
{ Function to write a log on file with timing elpased for execute }
LogModule.WriteLog(Format('[%p]%s.GoToID',[pointer(Self),Self.Classname]),
Format('Execute in %s',[FormatDateTime(LOG_ID_343_2,Now-t0)]),tpliv5,True);
{TSI:IGNORE OFF}
{$ENDREGION}
end;
end;