Lớp TkbmMWClientQuery có thuộc tính IsDataModified báo cáo trạng thái thay đổi dữ liệu. Tuy nhiên khi gán giá trị trùng khớp cho trường đã tồn tại, thuộc tính này vẫn chuyển trạng thái sang True. Ví dụ minh họa:
q.Edit;
q.FieldByName('FName').AsString:='test';
q.Post;
Sau nhiều lần thử nghiệm thay đổi mã nguồn gốc nhưng không thành công, dựa theo gợi ý từ cộng đồng, đã xây dựng phương thức kiểm tra sự khác biệt như sau:
function TDbCache.KiemTraThayDoi(
akbmMemTable: TkbmCustomMemTable): Boolean;
var
i: TkbmNativeInt;
j: TkbmNativeInt;
pGhiChu, pGoc, pCu: PkbmRecord;
danhSachGhiChu: TkbmList;
trangThai: TUpdateStatus;
giaTriCu, giaTriMoi: Variant;
begin
if akbmMemTable.State in [dsInsert, dsEdit] then
akbmMemTable.Post;
Result := False;
with akbmMemTable do
begin
danhSachGhiChu := Common.Records;
for i := 0 to danhSachGhiChu.Count - 1 do
begin
pGhiChu := PkbmRecord(danhSachGhiChu.Items[i]);
if pGhiChu = nil then
begin
Continue;
end;
// Tìm phiên bản gốc
pGoc := pGhiChu;
while pGoc^.PrevRecordVersion <> nil do
begin
pGoc := pGoc^.PrevRecordVersion;
end;
// Xác định trạng thái xử lý
if pGhiChu^.UpdateStatus = usDeleted then
begin
// Bỏ qua bản chèn bị xóa
if pGoc^.UpdateStatus = usInserted then
trangThai := usUnmodified
else
trangThai := usDeleted;
end
else if pGoc^.UpdateStatus = usInserted then
trangThai := usInserted
else
trangThai := pGhiChu^.UpdateStatus;
pCu := OverrideActiveRecordBuffer;
try
if trangThai = usModified then
begin
OverrideActiveRecordBuffer := pGhiChu; // Bản ghi đã thay đổi
for j := 0 to FieldCount - 1 do
begin
OverrideActiveRecordBuffer := pGhiChu; // Bản ghi mới
giaTriMoi := FieldByName(Fields[j].FieldName).Value;
OverrideActiveRecordBuffer := pGoc; // Bản ghi cũ
giaTriCu := FieldByName(Fields[j].FieldName).Value;
if giaTriMoi <> giaTriCu then
begin
Result:=True;
Break;
end;
end;
end
else if trangThai = usInserted then
begin
Result:=True;
end
else if trangThai = usDeleted then
begin
Result:=True;
end
else if pGhiChu.UpdateStatus = usUnmodified then
begin
end;
finally
OverrideActiveRecordBuffer := pCu;
end;
if Result then
Break;
end;
end;
end;
Phương thức này giúp xác định chính xác trạng thái thay đổi trước khi thực hiện q.Resolve.
Tác giả chân thành cảm ơn cộng sự **Thanh Dư**!