2010-11-01 222 views
1

我正在使用標準的數據感知組件和dbExpress在Delphi 6 + MySQL數據庫中創建應用程序。該應用程序允許用戶查看網格中的記錄並編輯數據(插入和/或刪除記錄)客戶端。這些數據編輯僅在點擊提交按鈕後才寫入數據庫。所有這一切工作正常,並具有下列設置:在Delphi中使用ClientDataSet,你能夠在DBGrid中顯示Data&Delta記錄嗎?

控制: 1. DBGrid1鏈接到DataSource1直觀地顯示數據。 2.將DataSource1鏈接到ClientDataSet1以提供DBGrid要顯示的數據。 3. ClientDataSet1鏈接到DataSetProvider1以提供客戶端數據進行編輯。 4. DataSetProvider1是鏈接SQLDataSet1,它從單個數據庫表中選擇記錄。 5. SQLDataSet1鏈接到SQLConnection以提供與MySQL數據庫的連接。

操作: 1.用戶插入記錄:我使用ClientDataSet1.InsertRecord; 2.用戶刪除記錄:我使用ClientDataSet.Delete; 3.用戶提交數據:我使用ClientDataSet1.ApplyUpdates(-1);

這對於處理數據&發佈數據(包含DataSetProvider1BeforeUpdateRecord中的一個小黑客來刪除記錄)很有效。

現在我的問題: 當用戶第一次加載表單時,DBGrid1顯示所有原始記錄,刪除所有已刪除的記錄。但是,當用戶在ClientDataSet1中插入新記錄時,DBGrid1中會顯示一條空白記錄。實際數據不會丟失或設置爲NULLS,因爲當您將ClientDataSet1.ApplyUpdates記錄正確寫入數據庫時​​。

我知道TClientDataSet具有原始數據的數據屬性和編輯數據的增量屬性。這兩個屬性可以通過一次顯示在單個DBGrid中的數據在一次&仍然允許用戶編輯數據?

我看了30多個資源和演示應用程序&都避免了這個問題。這可以做到嗎?

+1

爲什麼插入新記錄時出現空白記錄會出現問題?這不就是你填寫的空白記錄嗎? – LachlanG 2010-11-01 19:46:08

+0

沒有。我運行ClientDataSet1.InsertRecord([字段值數組]); InsertRecord執行Insert然後Post事件。 一旦這樣做,DBGrid顯示一個不可編輯的空白記錄。我執行ApplyUpdates提交到數據庫,然後查詢數據庫表和新插入的記錄在那裏。問題是DBGrid未在新插入的記錄中顯示字段值。 – Forer 2010-11-02 06:15:26

回答

2

好的...這個問題已被視爲一個沒有太多反饋的相當數量。我通過下載許多教程做了一些研究,演示應用程序&閱讀了多篇文章/幫助信息,討論了這些控件的使用。

淨結果:

  1. 這些控制通常有點馬車。
  2. 具體參考我的問題,可以肯定地說控件不能做我描述的標準。

這是基於我審查過的30多個演示應用程序,文章和教程,要麼不會在單個數據網格中顯示原始數據和Delta數據。當然你可以使用ListBox或StringGrid來破解這個結果(這是我所做的),但是這也表明該控件不能或不能用於提供此功能(可能性很小)。

這個功能在我看來是一個明顯的疏漏,因爲用戶希望看到他們的行爲的潛在結果,方便地在單個數據網格中,並且開發者想要以簡單的&無痛苦的方式提供,即使用數據網格顯示數據!

問題回答[如果您可以通過我想要查看的演示應用程序進行不同的驗證,我會將其刪除]。

如果您創建了演示應用程序,但無法啓動它,請投票回答我的問題。謝謝

+0

你走了。請查看我的答案。 – 2011-10-20 17:55:12

+0

您還在使用一個非常舊的版本,它可以追溯到11年前... – 2011-10-20 19:16:13

+0

@Idsandon:是的,它的舊。所有的開發人員都需要使用可用或提供給項目的工具(有時甚至是舊的,有時甚至是流血的邊緣)。解決方案不僅僅是更新(這意味着金錢並且常常引發其他問題)。所以對於我的項目獲得解決方案,版本的年齡並不重要,但會幫助其他人瞭解問題的背景。謝謝你對你的輸入 – Forer 2011-10-24 08:14:39

0

Delphi提供的TDBGrid控件沒有內置的功能來顯示字段的舊值和新值。當然,歡迎您繼承網格或創建自己的網站並添加功能,或購買完成您所需功能的第三方組件。您不僅限於標準控件,儘管它們確實提供了最常用的功能。

您還可以使用計算字段完成您想要的操作。例如,如果您有一個字符串字段Name,請向名爲OldName的數據集添加一個新的計算字符串字段,其長度與名稱相同。

然後在你的OnCalcFields事件數據集,只需像下面輸入代碼:

if DataSet.State = dsEdit then 
begin 
    DataSet.FieldByName('OldName').Value := DataSet.FieldByName('Name').OldValue; 
end 
else 
begin 
    DataSet.FieldByName('OldName').Value := Null; 
end; 
+0

我不確定這是否會在沒有測試的情況下運作。我的直覺是,它不會因爲我使用TClientDataSet,它有兩種存儲數據的「模式」:實際記錄狀態(數據存在於數據庫中)和日誌狀態(數據在客戶端數據集中更改)。這些不能在數據網格中並排顯示。但在拍攝之前,讓我們先試一試。感謝您的任何輸入。 – Forer 2011-10-24 08:11:49

+0

@ForerMedia,我在發佈答案之前嘗試了一個TClientDataset,它對我有用,所以讓我知道。 – 2011-10-24 14:03:10

0

的TClientdataSet將處理本身正確的記錄狀態。更改會記錄下來,但除非您明確要求顯示其他狀態(請參閱StatusFilter屬性),否則會顯示記錄的實際狀態。

InsertRecord可能會繞過某些通知機制,因此字段顯示不會更新。如果你執行簡單的Insert和set字段值會怎麼樣?

+0

我認爲這個問題與可用性有關。在一種狀態下,您可以看到記錄中的現有數據 - 非常好。如果用戶編輯或插入記錄,則需要在提交數據之前直觀確認這些編輯/插入的內容。可悲的是,這不能與其他記錄一起顯示,只是作爲空白記錄顯示(儘管有數據)。這從用戶的角度來看就搞砸了。用戶不需要提交插入以便能夠看到他們插入的數據。 – Forer 2011-10-24 08:18:42

+0

數據顯示控件的VCL體系結構需要soem通知,如果數據直接在數據集端進行更改。通常不需要提交,您是否嘗試更改插入方法並查看它是否是通知問題? – 2011-10-24 08:54:09

+0

還沒有。當我得到一個自由的時刻,我會看看。由於該職位已有一年,因此這不是優先考慮事項。我會再看看,如果及時。 – Forer 2011-10-24 10:27:49