gpt4 book ai didi

delphi - 刷新嵌套在 DataSetField 中的 ClientDataSet

转载 作者:行者123 更新时间:2023-12-02 07:52:37 28 4
gpt4 key购买 nike

我几乎已经完成了一些代码来解决去年这个未回答的问题中的问题:

Refresh Nested DataSet with poFetchDetailsOnDemand

公认的观点是,如果不关闭并重新打开主 CDS,就不可能从服务器刷新嵌套的详细 CDS,但显然,仅仅为了刷新单个主行及其详细信息行。

我想到了一个简单的方法来刷新详细CDS来自服务器,它几乎可以工作。我下面的代码基本上暂时进行了详细刷新对主 ADO 查询应用过滤器以将其过滤到当前主行,并且在该过滤器生效时,通过应用类似的过滤器来刷新主 CDS,然后调用其 Refresh 方法。这是由主 CDS AfterScroll 事件触发的。

只有一个很小问题:在我的表单以及 4 个数据集和随附的网格上,表单上有一个刷新按钮,它调用我的 RefreshcdsMasterAndDetails ,即也在 cdsMasterAfterScroll 中调用。如果我使用其网格在主 CDS 上移动,我的代码一切正常,并且详细信息 CDS 行以及 AdoQuery 详细信息 <> 中的行会立即正确更新,但如果我通过单击“刷新”按钮触发它,则 CDS 详细信息行仅在我单击“刷新”按钮时每秒更新一次。

我的问题是:为什么当我的代码是从按钮单击触发而不是从 AfterScroll 事件触发时,它的效果会有什么不同,因为它可靠地执行了从 AfterScroll 事件调用的应该执行的操作但只有在点击按钮时才会触发?

//Obviously MasterPKName below is a const and DoingRefresh is a boolean
// flag on the form

procedure TForm1.cdsMasterRowRefresh(MasterPK : Integer);
begin
if DoingRefresh then Exit;

DoingRefresh := True;

try
cdsMaster.Prior;
cdsMaster.Next;
cdsMaster.Filter := MasterPKName + ' = ' + IntToStr(MasterPK);
cdsMaster.Filtered := True;
cdsMaster.Refresh;
cdsMaster.Filtered := False;

cdsMaster.Locate(MasterPKName, MasterPK, []);

finally
DoingRefresh := False;
end;
end;

procedure TForm1.qMasterRowRefresh(MasterPK : Integer);
begin
qMaster.Filter := MasterPKName + ' = ' + IntToStr(MasterPK);
qMaster.Filtered := True;
qMaster.Refresh;

cdsMasterRowRefresh(MasterPK);

qMaster.Filtered := False;
qMaster.Locate(MasterPKName, MasterPK, []);
end;

procedure TForm1.RefreshcdsMasterAndDetails;
var
MasterPK : Integer;
begin
MasterPK := cdsMaster.FieldByName(MasterPKName).AsInteger;

cdsDetail.DisableControls;
cdsMaster.DisableControls;
qDetail.DisableControls;
qMaster.DisableControls;

try
qMasterRowRefresh(MasterPK);
finally
qMaster.EnableControls;
qDetail.EnableControls;
cdsMaster.EnableControls;
cdsDetail.EnableControls;
end;
end;

procedure TForm1.cdsMasterAfterScroll(DataSet: TDataSet);
begin
RefreshcdsMasterAndDetails;
end;

最佳答案

尽管进行了大量仔细的观察和调试,我仍然没有一个令人满意的解释来解释为什么我的 CDS 刷新代码如果在主 CDS 的 AfterScroll 事件中调用,则行为会有所不同,其中详细信息 CDS 始终会正确更新,并且在 ButtonClick 处理程序中,其中详细 CDS 仅在每秒单击一次时更新。我想那是某事与主 CDS 的光标此时已经移动的事实有关与我单击按钮的情况不同,调用 AfterScroll 处理程序。

但是,我找到了一个简单的解决方法和修复方法。

解决方法就是不要在之前的 4 个数据集上调用 DisableControls进行刷新。然后详细 CDS 始终会正确刷新。任何其他禁用部分或全部数据集的排列会导致我的 q 的差异。不过,我不喜欢这种解决方法,因为 cdsMaster DBGrid 必须一直滚动数据,只需刷新一个主行及其详细信息即可。

解决办法是做一些我一开始就应该做的事情,即强制详细 ADO 查询的刷新(使用我的数据,只需调用其刷新,这是我的第一次尝试在修复时,会引发熟悉的 Ado 错误“关键列信息不足用于更新...”尽管详细信息表在服务器上有一个 PK)。

因此,解决方法如下:

procedure TForm1.qMasterRowRefresh(MasterPK : Integer);
begin
try
qMaster.Filter := MasterPKName + ' = ' + IntToStr(MasterPK);
qMaster.Filtered := True;

qMaster.Refresh;

// Do NOT omit the next 3 lines, needed to ensure that the detail query
// and hence the detail CDS, is refreshed

qDetail.Parameters.ParamByName(MasterPKName).Value := MasterPK;
qDetail.Close;
qDetail.Open;

cdsMasterRowRefresh(MasterPK);

finally
qMaster.Filtered := False;
qMaster.Locate(MasterPKName, MasterPK, []);
end;
end;

当我通过调查一个早期未回答的问题来进入这个问题时,我会将代码的更新版本移植到该版本的答案。

关于delphi - 刷新嵌套在 DataSetField 中的 ClientDataSet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24685699/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com