最近維護一個項目,裡面用到ClientDataSet,由於之前接觸ClientDataSet比較少,所以這個星期補了一下關於ClientDataSet的知識,併在此記錄下我所瞭解到的並應用到實際項目中的ClientDataSet的知識。 項目新需求:1.從別的資料庫導入物料資料,並允許操作員做修改後 ...
最近維護一個項目,裡面用到ClientDataSet,由於之前接觸ClientDataSet比較少,所以這個星期補了一下關於ClientDataSet的知識,併在此記錄下我所瞭解到的並應用到實際項目中的ClientDataSet的知識。
項目新需求:1.從別的資料庫導入物料資料,並允許操作員做修改後保存提交;2.從別的資料庫導入價格資料,並允許操作員做出修改並保存;3.記錄相應的日誌。4.允許操作員過濾關鍵字查找。
(PS:項目的數據連接模式為:ADOConnection→ADOQuery→DataSetProvider→ClientDataSet→DataSource→數據集顯示控制項,包括DBGrid,DBLookupComboboxEh等)
更新單條記錄
If cdsRecord.UpdateStatus <> usUnModified then //讓clientdataset處於非編輯狀態
Raise Exception.Create('You must apply updates before refreshing the current record.');
cdsRecord.RefreshRecord;//更新單條記錄,此處要註意,不單要在ClientDataSet中設置主鍵,要去對應的adoquery設置主鍵(ProviderFlags的pfInKey設置為true)
過濾
cdsRecord.Filtered := False;
cdsRecord.Filter := 'itemcode='+QuotedStr(code);
cdsRecord.Filtered := True;
如果過濾條件為空,則顯示全部記錄
cdsRecord.Filtered := False;
cdsRecord.Filter :='itemcode like '+QuotedStr('%%');
cdsRecord.Filtered := True;
過濾條件集添加“全部”記錄
cdsLookUp.Close;
cdsLookUp.CommandText := 'select * from jc_zd_item';
cdsLookUp.Open;
cdsLookUp.First;
cdsLookUp.InsertRecord(['','全部','','QB']);
記錄日誌
在提交前的事件cdsRecordBeforeApplyUpdates中處理
procedure TForm1.cdsRecordBeforeApplyUpdates(Sender: TObject; var OwnerData: OleVariant); var csdTemp: TClientDataSet; i : Integer; begin //準備提交 if not (cdsRecord.ChangeCount>0) then //判斷數據集是否有更改,ChangeCount>0表示有更改 Exit; csdTemp := TClientDataSet.Create(nil); csdTemp.Data := cdsRecord.Data;//複製數據集,否則在這個事件裡面處理自身的數據集會進入死迴圈 csdTemp.First; if not adqLog.Active then //adqLog是連接日誌表的ADOQuery,屬性LockType選擇ltBatchOptimistic(批量提交),這就可以在提交前記錄好日誌,在提交後再把日誌批量上傳 adqLog.Active := True; for i:=0 to csdTemp.RecordCount-1 do //whilt not csdTemp.eof do同理 begin if csdTemp.UpdateStatus=usModified then //如果當前記錄是修改的 begin adqLog.Append; adqLog.FieldByName('pk').AsString := 'itemcode'; adqLog.FieldByName('newValue').AsString := csdTemp.FieldByName('itemcode').AsString; adqLog.FieldByName('remark').AsString := '修改'; adqLog.FieldByName('oldvalue').AsString := csdTemp.FieldByName('itemcode').OldValue; adqLog.Post; ShowMessage(IntToStr(Integer(csdTemp.UpdateStatus))); end; if csdTemp.UpdateStatus=usInserted then //如果當前記錄是新增的 begin adqLog.Append; adqLog.FieldByName('pk').AsString := 'itemcode'; adqLog.FieldByName('newValue').AsString := csdTemp.FieldByName('itemcode').AsString; adqLog.FieldByName('remark').AsString := '新增'; adqLog.FieldByName('oldvalue').AsString := ''; adqLog.Post; end; csdTemp.Next; end; end;
批量提交修改後的clientdataset數據集
if cdsRecord.State in [dsEdit, dsInsert] then //判斷數據集是否在編輯狀態,如果是,則把正在編輯的內容提交到記憶體
cdsRecord.Post;
cdsRecord.ApplyUpdates(0); //提交cdsRecord數據集到資料庫,參數0表示遇到提交異常則返回,如果你能容忍某一條記錄提交失敗仍然可以執行下一條的,那麼可以填寫你的容忍值
這裡要註意,DataSetProvider的UpdateMode要設置為upWhereKeyOnly,併在cdsRecord的主鍵(或其他不被修改的欄位)的ProviderFlags的pfInKey設置為true。
在cdsRecordAfterApplyUpdates中提交日誌
//提交後記錄提交日誌 if adqLog.State in [ dsEdit, dsInsert] then adqLog.Post; adqLog.UpdateBatch(arAll);//這裡是ADOQuery的一個批量上傳選項
ClientDataSet增加一條記錄
cdsRecord.AppendRecord(['7008','1982',false,false,'2018-06-28 19:19:26','','7993','PM','1000495']);
如果需要在ClientDataSet中處理SQL或生成欄位信息,那麼可以在ClientDataSet的CommandText處理,但前提是要在DataSetProvider的Options中設置poAllowCommandText為true。
待續......