  | 
				VFP 愛用者社區 本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.   
				 | 
			 
		 
		 
	
		| 上一篇主題 :: 下一篇主題   | 
	 
	
	
		| 發表人 | 
		內容 | 
	 
	
		goto-dream
 
 
  註冊時間: 2004-05-11 文章: 909
 
  第 1 樓
  | 
		
			
				 發表於: 星期二 九月 21, 2004 10:04 pm    文章主題: Visual FoxPro 9 C/S方面極富人性化的增強(轉貼) | 
				     | 
			 
			
				
  | 
			 
			
				動感游標---飛狐堂 VFP.CN BLOG
 
Visual FoxPro 9 C/S方面極富人性化的增強(轉貼)
 
http://www.vfp.cn/blog/more.asp?name=mihu&id=336
 
 
 
Visual FoxPro 9 C/S方面極富人性化的增強 
 
 
 
作者: mihu
 
 
 
 
 
今年6月,微軟公司如期發佈了全球Foxer翹首期盼代號為Europa的Visual FoxPro 9beta 版(以下簡稱VFP9),下文是我學習、探索 VFP9 C/S方面新增功能時的一些心得,供大家一起分享。
 
 
自從VFP 8 開始,在C/S方面提供了一個CursorAdapter 類, CursorAdapter 是一個基於鬆散耦合思想設計的對象化的 Cursor 處理模型。對 CursorAdapter 類很多人對其褒貶不一,特別是一些老的Foxer認為做C/S系統用SPT就足夠了,何必再增加一個類呢?但我可以這麼說,從VFP9 開始,幾個CursorAdapter新增加的功能,相信足以使那些純使用SPT 的Foxer 心動不已了。
 
 
下面我先談談VFP9 在 CursorAdapter 部分的幾個增加和增強。
 
 
1.       屬性值可以超過255 個字符
 
 
 
 
 
用過CursorAdapter 類的人都知道,VFP8 時其幾個屬性 SelectCmd、CursorSchema、UpdateNameList、UpdatableFieldList的長度不能超過255個字符,這在VFP8時讓人感覺是一件非常滑稽的事情,當後台表的字段數一多,連使用它自身生成器生成的字符串都要報錯,不能保存,這點造成CursorAdapter使用起來極為不便,也是全球Foxer要求解決的呼聲最多的地方,現在這個問題在VFP9 中終於得到了徹底解決。
 
 
2.       生成器生成的CursorSchema 不再是按照字母次序來排列了
 
 
 
 
 
當我們設計表單上控件時,只要在表單數據環境裡放入CursorAdapter,設置 CursorAdapter 的CursorSchema 屬性就會可視化的出現一個Cursor, 此時只要拖動相應字段到表單,即可完成一個個控件的設計,這也是CursorAdapter的優點之一,VFP8 時利用生成器生成的CursorSchema 是按照字母次序排列的,這點造成設計時非常的不方便,大家習慣的是自己設計表時的字段次序,現在VFP9 在這方面也做了非常人性化的修改,現在我們可以完全非常舒服的利用其本身的生成器來生成 CursorSchema 供我們設計表單使用。
 
 
 
 
 
 
 
 
3.         NoData 和 UseCursorSchema 屬性 
 
 
 
 
VFP8 時當把CursorAdapter 設計時放到表單的數據環境裡,使用CursorFill()裡的這兩個參數極為不便,現在好了,把這兩個屬性單獨列了出來。
 
 
 
 
 
4.         TimeStamp 時間戳字段 
 
 
 
 
VFP8 的CursorAdapter 雖然 WhereType 可以等於 4 ,可是其實時間戳字段真正在更新時卻過濾掉了,根本不起任何作用。現在VFP9 的CursorAdapter 增加了 TimestampFieldList屬性,如果你的後台表裡有時間戳的話,只要設置一下這個屬性,然後設置WhereType = 4即可。
 
 
 
 
 
5.         RecordRefresh()
 
 
 
 
 
VFP8時CursorAdapter只能用 CursorRefresh() 來刷新前台,可很多時候,我們可能只需要刷新其中一條或者幾條記錄的數據,可CursorRefresh(),如果前台記錄有 1000 條,也要全部重新讀一遍,讀取完畢以後,記錄指針卻始終定位在第一條記錄,這樣既巨大的浪費了網絡資源,同時很多情況下還要花費很大的精力重新定位記錄指針。
 
 
 
 
 
現在 VFP9 增加了這個極富人性化的方法-----RecordRefresh(),能做到任意刷新此Cursor裡的任意一條或者連續幾條記錄,而且當前記錄指針保持不變,看到這裡相信做過C/S程序的朋友們是不是有一種躍躍欲試的感覺?這個可以期盼已久的功能啊。
 
 
 
 
 
RecordRefresh()裡有2個參數,RecordRefresh(nRecords,nRecordOffset)
 
1) nRecords 表示要刷新幾條記錄
 
2) nRecordOffset記錄偏移量,指是當前記錄開始加幾條記錄
 
 
 
 
 
例子1,比如當前記錄號是第5條,我要刷新第7、8兩條記錄,
 
 
 
 
 
oCa.RecordRefresh(2,-2)
 
 
 
 
 
         例子2, 只刷新當前記錄,
 
 
 
 
 
oCa.RecordRefresh(1)
 
 
 
 
 
 
 
 
6.         CursorAdapter 的 Auto-Refresh
 
 
 
 
 
VFP9提供了記錄的Auto-Refresh,其作用、功能、效果和前面介紹的RecordRefresh() 基本相似,有異曲同功之妙用。
 
 
 
 
 
讓我們來看看具體是怎麼使用的吧:
 
 
 
 
 
InsertCmdRefreshFieldList、InsertCmdRefreshKeyFieldList、InsertCmdRefreshCmd 
 
 
 
 
這三個新增的屬性是針對新增記錄時使用,一般我們只需要設置InsertCmdRefreshFieldList、InsertCmdRefreshKeyFieldList即可,從字面已經非常好理解需要設置的內容,InsertCmdRefreshKeyFieldList可以和CursorAdapter的KeyFieldList相同。
 
 
 
 
 
UpdateCmdRefreshFieldList、UpdateCmdRefreshKeyFieldList、UpdateCmdRefreshCmd 
 
 
 
 
這三個新增的屬性是針對修改記錄時使用的,一般我們也只需設置UpdateCmdRefreshFieldList和UpdateCmdRefreshKeyFieldList即可。InsertCmdRefreshKeyFieldList完全可以和CursorAdapter的KeyFieldList相同。
 
 
 
 
 
         讓我們設置好這些屬性以後看看效果吧,當TableUpdate()提交後台成功以後,記錄就自動刷新了,而且當前的記錄指針保持不變,這難道不正是我們想要的嗎?
 
 
 
 
 
         
 
 
 
 
 
         請注意,RecordRefresh()和Auto-Refresh 的區別,雖然RecordRefresh() 也能刷新多條指定的記錄,可只能是連續的幾條記錄,而Auto-Refresh卻只刷新已修改過的記錄。RecordRefresh()刷新的記錄可以自己來指定,可Auto-Refresh 刷新的記錄卻是 CursorAdapter 來控制的。
 
 
 
 
 
 
 
 
7.         DelayedMemoFetch()
 
 
 
 
 
VFP8 的CursorAdapter 裡有一個屬性:FetchMemo,當設置FetchMemo = .F. 時,本表裡的所有Memo 字段都不讀取到前台,這樣來大大提高了讀取數據時的效率,特別是當Memo字段裡內容多的時候,可是當我們需要Memo字段裡的內容時怎麼辦呢?這點是我們一直以來不管用遠程視圖、SPT還是用CursorAdapter做 C/S 程序時的痛苦矛盾之處,現在我們終於在VFP9的CursorAdapter 裡找到了完美的解決辦法。
 
 
 
 
 
先用文字來說明一下 VFP9 的CursorAdapter 的解決方法,當 CursorFill() 時,所有Memo字段的內容全部為空,以提高讀取記錄時的效率,但當光標移動到這條記錄的這個字段時,自動從後台讀取這條記錄的當前Memo字段的內容到前台,填充進CursorAdapter裡,以我實際操作下來的感覺,幾乎根本感覺不到這個讀取過程,而數據確確實實讀到了前台。
 
 
 
 
 
整個設置過程如下:
 
 
 
 
 
1)oCa.FetchMemo = .F.
 
2)oCa.FetchMemoDataSourceType = oCa.DataSourceType
 
3)oCa.FetchMemoDataSource = oCa.DataSource
 
4)oCa.FetchMemoCmdList  這個是最關鍵的,也是最麻煩的:
 
oCA.FetchMemoCmdList= "f1 <SELECT f1 FROM testCAMemoFetch WHERE f0=?EVALUATE(this.RefreshAlias +'.f0')>, f2 <SELECT f2 FROM testCAMemoFetch WHERE f0=?EVALUATE(this.RefreshAlias +'.f0')>"
 
 
 
 
 
f1,f2這裡是Memo字段名簡稱
 
f0一般是關鍵字段名
 
 
 
 
 
this.RefreshAlias可以是this.Alias
 
 
 
 
 
我翻譯一下,就應該比較好理解了,意思如下:」 Memo字段名 <select Memo字段名 From 後台表名 where 關鍵字段名=?前台的Alias名.關鍵字段內容>,…..」
 
 
 
 
 
只要設置好了以上屬性,當前台記錄移動到Memo字段時 CursorAdapter 會自動調用DelayedMemoFetch(),來讀取Memo字段內容。
 
 
 
 
 
注意:DelayedMemoFetch是個內置保護方法,在程序裡不能直接調用。
 
 
 
 
 
 
 
 
         RecordRefrsh()、Auto-Refresh和DelayedMemoFetch() 此三項功能是 SPT 無法做到的,合理使用好此三項功能,能極大的提高整個 C/S 系統的效率,降低網絡和服務器開銷。但使用RecordRefrsh()和Auto-Refresh功能時有點需要特別注意:大家讀到這裡應該可以看出,其實此三項功能,都是依靠關鍵字來定位記錄的,可當我們用自增量型字段做關鍵字時,當新增記錄時,其值是更新成功以後才能得到,所以當在前台使用RecordRefrsh()和Auto-Refresh時會因無法定位記錄而要出錯或得不到正確結果。 
 
 
 
 
 
 
 
以上7點是我認為是 VFP9 CursorAdapter 類最具人性化和效率化的方面的功能增強,下面再說說其他幾個C/S 方面的功能增強。
 
 
 
 
 
 
 
 
1.         RecordsFetched 和 FetchIsComplete 
 
 
 
 
 
 
 
以前我們讀取大批量記錄的時候,如果想要做一個人性化的進度條,是一件非常不容易的事情,一般只能採取異步方式,先讀取記錄總數,然後用一個循環,
 
 
 
 
 
lnResult = SQLEXEC(lnHandle,「SELECT * FROM …. WHERE …」,「Temp」)
 
 
 
 
 
DO WHILE lnResult = 0
 
 
 
 
 
liResult = CURSORGETPROP("FetchSize") 
 
 
 
 
 
    此處寫入進度條代碼
 
 
 
 
 
ENDDO
 
 
 
 
 
         這樣做,效果是出來了,可是也有缺陷,異步其實變成了同步。現在 VFP9 在CursorGetProp() 裡增加了兩個參數,RecordsFetch 和 FetchIsComplete,意思和使用方法如下:
 
 
 
 
 
RecordsFetched 返回讀取遠程表過程中目前所傳回來的記錄數目
 
 
 
 
 
例如:lnResult = CURSORGETPROP("RecordsFetched")
 
 
 
 
 
FetchIsComplete 表示讀取過程是否已經完成
 
 
 
 
 
如果已完成 = .T. 
 
 
 
 
 
例如:llResult = CURSORGETPROP("FetchIsComplete")
 
 
 
 
 
有了這兩個屬性,要做一個進度條就輕而易舉了,而且能實現異步功能不喪失的效果。
 
 
 
 
 
RecordsFetch 和 FetchIsComplete應該還有其他用處,留待我們一起來慢慢挖掘吧。
 
 
 
 
 
 
 
 
 
 
 
2.         SQLIDLEDISCONNECT()  這是我認為 VFP9 中極其有意義的 C/S 功能增強。 
 
 
 
 
尤其是對CursorAdapter,當然對SPT和遠程視圖也同樣適用。
 
 
 
 
 
 
 
 
SQLIDLEDISCONNECT() 從字面上理解是暫時中斷連接。剛開始,我始終未能理解其意思,可當親手做了實驗以後,就不得不驚歎其功能之強大了。
 
 
 
 
 
以前在VFP8下我曾仔細做過 CursorAdapter 的斷線重連的測試,得出結論,CursorAdapter斷線重連以後,當前數據可以向後台更新,但已經無法CursorRefresh()了,只能重新CursorFill()以後才行,但重新CursorFill()以後,前台的Cursor 等於是重新生成了,這對前台如果是用GRID來綁定 Cursor 時尤為不便。
 
 
 
 
 
         現在終於盼到了----- SQLIDLEDISCONNECT(),當CursorFill()、
 
 
 
 
 
CursorRefresh()或者RecordRefresh()以後 SQLIDLEDISCONNECT(lnHandle),此時檢查服務器,確實此句柄已經不存在了,和服務器 完全脫離了關係,為了保險起見,把網線拔了,過一段時間再插上,再對CursoraAdapter 進行數據更新,提交後台,然後在前台執行CursorRefresh()或者RecordRefresh(),這個時候檢查服務器,連接句柄自動建立成功了,而且數據確實更新成功並重新刷新。 
 
 
 
 
 
         再用SPT 做了測試,同樣得到了完美的結果。
 
 
 
 
 
         綜上所述,一旦執行了SQLIDLEDISCONNECT(),這個句柄就處於休眠狀態,此時完全和服務器脫離了關係,一旦發生前台向後台請求任何的任務,此時 VFP 將無需任何條件、無需任何人工干預的自動喚醒此連接,且句柄號不變。
 
 
 
 
 
         此項功能在用戶數較多或者網絡環境較差的情況下尤其有用,特別是在降低服務器的資源消耗方面有著非常大的作用。
 
 
 
 
 
 
 
 
 
 
 
         以上是我在探索 VFP9 的 C/S 新功能過程中總結的幾點心得,從以上幾點不難看出微軟的VFP 開發小組在 C/S 人性化使用方面所做的努力,其實在VFP9裡所有新增或者增強的功能裡處處都能體會到這點。由於時間關係,先拿出這些來和大家共享,下筆匆匆,可能其中有不少不夠深入或者認識錯誤之處,請讀此篇的狐友諒解指正,謹以此文拋磚引玉,希望更多的狐友一起加入到探索VFP9 新功能的行列中來。 _________________ 福隆昌淨水有限公司--淨水器的專家,淨水器,飲水機,濾心!!
 
 
想了解更多,您可上幸福雞湯組.找尋!!丁澐瑄.老師.
 
 
          愛作夢 | 
			 
		  | 
	 
	
		| 回頂端 | 
		 | 
	 
	
		  | 
	 
	
		xwrj
 
 
  註冊時間: 2004-10-30 文章: 2
 
  第 2 樓
  | 
		
			
				 發表於: 星期一 一月 03, 2005 6:11 pm    文章主題:  | 
				     | 
			 
			
				
  | 
			 
			
				  ok | 
			 
		  | 
	 
	
		| 回頂端 | 
		 | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
  	 
	    
  	   | 
 	
您 無法 在這個版面發表文章 您 無法 在這個版面回覆文章 您 無法 在這個版面編輯文章 您 無法 在這個版面刪除文章 您 無法 在這個版面進行投票 您 無法 在這個版面附加檔案 您 無法 在這個版面下載檔案
  | 
   
  
		 |