In the OnReconcileError event for a ClientDataSet, you can tell it to raMerge, which saves the changes to the delta, ready for another apply updates without errors. Is there a way to tell the dataset to immediately apply the delta in the OnReconcileError event? I can only think of some convoluted way to check if errors were reconciled in the AfterApplyUpdates event.
1
votes
I tried the simple-minded approach of modifying a record in the OnReconcileError event, but calling .Post on the CDS just results in an "Operation not applicable" exception. Are you already using the RecError form (from the Object Repository) in OnReconcileError? Anyway, it would probably be much simpler to avoid reconcile errors from occurring in the first place as far as possible by setting some custom constraints on the CDS.
- MartynA
Yea I am. I've tweaked it to only allow merge or refresh. Refresh is great, but merge only does half of what I need.
- Eric G
Well, I think you'd better explain for readers exactly what the "other half" is. If I'm understanding you correctly, the most difficult bit would be to identify (without human assistance) in the OnReconcileError exactly what changes need to be made to the modified record to overcome the reconciliation errors. If you can do that. I'd have thought that executing the changes in a later call up ApplyUpdates would be relatively trivial.
- MartynA
The other half is applying the stored delta. The first half was the user deciding to keep their changes. It's a multi user application. In rare cases, two users might make edits to the same field. When that user clicks save, the get the conflict form and choose to keep their change or the other users change. Now I need to know how to store that without them clicking save again.
- Eric G
According to cary Jensen's book, the purpose of setting Action := raCorrect is to "attempt to update the record again". Similarly Action := raSkip is to "Ignore the error and leave the modified record in the change cache". It might be possible to do a recursive call to applyupdates from within the ReconcileError handler. Try it and see.
- nolaspeaker
1 Answers
1
votes
So I did have centralized code for applying the updates, and i eventually realized that would probably be the best place to check if the user requested a merge. I may still need to clean this up a bit, but might be a solution for others running into this problem.
if(cds.ChangeCount > 0)then
begin
fIsMerged := false;
errors := cds.ApplyUpdates(0);
if(errors = 0)then
begin
cds.Refresh;
end
//If there is a conflict, the user might try to merge.
//If they do, we need to reapply the update.
else if(fIsMerged)then
begin
errors := cds.ApplyUpdates(0);
if(errors = 0)then
begin
cds.Refresh;
end;
end;
end;
fIsMerged is a class variable that I set in the on reconciled handler.
Action := HandleReconcileError(DataSet, UpdateKind, E);
if(Action = raMerge)then
begin
fIsMerged := true;
end;