這是一個園長學習VFP(Visual Foxpro)的Blog歡迎同好一起來參與

星期二, 3月 16, 2010

VFP VS CodePage

VFP VS CodePage

20060920104513107

不同的字元編碼在顯示上一直是程式設計師會碰到的問題,
VFP在這方面提供了CPCONVERT()這個函數,讓使用者透過此函數轉換不同的字碼,讓不同字碼的資料可以正常的顯示,而不是顯示出亂碼

處理前的GRID顯示畫面如下:

2

本例介紹為如何在GRID中顯示不同字碼之資料
您需要知道的項目:
1.來源資料之CodePage,本例為Sybase ASE Server 11.9.2
其預設之CodePage為850
2.顯示資料之CodePage,繁體中文之作業系統預設為950
以上都了解之後,先看看直接抓取資料顯示之結果:

要如何讓資料可以在GRID正確的顯示呢?
首先我們先了解一下CPCONVERT()這個函式的用法

Converts character or memo fields or character expressions to another code page.

CPCONVERT(nCurrentCodePage, nNewCodePage, cExpression)


Parameters



<?XML:NAMESPACE PREFIX = [default] http://ddue.schemas.microsoft.com/authoring/2003/5 NS = "http://ddue.schemas.microsoft.com/authoring/2003/5" />
nCurrentCodePage
Specifies the code page that cExpression is being converted from.
nNewCodePage
Specifies the code page to which cExpression is converted.
cExpression
Specifies the character expression that's converted.


Remarks



Note that CPCONVERT( ) isn't required for normal cross-platform functioning of the product. It is used strictly to access the underlying translation facilities of Visual FoxPro.



For example, if the variable gcCharExpr contains a character that looks like on the Macintosh (in code page 10000) then CPCONVERT( ) will return a character that looks like in Microsoft Windows (code page 1252):



以上若有不懂英文的地方,請自行查閱字典,或參考其他熱心狐友所翻譯之說明文件



簡要的解釋:



轉換後的字元=CPCONVERT(來源字元之CODEPAGE,目的字元之CODEPAGE,要轉換之字元)



例 :要將CodePage 850 編碼的資料在 CodePage 950 編碼的系統中正確顯示



? cpconvert(850,950,SourceString) &&SourceString 為字元型態



然而在GRID這個VFP USER最常使用的控制項來說,似乎感覺就有點棘手了



注意:我們預設是使用SQL指令從Sybase ASE資料庫撈資料到本地端的cursor



思考方向:



1.建立另一個欄位一致的暫存檔,使用scan .... endscan ,將欄位為字元型態之資料使用cpconvert()



函式轉換為正確的字元編碼後,再將Grid的ControlSource指定為本暫存檔



(這裏不列出程式碼,因不建議如此做)



2.直接分別指定Grid中各Columns的ControlSource,若為字元型態之欄位,



直接使用cpconvert()函式轉換



※注意:這裏一直強調是『字元』型態之欄位,因為cpconvert函式只處理字元



運算式,數字或其它欄位型態若未轉換為字元型態,將會發生錯誤



使用第1個方式,資料量小的話還ok,但資料量多的話,處理速度可想而知



因此我介紹第二個做法給大家參考:



假設我們透過SQLEXEC()從Sybase ASE SERVER(CodePage850)抓下來的cursor為dtmp



SELECT dtmp

fmx=Afields(mx)


For ii=1 To fmx


    wfld=ALLTRIM(mx(ii,1))


IF mx(ii,2)='C' AND Thisform.server_type=0 && Sybase Server


       Thisform.grid1.Columns[ii].ControlSource="WCPCONVERT(850,950,"+"dtmp."+wfld+")"


    ELSE


Thisform.grid2.Columns[ii].ControlSource=wfld


EndIf


Endfor



這裏我們呼叫一個自訂函式WCPCONVERT()



為何不直接使用CPCONVERT()呢?看看函式說明



Function WCPCONVERT

Lparameters nCurrentCodePage, nNewCodePage, cExpression


IF !IsNull(cExpression)


Return Cpconvert(nCurrentCodePage, nNewCodePage, cExpression)


ELSE


RETURN ''


endif


Endfunc



看出來為什麼了嗎?



沒錯!因為就算欄位型態是字元的資料,可能會是Null,但資料Null會造成cpconvert()函式的錯誤



因此需要做處理,所以用 WCPCONVERT()的自訂函式將Null的資料返回空字串



結果如下:



20060920102846302



Ya! 可以正常顯示中文了



發表於 2006/09/20 09:13 AM

沒有留言: