<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>No Money No Honey &#187; DELPHI</title>
	<atom:link href="http://blog.infinity.idv.tw/index.php/category/delphi/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.infinity.idv.tw</link>
	<description>Just Another Beginning</description>
	<lastBuildDate>Sat, 28 Jan 2012 18:25:36 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>使用 DELPHI 抓取 WINDOWS 內的環境變數值</title>
		<link>http://blog.infinity.idv.tw/index.php/2011/10/28/%e4%bd%bf%e7%94%a8-delphi-%e6%8a%93%e5%8f%96-windows-%e5%85%a7%e7%9a%84%e7%92%b0%e5%a2%83%e8%ae%8a%e6%95%b8%e5%80%bc/</link>
		<comments>http://blog.infinity.idv.tw/index.php/2011/10/28/%e4%bd%bf%e7%94%a8-delphi-%e6%8a%93%e5%8f%96-windows-%e5%85%a7%e7%9a%84%e7%92%b0%e5%a2%83%e8%ae%8a%e6%95%b8%e5%80%bc/#comments</comments>
		<pubDate>Fri, 28 Oct 2011 08:56:52 +0000</pubDate>
		<dc:creator>Roger Lin</dc:creator>
				<category><![CDATA[DELPHI]]></category>
		<category><![CDATA[Windows 環境變數 DELPHI]]></category>

		<guid isPermaLink="false">http://blog.infinity.idv.tw/index.php/2011/10/28/%e4%bd%bf%e7%94%a8-delphi-%e6%8a%93%e5%8f%96-windows-%e5%85%a7%e7%9a%84%e7%92%b0%e5%a2%83%e8%ae%8a%e6%95%b8%e5%80%bc/</guid>
		<description><![CDATA[<p>使用 DELPHI 抓取 WINDOWS 內的環境變數值</p>
<p>GetEnvironmentVariable(&#8217;TEMP&#8217;)</p>
<p>其中TEMP為WINDOWS的環境變數</p>
<p>Windows 在 command 模式下輸入 set 也可秀出現有 Windows 的環境變數，把變數值帶入這個 Function 內即可取得，回傳值是文字型態。</p>
<p>Windows常用變數:   參考來源：http://jck11.pixnet.net/blog/post/13459124-windows%E7%B3%BB%E7%B5%B1%E5%85%A7%E5%BB%BA%E7%9A%84%E5%B8%B8%E8%A6%8B%E7%92%B0%E5%A2%83%E8%AE%8A%E6%95%B8</p>
<p>%ALLUSERSPROFILE%：All Users設定檔的資料夾位置。    %APPDATA%：目前使用者的Application Data資料夾位置。    %CD%：目前的工作資料夾。    %CLIENTNAME%：目前使用者的NETBIOS電腦名稱。    %CMDCMDLINE%：處理目前命令提示字元視窗命令的cmd.exe的完整路徑。    %CMDEXTVERSION%：目前Command Processor Extensions的版本。    %COMPUTERNAME%：電腦名稱。    %COMSPEC%:：命令提示字元視窗的解譯程式路徑，通常與%CMDCMDLINE%相同。    %CommonProgramFiles%：Common Files資料夾的路徑。  [...]]]></description>
			<content:encoded><![CDATA[<p>使用 DELPHI 抓取 WINDOWS 內的環境變數值</p>
<p>GetEnvironmentVariable(&#8217;TEMP&#8217;)</p>
<p>其中TEMP為WINDOWS的環境變數</p>
<p>Windows 在 command 模式下輸入 set 也可秀出現有 Windows 的環境變數，把變數值帶入這個 Function 內即可取得，回傳值是文字型態。</p>
<p>Windows常用變數:   <br />參考來源：<a title="http://jck11.pixnet.net/blog/post/13459124-windows%E7%B3%BB%E7%B5%B1%E5%85%A7%E5%BB%BA%E7%9A%84%E5%B8%B8%E8%A6%8B%E7%92%B0%E5%A2%83%E8%AE%8A%E6%95%B8" href="http://jck11.pixnet.net/blog/post/13459124-windows%E7%B3%BB%E7%B5%B1%E5%85%A7%E5%BB%BA%E7%9A%84%E5%B8%B8%E8%A6%8B%E7%92%B0%E5%A2%83%E8%AE%8A%E6%95%B8">http://jck11.pixnet.net/blog/post/13459124-windows%E7%B3%BB%E7%B5%B1%E5%85%A7%E5%BB%BA%E7%9A%84%E5%B8%B8%E8%A6%8B%E7%92%B0%E5%A2%83%E8%AE%8A%E6%95%B8</a></p>
<p><em>%ALLUSERSPROFILE%</em>：All Users設定檔的資料夾位置。    <br /><em>%APPDATA%</em>：目前使用者的Application Data資料夾位置。    <br /><em>%CD%</em>：目前的工作資料夾。    <br /><em>%CLIENTNAME%</em>：目前使用者的NETBIOS電腦名稱。    <br /><em>%CMDCMDLINE%</em>：處理目前命令提示字元視窗命令的cmd.exe的完整路徑。    <br /><em>%CMDEXTVERSION%</em>：目前Command Processor Extensions的版本。    <br /><em>%COMPUTERNAME%</em>：電腦名稱。    <br /><em>%COMSPEC%:</em>：命令提示字元視窗的解譯程式路徑，通常與%CMDCMDLINE%相同。    <br /><em>%CommonProgramFiles%</em>：Common Files資料夾的路徑。    <br /><em>%DATE%</em>：目前的系統日期。    <br /><em>%ERRORLEVEL%</em>：最近執行過的命令的錯誤碼；非零的值表示發生過的錯誤碼。    <br /><em>%HOMESHARE%</em>：目前使用者共用資料夾的網路路徑。    <br /><em>%HomeDrive%</em>：使用者目錄的磁碟機。    <br /><em>%HomePath%</em>：使用者家目錄。    <br /><em>%LOGONSEVER%</em>：目前使用者所登入的網路控制器名稱。    <br /><em>%NUMBER_OF_PROCESSORS%</em>：電腦的處理器數量。    <br /><em>%OS%</em>：作業系統名稱，其值固定為Windows_NT    <br /><em>%PATHEXT%</em>：作業系統是為執行檔的副檔名。    <br /><em>%PROCESSOR_ARCHITECTURE%</em>：處理器的架構名稱，例如x86。    <br /><em>%PROCESSOR_IDENTFIER%</em>：說明處理器的文字（不一定會有此環境變數）。    <br /><em>%PROCESSOR_LEVEL%</em>：處理器的model number。    <br /><em>%PROCESSOR_REVISION%</em>：處理器的revision number。    <br /><em>%PROMPT%</em>：目前解譯程式的命令提示字串。    <br /><em>%Path%</em>：執行檔的搜尋路徑。    <br /><em>%ProgramFiles%</em>：應用程式目錄，預設是C:\Program Files。    <br /><em>%RANDOM%</em>：顯示0到32767之間的十進位整數亂數。    <br /><em>%SESSIONNAME%</em>：連上終端伺服器的session names。    <br /><em>%SystemDirectory%</em>：系統目錄，預設是C:\WINNT\System32或C:\WINDOWS\System32。    <br /><em>%SystemDrive%</em>：系統磁碟機，預設是C:。    <br /><em>%SystemRoot%</em>：系統根目錄，預設是C:\WINNT或C:\WINDOWS。    <br /><em>%TIME%</em>：目前的系統時間。    <br /><em>%Temp%、%Tmp%</em>：暫存檔目錄。    <br /><em>%USERPROFILE%</em>：目前使用者的設定檔路徑。    <br /><em>%UserDomain%</em>：包含使用者帳號的網域名稱，或者電腦名稱。    <br /><em>%UserName%</em>：使用者帳號名稱。    <br /><em>%WinDir%</em>：Windows目錄，預設是C:\WINNT或C:\WINDOWS。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.infinity.idv.tw/index.php/2011/10/28/%e4%bd%bf%e7%94%a8-delphi-%e6%8a%93%e5%8f%96-windows-%e5%85%a7%e7%9a%84%e7%92%b0%e5%a2%83%e8%ae%8a%e6%95%b8%e5%80%bc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DELPHI 7 下 TEXT檔 ANSI與UTF8互轉方式-Write &amp; Read UTF-8 Text File</title>
		<link>http://blog.infinity.idv.tw/index.php/2011/09/09/delphi-7-%e4%b8%8b-text%e6%aa%94-ansi%e8%88%87utf8%e4%ba%92%e8%bd%89%e6%96%b9%e5%bc%8f-write-read-utf-8-text-file/</link>
		<comments>http://blog.infinity.idv.tw/index.php/2011/09/09/delphi-7-%e4%b8%8b-text%e6%aa%94-ansi%e8%88%87utf8%e4%ba%92%e8%bd%89%e6%96%b9%e5%bc%8f-write-read-utf-8-text-file/#comments</comments>
		<pubDate>Fri, 09 Sep 2011 08:43:55 +0000</pubDate>
		<dc:creator>Roger Lin</dc:creator>
				<category><![CDATA[DELPHI]]></category>
		<category><![CDATA[UTF8 ANSI 轉換]]></category>

		<guid isPermaLink="false">http://blog.infinity.idv.tw/index.php/2011/09/09/delphi-7-%e4%b8%8b-text%e6%aa%94-ansi%e8%88%87utf8%e4%ba%92%e8%bd%89%e6%96%b9%e5%bc%8f-write-read-utf-8-text-file/</guid>
		<description><![CDATA[<p>DELPHI 7 下 TEXT檔 ANSI與UTF8互轉方式</p>
<p>出處:http://tw.myblog.yahoo.com/cschen99ws/article?mid=16596&#38;prev=18175&#38;l=f&#38;fid=52</p>
<p>procedure TForm1.Button1Click(Sender: TObject);   var&#160; S:string;&#160;&#160; begin&#160;&#160; &#160; with&#160;&#160; TMemoryStream.Create&#160;&#160; do&#160;&#160; try&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; S&#160;&#160; :=&#160;&#160; #$EF#$BB#$BF;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Write(S[1],&#160;&#160; Length(S));&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; S&#160;&#160; :=&#160;&#160; AnsiToUtf8(Memo1.Text);&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Write(S[1],&#160;&#160; Length(S));&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Position&#160;&#160; :=&#160;&#160; 0;    &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; SaveToFile(&#8217;c:\temp.txt&#8217;);&#160;&#160; &#160;&#160;&#160; finally&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Free;&#160;&#160; &#160;&#160;&#160;&#160;&#160; end;&#160;&#160; end;&#160;&#160;&#160;&#160;&#160; procedure TForm1.Button2Click(Sender: TObject);    var&#160;&#160; &#160;&#160;&#160;&#160;&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>DELPHI 7 下 TEXT檔 ANSI與UTF8互轉方式</p>
<p>出處:<a title="http://tw.myblog.yahoo.com/cschen99ws/article?mid=16596&amp;prev=18175&amp;l=f&amp;fid=52" href="http://tw.myblog.yahoo.com/cschen99ws/article?mid=16596&amp;prev=18175&amp;l=f&amp;fid=52">http://tw.myblog.yahoo.com/cschen99ws/article?mid=16596&amp;prev=18175&amp;l=f&amp;fid=52</a></p>
<p>procedure TForm1.Button1Click(Sender: TObject);   <br />var&#160; S:string;&#160;&#160; <br />begin&#160;&#160; <br />&#160; with&#160;&#160; TMemoryStream.Create&#160;&#160; do&#160;&#160; try&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; S&#160;&#160; :=&#160;&#160; #$EF#$BB#$BF;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Write(S[1],&#160;&#160; Length(S));&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; S&#160;&#160; :=&#160;&#160; AnsiToUtf8(Memo1.Text);&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Write(S[1],&#160;&#160; Length(S));&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Position&#160;&#160; :=&#160;&#160; 0;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; SaveToFile(&#8217;c:\temp.txt&#8217;);&#160;&#160; <br />&#160;&#160;&#160; finally&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Free;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; end;&#160;&#160; <br />end;&#160;&#160;&#160;&#160;&#160; <br />procedure TForm1.Button2Click(Sender: TObject);    <br />var&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; S:&#160;&#160; string;&#160;&#160; <br />&#160; begin&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; //取&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; if&#160;&#160; not&#160;&#160; FileExists(&#8217;c:\temp\temp.txt&#8217;)&#160;&#160; then&#160;&#160; Exit;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; with&#160;&#160; TMemoryStream.Create&#160;&#160; do&#160;&#160; try&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; LoadFromFile(&#8217;c:\temp\temp.txt&#8217;);&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; SetLength(S,&#160;&#160; Size);&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Read(S[1],&#160;&#160; Length(S));&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if&#160;&#160; Copy(S,&#160;&#160; 1,&#160;&#160; 3)&#160;&#160; &lt;&gt;&#160;&#160; #$EF#$BB#$BF&#160;&#160; then&#160;&#160; Exit;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Memo1.Text&#160;&#160; :=&#160;&#160; Utf8ToAnsi(Copy(S,&#160;&#160; 4,&#160;&#160; MaxInt));&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; finally&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Free;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160; end;&#160;&#160; <br />&#160; end; </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.infinity.idv.tw/index.php/2011/09/09/delphi-7-%e4%b8%8b-text%e6%aa%94-ansi%e8%88%87utf8%e4%ba%92%e8%bd%89%e6%96%b9%e5%bc%8f-write-read-utf-8-text-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Delphi 2010自帶TIdFTP的中文問題</title>
		<link>http://blog.infinity.idv.tw/index.php/2011/06/27/delphi-2010%e8%87%aa%e5%b8%b6tidftp%e7%9a%84%e4%b8%ad%e6%96%87%e5%95%8f%e9%a1%8c/</link>
		<comments>http://blog.infinity.idv.tw/index.php/2011/06/27/delphi-2010%e8%87%aa%e5%b8%b6tidftp%e7%9a%84%e4%b8%ad%e6%96%87%e5%95%8f%e9%a1%8c/#comments</comments>
		<pubDate>Mon, 27 Jun 2011 07:56:19 +0000</pubDate>
		<dc:creator>Roger Lin</dc:creator>
				<category><![CDATA[DELPHI]]></category>
		<category><![CDATA[idftp utf8 中文]]></category>

		<guid isPermaLink="false">http://blog.infinity.idv.tw/index.php/2011/06/27/delphi-2010%e8%87%aa%e5%b8%b6tidftp%e7%9a%84%e4%b8%ad%e6%96%87%e5%95%8f%e9%a1%8c/</guid>
		<description><![CDATA[<p>DELPHI7 + INDY   </p>
<p>抓檔前先轉UTF8Encode    filename:= UTF8Encode(filename);&#160;&#160; FIdFtp.Get(filename,tStream,true); </p>
<p>未測試………………</p>
<p>==================================================================================</p>
<p>出處:http://hi.baidu.com/syncgrey/blog/item/8c894e823c7f78aa6c8119f1.html</p>
<p>1、Delphi 2010自帶TIdFTP的中文問題    &#160; 最近使用TIdTFP，使用ChangeDir切換到中文目錄時報錯，錯誤提示中的中文目錄成了一串“?”號，閱讀源代碼得知，該控件的默認IOHandle的默認Encoding是ASCII（代碼頁為20127），ITdFTP在Connect方法中，連接成功後，有這麼一句：</p>
<p>&#160;&#160;&#160; // RLebeau: must not send/receive UTF-8 before negotiating for it&#8230;    &#160;&#160;&#160; IOHandler.DefStringEncoding := Indy8BitEncoding;</p>
<p>再轉到Indy8BitEncoding 中看看：</p>
<p>function Indy8BitEncoding(const AOwnedByIndy: Boolean = True): TIdTextEncoding;    var     &#160; LEncoding: TIdTextEncoding;  [...]]]></description>
			<content:encoded><![CDATA[<p>DELPHI7 + INDY   </p>
<p>抓檔前先轉UTF8Encode    <br />filename:= UTF8Encode(filename);&#160;&#160; <br />FIdFtp.Get(filename,tStream,true); </p>
<p>未測試………………</p>
<p>==================================================================================</p>
<p>出處:<a href="http://hi.baidu.com/syncgrey/blog/item/8c894e823c7f78aa6c8119f1.html">http://hi.baidu.com/syncgrey/blog/item/8c894e823c7f78aa6c8119f1.html</a></p>
<p>1、Delphi 2010自帶TIdFTP的中文問題    <br />&#160; 最近使用TIdTFP，使用ChangeDir切換到中文目錄時報錯，錯誤提示中的中文目錄成了一串“?”號，閱讀源代碼得知，該控件的默認IOHandle的默認Encoding是ASCII（代碼頁為20127），ITdFTP在Connect方法中，連接成功後，有這麼一句：</p>
<p>&#160;&#160;&#160; // RLebeau: must not send/receive UTF-8 before negotiating for it&#8230;    <br />&#160;&#160;&#160; IOHandler.DefStringEncoding := Indy8BitEncoding;</p>
<p>再轉到Indy8BitEncoding 中看看：</p>
<p>function Indy8BitEncoding(const AOwnedByIndy: Boolean = True): TIdTextEncoding;    <br />var     <br />&#160; LEncoding: TIdTextEncoding;     <br />begin     <br />&#160; if not AOwnedByIndy then begin     <br />&#160;&#160;&#160; LEncoding := TIdTextEncoding.GetEncoding(28591);     <br />&#160; end else     <br />&#160; begin     <br />&#160;&#160;&#160; if GId8BitEncoding = nil then begin     <br />&#160;&#160;&#160;&#160;&#160; LEncoding := TIdTextEncoding.GetEncoding( 28591);     <br />&#160;&#160;&#160;&#160;&#160; if InterlockedCompareExchangePtr(Pointer(GId8BitEncoding), LEncoding, nil) &lt;&gt; nil then begin     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; LEncoding.Free;     <br />&#160;&#160;&#160;&#160;&#160; end;     <br />&#160;&#160;&#160; end;     <br />&#160;&#160;&#160; LEncoding := GId8BitEncoding;     <br />&#160; end;     <br />&#160; Result := LEncoding;     <br />end;</p>
<p>可以看到，這裡會創建（如果還沒創建的話）返回一個代碼頁為28591 的TEncoding，那這個28591 到底是啥子呢？搜索結果如下：</p>
<p>&#160; 28591 iso-8859-1 Western European (ISO)</p>
<p>原來是西歐的編碼，不支持中文就不足為奇了，那該如何處理呢？只要在調用TIdFTP.Connect 後，增加一句</p>
<p>TIdFTP.IOHandler.DefStringEncoding := TEncoding.Default</p>
<p>就正常了，注意一定要放在Connect 之後，否則會被Connect 方法重置為28591 代碼頁。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.infinity.idv.tw/index.php/2011/06/27/delphi-2010%e8%87%aa%e5%b8%b6tidftp%e7%9a%84%e4%b8%ad%e6%96%87%e5%95%8f%e9%a1%8c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[DELPHI] cxGrid的使用方法</title>
		<link>http://blog.infinity.idv.tw/index.php/2011/06/02/delphi-cxgrid%e7%9a%84%e4%bd%bf%e7%94%a8%e6%96%b9%e6%b3%95/</link>
		<comments>http://blog.infinity.idv.tw/index.php/2011/06/02/delphi-cxgrid%e7%9a%84%e4%bd%bf%e7%94%a8%e6%96%b9%e6%b3%95/#comments</comments>
		<pubDate>Thu, 02 Jun 2011 08:16:11 +0000</pubDate>
		<dc:creator>Roger Lin</dc:creator>
				<category><![CDATA[DELPHI]]></category>
		<category><![CDATA[cxGrid]]></category>
		<category><![CDATA[DELPHI cxGrid]]></category>

		<guid isPermaLink="false">http://blog.infinity.idv.tw/index.php/2011/06/02/delphi-cxgrid%e7%9a%84%e4%bd%bf%e7%94%a8%e6%96%b9%e6%b3%95/</guid>
		<description><![CDATA[<p>朋友貼給我的，只知道是大陸網站上分享的資料，可在cxGrid內使用CheckBox喔!!!只是用了之後以前可使用 Shift 選區段的功能似乎不能用了。</p>
<p>======================================================================</p>
<p>cxGrid的使用方法</p>
<p>cxGrid功能強大，適合做企業級的複雜查詢。非常方便。</p>
<p>但是對其用法介紹的並不多，在此總結他人的使用經驗和自己的一點小經驗，供大家參考。</p>
（１）動態設置顯示格式
<p>procedure SetDisplayFormat(ACtrlData: TClientDataSet;</p>
<p>&#160; TbView: TcxGridDBTableView);</p>
<p>var</p>
<p>&#160; i: integer;</p>
<p>begin</p>
<p>&#160; if ACtrlData.RecordCount &#60;= 0 then Exit;</p>
<p>&#160; try</p>
<p>&#160;&#160;&#160; TbView.ClearItems;</p>
<p>&#160;&#160;&#160; ACtrlData.First;</p>
<p>&#160;&#160;&#160; for i := 0 to ACtrlData.RecordCount &#8211; 1 do</p>
<p>&#160;&#160;&#160; begin</p>
<p>&#160;&#160;&#160;&#160;&#160; if ACtrlData.FieldByName(&#8217;SQBF_DisplayInGrid&#8217;).AsString = &#8216;1&#8242; then //在表格中顯示</p>
<p>&#160;&#160;&#160;&#160;&#160; with TbView.CreateColumn do</p>
<p>&#160;&#160;&#160;&#160;&#160; begin</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataBinding.FieldName := ACtrlData.FieldByName(&#8217;SQBF_FieldName&#8217;).AsString;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Caption := ACtrlData.FieldByName(&#8217;SQBF_Caption&#8217;).AsString; //欄位中文標題</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Hint := ACtrlData.FieldByName(&#8217;SQBF_Hint&#8217;).AsString;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Width := ACtrlData.FieldByName(&#8217;SQBF_Width&#8217;).AsInteger;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; HeaderAlignmentHorz := taCenter;</p>
<p>&#160;&#160;&#160;&#160;&#160; end;</p>
<p>&#160;&#160;&#160;&#160;&#160; [...]]]></description>
			<content:encoded><![CDATA[<p><b>朋友貼給我的，只知道是大陸網站上分享的資料，可在cxGrid內使用CheckBox喔!!!只是用了之後以前可使用 Shift 選區段的功能似乎不能用了。</b></p>
<p><strong>======================================================================</strong></p>
<p><b>cxGrid</b><b>的使用方法</b><b></b></p>
<p>cxGrid功能強大，適合做企業級的複雜查詢。非常方便。</p>
<p>但是對其用法介紹的並不多，在此總結他人的使用經驗和自己的一點小經驗，供大家參考。</p>
<h5>（１）動態設置顯示格式</h5>
<blockquote><p>procedure SetDisplayFormat(ACtrlData: TClientDataSet;</p>
<p>&#160; TbView: TcxGridDBTableView);</p>
<p>var</p>
<p>&#160; i: integer;</p>
<p>begin</p>
<p>&#160; if ACtrlData.RecordCount &lt;= 0 then Exit;</p>
<p>&#160; try</p>
<p>&#160;&#160;&#160; TbView.ClearItems;</p>
<p>&#160;&#160;&#160; ACtrlData.First;</p>
<p>&#160;&#160;&#160; for i := 0 to ACtrlData.RecordCount &#8211; 1 do</p>
<p>&#160;&#160;&#160; begin</p>
<p>&#160;&#160;&#160;&#160;&#160; if ACtrlData.FieldByName(&#8217;SQBF_DisplayInGrid&#8217;).AsString = &#8216;1&#8242; then //在表格中顯示</p>
<p>&#160;&#160;&#160;&#160;&#160; with TbView.CreateColumn do</p>
<p>&#160;&#160;&#160;&#160;&#160; begin</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataBinding.FieldName := ACtrlData.FieldByName(&#8217;SQBF_FieldName&#8217;).AsString;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Caption := ACtrlData.FieldByName(&#8217;SQBF_Caption&#8217;).AsString; //欄位中文標題</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Hint := ACtrlData.FieldByName(&#8217;SQBF_Hint&#8217;).AsString;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Width := ACtrlData.FieldByName(&#8217;SQBF_Width&#8217;).AsInteger;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; HeaderAlignmentHorz := taCenter;</p>
<p>&#160;&#160;&#160;&#160;&#160; end;</p>
<p>&#160;&#160;&#160;&#160;&#160; ACtrlData.Next;</p>
<p>&#160;&#160;&#160; end;</p>
<p>&#160; except</p>
<p>&#160;&#160;&#160; on E: Exception do</p>
<p>&#160;&#160;&#160;&#160;&#160; SaveLog(&#8217;設置顯示格式時出錯：&#8217; + E.Message);</p>
<p>&#160; end;</p>
<p>end;</p>
</blockquote>
<h5>（２）顯示行號</h5>
<blockquote><p>procedure TFmQueryBase.cxDBViewMasterCustomDrawIndicatorCell(</p>
<p>&#160; Sender: TcxGridTableView; ACanvas: TcxCanvas;</p>
<p>&#160; AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean);</p>
<p>var</p>
<p>&#160; FValue: string;</p>
<p>&#160; FBounds: TRect;</p>
<p>begin</p>
<p>&#160; FBounds := AViewInfo.Bounds;</p>
<p>&#160; if (AViewInfo is TcxGridIndicatorRowItemViewInfo) then</p>
<p>&#160; begin</p>
<p>&#160;&#160;&#160; ACanvas.FillRect(FBounds);</p>
<p>&#160;&#160;&#160; ACanvas.DrawComplexFrame(FBounds, clBlack, clBlack, [bBottom, bLeft, bRight], 1);</p>
<p>&#160;&#160;&#160; FValue := IntToStr(TcxGridIndicatorRowItemViewInfo(AViewInfo).GridRecord.Index+1);</p>
<p>&#160;&#160;&#160; InflateRect(FBounds, -3, -2); //Platform specific. May not work on Linux.</p>
<p>&#160;&#160;&#160; ACanvas.Font.Color := clBlack;</p>
<p>&#160;&#160;&#160; ACanvas.Brush.Style := bsClear;</p>
<p>&#160;&#160;&#160; ACanvas.DrawText(FValue, FBounds, cxAlignCenter or cxAlignTop);</p>
<p>&#160;&#160;&#160; ADone := True;</p>
<p>&#160; end;</p>
<p>end;</p>
</blockquote>
<h5>（３）設置顯示格式，我的專案要求先動態添加欄位，這時不知道欄位類型，所以設置DisplayFormat不方便，我還沒有找到好方法。</h5>
<p>所以採用打開資料集後再設置：</p>
<blockquote><p>procedure TFmQueryBase.cdsMasterAfterOpen(DataSet: TDataSet);</p>
<p>var</p>
<p>&#160; i: Integer;</p>
<p>begin</p>
<p>&#160; for i := 0 to cxDBViewMaster.DataController.DataSet.FieldCount -1 do</p>
<p>&#160; begin</p>
<p>&#160;&#160;&#160; if cxDBViewMaster.DataController.DataSet.Fields[i] is TNumericField then</p>
<p>&#160;&#160;&#160; begin</p>
<p>&#160;&#160;&#160;&#160;&#160; if Pos(&#8217;AMOUNT&#8217;, UpperCase(cxDBViewMaster.DataController.DataSet.Fields[i].FieldName)) &gt; 0 then</p>
<p>&#160;&#160;&#160;&#160;&#160; begin</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; TNumericField(cxDBViewMaster.DataController.DataSet.Fields[i]).DisplayFormat := &#8216;#,##0.000&#8242;;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Continue;</p>
<p>&#160;&#160;&#160;&#160;&#160; end;</p>
<p>&#160;&#160;&#160;&#160;&#160; if Pos(&#8217;QUANTITY&#8217;, UpperCase(cxDBViewMaster.DataController.DataSet.Fields[i].FieldName)) &gt; 0 then</p>
<p>&#160;&#160;&#160;&#160;&#160; begin</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; TNumericField(cxDBViewMaster.DataController.DataSet.Fields[i]).DisplayFormat := &#8216;#,##0.000&#8242;;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Continue;</p>
<p>&#160;&#160;&#160;&#160;&#160; end;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160; if Pos(&#8217;MONEY&#8217;, UpperCase(cxDBViewMaster.DataController.DataSet.Fields[i].FieldName)) &gt; 0 then</p>
<p>&#160;&#160;&#160;&#160;&#160; begin</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; TNumericField(cxDBViewMaster.DataController.DataSet.Fields[i]).DisplayFormat := &#8216;#,##0.00&#8242;;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Continue;</p>
<p>&#160;&#160;&#160;&#160;&#160; end;</p>
<p>&#160;&#160; end;</p>
<p>&#160; end;</p>
<p>end;</p>
</blockquote>
<p>最近在學習使用cxGrid,安裝的版本是ExpressQuantumGrid&#160;&#160; Suite&#160;&#160; v5.10&#160; </p>
<p>我發現這個控制項功能雖然強大,但是非常難用。</p>
<p>現在我手頭就有幾個問題還沒解決：</p>
<p>&#160; 1）主從模式下導出Excel中文會產生亂碼，而且從表內容沒有導出。</p>
<p>我不知道是不是因為我的欄位名包括單引號的原因。</p>
<p>導出代碼：ExportGrid4ToExcel(FileName,&#160;&#160; cxGrid);&#160; </p>
<p>&#160; 2）主從模式下通過按鈕對從表添加/刪除行，代碼怎么寫。</p>
<h5>附：單表添加/刪除行的代碼</h5>
<blockquote><p>&#160; procedure&#160;&#160; TFormAccount.cxButtonNewClick(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Self.tvAccount.DataController.Append;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Self.tvAccount.Columns[0].Focused&#160;&#160; :=&#160;&#160; True;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; cxGrid.SetFocus;&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; procedure&#160;&#160; TFormAccount.cxButtonDeleteClick(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; Self.tvAccount.DataController.RowCount&#160;&#160; =&#160;&#160; 0&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Exit;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; Application.MessageBox(&#8217;確認刪除當前記錄?&#8217;,&#160;&#160; &#8216;確認刪除&#8217;,&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; MB_YesNo&#160;&#160; +&#160;&#160; MB_IconQuestion)&#160;&#160; =&#160;&#160; IDNO&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Exit;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Self.tvAccount.DataController.DeleteFocused;&#160; </p>
<p>&#160; end;&#160; </p>
</blockquote>
<p>&#160; 3）動態創建主從結構出錯（Compiler沒錯，運行時出現系統錯誤0000000018），</p>
<p>我使用了二個ADOStoreProcedure作主從表</p>
<p>代碼如下：</p>
<blockquote><p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Level:&#160;&#160; TcxGridLevel;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView:&#160;&#160; TcxGridDBTableView;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Level&#160;&#160; :=&#160;&#160; cxGrid1.Levels[0].Add;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView&#160;&#160; :=&#160;&#160; TcxGridDBTableView(cxGrid1.CreateView(TcxGridDBTableView));&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView.DataController.DataSource&#160;&#160; :=&#160;&#160; Self.dsDetail;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView.DataController.KeyFieldNames&#160;&#160; :=&#160;&#160; &#8216;PurchOrderID;POLineNbr;PromiseDate;ReceiverDate&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView.DataController.MasterKeyFieldNames&#160;&#160; :=&#160;&#160; &#8216;VendorID&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView.DataController.DetailKeyFieldNames&#160;&#160; :=&#160;&#160; &#8216;VendorID&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView.DataController.DataModeController.SmartRefresh&#160;&#160; :=&#160;&#160; True;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView.OptionsCustomize.ColumnHiding&#160;&#160; :=&#160;&#160; True;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView.OptionsCustomize.ColumnsQuickCustomization&#160;&#160; :=&#160;&#160; True;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView.OptionsData.Deleting&#160;&#160; :=&#160;&#160; False;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView.OptionsData.Inserting&#160;&#160; :=&#160;&#160; False;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView.OptionsView.Indicator&#160;&#160; :=&#160;&#160; True;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Level.GridView&#160;&#160; :=&#160;&#160; GridView;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView&#160;&#160; :=&#160;&#160; TcxGridDBTableView(cxGrid1.Levels[0].GridView);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView.DataController.KeyFieldNames&#160;&#160; :=&#160;&#160; &#8216;VendorID&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView.OptionsView.GroupByBox&#160;&#160; :=&#160;&#160; False;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //顯示主表內容</p>
<p>&#160;&#160;&#160;&#160;&#160; tvResult.BeginUpdate;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; tvResult.ClearItems;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; tvResult.DataController.CreateAllItems;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; tvResult.EndUpdate;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //顯示明細表內容</p>
<p>&#160;&#160;&#160;&#160;&#160; GridView&#160;&#160; :=&#160;&#160; TcxGridDBTableView(cxGrid1.Levels[0].Items[0].GridView);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView.BeginUpdate;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView.ClearItems;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView.DataController.CreateAllItems;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView.DataController.Refresh;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; GridView.EndUpdate;&#160; </p>
<p>&#160; end;&#160; </p>
</blockquote>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>小技巧:用代碼展開/收縮主從結構</p>
<p>&#160; Self.tvDepartment.ViewData.Expand(True);&#160; </p>
<p>&#160; Self.tvDepartment.ViewData.Collaspe(True);&#160; </p>
<p>注:tvDepartment為主表對應的TableView</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>你說的這幾個問題我也遇到過。</p>
<p>第一個問題是編碼的問題，修改了其中關於編碼的函數，OK.&#160; </p>
<p>第二個問題在cxGrid的社區可以找到解答，但從表必須滿足某種條件，例如關鍵字排序。</p>
<p>第三個問題的解決辦法，你可以嘗試在動態創建的代碼前後加上：</p>
<p>&#160; grid.beginupdate;&#160; </p>
<p>&#160; &#8230;&#160; </p>
<p>&#160; grid.endupdate&#160; </p>
<p>來解決。</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>沒用過</p>
<p>不要經常使用三方控制項</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>to&#160;&#160; tttk(網路芝麻)：</p>
<p>第一個問題：如何修改啊，貼出代碼</p>
<p>第二個問題：沒搜到啊</p>
<p>第三個問題：試一下再說</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>不要經常使用三方控制項</p>
<p>&#160; ======================&#160; </p>
<p>我感覺不用cxGrid的話，沒必要用Delphi了，呵呵</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>樓上這話是不是有點問題?DELPHI能做得事情很多很多,難道非要用CXGRID?CXGRID不是用DELPHI做出來得?</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>沒用過&#8230;..</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>回復人：&#160;&#160; zxkid(沒有人會像我這樣&#8230;)&#160;&#160; (&#160;&#160; )&#160;&#160; 信譽：101&#160;&#160;&#160;&#160; 2006-01-06&#160;&#160; 16:58:00&#160;&#160;&#160;&#160; 得分:&#160;&#160; 0&#160;&#160;&#160;&#160;&#160; </p>
<p>不要經常使用三方控制項</p>
<p>&#160; ======================&#160; </p>
<p>我感覺不用cxGrid的話，沒必要用Delphi了，呵呵</p>
<p>&#160; **********&#160; </p>
<p>樓主乃天人也！！</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>呵呵</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>cxGrid比較不錯,我也使用過導出到Excel,沒有遇到你說的亂碼</p>
<p>主從表也沒有問題的，其實跟單表操作還不是一回事</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>up</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>沒用過cxGrid，以後考慮</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>樓主乃天人也！！</p>
<p>&#160; =============================&#160; </p>
<p>&#160; Delphi下有cxGrid,&#160;&#160; .NET下有XtraGrid,&#160;&#160; 它們都是同一公司出的。</p>
<p>遲早都會轉到.NET，所以。。。</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>路過</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>用過，挺好，只會使用最簡單的。</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>發一個郵件給我，我把解決亂碼後的源代碼發一分給你，放到你的專案檔夾下即可。</p>
<p>&#160; tttk2000@hotmail.com</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>第二個問題：https://www.devexpress.com/Support/Center/default.aspx?view=ViewIssue&amp;issueid=B2691</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>謝謝tttk(網路芝麻)&#160;&#160;&#160; </p>
<p>第二個問題：我現在直接讓用戶用導航條的刪除/添加按鈕了。根據你給的網址上的內容我知道大概該怎么寫了，有空再試試。</p>
<p>第一個問題：不光是亂碼問題，還有從表內容沒導出的問題。</p>
<p>只有一個表的話是不會出現亂碼的。</p>
<p>第三個問題：還沒來得及試。</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>第一個問題：看了一下幫助，原來cxGrid不支持主從表的導出，只能導出主表（頂層表）的內容。暈</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>貼一些小技巧,希望與各位使用cxGrid的朋友共同交流</p>
<p>各位有什么好個技巧也可以貼出來:&#160; </p>
<h5>技巧二：在內置右鍵功能表的後面增加功能表項</h5>
<p>首先應在Form上加一個cxGridPopupMenu控制項 以啟用右鍵功能表</p>
<blockquote><p>&#160; UseBuildInPopupMenus設為True&#160; </p>
<p>&#160; procedure&#160;&#160; TFormItemList.FormCreate(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AMenu:&#160;&#160; TComponent;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; FMenuItem,&#160;&#160; FSubMenuItem:&#160;&#160; TMenuItem;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AMenu&#160;&#160; :=&#160;&#160; nil;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; cxGridPopupMenu.BuiltInPopupMenus.Count&#160;&#160; =&#160;&#160; 0&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Exit;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AMenu&#160;&#160; :=&#160;&#160; cxGridPopupMenu.BuiltInPopupMenus[0].PopupMenu; //第一個內置右鍵功能表(表頭功能表)&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; Assigned(AMenu)&#160;&#160; and&#160;&#160; AMenu.InheritsFrom(TPopupMenu)&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TPopupMenu(AMenu).AutoHotkeys&#160;&#160; :=&#160;&#160; maManual;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //手動熱鍵</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem&#160;&#160; :=&#160;&#160; TMenuItem.Create(Self);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Caption&#160;&#160; :=&#160;&#160; &#8216;-&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Name&#160;&#160; :=&#160;&#160; &#8216;miLineForGroup&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TPopupMenu(AMenu).Items.Add(FMenuItem);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //展開所有組</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem&#160;&#160; :=&#160;&#160; TMenuItem.Create(Self);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Name&#160;&#160; :=&#160;&#160; &#8216;miExpandAllGroup&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Caption&#160;&#160; :=&#160;&#160; &#8216;展開所有組(&amp;X)&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.OnClick&#160;&#160; :=&#160;&#160; miExpandAllGroupClick;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TPopupMenu(AMenu).Items.Add(FMenuItem);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //收縮所有組</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem&#160;&#160; :=&#160;&#160; TMenuItem.Create(Self);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Name&#160;&#160; :=&#160;&#160; &#8216;miCollapseAllGroup&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Caption&#160;&#160; :=&#160;&#160; &#8216;收縮所有組(&amp;O)&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.OnClick&#160;&#160; :=&#160;&#160; miCollapseAllGroupClick;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TPopupMenu(AMenu).Items.Add(FMenuItem);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem&#160;&#160; :=&#160;&#160; TMenuItem.Create(Self);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Caption&#160;&#160; :=&#160;&#160; &#8216;-&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TPopupMenu(AMenu).Items.Add(FMenuItem);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //過濾面板</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem&#160;&#160; :=&#160;&#160; TMenuItem.Create(Self);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Name&#160;&#160; :=&#160;&#160; &#8216;miFilterPanel&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Caption&#160;&#160; :=&#160;&#160; &#8216;過濾面板(&amp;P)&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //自動顯示</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem&#160;&#160; :=&#160;&#160; TMenuItem.Create(Self);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem.Name&#160;&#160; :=&#160;&#160; &#8216;miFilterPanelAuto&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem.Caption&#160;&#160; :=&#160;&#160; &#8216;自動(&amp;A)&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem.RadioItem&#160;&#160; :=&#160;&#160; True;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem.GroupIndex&#160;&#160; :=&#160;&#160; 5; //指定同一組</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem.Checked&#160;&#160; :=&#160;&#160; True;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem.OnClick&#160;&#160; :=&#160;&#160; miFilterPanelClick;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Add(FSubMenuItem); //加入二級子功能表</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //總是顯示</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem&#160;&#160; :=&#160;&#160; TMenuItem.Create(Self);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem.Name&#160;&#160; :=&#160;&#160; &#8216;miFilterPanelAlways&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem.Caption&#160;&#160; :=&#160;&#160; &#8216;總是顯示(&amp;W)&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem.RadioItem&#160;&#160; :=&#160;&#160; True;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem.GroupIndex&#160;&#160; :=&#160;&#160; 5;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem.OnClick&#160;&#160; :=&#160;&#160; miFilterPanelClick;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Add(FSubMenuItem);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //從不顯示</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem&#160;&#160; :=&#160;&#160; TMenuItem.Create(Self);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem.Name&#160;&#160; :=&#160;&#160; &#8216;miFilterPanelNerver&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem.Caption&#160;&#160; :=&#160;&#160; &#8216;從不顯示(&amp;N)&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem.RadioItem&#160;&#160; :=&#160;&#160; True;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem.GroupIndex&#160;&#160; :=&#160;&#160; 5;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FSubMenuItem.OnClick&#160;&#160; :=&#160;&#160; miFilterPanelClick;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Add(FSubMenuItem);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TPopupMenu(AMenu).Items.Add(FMenuItem);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //自定義過濾</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem&#160;&#160; :=&#160;&#160; TMenuItem.Create(Self);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Name&#160;&#160; :=&#160;&#160; &#8216;miCustomFilter&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Caption&#160;&#160; :=&#160;&#160; &#8216;自定義過濾(&amp;M)&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.OnClick&#160;&#160; :=&#160;&#160; miCustomFilterClick;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TPopupMenu(AMenu).Items.Add(FMenuItem);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //過濾管理器</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem&#160;&#160; :=&#160;&#160; TMenuItem.Create(Self);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Name&#160;&#160; :=&#160;&#160; &#8216;miFilterBuilder&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TPopupMenu(AMenu).Images.AddImage(FormMain.ImageListExtend,&#160;&#160; 44); //添加圖示圖像</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.ImageIndex&#160;&#160; :=&#160;&#160; TPopupMenu(AMenu).Images.Count&#160;&#160; -&#160;&#160; 1; //指定圖示序號</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Caption&#160;&#160; :=&#160;&#160; &#8216;過濾管理器&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.OnClick&#160;&#160; :=&#160;&#160; Self.miFilterBuilderClick;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TPopupMenu(AMenu).Items.Add(FMenuItem);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem&#160;&#160; :=&#160;&#160; TMenuItem.Create(Self);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Caption&#160;&#160; :=&#160;&#160; &#8216;-&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TPopupMenu(AMenu).Items.Add(FMenuItem);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //導出</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem&#160;&#160; :=&#160;&#160; TMenuItem.Create(Self);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Name&#160;&#160; :=&#160;&#160; &#8216;miExport&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TPopupMenu(AMenu).Images.AddImage(FormMain.ImageListExtend,&#160;&#160; 37);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.ImageIndex&#160;&#160; :=&#160;&#160; TPopupMenu(AMenu).Images.Count&#160;&#160; -&#160;&#160; 1;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Caption&#160;&#160; :=&#160;&#160; &#8216;導出(&amp;E)&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.OnClick&#160;&#160; :=&#160;&#160; Self.miExportClick;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TPopupMenu(AMenu).Items.Add(FMenuItem);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //列印</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem&#160;&#160; :=&#160;&#160; TMenuItem.Create(Self);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Name&#160;&#160; :=&#160;&#160; &#8216;miPrint&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.Caption&#160;&#160; :=&#160;&#160; &#8216;列印(&amp;P)&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TPopupMenu(AMenu).Images.AddImage(FormMain.ImageListExtend,&#160;&#160; 14);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.ImageIndex&#160;&#160; :=&#160;&#160; TPopupMenu(AMenu).Images.Count&#160;&#160; -&#160;&#160; 1;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FMenuItem.OnClick&#160;&#160; :=&#160;&#160; Self.miPrintClick;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TPopupMenu(AMenu).Items.Add(FMenuItem);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; procedure&#160;&#160; TFormItemList.miExportClick(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; FileName,&#160;&#160; FileExt,&#160;&#160; msg:&#160;&#160; String;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; Self.aqyQuery.IsEmpty&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; msg&#160;&#160; :=&#160;&#160; &#8216;沒有導出資料&#8230;&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Application.MessageBox(PChar(msg),&#160;&#160; PChar(Application.Title),&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; MB_OK&#160;&#160; or&#160;&#160; MB_IconWarning);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Exit;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Self.SaveDialogExport.Filter&#160;&#160; :=&#160;&#160; &#8216;Excel文件&#160;&#160; (*.xls)|*.xls|XML文件&#160;&#160; (*.xml)|*.xml&#8217;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +&#160;&#160; &#8216;|文字檔案&#160;&#160; (*.txt)|*.txt|網頁文件&#160;&#160; (*.html)|*.html&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Self.SaveDialogExport.Title&#160;&#160; :=&#160;&#160; &#8216;導出為&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; not&#160;&#160; Self.SaveDialogExport.Execute&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Exit;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; FileName&#160;&#160; :=&#160;&#160; Self.SaveDialogExport.FileName;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; FileExt&#160;&#160; :=&#160;&#160; LowerCase(ExtractFileExt(FileName));&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; FileExt&#160;&#160; =&#160;&#160; &#8216;.xls&#8217;&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ExportGrid4ToExcel(FileName,&#160;&#160; Self.cxGrid1)&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; else&#160;&#160; if&#160;&#160; FileExt&#160;&#160; =&#160;&#160; &#8216;.xml&#8217;&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ExportGrid4ToXML(FileName,&#160;&#160; Self.cxGrid1)&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; else&#160;&#160; if&#160;&#160; FileExt&#160;&#160; =&#160;&#160; &#8216;.txt&#8217;&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ExportGrid4ToText(FileName,&#160;&#160; Self.cxGrid1)&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; else&#160;&#160; if&#160;&#160; FileExt&#160;&#160; =&#160;&#160; &#8216;.html&#8217;&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ExportGrid4ToHTML(FileName,&#160;&#160; Self.cxGrid1)&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; else&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; msg&#160;&#160; :=&#160;&#160; &#8216;不支援的導出檔類型&#8230;&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Application.MessageBox(PChar(msg),&#160;&#160; PChar(Application.Title),&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; MB_OK&#160;&#160; or&#160;&#160; MB_IconError);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Exit;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; msg&#160;&#160; :=&#160;&#160; &#8216;導出完成&#8230;&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Application.MessageBox(PChar(msg),&#160;&#160; PChar(Application.Title),&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; MB_OK&#160;&#160; or&#160;&#160; MB_IconInformation);&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; procedure&#160;&#160; TFormItemList.miPrintClick(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //列印</p>
<p>&#160;&#160;&#160;&#160;&#160; Self.dxComponentPrinter.Preview(True,&#160;&#160; Self.dxComponentPrinterLink1);&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; procedure&#160;&#160; TFormItemList.cxGridPopupMenuPopup(ASenderMenu:&#160;&#160; TComponent;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AHitTest:&#160;&#160; TcxCustomGridHitTest;&#160;&#160; X,&#160;&#160; Y:&#160;&#160; Integer;&#160;&#160; var&#160;&#160; AllowPopup:&#160;&#160; Boolean);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; GetHitTypeByHitCode(AHitTest.HitTestCode)&#160;&#160; =&#160;&#160; gvhtColumnHeader&#160;&#160; then //右擊列標題時</p>
<p>&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //if&#160;&#160; tvResult.DataController.Groups.GroupingItemCount&#160;&#160; &gt;&#160;&#160; 0&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if&#160;&#160; tvResult.GroupedColumnCount&#160;&#160; &gt;&#160;&#160; 0&#160;&#160; then //有分組時顯示</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TMenuItem(Self.FindComponent(&#8217;miLineForGroup&#8217;)).Visible&#160;&#160; :=&#160;&#160; True;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TMenuItem(Self.FindComponent(&#8217;miExpandAllGroup&#8217;)).Visible&#160;&#160; :=&#160;&#160; True;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TMenuItem(Self.FindComponent(&#8217;miCollapseAllGroup&#8217;)).Visible&#160;&#160; :=&#160;&#160; True;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TMenuItem(Self.FindComponent(&#8217;miLineForGroup&#8217;)).Visible&#160;&#160; :=&#160;&#160; False;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TMenuItem(Self.FindComponent(&#8217;miExpandAllGroup&#8217;)).Visible&#160;&#160; :=&#160;&#160; False;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TMenuItem(Self.FindComponent(&#8217;miCollapseAllGroup&#8217;)).Visible&#160;&#160; :=&#160;&#160; False;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; procedure&#160;&#160; TFormItemList.miFilterBuilderClick(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //過濾管理器</p>
<p>&#160;&#160;&#160;&#160;&#160; //彈出Filter&#160;&#160; Builder&#160;&#160; Dialog對話方塊</p>
<p>&#160;&#160;&#160;&#160;&#160; tvResult.Filtering.RunCustomizeDialog;&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; procedure&#160;&#160; TFormItemList.miCustomFilterClick(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AHitTest:&#160;&#160; TcxCustomGridHitTest;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //自定義過濾</p>
<p>&#160;&#160;&#160;&#160;&#160; //彈出Custom&#160;&#160; Filter&#160;&#160; Dialog對話方塊</p>
<p>&#160;&#160;&#160;&#160;&#160; AHitTest&#160;&#160; :=&#160;&#160; cxGridPopupMenu.HitTest;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; GetHitTypeByHitCode(AHitTest.HitTestCode)&#160;&#160; =&#160;&#160; gvhtColumnHeader&#160;&#160; then //獲得右擊的列</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; tvResult.Filtering.RunCustomizeDialog(TcxGridColumnHeaderHitTest(AHitTest).Column);&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; procedure&#160;&#160; TFormItemList.miFilterPanelClick(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; mi:&#160;&#160; TMenuItem;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //隱藏/顯示過濾面板</p>
<p>&#160;&#160;&#160;&#160;&#160; mi&#160;&#160; :=&#160;&#160; TMenuItem(Sender);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; mi.Checked&#160;&#160; :=&#160;&#160; True;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; mi.Name&#160;&#160; =&#160;&#160; &#8216;miFilterPanelAlways&#8217;&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; tvResult.Filtering.Visible&#160;&#160; :=&#160;&#160; fvAlways&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; else&#160;&#160; if&#160;&#160; mi.Name&#160;&#160; =&#160;&#160; &#8216;miFilterPanelNerver&#8217;&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; tvResult.Filtering.Visible&#160;&#160; :=&#160;&#160; fvNever&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; else&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; tvResult.Filtering.Visible&#160;&#160; :=&#160;&#160; fvNonEmpty;&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; procedure&#160;&#160; TFormItemList.miExpandAllGroupClick(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //展開所有組</p>
<p>&#160;&#160;&#160;&#160;&#160; tvResult.DataController.Groups.FullExpand;&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; procedure&#160;&#160; TFormItemList.miCollapseAllGroupClick(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //收縮所有組</p>
<p>&#160;&#160;&#160;&#160;&#160; tvResult.DataController.Groups.FullCollapse;&#160; </p>
<p>&#160; end;&#160; </p>
</blockquote>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>在用，留名</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<h5>技巧三 按條件計算合計值</h5>
<p>在Footer的第一列顯示[合計:]&#160; </p>
<p>加一個Summary項,Column設為Grid的第一列,Kind設為skNone&#160; </p>
<p>在該Summary項的OnGetText事件中,輸入:&#160; </p>
<blockquote><p>&#160; procedure&#160;&#160; TFormExpense.tvExpenseTcxGridDBDataControllerTcxDataSummaryFooterSummaryItems2GetText(&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Sender:&#160;&#160; TcxDataSummaryItem;&#160;&#160; const&#160;&#160; AValue:&#160;&#160; Variant;&#160;&#160; AIsFooter:&#160;&#160; Boolean;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; var&#160;&#160; AText:&#160;&#160; String);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AText&#160;&#160; :=&#160;&#160; &#8216;合計:&#8217;;&#160; </p>
<p>&#160; end;&#160; </p>
<p>按條件匯總:&#160; </p>
<p>在TableView的DataController-&gt;Summary-&gt;FooterSummary-&gt;OnSummary事件中,輸入:&#160; </p>
<p>&#160; procedure&#160;&#160; TFormExpense.tvExpenseDataControllerSummaryFooterSummaryItemsSummary(&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; ASender:&#160;&#160; TcxDataSummaryItems;&#160;&#160; Arguments:&#160;&#160; TcxSummaryEventArguments;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; var&#160;&#160; OutArguments:&#160;&#160; TcxSummaryEventOutArguments);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //得到欄位名&#160;&#160; TcxDBDataSummaryItem(Arguments.SummaryItem).FieldName;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; (ASender.DataController.Values[Arguments.RecordIndex,&#160;&#160; tvExpenseLevel.Index]&#160;&#160; &gt;&#160;&#160; 1)&#160;&#160;&#160;&#160;&#160;&#160; //只統計Level列=1的值</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; and&#160;&#160; (TcxDBDataSummaryItem(Arguments.SummaryItem).Kind&#160;&#160; =&#160;&#160; skSum)&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; OutArguments.Value&#160;&#160; :=&#160;&#160; 0; //Level&#160;&#160; &gt;&#160;&#160; 1的統計值設為0&#160; </p>
<p>&#160; end;&#160; </p>
</blockquote>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>借貴地一用,問個CXGrid問題,在cxgrid中如何使一些行不能編輯,如:欄位isenable&#160;&#160; =&#160;&#160; false的行</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>樓上的問題</p>
<p>請參考下面的技巧</p>
<h5>技巧四:根據某列的值設定其他列的可編輯性</h5>
<blockquote><p>&#160; procedure&#160;&#160; TFormUser.tvUserEditing(Sender:&#160;&#160; TcxCustomGridTableView;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AItem:&#160;&#160; TcxCustomGridTableItem;&#160;&#160; var&#160;&#160; AAllow:&#160;&#160; Boolean);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //如果第三列值為True,則第4列不能修改</p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; (tvUser.Controller.FocusedRecord.Values[2]&#160;&#160; =&#160;&#160; True)&#160;&#160; and&#160;&#160; (AItem.Index&#160;&#160; =&#160;&#160; 4)&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AAllow&#160;&#160; :=&#160;&#160; False&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; else&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AAllow&#160;&#160; :=&#160;&#160; True;&#160; </p>
<p>&#160; end;&#160; </p>
</blockquote>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<h5>技巧五:保存/恢復Grid佈局</h5>
<p>&#160; //恢復佈局</p>
<blockquote><p>&#160; IniFileName&#160;&#160; :=&#160;&#160; ExtractFilePath(Application.ExeName)&#160;&#160; +&#160;&#160; &#8216;Layout\&#8217;&#160;&#160; +&#160;&#160; Self.Name&#160;&#160; +&#160;&#160; &#8216;.ini&#8217;;&#160; </p>
<p>&#160; if&#160;&#160; FileExists(IniFileName)&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Self.tvResult.RestoreFromIniFile(IniFileName) //從佈局檔中恢復</p>
<p>&#160; else&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Self.tvResult.BeginUpdate;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; for&#160;&#160; i&#160;&#160; :=&#160;&#160; 0&#160;&#160; to&#160;&#160; Self.tvResult.ItemCount&#160;&#160; -&#160;&#160; 1&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Self.tvResult.Items[i].ApplyBestFit; //調整為最佳寬度</p>
<p>&#160;&#160;&#160;&#160;&#160; Self.tvResult.EndUpdate;&#160; </p>
<p>&#160; end;&#160; </p>
</blockquote>
<p>&#160; //保存佈局</p>
<blockquote><p>&#160; IniFileName&#160;&#160; :=&#160;&#160; ExtractFilePath(Application.ExeName)&#160;&#160; +&#160;&#160; &#8216;Layout\&#8217;&#160;&#160; +&#160;&#160; Self.Name&#160;&#160; +&#160;&#160; &#8216;.ini&#8217;;&#160; </p>
<p>&#160; if&#160;&#160; not&#160;&#160; DirectoryExists(ExtractFileDir(IniFileName))&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; CreateDir(ExtractFileDir(IniFileName));&#160; </p>
<p>&#160; Self.tvResult.StoreToIniFile(IniFileName); //保存為佈局檔</p>
</blockquote>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>借用地問一下：在&#160;&#160; cxgrid中，如果我同時選中主表與子表中的記錄，怎么樣能同時進行對其所選記錄進行處理呢。</p>
<p>我現在只能判斷 焦點是在主表還是從表中，然後只能對主表或子表中的資料進行處理。</p>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>看來用cxGrid人不多啊</p>
<p>再多貼一些技巧,需要的朋友頂一下</p>
<p>&#160; ==========================================================================&#160; </p>
<h5>在主從TableView中根據主TableView得到對應的從TableView&#160; </h5>
<blockquote><p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; ADetailDC:&#160;&#160; TcxGridDataController;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AView:&#160;&#160; TcxCustomGridTableView;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; with&#160;&#160; cxGrid1DBTableView1.DataController&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ADetailDC&#160;&#160; :=&#160;&#160; TcxGridDataController(GetDetailDataController(FocusedRecordIndex,&#160;&#160; 0));&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AView&#160;&#160; :=&#160;&#160; ADetailDC.GridView;&#160; </p>
<p>&#160; end;&#160; </p>
</blockquote>
<p>&#160; ==============================================================================&#160; </p>
<h5>定位在第一行並顯示內置編輯器</h5>
<blockquote><p>&#160; cxDBVerticalGrid1.FocusedRow&#160;&#160; :=&#160;&#160; cxDBVerticalGrid1.Rows[0];&#160; </p>
<p>&#160; cxDBVerticalGrid1.ShowEdit;&#160; </p>
</blockquote>
<p>&#160; ==============================================================================&#160; </p>
<p>隱藏&#160;&#160; &quot;&lt;No&#160;&#160; data&#160;&#160; to&#160;&#160; display&gt;&quot;&#160;&#160; 字串</p>
<p>該文本存儲在scxGridNoDataInfoText資源字串,可以將該資源字串的內容設為空</p>
<p>來隱藏該文本。</p>
<blockquote><p>&#160; uses&#160;&#160; cxClasses,&#160;&#160; cxGridStrs;&#160;&#160;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; &#8230;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; cxSetResourceString(@scxGridNoDataInfoText,&#160;&#160; 』);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //如果&quot;&lt;No&#160;&#160; data&#160;&#160; to&#160;&#160; display&gt;&quot;&#160;&#160; 字串已經顯示，需要調用：</p>
<p>&#160;&#160;&#160;&#160;&#160; &lt;View&gt;.LayoutChanged;&#160; </p>
</blockquote>
<p>&#160; ============================================================&#160; </p>
<h5>刪除應用過濾後的行</h5>
<blockquote><p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; I:&#160;&#160; Integer;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; with&#160;&#160; &lt;GridView&gt;&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; for&#160;&#160; I&#160;&#160; :=&#160;&#160; 0&#160;&#160; to&#160;&#160; ViewData.RecordCount&#160;&#160; -&#160;&#160; 1&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ViewData.Records[0].Focused&#160;&#160; :=&#160;&#160; True;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataController.DataSet.Delete;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
</blockquote>
<p>&#160; =============================================================&#160; </p>
<h5>根據單元的值設置樣式</h5>
<blockquote><p>&#160; procedure&#160;&#160; &lt;aForm&gt;.&lt;aColumn&gt;StylesGetContentStyle(&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Sender:&#160;&#160; TcxCustomGridTableView;&#160;&#160; ARecord:&#160;&#160; TcxCustomGridRecord;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AItem:&#160;&#160; TcxCustomGridTableItem;&#160;&#160; out&#160;&#160; AStyle:&#160;&#160; TcxStyle);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; ARecord.Values[AItem.Index]&#160;&#160; =&#160;&#160; aSomeValue&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AStyle&#160;&#160; :=&#160;&#160; &lt;aSomeStyle&gt;;&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; procedure&#160;&#160; &lt;aForm&gt;.&lt;aView&gt;StylesGetContentStyle(&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Sender:&#160;&#160; TcxCustomGridTableView;&#160;&#160; ARecord:&#160;&#160; TcxCustomGridRecord;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AItem:&#160;&#160; TcxCustomGridTableItem;&#160;&#160; out&#160;&#160; AStyle:&#160;&#160; TcxStyle);&#160; </p>
<p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AColumn:&#160;&#160; TcxCustomGridTableItem;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AColumn&#160;&#160; :=&#160;&#160; (Sender&#160;&#160; as&#160;&#160; TcxGridDBTableView).GetColumnByFieldName(&#8217;Email&#8217;);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; VarToStr(ARecord.Values[AColumn.Index])&#160;&#160; =&#160;&#160; 』&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AStyle&#160;&#160; :=&#160;&#160; cxStyleNullEmail;&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; ==============================================================================&#160; </p>
<p>&#160; TcxCustomGridTableView.FindItemByName,&#160;&#160; TcxGridDBTableView.GetColumnByFieldName&#160;&#160; or&#160; </p>
<p>&#160; TcxGridDBDataController.GetItemByFieldName&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; with&#160;&#160; cxGrid1DBBandedTableView1.DataController&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AValue&#160;&#160; :=&#160;&#160; Values[FocusedRecordIndex,&#160;&#160; GetItemByFieldName('SomeFieldName').Index];&#160; </p>
</blockquote>
<p>&#160; ===================================================================&#160; </p>
<h5>動態生成BandedView&#160; </h5>
<blockquote><p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AView:&#160;&#160; TcxCustomGridView;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AView&#160;&#160; :=&#160;&#160; &lt;cxGrid&gt;.CreateView(TcxGridDBBandedTableView);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; TcxGridDBBandedTableView(AView).DataController.DataSource&#160;&#160; :=&#160;&#160; &lt;DataSource&gt;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; TcxGridDBBandedTableView(AView).Bands.Add;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; with&#160;&#160; TcxGridDBBandedTableView(AView).Bands.Add&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Visible&#160;&#160; :=&#160;&#160; False;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FixedKind&#160;&#160; :=&#160;&#160; fkLeft;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; TcxGridDBBandedTableView(AView).DataController.CreateAllItems;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; &lt;cxGridLevel&gt;.GridView&#160;&#160; :=&#160;&#160; AView;&#160; </p>
</blockquote>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>======================================================================&#160; </p>
<h5>當底層資料集為空時顯示一條空記錄</h5>
<blockquote><p>&#160; procedure&#160;&#160; &lt;Form&gt;.&lt;cxGrid&gt;Enter(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; View:&#160;&#160; TcxGridDBTableView;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; View&#160;&#160; :=&#160;&#160; TcxGridDBTableView((Sender&#160;&#160; as&#160;&#160; TcxGrid).FocusedView);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; View.DataController.DataSet.IsEmpty&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; View.DataController.DataSet.Append;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; View.Controller.EditingController.ShowEdit;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160; end;&#160; </p>
</blockquote>
<p>&#160; =======================================================================&#160; </p>
<h5>在當前View插入記錄</h5>
<p>使用FocusedView屬性得到當前焦點View，用View.DataController得到對應的Data&#160;&#160; Controller，</p>
<p>之後使用Data&#160;&#160; Controller的方法來運算元據：</p>
<p>&#160; -&#160;&#160; Append&#160; </p>
<p>&#160; -&#160;&#160; Insert&#160; </p>
<p>&#160; -&#160;&#160; Post&#160; </p>
<p>&#160; -&#160;&#160; Cancel&#160; </p>
<p>&#160; -&#160;&#160; DeleteFocused&#160; </p>
<p>&#160; -&#160;&#160; DeleteSelection&#160; </p>
<p>示例：</p>
<blockquote><p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; ARecIndex:&#160;&#160; Integer;&#160; </p>
<p>&#160; …&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; View.DataController.Append;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; ARecIndex&#160;&#160; :=&#160;&#160; View.DataController.FocusedRecordIndex;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; View.DataController.Values[ARecIndex,&#160;&#160; SomeItemIndex]&#160;&#160; :=&#160;&#160; SomeValue;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; View.DataController.Post;&#160; </p>
</blockquote>
<p>另外一種方法是使用View.DataController.DataSource.DataSet得到底層資料集後，再用資料集的</p>
<p>方法來運算元據。</p>
<p>&#160; ========================================================================&#160; </p>
<h5>啟動內置編輯控制項</h5>
<blockquote><p>&#160;&#160;&#160; 1)&#160;&#160; &lt;aView&gt;.Controller.EditingController.ShowEdit(&lt;aColumn&gt;);&#160; </p>
<p>&#160;&#160;&#160; 2)&#160;&#160; &lt;aView&gt;.Controller.EditingController.StartEditShowingTimer(&lt;aColumn&gt;);&#160; </p>
<p>&#160;&#160;&#160; 3)&#160;&#160; &lt;aView&gt;.Controller.EditingItem&#160;&#160; :=&#160;&#160; &lt;aColumn&gt;;&#160; </p>
<p>&#160;&#160;&#160; 4)&#160;&#160; &lt;aColumn&gt;.Editing&#160;&#160; :=&#160;&#160; True;&#160; </p>
</blockquote>
<h5>隱藏內置編輯控制項</h5>
<blockquote><p>&#160;&#160;&#160;&#160;&#160; &lt;aView&gt;.Controller.EditingController.HideEdit(True);&#160; </p>
</blockquote>
<p>&#160; ===========================================================================&#160; </p>
<h5>移除一個分組列</h5>
<blockquote><p>&#160;&#160;&#160;&#160;&#160; &lt;aColumn&gt;.GroupIndex&#160;&#160; :=&#160;&#160; -1;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; &lt;aColumn&gt;.Visible&#160;&#160; :=&#160;&#160; True;&#160; </p>
</blockquote>
<p>&#160; ===========================================================================&#160; </p>
<h5>保存修改到資料庫</h5>
<blockquote><p>&#160; procedure&#160;&#160; &lt;aForm&gt;.FormClose(Sender:&#160;&#160; TObject;&#160;&#160; var&#160;&#160; Action:&#160;&#160; TCloseAction);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; (&lt;aGrid&gt;.FocusedView&#160;&#160; &lt;&gt;&#160;&#160; nil)&#160;&#160; and&#160;&#160; (&lt;aGrid&gt;.FocusedView.DataController.EditState&#160;&#160; &lt;&gt;&#160;&#160; [])&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;aGrid&gt;.FocusedView.DataController.Post;&#160; </p>
<p>&#160; end;&#160; </p>
</blockquote>
<p>&#160; ============================================================================&#160; </p>
<h5>設置內置右鍵菜單</h5>
<p>內置右鍵功能表包括二個功能表:cxGridStdHeaderMenu,&#160;&#160; TcxGridStdFooterMenu&#160; </p>
<blockquote><p>&#160; uses&#160;&#160; cxGridStdPopupMenu;&#160; </p>
<p>&#160; procedure&#160;&#160; TForm1.cxGridPopupMenu1Popup(ASenderMenu:&#160;&#160; TComponent;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AHitTest:&#160;&#160; TcxCustomGridHitTest;&#160;&#160; X,&#160;&#160; Y:&#160;&#160; Integer;&#160;&#160; var&#160;&#160; AllowPopup:&#160;&#160; Boolean);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; ASenderMenu&#160;&#160; is&#160;&#160; TcxGridStdHeaderMenu&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TcxGridStdHeaderMenu(ASenderMenu).OnPopup&#160;&#160; :=&#160;&#160; StdHeaderMenuPopup;&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; procedure&#160;&#160; TForm1.StdHeaderMenuPopup(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; I:&#160;&#160; Integer;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; with&#160;&#160; TcxGridStdHeaderMenu(Sender).Items&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; for&#160;&#160; I&#160;&#160; :=&#160;&#160; 0&#160;&#160; to&#160;&#160; Count&#160;&#160; -&#160;&#160; 1&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if&#160;&#160; Items[I].Caption&#160;&#160; =&#160;&#160; &#8216;Group&#160;&#160; By&#160;&#160; Box&#8217;&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Items[I].Enabled&#160;&#160; :=&#160;&#160; False;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Break;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end&#160; </p>
<p>&#160; end;&#160; </p>
</blockquote>
<p>&#160; ===========================================================================&#160; </p>
<h5>得到選中記錄的值(MultiSelect)&#160; </h5>
<blockquote><p>&#160; 1)&#160;&#160; View.DataController.DataModeController.GridMode&#160;&#160; =&#160;&#160; False時</p>
<p>&#160;&#160;&#160;&#160;&#160; RecIdx&#160;&#160; :=&#160;&#160; View.Controller.SelectedRecords[i].RecordIndex;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; ColIdx&#160;&#160; :=&#160;&#160; View.DataController.GetItemByFieldName(AFieldName).Index;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; OutputVal&#160;&#160; :=&#160;&#160; View.DataController.Values[RecIdx,&#160;&#160; ColIdx];&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //RecID&#160;&#160; :=&#160;&#160; View.DataController.GetRecordId(RecIdx);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //OutputVal&#160;&#160; :=&#160;&#160; ADataSet.Lookup(View.DataController.KeyFieldNames,&#160;&#160; RecID,&#160;&#160; AFieldName);&#160; </p>
<p>&#160; 2)&#160;&#160; Bkm: string;&#160; </p>
<p>View.DataController.DataModeController.GridMode&#160;&#160; =&#160;&#160; True時</p>
<p>&#160;&#160;&#160;&#160;&#160; Bkm&#160;&#160; :=&#160;&#160; View.DataController.GetSelectedBookmark(ASelectedRecordIndex);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; ADataSet.BookmarkValid(TBookmark(Bkm))&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ADataSet.Bookmark&#160;&#160; :=&#160;&#160; Bkm;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; OutputVal&#160;&#160; :=&#160;&#160; ADataSet.FieldByName(AFieldName).Value;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; View.BeginUpdate;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; View.DataController.BeginLocate;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; try&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //&#160;&#160; make&#160;&#160; changes&#160;&#160; here…&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; finally&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; View.DataController.EndLocate;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; View.EndUpdate;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
</blockquote>
<p>&#160;&#160;&#160; //直接讀取選擇的單格內容</p>
<blockquote><p>var</p>
<p>I, J: Integer;</p>
<p>val: Variant;</p>
<p>begin</p>
<p>Result := 0;</p>
<p>for I := 0 to TableView.Controller. SelectedRowCount &#8211; 1 do</p>
<p>for J := 0 to TableView.Controller. SelectedColumnCount &#8211; 1 do</p>
<p>begin</p>
<p>val := TableView.DataController.GetValue(</p>
<p>TableView.Controller.SelectedRows[I].RecordIndex,</p>
<p>TableView.Controller.SelectedColumns[J].Index);</p>
<p>Showmessage(val);</p>
<p>end;</p>
<p>end;</p>
</blockquote>
<p>&#160; =============================================================&#160; </p>
<h5>在GridMode禁用內置的右鍵Footer菜單</h5>
<blockquote><p>&#160; uses&#160;&#160; cxGridStdPopupMenu;&#160; </p>
<p>&#160; procedure&#160;&#160; cxGridPopupMenuOnPopup(&#8230;)&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; (ASenderMenu&#160;&#160; is&#160;&#160; TcxGridStdFooterMenu)&#160;&#160; and&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;GridView&gt;.DataController.DataModeController.GridMode&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AllowPopup&#160;&#160; :=&#160;&#160; False;&#160; </p>
<p>&#160; end;&#160; </p>
</blockquote>
<p>&#160; ==============================================================&#160; </p>
<h5>主從表任何時候只能展開一個組</h5>
<blockquote><p>&#160; procedure&#160;&#160; TForm1.ADetailDataControllerCollapsing(&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; ADataController:&#160;&#160; TcxCustomDataController;&#160;&#160; ARecordIndex:&#160;&#160; Integer;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; var&#160;&#160; AAllow:&#160;&#160; Boolean);&#160; </p>
<p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; I:&#160;&#160; Integer;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; C:&#160;&#160; Integer;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AAllow&#160;&#160; :=&#160;&#160; False;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; C&#160;&#160; :=&#160;&#160; 0;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; for&#160;&#160; I&#160;&#160; :=&#160;&#160; 0&#160;&#160; to&#160;&#160; ADataController.RecordCount&#160;&#160; -&#160;&#160; 1&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if&#160;&#160; ADataController.GetDetailExpanding(I)&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Inc(C);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if&#160;&#160; C&#160;&#160; &gt;&#160;&#160; 1&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AAllow&#160;&#160; :=&#160;&#160; True;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; procedure&#160;&#160; TForm1.ADetailDataControllerExpanding(&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; ADataController:&#160;&#160; TcxCustomDataController;&#160;&#160; ARecordIndex:&#160;&#160; Integer;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; var&#160;&#160; AAllow:&#160;&#160; Boolean);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; ADataController.CollapseDetails;&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; procedure&#160;&#160; TForm1.FormCreate(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; cxGrid1DBTableView1.DataController.OnDetailExpanding&#160;&#160; :=&#160;&#160; ADetailDataControllerExpanding;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; cxGrid1DBTableView1.DataController.OnDetailCollapsing&#160;&#160; :=&#160;&#160; ADetailDataControllerCollapsing;&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; =================================================================&#160; </p>
</blockquote>
<h5>動態創建層次(Level)和視圖(View)&#160; </h5>
<blockquote><p>&#160; var&#160;&#160;&#160;&#160;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Grid:&#160;&#160; TcxGrid;&#160;&#160;&#160;&#160;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Level:&#160;&#160; TcxGridLevel;&#160;&#160;&#160;&#160;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; View:&#160;&#160; TcxGridDBTableView;&#160;&#160;&#160;&#160;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //&#160;&#160; Creates&#160;&#160; a&#160;&#160; Grid&#160;&#160; instance&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Grid&#160;&#160; :=&#160;&#160; TcxGrid.Create(SomeOwner);&#160;&#160;&#160;&#160;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Grid.Parent&#160;&#160; :=&#160;&#160; SomeParent;&#160;&#160;&#160;&#160;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //&#160;&#160; Creates&#160;&#160; a&#160;&#160; Level&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Level&#160;&#160; :=&#160;&#160; Grid.Levels.Add;&#160;&#160;&#160;&#160;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Level.Name&#160;&#160; :=&#160;&#160; &#8216;SomeLevelName&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //&#160;&#160; Creates&#160;&#160; a&#160;&#160; View&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; View&#160;&#160; :=&#160;&#160; Grid.CreateView(TcxGridDBTableView)&#160;&#160; as&#160;&#160; TcxGridDBTableView;&#160;&#160;&#160;&#160;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; View.Name&#160;&#160; :=&#160;&#160; &#8216;SomeViewName&#8217;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //&#160;&#160; …&#160;&#160; and&#160;&#160; binds&#160;&#160; it&#160;&#160; to&#160;&#160; the&#160;&#160; Level&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Level.GridView&#160;&#160; :=&#160;&#160; View;&#160;&#160;&#160;&#160;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //&#160;&#160; Hooks&#160;&#160; up&#160;&#160; the&#160;&#160; View&#160;&#160; to&#160;&#160; the&#160;&#160; data&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; View.DataController.DataSource&#160;&#160; :=&#160;&#160; SomeDataSource;&#160;&#160;&#160;&#160;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //&#160;&#160; …&#160;&#160; and&#160;&#160; creates&#160;&#160; all&#160;&#160; columns&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; View.DataController.CreateAllItems;&#160;&#160;&#160;&#160;&#160; </p>
<p>&#160; end;&#160;&#160;&#160; </p>
</blockquote>
<p>此樓回復Re：</p>
<hr align="center" size="2" width="100%" />
<p>======================================================================&#160; </p>
<h5>獲得Group&#160;&#160; Footer合計行對應的記錄</h5>
<blockquote><p>&#160; procedure&#160;&#160; TForm1.cxGrid1DBTableView1CustomDrawFooterCell(&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Sender:&#160;&#160; TcxGridTableView;&#160;&#160; ACanvas:&#160;&#160; TcxCanvas;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AViewInfo:&#160;&#160; TcxGridColumnHeaderViewInfo;&#160;&#160; var&#160;&#160; ADone:&#160;&#160; Boolean);&#160; </p>
<p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; ALevel,&#160;&#160; ADataGroupIndex:&#160;&#160; Integer;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; AGridRecord,&#160;&#160; AGroupRecord:&#160;&#160; TcxCustomGridRecord;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; if&#160;&#160; AViewInfo&#160;&#160; is&#160;&#160; TcxGridRowFooterCellViewInfo&#160;&#160; and&#160;&#160;&#160;&#160;&#160;&#160; //&#160;&#160; Row&#160;&#160; footer&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (TcxGridDBColumn(AViewInfo.Column).DataBinding.FieldName&#160;&#160; =&#160;&#160; &#8216;Area&#8217;)&#160;&#160; then&#160;&#160;&#160;&#160; //&#160;&#160; Area&#160;&#160; column&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AGridRecord&#160;&#160; :=&#160;&#160; TcxGridRowFooterCellViewInfo(AViewInfo).GridRecord;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ALevel&#160;&#160; :=&#160;&#160; TcxGridRowFooterCellViewInfo(AViewInfo).Container.GroupLevel;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ADataGroupIndex&#160;&#160; :=&#160;&#160; Sender.DataController.Groups.DataGroupIndexByRowIndex[AGridRecord.Index];&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if&#160;&#160; ADataGroupIndex&#160;&#160; &lt;&gt;&#160;&#160; -1&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AGroupRecord&#160;&#160; :=&#160;&#160; AGridRecord;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; while&#160;&#160; AGroupRecord.Level&#160;&#160; &lt;&gt;&#160;&#160; ALevel&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AGroupRecord&#160;&#160; :=&#160;&#160; AGroupRecord.ParentRecord;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AViewInfo.Text&#160;&#160; :=&#160;&#160; AGroupRecord.DisplayTexts[0];&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160; end;&#160; </p>
</blockquote>
<p>&#160; ===========================================================================&#160; </p>
<h5>訪問過濾之後的記錄</h5>
<blockquote><p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; I:&#160;&#160; Integer;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Memo1.Lines.Clear;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; with&#160;&#160; cxGrid1DBTableView1.DataController&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; for&#160;&#160; I&#160;&#160; :=&#160;&#160; 0&#160;&#160; to&#160;&#160; FilteredRecordCount&#160;&#160; -&#160;&#160; 1&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Memo1.Lines.Add(DisplayTexts[FilteredRecordIndex[I],&#160;&#160; 0]);&#160; </p>
<p>&#160; end;&#160; </p>
</blockquote>
<p>&#160; ============================================================================&#160; </p>
<h5>獲得單元的Font&#160; </h5>
<blockquote><p>&#160; cxGrid1DBTableView1.ViewInfo.RecordsViewInfo.Items[1].GetCellViewInfoByItem(&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; cxGrid1DBTableView1Company).EditViewInfo.Font;&#160; </p>
</blockquote>
<p>&#160; ============================================================================&#160; </p>
<h5>根據Level名稱找到Level物件</h5>
<blockquote><p>&#160; function&#160;&#160; GetLevelByName(AGrid:&#160;&#160; TcxGrid;&#160;&#160; ALevelName:&#160;&#160; string):&#160;&#160; TcxGridLevel;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; function&#160;&#160; LoopThroughLevels(ALevel:&#160;&#160; TcxGridLevel;&#160;&#160; ALevelName:&#160;&#160; string):&#160;&#160; TcxGridLevel;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; I:&#160;&#160; Integer;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Result&#160;&#160; :=&#160;&#160; nil;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; for&#160;&#160; I&#160;&#160; :=&#160;&#160; 0&#160;&#160; to&#160;&#160; ALevel.Count&#160;&#160; -&#160;&#160; 1&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if&#160;&#160; ALevel[I].Name&#160;&#160; =&#160;&#160; ALevelName&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Result&#160;&#160; :=&#160;&#160; ALevel[I];&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Exit;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if&#160;&#160; ALevel[I].Count&#160;&#160; &gt;&#160;&#160; 0&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Result&#160;&#160; :=&#160;&#160; LoopThroughLevels(ALevel[I],&#160;&#160; ALevelName);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if&#160;&#160; Result&#160;&#160; &lt;&gt;&#160;&#160; nil&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Exit;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; I:&#160;&#160; Integer;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Result&#160;&#160; :=&#160;&#160; nil;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; for&#160;&#160; I&#160;&#160; :=&#160;&#160; 0&#160;&#160; to&#160;&#160; AGrid.Levels.Count&#160;&#160; -&#160;&#160; 1&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if&#160;&#160; AGrid.Levels[I].Name&#160;&#160; =&#160;&#160; ALevelName&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Result&#160;&#160; :=&#160;&#160; AGrid.Levels[I];&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Exit;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if&#160;&#160; AGrid.Levels[I].Count&#160;&#160; &gt;&#160;&#160; 0&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Result&#160;&#160; :=&#160;&#160; LoopThroughLevels(AGrid.Levels[I],&#160;&#160; ALevelName);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if&#160;&#160; Result&#160;&#160; &lt;&gt;&#160;&#160; nil&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Exit;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160; end;&#160; </p>
</blockquote>
<p>&#160; ============================================================================&#160; </p>
<h5>指定Filter&#160;&#160; Builder打開/保存過濾檔的默認路徑</h5>
<blockquote><p>&#160; uses&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; &#8230;,&#160;&#160; cxFilterControlDialog;&#160; </p>
<p>&#160; procedure&#160;&#160; TForm.GridView1FilterControlDialogShow(&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; TfmFilterControlDialog(Sender).OpenDialog.InitialDir&#160;&#160; :=&#160;&#160; &#8216;D:\&#8217;&#160; </p>
<p>&#160; end;&#160;&#160;&#160; </p>
</blockquote>
<p>&#160; ============================================================================&#160; </p>
<h5>保存/恢復帶匯總行的佈局</h5>
<blockquote><p>&#160; &lt;TableView&gt;.StoreToIniFile(&#8217;c:\Grid.ini&#8217;,&#160;&#160; True,&#160;&#160; [gsoUseSummary]);&#160;&#160;&#160; </p>
<p>&#160; &lt;GridView&gt;.RestoreFromIniFile(&lt;inifilename&gt;,True,False&#160;&#160; {or&#160;&#160; True,&#160;&#160; optional},[gsoUseSummary]);&#160; </p>
</blockquote>
<p>&#160; ============================================================================&#160; </p>
<h5>取消過濾時移到第一行</h5>
<blockquote><p>&#160; uses&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; cxCustomData;&#160; </p>
<p>&#160; procedure&#160;&#160; TYour_Form.AViewDataControllerFilterChanged(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Filter:&#160;&#160; TcxDataFilterCriteria;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; with&#160;&#160; Sender&#160;&#160; as&#160;&#160; TcxDataFilterCriteria&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if&#160;&#160; IsEmpty&#160;&#160; then&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataController.FocusedRowIndex&#160;&#160; :=&#160;&#160; 0;&#160; </p>
<p>&#160; end;&#160; </p>
</blockquote>
<p>&#160; =============================================================================&#160; </p>
<h5>排序後移到第一行</h5>
<p>可以設置DataController.Options.FocusTopRowAfterSorting&#160;&#160; :=&#160;&#160; True，也可以使用如下的代碼：</p>
<blockquote><p>&#160; uses&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; cxCustomData;&#160; </p>
<p>&#160; procedure&#160;&#160; TYour_Form.Your_ViewDataControllerSortingChanged(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; TcxCustomDataController(Sender).FocusedRowIndex&#160;&#160; :=&#160;&#160; 0;&#160; </p>
<p>&#160; end;&#160; </p>
</blockquote>
<p>&#160; ==============================================================================&#160; </p>
<h5>判斷當前行是否第一行或最後一行</h5>
<p>可以使用DataController的IsBOF,&#160;&#160; IsEOF方法，或者：</p>
<blockquote><p>&#160; &lt;AView&gt;.Controller.Controller.FocusedRow.IsFirst&#160; </p>
<p>&#160; &lt;AView&gt;.Controller.Controller.FocusedRow.IsLast&#160; </p>
</blockquote>
<p>&#160; ==============================================================================&#160; </p>
<h5>根據指定值查找記錄</h5>
<p>&#160; DataController提供了好幾個方法來得到指定值對應的RecordIndex&#160; </p>
<p>對於Bound&#160;&#160; View可以使用FindRecordIndexByKeyValue方法</p>
<p>&#160; ===============================================================================&#160; </p>
<h5>編輯和顯示Blob欄位</h5>
<p>該欄位的Properties設置為BlobEdit，並將BlobPaintStyle&#160;&#160; 屬性設為&#160;&#160; bpsText&#160; </p>
<p>&#160; ===============================================================================&#160; </p>
<h5>得到可見行數</h5>
<blockquote><p>&#160; &lt;View&gt;.ViewInfo.VisibleRecordCount&#160; </p>
</blockquote>
<p>&#160; ===============================================================================&#160; </p>
<h5>保存後的行設置為當前行</h5>
<blockquote><p>&#160; const&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; CM_SETFOCUSEDRECORD&#160;&#160; =&#160;&#160; WM_USER&#160;&#160; +&#160;&#160; 1002;&#160; </p>
<p>&#160; type&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; TForm1&#160;&#160; =&#160;&#160; class(TForm)&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; cxGrid1DBTableView1:&#160;&#160; TcxGridDBTableView;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; cxGrid1Level1:&#160;&#160; TcxGridLevel;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; cxGrid1:&#160;&#160; TcxGrid;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dxMemData1:&#160;&#160; TdxMemData;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dxMemData1Field1:&#160;&#160; TStringField;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dxMemData1Field2:&#160;&#160; TIntegerField;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataSource1:&#160;&#160; TDataSource;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; cxGrid1DBTableView1RecId:&#160;&#160; TcxGridDBColumn;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; cxGrid1DBTableView1Field1:&#160;&#160; TcxGridDBColumn;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; cxGrid1DBTableView1Field2:&#160;&#160; TcxGridDBColumn;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Timer1:&#160;&#160; TTimer;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CheckBox1:&#160;&#160; TCheckBox;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; procedure&#160;&#160; Timer1Timer(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; procedure&#160;&#160; dxMemData1AfterPost(DataSet:&#160;&#160; TDataSet);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; procedure&#160;&#160; CheckBox1Click(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; private&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; procedure&#160;&#160; CMSetFocusedRecord(var&#160;&#160; Msg:&#160;&#160; TMessage);&#160;&#160; message&#160;&#160; CM_SETFOCUSEDRECORD;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; public&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {&#160;&#160; Public&#160;&#160; declarations&#160;&#160; }&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Form1:&#160;&#160; TForm1;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; FocusedIdx:&#160;&#160; Integer;&#160; </p>
<p>&#160; implementation&#160; </p>
<p>&#160; {$R&#160;&#160; *.dfm}&#160; </p>
<p>&#160; procedure&#160;&#160; TForm1.Timer1Timer(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; dxMemData1.AppendRecord(['',&#160;&#160; IntToStr(Random(1000)),&#160;&#160; Random(1000)]);&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; procedure&#160;&#160; TForm1.dxMemData1AfterPost(DataSet:&#160;&#160; TDataSet);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; PostMessage(Handle,&#160;&#160; CM_SETFOCUSEDRECORD,&#160;&#160; Integer(cxGrid1DBTableView1),&#160;&#160; MakeLParam(cxGrid1DBTableView1.Controller.FocusedRowIndex,&#160;&#160; cxGrid1DBTableView1.Controller.TopRowIndex));&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; procedure&#160;&#160; TForm1.CMSetFocusedRecord(var&#160;&#160; Msg:&#160;&#160; TMessage);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; TcxGridDBTableView(msg.WParam).Controller.FocusedRowIndex&#160;&#160; :=&#160;&#160; Msg.LParamLo;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; TcxGridDBTableView(msg.WParam).Controller.TopRowIndex&#160;&#160; :=&#160;&#160; Msg.LParamHi;&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; procedure&#160;&#160; TForm1.CheckBox1Click(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; Timer1.Enabled&#160;&#160; :=&#160;&#160; TCheckBox(Sender).Checked;&#160; </p>
<p>&#160; end;&#160; </p>
<p>&#160; end.&#160; </p>
</blockquote>
<p>&#160; =================================================================================&#160; </p>
<h5>刪除記錄並獲得焦點</h5>
<blockquote><p>&#160; procedure&#160;&#160; TForm1.BtnDeleteClick(Sender:&#160;&#160; TObject);&#160; </p>
<p>&#160; var&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; FocusedRow,&#160;&#160; TopRow:&#160;&#160; Integer;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; View:&#160;&#160; TcxGridTableView;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; DataController:&#160;&#160; TcxGridDataController;&#160; </p>
<p>&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; View&#160;&#160; :=&#160;&#160; cxGrid1.FocusedView&#160;&#160; as&#160;&#160; TcxGridTableView;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; DataController&#160;&#160; :=&#160;&#160; View.DataController;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //&#160;&#160; Remember&#160;&#160; the&#160;&#160; top&#160;&#160; row&#160;&#160; (the&#160;&#160; vertical&#160;&#160; scrollbar&#160;&#160; position)&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; TopRow&#160;&#160; :=&#160;&#160; View.Controller.TopRowIndex;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //&#160;&#160; Remember&#160;&#160; the&#160;&#160; focused&#160;&#160; row(!)&#160;&#160; index&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; FocusedRow&#160;&#160; :=&#160;&#160; DataController.FocusedRowIndex;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; DataController.DeleteFocused;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //&#160;&#160; After&#160;&#160; deletion&#160;&#160; the&#160;&#160; same&#160;&#160; row&#160;&#160; must&#160;&#160; be&#160;&#160; focused,&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //&#160;&#160; although&#160;&#160; it&#160;&#160; will&#160;&#160; correspond&#160;&#160; to&#160;&#160; a&#160;&#160; different&#160;&#160; data&#160;&#160; record&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; DataController.FocusedRowIndex&#160;&#160; :=&#160;&#160; FocusedRow;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; //&#160;&#160; Restore&#160;&#160; the&#160;&#160; top&#160;&#160; row&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; View.Controller.TopRowIndex&#160;&#160; :=&#160;&#160; TopRow;&#160; </p>
<p>&#160; end;&#160; </p>
</blockquote>
<p>//====================================================================================</p>
<h5>報表匯總的設置</h5>
<p>資料庫中的財務表為：</p>
<p>&#160;&#160;&#160;&#160;&#160; ID&#160;&#160;&#160;&#160; 收支類型 金額 其他屬性</p>
<p>其中收支類型只有兩種值：0&#160;&#160; 表示收入，1&#160;&#160; 表示支出 ；金額都是正數。</p>
<p>設置cxGrid的Footer&#160;&#160; 可以使得在顯示時，列表的下方出現匯總行：“金額”的和</p>
<p>同樣設置Default&#160;&#160; For&#160;&#160; Groups可以使得在用戶拖動表頭屬性實現分組時，顯示組內的匯總行：“金額”的和。</p>
<p>上面說的，用過cxGrid應該都會，下面就有這么一個問題</p>
<h5>如果我想使匯總行的值變為如下的值應該怎樣實現：</h5>
<p>收支類型為0的金額的和&#160;&#160; -&#160;&#160; 收支類型為1的金額的和</p>
<p>實現Footer的功能好辦，因為它的值不會變，自己用迴圈寫一個就完了，但是Default&#160;&#160; For&#160;&#160; Groups的功能就不好說了，因為它的值是根據用戶拖動的屬性計算的，而且還有可能是多層分組，想不出來了，所有到這來問</p>
<p>是不是要設置什么屬性？或者cxGrid根本就沒這個功能，那該用什么方法解決？希望哪位幫我解決，謝謝了先！</p>
<p>給你一個例子,可能對你有幫助,&#160; </p>
<blockquote><p>&#160;&#160;&#160; with&#160;&#160; tvOrders.DataController.Summary&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; BeginUpdate;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; try&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; SummaryGroups.Clear;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //The&#160;&#160; first&#160;&#160; summary&#160;&#160; group&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; with&#160;&#160; SummaryGroups.Add&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //Add&#160;&#160; proposed&#160;&#160; grouping&#160;&#160; column(s)&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TcxGridTableSummaryGroupItemLink(Links.Add).Column&#160;&#160; :=&#160;&#160; tvOrdersCustomerID;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //Add&#160;&#160; summary&#160;&#160; items&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; with&#160;&#160; SummaryItems.Add&#160;&#160; as&#160;&#160; TcxGridDBTableSummaryItem&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Column&#160;&#160; :=&#160;&#160; tvOrdersPaymentAmount;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Kind&#160;&#160; :=&#160;&#160; skSum;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Format&#160;&#160; :=&#160;&#160; &#8216;Amount&#160;&#160; Paid:&#160;&#160; $,0&#8242;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; with&#160;&#160; SummaryItems.Add&#160;&#160; as&#160;&#160; TcxGridDBTableSummaryItem&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Column&#160;&#160; :=&#160;&#160; tvOrdersPaymentAmount;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Kind&#160;&#160; :=&#160;&#160; skCount;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Format&#160;&#160; :=&#160;&#160; &#8216;Records:&#160;&#160; 0&#8242;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //The&#160;&#160; second&#160;&#160; summary&#160;&#160; group&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; with&#160;&#160; SummaryGroups.Add&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //Add&#160;&#160; proposed&#160;&#160; grouping&#160;&#160; column(s)&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; TcxGridTableSummaryGroupItemLink(Links.Add).Column&#160;&#160; :=&#160;&#160; tvOrdersProductID;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; //Add&#160;&#160; summary&#160;&#160; items&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; with&#160;&#160; SummaryItems.Add&#160;&#160; as&#160;&#160; TcxGridDBTableSummaryItem&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Column&#160;&#160; :=&#160;&#160; tvOrdersQuantity;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Kind&#160;&#160; :=&#160;&#160; skSum;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Position&#160;&#160; :=&#160;&#160; spFooter;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Format&#160;&#160; :=&#160;&#160; &#8216;TOTAL&#160;&#160; =&#160;&#160; 0&#8242;;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; with&#160;&#160; SummaryItems.Add&#160;&#160; as&#160;&#160; TcxGridDBTableSummaryItem&#160;&#160; do&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Column&#160;&#160; :=&#160;&#160; tvOrdersPurchaseDate;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Kind&#160;&#160; :=&#160;&#160; skMin;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Position&#160;&#160; :=&#160;&#160; spFooter;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; finally&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; EndUpdate;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;&#160; </p>
<p>&#160;&#160;&#160;&#160;&#160; end;&#160;&#160;&#160; </p>
</blockquote>
<p> 2007-7-19 12:56:41&#160;&#160;&#160; go on</p>
<p>訂單號 商品名 單價 數量 金額</p>
<p>001 aa 11.00 2 22.00</p>
<p>001 bb 2.00 2 4.00</p>
<p>001 cc 3.00 3 9.00</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-合計 7 35.00</p>
<p>002 ee 11.00 2 22.00</p>
<p>002 bb 3.00 2 6.00</p>
<p>002 cc 3.00 3 9.00</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-合計 7 37.00</p>
<p>總計14 72.00</p>
<h5>每個單號分一個小結，能實現嗎？最後在底下實現總的合計</h5>
<p>可以的，cxGrid的功能比你想像的還要強大。</p>
<p>1.你先放一個cxGrid，設置好View，設置View.DataController連接的DataSource</p>
<p>2.啟動DataSource連接的DataSet，雙擊cxGrid，點擊Retrieve Fields，取得所有的Column</p>
<p>3.設置View的OptionsView.Footer=True，OptionsView.GroupFooters=True，這是為了把分組小計和總計面板顯示出來</p>
<p>4.將“訂單號”欄位拖到cxGrid上方的分組面板(GroupbyBox)，將資料按“訂單號”分組。這時你會發現單身所有的資料都縮起來了，如果想使所有的資料都展開，可以設置View.DataController.Options.dcoGroupsAlwaysExpanded=True</p>
<p>5.設置分組小計：把View.DataController.Summary.DefaultGroupSummaryItems點開，新增一個Item，Column屬性在下拉裏選擇“數量”欄位，FieldName屬性為空，Format屬性可以設置數值的顯示格式，Kind屬性下拉skSum加總，Position屬性一定要選擇spFooter。</p>
<p>6.設置總計：把View.DataController.Summary.FooterSummaryItems點開，新增一個Item，Column屬性在下拉裏選擇“數量”欄位，FieldName屬性為空，Format屬性可以設置數值的顯示格式，Kind屬性下拉skSum加總，Position屬性一定要選擇spFooter。</p>
<p>大功告成，按F9看一下勝利果實吧。</p>
<p>再奉送一個技巧，在Form1再放一個TcxGridPopupMenu控制項，就在cxGrid控制項旁邊的那個，把TcxGridPopupMenu的Grid屬性設置成你的cxGrid。</p>
<p>然後運行程式，在運行狀態，點擊Grid上的所有地方，左鍵或右鍵，你都會有意外收穫。</p>
<p>ExpressQuantumGrid控制項實在是太複雜，太龐大，最好的瞭解它的方法就是查幫助。</p>
<h5>cxGrid的多選我一般都是用這個方法：</h5>
<p>//&#8212;&#8212;&#8212;&#8212;&#8212; .Pas文件</p>
<blockquote><p>unit Unit1;</p>
<p>interface</p>
<p>uses</p>
<p><a href="http://www.newasp.cn/">Windows</a>, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,</p>
<p>Dialogs, cxStyles, cxCustomData, cxGraphics, cxFilter, cxData, cxEdit,</p>
<p>DB, cxDBData, DBTables, cxGridLevel, cxGridCustomTableView,</p>
<p>cxGridTableView, cxGridDBTableView, cxClasses, cxControls,</p>
<p>cxGridCustomView, cxGrid, cxLookAndFeelPainters, cxGridRows, cxContainer,</p>
<p>cxCheckBox, cxDataStorage;</p>
<p>type</p>
<p>TForm1 = class(TForm)</p>
<p>cxGrid1: TcxGrid;</p>
<p>cxGrid1DBTableView1: TcxGridDBTableView;</p>
<p>cxGrid1DBTableView1CustNo: TcxGridDBColumn;</p>
<p>cxGrid1DBTableView1Company: TcxGridDBColumn;</p>
<p>cxGrid1DBTableView1Addr1: TcxGridDBColumn;</p>
<p>cxGrid1DBTableView1City: TcxGridDBColumn;</p>
<p>cxGrid1DBTableView1State: TcxGridDBColumn;</p>
<p>cxGrid1DBTableView1Country: TcxGridDBColumn;</p>
<p>cxGrid1Level1: TcxGridLevel;</p>
<p>Table1: TTable;</p>
<p>DataSource1: TDataSource;</p>
<p>cxGrid1DBTableView1DBColumn1: TcxGridDBColumn;</p>
<p>procedure FormCreate(Sender: TObject);</p>
<p>procedure cxGrid1DBTableView1MouseDown(Sender: TObject;</p>
<p>Button: TMouseButton; Shift: TShiftState; X, Y: Integer);</p>
<p>procedure cxGrid1DBTableView1DBColumn1CustomDrawCell(</p>
<p>Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;</p>
<p>AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);</p>
<p>procedure FormClose(Sender: TObject; var Action: TCloseAction);</p>
<p>procedure cxGrid1DBTableView1CustomDrawCell(</p>
<p>Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;</p>
<p>AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);</p>
<p>private</p>
<p>AList: TList;</p>
<p>function CheckList(ARecord: TcxCustomGridRecord): Boolean;</p>
<p>{ Private declarations }</p>
<p>public</p>
<p>{ Public declarations }</p>
<p>end;</p>
<p>var</p>
<p>Form1: TForm1;</p>
<p>implementation</p>
<p>{$R *.dfm}</p>
<p>procedure TForm1.FormCreate(Sender: TObject);</p>
<p>begin</p>
<p>AList := TList.Create;</p>
<p>end;</p>
<p>function TForm1.CheckList(ARecord: TcxCustomGridRecord): Boolean;</p>
<p>begin</p>
<p>Result := AList.IndexOf(Pointer(ARecord.RecordIndex)) &lt;&gt; &#8211; 1;</p>
<p>end;</p>
<p>procedure TForm1.cxGrid1DBTableView1MouseDown(Sender: TObject;</p>
<p>Button: TMouseButton; Shift: TShiftState; X, Y: Integer);</p>
<p>var</p>
<p>AHitTest: TcxCustomGridHitTest;</p>
<p>AGridRecord: TcxCustomGridRecord;</p>
<p>begin</p>
<p>if Sender is TcxGridSite then</p>
<p>begin</p>
<p>with TcxGridSite(Sender).GridView do</p>
<p>AHitTest := ViewInfo.GetHitTest(X, Y);</p>
<p>if (AHitTest.HitTestCode = htCell) and (TcxGridDBColumn(TcxGridRecordCellHitTest (AhitTest). Item ). DataBinding . FieldName = ) then</p>
<p>AGridRecord := TcxGridRecordCellHitTest(AHitTest).GridRecord</p>
<p>else</p>
<p>Exit;</p>
<p>end;</p>
<p>if (AGridRecord &lt;&gt; nil) then</p>
<p>if CheckList(AGridRecord) then</p>
<p>AList.Remove(Pointer(AGridRecord.RecordIndex))</p>
<p>else</p>
<p>AList.Add(Pointer(AGridRecord.RecordIndex));</p>
<p>end;</p>
<p>procedure TForm1.cxGrid1DBTableView1DBColumn1CustomDrawCell(</p>
<p>Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;</p>
<p>AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);</p>
<p>begin</p>
<p>if AViewInfo.EditViewInfo is TcxCustomCheckBoxViewInfo then</p>
<p>TcxCustomCheckBoxViewInfo(AViewInfo.EditViewInfo).State:= TcxCheckBoxState(CheckList(AViewInfo.GridRecord));</p>
<p>end;</p>
<p>procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);</p>
<p>begin</p>
<p>AList.Free;</p>
<p>end;</p>
<p>procedure TForm1.cxGrid1DBTableView1CustomDrawCell(</p>
<p>Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;</p>
<p>AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);</p>
<p>begin</p>
<p>with AViewInfo do</p>
<p>if CheckList(GridRecord) then</p>
<p>ACanvas.Brush.Color := clHighlight</p>
<p>else</p>
<p>ACanvas.Brush.Color := clWindow;</p>
<p>ACanvas.Font.Color := clBlack;</p>
<p>end;</p>
<p>end.</p>
<p>//&#8212;&#8212;&#8212;&#8212;&#8212;cxGrid的Dfm屬性</p>
<p>object cxGrid1: TcxGrid</p>
<p>Left = 0</p>
<p>Top = 0</p>
<p>Width = 688</p>
<p>Height = 446</p>
<p>Align = alClient</p>
<p>TabOrder = 0</p>
<p>object cxGrid1DBTableView1: TcxGridDBTableView</p>
<p>OnMouseDown = cxGrid1DBTableView1MouseDown</p>
<p>NavigatorButtons.ConfirmDelete = False</p>
<p>OnCustomDrawCell = cxGrid1DBTableView1CustomDrawCell</p>
<p>DataController.DataSource = DataSource1</p>
<p>DataController.DetailKeyFieldNames = CustNo</p>
<p>DataController.KeyFieldNames = CustNo</p>
<p>DataController.Summary.DefaultGroupSummaryItems = &lt;&gt;</p>
<p>DataController.Summary.FooterSummaryItems = &lt;&gt;</p>
<p>DataController.Summary.SummaryGroups = &lt;&gt;</p>
<p>OptionsSelection.MultiSelect = True</p>
<p>object cxGrid1DBTableView1CustNo: TcxGridDBColumn</p>
<p>DataBinding.FieldName = CustNo</p>
<p>end</p>
<p>object cxGrid1DBTableView1DBColumn1: TcxGridDBColumn</p>
<p>Caption = CheckColumn</p>
<p>PropertiesClassName = TcxCheckBoxProperties</p>
<p>Properties.DisplayUnchecked = False</p>
<p>OnCustomDrawCell = cxGrid1DBTableView1DBColumn1CustomDrawCell</p>
<p>Options.Editing = False</p>
<p>Options.Filtering = False</p>
<p>Options.IncSearch = False</p>
<p>Options.ShowEditButtons = isebNever</p>
<p>Options.Grouping = False</p>
<p>Options.Sorting = False</p>
<p>Width = 123</p>
<p>end</p>
<p>object cxGrid1DBTableView1Company: TcxGridDBColumn</p>
<p>DataBinding.FieldName = Company</p>
<p>end</p>
<p>object cxGrid1DBTableView1Addr1: TcxGridDBColumn</p>
<p>DataBinding.FieldName = Addr1</p>
<p>end</p>
<p>object cxGrid1DBTableView1City: TcxGridDBColumn</p>
<p>DataBinding.FieldName = City</p>
<p>end</p>
<p>object cxGrid1DBTableView1State: TcxGridDBColumn</p>
<p>DataBinding.FieldName = State</p>
<p>end</p>
<p>object cxGrid1DBTableView1Country: TcxGridDBColumn</p>
<p>DataBinding.FieldName = Country</p>
<p>end</p>
<p>end</p>
<p>object cxGrid1Level1: TcxGridLevel</p>
<p>GridView = cxGrid1DBTableView1</p>
<p>end</p>
<p>end</p>
</blockquote>
<p>cyblueboy83 發表於 2005-12-9 11:30:45</p>
<p>學習</p>
<p>hanlin2004 發表於 2005-12-9 13:14:52</p>
<h5>我一般是這樣取cxGrid選中的紀錄的值的：</h5>
<blockquote><p>function TFrameAccount.GetSelectedID:variant;</p>
<p>var</p>
<p>AccID: array of string;</p>
<p>i, n: Integer;</p>
<p>Index: Integer;</p>
<p>begin</p>
<p>n := cxGrid1DBTableView1.DataController.GetSelectedCount;</p>
<p>for i:=0 to n &#8211; 1 do</p>
<p>begin</p>
<p>Index := cxGrid1DBTableView1.DataController.GetSelectedRowIndex(i);</p>
<p>setlength(AccID, length(AccID) + 1);</p>
<p>AccID[High(AccID)] :=cxGrid1DBTableView1.DataController.GetRowValue(cxGrid1DBTableView1.DataController.GetRowInfo(Index),0); //這裏的0是Grid中列的索引，0表示第一個列綁定的欄位</p>
<p>end;</p>
<p>result := AccID;</p>
<p>end;</p>
</blockquote>
<p>DevExpress cxGrid的應用</p>
<p>在cxGrid下建立view，取名myView</p>
<h5>1. 允許選擇多條記錄(MultiSelect)：</h5>
<blockquote><p>&#160;&#160; myView&#8211;OptionsSelection&#8211;MultiSelect 設成true</p>
</blockquote>
<h5>2. 取得選定行的值：</h5>
<blockquote><p>&#160;&#160; myView-&gt;DataController-&gt;FocusedRowIndex 獲得選擇行的行號</p>
<p>&#160;&#160; myView-&gt;DataController-&gt;Values[myView-&gt;DataController-&gt;FocusedRowIndex+1][0] 選擇的行的第一列的值</p>
<p>&#160;&#160; myView-&gt;DataController-&gt;GetSelectedCount() 選擇多行的行數</p>
<p>&#160;&#160; myView-&gt;DataController-&gt;GetSelectedRowIndex(行號n) 所選多行裏的第n行</p>
</blockquote>
<h5>3. VerticalGrid的單元值</h5>
<blockquote><p>控制項-&gt;Properties-&gt;Value 獲得單元的值，此值為variant類型，需要強制轉換成AnsiString</p>
</blockquote>
<h5>4. VerticalGrid裏的CheckGroup的使用</h5>
<p>得到的值為: (;1,3,8)此為選擇了選項裏的第1、3、8項</p>
<p>5. VerticalGrid裏驗證</p>
<p>&#160;&#160; TcxEditorRow的properties-&gt;EditorProperties選MaskEdit，然後再選下面的MaskEdit和MaskKind，可以限定輸入的東西</p>
<h5>6. TcxPopupEdit控制項的應用，Form1加一個控制項cxPopupEdit1</h5>
<p>屬性裏PopupControl指向你要彈出的表單Form2，Form2裏添加一個按鈕，說明文件裏添加</p>
<p><a href="http://cache.baidu.com/c?word=multiselect%2Ccxgrid&amp;url=http%3A//forum%2Enetec%2Ecom/###">[Copy to clipboard]</a> <a href="http://cache.baidu.com/c?word=multiselect%2Ccxgrid&amp;url=http%3A//forum%2Enetec%2Ecom/###">[ - ]</a></p>
<p>CODE:</p>
<blockquote><p>private:&#160;&#160;&#160;&#160;&#160;&#160;&#160; // User declarations</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; AnsiString FEditValue;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; TcxPopupEdit *FPopupEdit;</p>
<p>。。。</p>
<p>public:</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; __property AnsiString EditValue = {read=FEditValue,write=FEditValue};</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; __property TcxPopupEdit *PopupEdit = {read=FPopupEdit, write=FPopupEdit};</p>
</blockquote>
<p>在Form1的cxPopupEdit1控制項的事件裏添加下面的代碼</p>
<p><a href="http://cache.baidu.com/c?word=multiselect%2Ccxgrid&amp;url=http%3A//forum%2Enetec%2Ecom/###">[Copy to clipboard]</a> <a href="http://cache.baidu.com/c?word=multiselect%2Ccxgrid&amp;url=http%3A//forum%2Enetec%2Ecom/###">[ - ]</a></p>
<p>CODE:</p>
<p>//&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>void __fastcall TForm1::cxPopupEdit1PropertiesInitPopup(TObject *Sender)</p>
<p>{</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Form2-&gt;PopupEdit = (TcxPopupEdit*)Sender;</p>
<p>}</p>
<p>//&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>void __fastcall TForm1::cxPopupEdit1PropertiesCloseUp(TObject *Sender)</p>
<p>{</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; cxPopupEdit1-&gt;EditValue = Form2-&gt;EditValue;</p>
<p>}</p>
<p>在Form1的按鈕事件裏可以加入</p>
<p><a href="http://cache.baidu.com/c?word=multiselect%2Ccxgrid&amp;url=http%3A//forum%2Enetec%2Ecom/###">[Copy to clipboard]</a> <a href="http://cache.baidu.com/c?word=multiselect%2Ccxgrid&amp;url=http%3A//forum%2Enetec%2Ecom/###">[ - ]</a></p>
<p>CODE:</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; FEditValue = &quot;嘻嘻哈哈&quot;;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; FAccepted = AAccepted;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; FPopupEdit-&gt;DroppedDown = false;&#160; </p>
<p>//&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>7. TcxGrid控制項去掉上面的&quot;Drag a column header here to group by that column&quot;欄</p>
<p>在控制項的view的OptionsView屬性裏有一個GroupByBox，設為false即可</p>
<p>呵呵，寫的有些亂，自己試著做吧</p>
<h5>選擇了若干條記錄(MultiSelect)</h5>
<p>選擇了若干條記錄(MultiSelect),現在要把這些選中的記錄從該資料庫複製到另一庫中，該如何做？</p>
<p>可以參考。我的程式是列印選擇的記錄 ，</p>
<p>你可以保存到其他表就好。</p>
<blockquote><p>var i:integer;</p>
<p>begin</p>
<p>&#160; if cxview1.DataController.Controller.SelectedRecordCount&gt;0 then</p>
<p>&#160;&#160;&#160; with cxview1.DataController.DataSource.DataSet do</p>
<p>&#160;&#160;&#160; begin</p>
<p>&#160;&#160;&#160;&#160;&#160; global.BQ_ppp(』,3); //只進行資料清除</p>
<p>&#160;&#160;&#160;&#160;&#160; for i:=0 to cxview1.DataController.Controller.SelectedRecordCount-1 do</p>
<p>&#160;&#160;&#160;&#160;&#160; begin</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; GotoBookmark(Pointer(cxview1.DataController.GetSelectedBookmark(i)));</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; if Pos(&#8217;計&#8217;,fields[0].AsString)=0 then</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; begin</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if CheckBox2.Checked then</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; global.BQ_ppp(fields[0].AsString,0)//立即進行標籤列印，不把資料加到臨時資料庫。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; else</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; global.BQ_ppp(fields[0].AsString,1); //加入資料到臨時資料庫。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; end;</p>
<p>&#160;&#160;&#160;&#160;&#160; end;</p>
<p>&#160;&#160;&#160;&#160;&#160; if CheckBox2.Checked=false then //列印中的資料只是包含一種標籤。 不是多種標籤列印，集中列印臨時資料庫中的資料。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; global.BQ_ppp(』,2); //只進行標籤列印</p>
<p>&#160;&#160;&#160;&#160;&#160; Log_save(&#8217;標籤補打&#8217;,'標籤列印&#8217;);</p>
<p>&#160;&#160;&#160; end;</p>
<p>end;</p>
</blockquote>
<p>來自：<a href="http://www.delphibbs.com/delphibbs/dispu.asp?username=lihoulong">lihoulong</a>, 時間：2006-7-8 23:59:31, ID：3500034</p>
<blockquote><p>function CopyRecord(var recData: TArrayVariant): boolean;</p>
<p>var</p>
<p>&#160; i: integer;</p>
<p>begin</p>
<p>&#160; with FDataset do</p>
<p>&#160; begin</p>
<p>&#160;&#160;&#160; SetLength(recData, Fields.Count);</p>
<p>&#160;&#160;&#160; for i := 0 to Fields.Count &#8211; 1 do</p>
<p>&#160;&#160;&#160;&#160;&#160; recData[i] := Fields[i].Value;</p>
<p>&#160; end;</p>
<p>&#160; Result := true;</p>
<p>end;</p>
<p>function TwpQDTable.PasteRecord(</p>
<p>&#160; const RecData: array of Variant): boolean;</p>
<p>var</p>
<p>&#160; fcnt,</p>
<p>&#160;&#160;&#160; i: integer;</p>
<p>begin</p>
<p>&#160; with FDataset do</p>
<p>&#160; try</p>
<p>&#160;&#160;&#160; fcnt :=&#160; Length(RecData) &#8211; 1;</p>
<p>&#160;&#160;&#160; for i := 0 to fcnt do</p>
<p>&#160;&#160;&#160; begin</p>
<p>&#160;&#160;&#160;&#160;&#160; if FDataset.State in [dsBrowse] then</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Edit;</p>
<p>&#160;&#160;&#160;&#160;&#160; Fields[i].Value := RecData[i];</p>
<p>&#160;&#160;&#160; end;</p>
<p>&#160;&#160;&#160; Result := true;</p>
<p>&#160; except</p>
<p>&#160;&#160;&#160; Result := false;</p>
<p>&#160; end;</p>
<p>end;</p>
</blockquote>
<p>定義一個記錄陣列</p>
<blockquote><p>for i := 0 to cxgrid.SelectedCount-1 do&#160; begin</p>
<p>依據關鍵字定位資料集,再執行CopyRecord</p>
<p>end;</p>
<p>在粘貼的地方用pasteRecord</p>
</blockquote>
<h5>cxGrid的使用方法</h5>
<p>1.&#160; 去掉cxgrid中台頭的box ,在tableview1的ptionsview的groupbybox=false;</p>
<p>2.&#160; 在GRID footer 中加入sum(列), tableview1的optionsviewàfooter=ture</p>
<p>然後在cxGRid1的customize..中的summary 的footer.add需要合計的列kind= skSum</p>
<p>3.&#160; 去掉cxgrid 中的過濾下拉箭頭 選擇tableview1.optionscustomize.columnfiltering=fasle;</p>
<p>4.&#160;&#160; cxGrid1DBTableView1 的 OptionView中屬性GroupFooters設為gfAlwaysVisible並設置需要求和的列,在summary.default for Groups 下add加入需要合計的欄位,column下顯示fieldname 為統計欄位,format為格式,kind為統計方法,position 為位子 spfooter 在分組的下面,spgroup 在分組的上面</p>
<p>或用cxGridPopupMenu1,在運行時可對任意數字類型列求和,方法是只需設置cxGridPopupMenu1的屬性Grid為cxGrid1DBTableView1的cxGrid,</p>
<p>即可實現您所需功能</p>
<p>5.&#160; DEV Express裏的cxGrid默認的數值格式帶￥，怎么去掉啊！</p>
<p>6.&#160; 雙擊Cxgrid，選擇colmnum改變類型 options.properties.Memo</p>
<p>7.&#160; 在displayformat中進行設置</p>
<p>來源於大富翁論壇</p>
<p>使用cxGrid有一些時間了，在這裏總結一下使用cxGrid的一些方法，希望給剛開始接觸cxGrid的人一些幫助。</p>
<p>1.簡單介紹：cxGrid右下方的cxGrid1Level1是表示Grid表的層，cxGrid可以有多層，這相當於集合了PageControl的</p>
<p>功能,而cxGrid1Level1右邊的cxGrid1DBTableView1相當於DBGrid一樣。右擊cxGrid1可以添加cxGrid1Level2，右擊</p>
<p>cxGrid1Level2，可以選擇Create View , Add level 或者Delete Level。Add level可以增加子Level，Create View</p>
<p>裏面可以選擇很多不同總類的View。其中</p>
<p>&#160; 1)DB Table可以和資料庫連接的View，更一般的DBGrid類似，它比DBGrid多了比如滑鼠中鍵可以用，可以統計，</p>
<p>查詢，等等功能；</p>
<p>&#160; 2)DB Banded Table 則可以實現比如：</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; |&#160;&#160;&#160;&#160; 說明1&#160;&#160;&#160;&#160; |&#160;&#160;&#160;&#160; 說明2&#160;&#160;&#160;&#160; |</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; | 欄位1 | 欄位2 | 欄位3 | 欄位4 |</p>
<p>等類似的功能；</p>
<p>&#160; 3)DB Card View 則提供了卡片方式的顯示資料的功能，這個用在比如人事檔案管理比較不錯；</p>
<p>&#160; 4)其他不一一贅述。</p>
<p>2.一些使用方法：</p>
<p>&#160; 1)有圖片和MEMO的例子：</p>
<p>拖入一個cxGrid1，Table1，DataSource1。 Table1的DatabaseName設為DBDEMOS，TableName設為biolife.db，</p>
<p>&#160;&#160; Active設為True;DataSource1的DataSet設為Table1；cxGrid1DBTableView1的DataController中的DataSource&#160; </p>
<p>設為DataSource1;右擊cxGrid1DBTableView1選擇Create All Columns；雙擊cxGrid1，在彈出的窗口中找到</p>
<p>&#160; cxGrid1DBTableView1Notes和cxGrid1DBTableView1Graphic，將它們的Properties屬性設為BlobEdit；運行看看</p>
<p>結果。再將cxGrid1DBTableView1Graphic的Properties屬性設為Image，再將Properties下的Stretch設為True，</p>
<p>將cxGrid1DBTableView1-&gt;optionsview-&gt;CellAutoHeight 設為True，看看結果。</p>
<p>&#160; 2)如何讓“Drag a column here to group by that column”不顯示</p>
<p>解決：點擊cxGrid1上的cxGrid1DBTableView1</p>
<p>在cxGrid1DBTableView1-&gt;optionsview-&gt;groupbybox:=false即可</p>
<p>注：OptionsView裏面有很多屬性可能經常要用，比如：ColumnAutoWith,Navigator等等，慢慢琢磨吧:)</p>
<p>&#160; 3)GroupPanel上面的英文[Drag a column header to group by that column]怎么可以改成中文？</p>
<p>解決：最簡單的方法是 TcxGridTableView.OnCustomDrawPartBackground ，也可用 OnCustomDrawGroupCell：</p>
<p>&#160;&#160;&#160; procedure TForm1.cxGrid1DBTableView1CustomDrawPartBackground(</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Sender: TcxGridTableView; ACanvas: TcxCanvas;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AViewInfo: TcxCustomGridCellViewInfo; var ADone: Boolean);</p>
<p>&#160;&#160;&#160; begin</p>
<p>&#160;&#160;&#160;&#160;&#160; AViewInfo.Text:=&#8217;動態設置 GroupBox 的顯示內容&#8217;;</p>
<p>&#160;&#160;&#160;&#160;&#160; ACanvas.FillRect(AViewInfo.Bounds);</p>
<p>&#160;&#160;&#160; end;</p>
<p>&#160; 4)如何實現如下功能：</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +財務部</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +原材料倉庫</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +成品庫</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +衝壓車間</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +軟體發展部</p>
<p>這個是部門的名稱,點擊加號就可以將本部門的人員情況顯示出來。</p>
<p>解決：其實這是一個主從表關係，1：填好主表的keyfieldnames</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2：填好從表的keyfieldnames</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 3：填好從表的 detaikeyfieldNames與masterkeyfieldnames</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 4: 從表的資料源一定要按與主表關聯的欄位排序</p>
<p>注：其他地方設置了主從表結構那樣就顯示不出來，比如設置了從表的Table或者Query的mastersource和</p>
<p>&#160;&#160; asterfield就會不能顯示資料！如果是兩個cxGrid的主從關係，這樣設置就很OK了。</p>
<p> 5)統計功能</p>
<p>解決：cxGrid1DBTableView1-&gt;optionsview-&gt;Footer 設為True</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; cxGrid1DBTableView1-&gt;DataController-&gt;Summary設置FooterSummaryItems即可</p>
<p> 6)類似PageControl顯示</p>
<p>解決：增加一個Level,將cxGrid1-&gt;RootLevelOptions-&gt;DetailTabsPosition設為dtpTop，然後相應的設置cxGrid1Level1,和cxGrid1Level2的Caption值。</p>
<p>未完待續。。。。。。。。。</p>
<p>7)如何設定左邊幾列，不能滾動?</p>
<p>解決：使用DB Banded Table才可以實現，</p>
<p>在cxGrid1DBBandedTableView裏建立Band0,Band1</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Band0的Fixed=tfLeft</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Band1的Fixed=tfnone</p>
<p>設置要鎖定的欄位的BandIndex=0,其他為1，就OK了。</p>
<p> 8)怎樣實現如EXCEL一樣的，當前格=G14+G15+G16 這樣的功能</p>
<p>解決：舉一個簡單的例子：label1.Caption := cxGrid1DBTableView1.DataController.Values[2,</p>
<p>3]+cxGrid1DBTableView2.DataController.Values[1, 1]+cxGrid1DBTableView3.DataController.Values[1, 1];</p>
<p>所以不同cxGrid1DBTableView中的資料都可以給當前格，這樣就做到了EXCEL中的當前格=G14+G15+G16 類似的功能。</p>
<p> 9)滑鼠右擊cxGrid1DBBandedTableView1功能表裏的Edit Layout什么用，怎么使用？</p>
<p>解決：可以拖動欄位，並列的可以拖成有層次感（一層層）， 拖動時會顯示箭頭的，就是說可以拖一個欄位放</p>
<p>到最上面，就可以使記錄按此欄位進行分組。點擊其中一個欄位，上面還會出現一個上升或者下降的小三角形，這個</p>
<p>小三角形的作用是在運行階段，資料就會按照這個欄位上升或者下降排序。</p>
<p>還有一個Set as Default的作用是保持當前TableView的參數，下此產生新的TableView的時候就會可以和上次保持的參數一樣。這個還沒有做過試驗。</p>
<p>10）怎樣將cxGrid裏的數據導入到EXCEL，HTML，XML和TEXT</p>
<p>解決：這個問題在用了cxGrid以後變得異常簡單，</p>
<blockquote><p>uses</p>
<p> cxExportGrid4Link;</p>
<p>procedure TForm1.Button1Click(Sender: TObject);</p>
<p>begin</p>
<p> ExportGrid4ToEXCEL(&#8217;d:\wang.xsl&#8217;,cxGrid1,True,True);</p>
<p> ExportGrid4ToTEXT(&#8217;d:\wang.txt&#8217;,cxGrid1,True,True);</p>
<p> ExportGrid4ToXML(&#8217;d:\wang.xml&#8217;,cxGrid1,True,True);</p>
<p> ExportGrid4ToHTML(&#8217;d:\wang.html&#8217;,cxGrid1,True,True);</p>
<p>end;</p>
</blockquote>
<p>11)如何使滿足條件的資料顯示不同的顏色？</p>
<p>解決：</p>
<blockquote><p>var</p>
<p>AYellowStyle: TcxStyle;</p>
<p>procedure TForm1.FormCreate(Sender: TObject);</p>
<p>begin</p>
<p> //行顏色</p>
<p>AYellowStyle := TcxStyle.Create(Self);</p>
<p>AYellowStyle.Color := $0080FFFF;</p>
<p>AYellowStyle.TextColor := clMaroon;</p>
<p>end;</p>
<p>procedure TForm1.cxGrid1DBBandedTableView1StylesGetContentStyle(</p>
<p>Sender: TcxCustomGridTableView; ARecord: TcxCustomGridRecord;</p>
<p>AItem: TcxCustomGridTableItem; out AStyle: TcxStyle);</p>
<p>begin</p>
<p>if ARecord.Values[cxGrid1DBBandedTableView1Lengthcm.Index] &lt; 81 then</p>
<p>&#160; AStyle := AYellowStyle;</p>
<p>end;</p>
</blockquote>
<p>這裏cxGrid1DBBandedTableView1Lengthcm.Index小於81時就顯示黃色</p>
<p>12）如何從外邊的TXT文件導入到cxGrid？</p>
<blockquote><p>解決：&#160;&#160;&#160; procedure CustomizeColumns;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; procedure LoadData;</p>
<p>procedure TForm1.CustomizeColumns;</p>
<p>const</p>
<p> cDistance = 1;</p>
<p> cRadius = 5;</p>
<p> cPeriod = 4;</p>
<p> cPstring = 0;</p>
<p>var</p>
<p> I: Integer;</p>
<p>begin</p>
<p> DecimalSeparator := &#8216;.&#8217;;</p>
<p> with cxGrid1TableView2 do</p>
<p> for I := 0 to ColumnCount &#8211; 1 do</p>
<p>&#160;&#160; if I in [cDistance, cRadius] then</p>
<p>&#160;&#160;&#160;&#160; Columns[I].DataBinding.ValueTypeClass := TcxIntegerValueType//1，5列為Integer</p>
<p>&#160;&#160; else</p>
<p>&#160;&#160;&#160;&#160; if I in [cPstring,cPeriod] then</p>
<p>&#160;&#160;&#160;&#160; Columns[I].DataBinding.ValueTypeClass := TcxStringValueType//0，4列為String</p>
<p>&#160;&#160;&#160;&#160; else</p>
<p>&#160;&#160;&#160;&#160;&#160; Columns[I].DataBinding.ValueTypeClass := TcxFloatValueType;//其他為Float</p>
<p>end;</p>
<p>procedure TForm1.LoadData;</p>
<p>const</p>
<p> AFileName = &#8216;資產負債表.txt&#8217;;</p>
<p> AHeaderLineCount = 2;</p>
<p>var</p>
<p> ARecords, AValues: TStringList;</p>
<p> I: Integer;</p>
<p> procedure InitRecord(const Str: string);</p>
<p> var</p>
<p>&#160;&#160; J: Integer;</p>
<p>&#160;&#160; V: Variant;</p>
<p> begin</p>
<p>&#160;&#160; AValues.CommaText := Str;</p>
<p>&#160;&#160; for J := 0 to AValues.Count &#8211; 1 do</p>
<p>&#160;&#160;&#160; if AValues.Strings[J] &lt;&gt; &#8216;-&#8217; then</p>
<p>&#160;&#160;&#160; begin</p>
<p>&#160;&#160;&#160;&#160; V := AValues.Strings[J];</p>
<p>&#160;&#160;&#160;&#160; if not VarIsNull(V) then</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160; cxGrid1TableView2.DataController.Values[I, J] := V;</p>
<p>&#160;&#160;&#160; end;</p>
<p> end;</p>
<p>begin</p>
<p> if not FileExists(AFileName) then</p>
<p>&#160;&#160; raise Exception.Create(&#8217;Data file not found&#8217;);</p>
<p> ARecords := TStringList.Create;</p>
<p> AValues := TStringList.Create;</p>
<p> with ARecords do</p>
<p> try</p>
<p>&#160;&#160; LoadFromFile(AFileName);</p>
<p>&#160;&#160; cxGrid1TableView2.BeginUpdate;</p>
<p>&#160;&#160; cxGrid1TableView2.DataController.RecordCount := Count &#8211; AHeaderLineCount;</p>
<p>&#160;&#160; for I := 0 to Count &#8211; (AHeaderLineCount + 1) do</p>
<p>&#160;&#160;&#160;&#160; InitRecord(Strings[I + AHeaderLineCount]);</p>
<p> finally</p>
<p>&#160;&#160; cxGrid1TableView2.EndUpdate;</p>
<p>&#160;&#160; ARecords.Free;</p>
<p>&#160;&#160; AValues.Free;</p>
<p> end;</p>
<p>end;</p>
<p>procedure TForm1.FormCreate(Sender: TObject);</p>
<p>begin</p>
<p> CustomizeColumns;</p>
<p> LoadData_Zcfz;</p>
<p>end;</p>
<p>13）如何改變列的顏色？</p>
<p>var</p>
<p> AFirstColumnStyle: TcxStyle;</p>
<p>procedure TForm1.FormCreate(Sender: TObject);</p>
<p>begin</p>
<p> //列顏色</p>
<p> AFirstColumnStyle := TcxStyle.Create(Self);</p>
<p> AFirstColumnStyle.Color := clAqua;</p>
<p> AFirstColumnStyle.TextColor := clBlue;</p>
<p> cxGrid1TableView1.Columns[1].Styles.Content := AFirstColumnStyle;</p>
<p>end;</p>
</blockquote>
<p>14）Set as default的用法？</p>
<p>解決：Set as default的用法是為了解決設置參數的方便而做的，比如：</p>
<p>連好資料庫以後，更改cxGrid1DBBandedTableView1-&gt;OptionsCustomize-&gt;ColumnFiltering 設為False。（這個設置可以將欄位名的下拉單給去掉）更改cxGrid1DBBandedTableView1-&gt;OptionsView-&gt;Navigator 設置為True。然後右擊cxGrid1DBBandedTableView1，在彈出的菜單欄裏麵點擊Set as default。</p>
<p>&#160; OK，下次你再產生一個新的cxGrid1DBBandedTableView1時這些設置和剛才的一樣了。如果需要設置的參數很多的時候，這個Set as default很有用！</p>
<p>15）怎樣使滑鼠移動時，相應的單元裏的文字變色？</p>
<p>解決：</p>
<blockquote><p>var</p>
<p> FTrackItem: TcxCustomGridTableItem;</p>
<p> FTrackRec: TcxCustomGridRecord;</p>
<p>procedure TForm1.cxGrid1DBTableView1CustomDrawCell(</p>
<p> Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;</p>
<p> AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);</p>
<p>begin</p>
<p> if (AViewInfo.GridRecord = FTrackRec) and (AViewInfo.Item = FTrackItem) then</p>
<p> begin</p>
<p>&#160;&#160; ACanvas.Font.Color := clred;&#160;&#160; //紅色字體</p>
<p>&#160;&#160; ACanvas.Font.Style := [fsUnderline];//帶下劃線</p>
<p> end;</p>
<p>end;</p>
<p>procedure TForm1.cxGrid1DBTableView1MouseMove(Sender: TObject;</p>
<p> Shift: TShiftState; X, Y: Integer);</p>
<p>var</p>
<p> AHitTest: TcxCustomGridHitTest;</p>
<p> ATrackItem: TcxCustomGridTableItem;</p>
<p> ATrackRec: TcxCustomGridRecord;</p>
<p>begin</p>
<p> ATrackItem := FTrackItem;</p>
<p> ATrackRec := FTrackRec;</p>
<p> AHitTest := (Sender as TcxGridSite).GridView.ViewInfo.GetHitTest(X, Y);</p>
<p> if AHitTest is TcxGridRecordCellHitTest then</p>
<p> begin</p>
<p>&#160;&#160; FTrackItem := TcxGridRecordCellHitTest(AHitTest).Item;</p>
<p>&#160;&#160; FTrackRec := TcxGridRecordCellHitTest(AHitTest).GridRecord;</p>
<p> end</p>
<p> else</p>
<p> begin</p>
<p>&#160;&#160; FTrackItem := nil;</p>
<p>&#160;&#160; FTrackRec := nil;</p>
<p> end;</p>
<p> if (ATrackItem &lt;&gt; FTrackItem) or (ATrackRec &lt;&gt; FTrackRec) then</p>
<p> begin</p>
<p>&#160;&#160; // Invalidate old cell</p>
<p>&#160;&#160; if ATrackRec &lt;&gt; nil then</p>
<p>&#160;&#160;&#160;&#160; ATrackRec.Invalidate(ATrackItem);</p>
<p>&#160;&#160; // Invalidate new cell</p>
<p>&#160;&#160; if FTrackRec &lt;&gt; nil then</p>
<p>&#160;&#160;&#160;&#160; FTrackRec.Invalidate(FTrackItem);</p>
<p> end;</p>
<p>end;</p>
</blockquote>
<p>16)ExpressQuantumGrid 3.2.2中的dxdbgrid和4.2版本中的cxgrid有什么區別?</p>
<p>有很大的區別，基本上相當於是兩個控制項一樣。</p>
<p>cxgrid是在dxdbgrid基礎上完全重寫的，所以cxgrid不支持dxdbgrid</p>
<p>所以cxgrid裏面特意提供了一個將dxdbgrid導入到cxgrid的功能。</p>
<p>17）怎樣設計多表頭的cxGrid？</p>
<p>解決：cxGrid可以解決如下的表頭：</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; |&#160;&#160;&#160;&#160; 說明1&#160;&#160;&#160;&#160; |&#160;&#160;&#160;&#160; 說明2&#160;&#160;&#160;&#160; |</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; | 欄位1 | 欄位2 | 欄位3 | 欄位4 |</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; |&#160;&#160;&#160;&#160;&#160; 欄位5&#160;&#160;&#160; |&#160;&#160;&#160;&#160; 欄位6&#160;&#160;&#160;&#160; |</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; |&#160;&#160;&#160;&#160;&#160; 欄位7&#160;&#160;&#160; | 欄位8 | 欄位9 |</p>
<p>實現這個很簡單，你可以直接在上面拖動欄位名，拖動時會顯示箭頭的，放入你想顯示的位置就OK了。或者在滑鼠右擊cxGrid1DBBandedTableView1功能表裏的Edit Layout裏也可以拖放。</p>
<p>但是cxGrid不能實現如下的多表頭形式：</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; |&#160;&#160;&#160;&#160; 說明1&#160;&#160;&#160;&#160; |&#160;&#160;&#160;&#160; 說明2&#160;&#160;&#160;&#160; |</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; | 說明3 | 說明4 | 說明5 | 說明6 |</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; |&#160;&#160;&#160;&#160;&#160; 欄位1&#160;&#160;&#160; |&#160;&#160;&#160;&#160; 欄位2&#160;&#160;&#160;&#160; |</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; |&#160;&#160;&#160;&#160;&#160; 欄位3&#160;&#160;&#160; | 欄位4 | 欄位5 |</p>
<p>不知道有誰能實現這樣的多表頭？</p>
<p>18）在主從表結構時，當點開“+”時怎樣將焦點聚在相應主表的記錄上？</p>
<p>解決：</p>
<blockquote><p>var</p>
<p> HitTest: TcxCustomGridHitTest;</p>
<p>procedure TColumnsShareDemoMainForm.tvProjectsMouseDown(Sender: TObject;</p>
<p> Button: TMouseButton; Shift: TShiftState; X, Y: Integer);</p>
<p>begin</p>
<p> // Note that the Sender parameter is a Site</p>
<p> HitTest := (Sender as TcxGridSite).GridView.ViewInfo.GetHitTest(X, Y);</p>
<p> // The point belongs to the [+]/[-] button area</p>
<p> if HitTest is TcxGridExpandButtonHitTest then</p>
<p>&#160;&#160; // Move focus to the record</p>
<p>&#160;&#160; TcxGridExpandButtonHitTest(HitTest).GridRecord.Focused := True;</p>
<p>end;</p>
</blockquote>
<p>19)CXGrid4如何展開全部節點</p>
<blockquote><p>解決：GridDBTableView1.DataController.Groups.FullExpand;</p>
</blockquote>
<p> 2003-12-12 17:07:30&#160;&#160;&#160; 問題20</p>
<p>20）cxGrid如何動態創建Items的Editor的項?</p>
<p>&#160;&#160; cxGrid的列有一個屬性,它的編輯框可以指定combobox,spinedit等.在設計時,可以為</p>
<p>&#160;&#160; combobox的items添加項目.請問是否可以動態創建?(run-time時由程式加入)</p>
<p>解決：</p>
<blockquote><p>var</p>
<p>&#160; A:TDataSource:</p>
<p>&#160; B:TcxlookupcomboboxProperties;</p>
<p>&#160;&#160;&#160;&#160;&#160; begin</p>
<p>&#160; A:=TDataSource.create(self);</p>
<p>&#160; B:=tcxlookupcomboboxproperties.create(self);</p>
<p>&#160; A.Dataset:=Dic_ry_xb;//此處指定數據源。</p>
<p>&#160; b.listdource:=a;//此處指明欄位的listsource屬性。</p>
<p>&#160; b.keyfieldnames:=&#8217;a';&#160;&#160;&#160; //此處指明欄位的關鍵字段</p>
<p>&#160; b.listfieldnames:=&#8217;b';&#160;&#160; //此處指明欄位的返回值。</p>
<p>&#160; b.listcolumns.items[0].caption:=&#8217;x;&#160; //此處默認是會建立一個欄位，但是顯示的表頭是name，所以此處讓它顯示為自己想要的中午顯示。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; cxGrid1DBTableView1c1_sex_code.Properties:=b;&#160; //此處指明是那個欄位。</p>
<p>end;&#160; //這個是初始化的代碼，</p>
</blockquote>
<p> 2004-1-7 14:05:14&#160;&#160;&#160; 問題21</p>
<p>21）ExpressQuantumGrid4.5的漢化包</p>
<p>在這裏可以下載ExpressQuantumGrid4.5的漢化包，將檔直接覆蓋到原始檔案就可以了。</p>
<h5>如何在dxMemData1或cxGrid1中動態添加欄位？</h5>
<blockquote><p>Procedure TcxGridDBTableView.CreateDefaultColumn;&#160;&#160;&#160;&#160;&#160; //建立默認的列&#160; //Add By Pgt</p>
<p>Var</p>
<p>&#160; CxColumn:TcxGridDBColumn;</p>
<p>&#160; FootItem:TcxDataSummaryItem;</p>
<p>&#160; i:Integer;</p>
<p>&#160; OldAutoWidth:Boolean;</p>
<p>Begin</p>
<p>&#160; If Assigned(DataController.DataSource) And</p>
<p>&#160;&#160;&#160;&#160; Assigned(DataController.DataSource.DataSet) And</p>
<p>&#160;&#160;&#160;&#160; DataController.DataSource.DataSet.Active Then Begin</p>
<p>&#160;&#160;&#160;&#160; With DataController.DataSource.DataSet Do Begin</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160; While ColumnCount&gt;0 Do</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Columns[0].Free ;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160; For i:=0 to FieldCount -1 Do Begin</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; If (Fields[i].DataType&lt;&gt;ftAutoInc) And (UpperCase(Fields[i].FullName)&lt;&gt;&#8217;ID&#8217;) Then Begin</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CxColumn:=Self.CreateColumn ;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CxColumn.DataBinding.FieldName := Fields[i].FullName ;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CxColumn.HeaderAlignmentHorz := taCenter ;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CxColumn.HeaderAlignmentVert := VaCenter ;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; If CxColumn.Width &gt;150 Then CxColumn.Width := 150 ;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; If i=0 Then Begin</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FootItem := DataController.Summary.FooterSummaryItems.Add ;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FootItem.ItemLink :=CxColumn ;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FootItem.Format := &#8216;共0條&#8217;;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FootItem.Kind := skCount ;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; End Else Begin</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; If (Fields[i].DataType = ftFloat) And (Pos(&#8217;價&#8217;,Fields[i].FullName)=0) Then Begin</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FootItem := DataController.Summary.FooterSummaryItems.Add ;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FootItem.ItemLink :=CxColumn ;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; If Pos(&#8217;數量&#8217;,Fields[i].FullName)&lt;&gt;0 Then</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FootItem.Format := &#8216;,0;-,0&#8242;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Else Begin</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FootItem.Format := &#8216;,0.00;-,0.00&#8242; ; // &#8216;￥,0.00;-￥,0.00&#8242;;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; If CxColumn.Width&lt;80 Then CxColumn.Width := 80 ;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; End;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FootItem.DisplayName := Fields[i].FullName ;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FootItem.Kind := skSum ;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; End;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; End;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; End;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160; End;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160; OldAutoWidth := Self.OptionsView.ColumnAutoWidth ;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160; Self.OptionsView.ColumnAutoWidth := True ;</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160; Self.OptionsView.ColumnAutoWidth := OldAutoWidth ;</p>
<p>&#160;&#160;&#160;&#160; End;</p>
<p>&#160; End;</p>
<p>End;</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.infinity.idv.tw/index.php/2011/06/02/delphi-cxgrid%e7%9a%84%e4%bd%bf%e7%94%a8%e6%96%b9%e6%b3%95/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Delphi 下讓使用者選擇目錄方式:</title>
		<link>http://blog.infinity.idv.tw/index.php/2011/03/17/delphi-%e4%b8%8b%e8%ae%93%e4%bd%bf%e7%94%a8%e8%80%85%e9%81%b8%e6%93%87%e7%9b%ae%e9%8c%84%e6%96%b9%e5%bc%8f/</link>
		<comments>http://blog.infinity.idv.tw/index.php/2011/03/17/delphi-%e4%b8%8b%e8%ae%93%e4%bd%bf%e7%94%a8%e8%80%85%e9%81%b8%e6%93%87%e7%9b%ae%e9%8c%84%e6%96%b9%e5%bc%8f/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 03:05:55 +0000</pubDate>
		<dc:creator>Roger Lin</dc:creator>
				<category><![CDATA[DELPHI]]></category>
		<category><![CDATA[delphi 目錄 選擇]]></category>

		<guid isPermaLink="false">http://blog.infinity.idv.tw/index.php/2011/03/17/delphi-%e4%b8%8b%e8%ae%93%e4%bd%bf%e7%94%a8%e8%80%85%e9%81%b8%e6%93%87%e7%9b%ae%e9%8c%84%e6%96%b9%e5%bc%8f/</guid>
		<description><![CDATA[<p>Delphi 下讓使用者選擇目錄方式:</p>
<p>OpenDialog 元件是讓使用者選檔案,那選目錄要使用什麼方式呢?</p>
<p>USE QDialogs</p>
<p>procedure TForm1.cxButton1Click(Sender: TObject);   var    &#160; Dir: WideString;    begin    &#160; if SelectDirectory(&#8217;請選擇目錄&#8217;, 』, Dir) then    &#160; begin    &#160;&#160;&#160; ShowMessage(Dir);    &#160; end;    end;</p>
<p>SelectDirectory(&#8217;請選擇目錄&#8217;, 』, Dir)</p>
<p>第一個參數為提示文字,第二個參數可設定預設目錄,第三個參數為使用者選取目錄後的目錄路徑</p>
<p>可對SelectDirectory按F1查詢使用方式,還有VCL的用法可用,代的參數又不一樣,有興趣的可研究一下。</p>
]]></description>
			<content:encoded><![CDATA[<p>Delphi 下讓使用者選擇目錄方式:</p>
<p>OpenDialog 元件是讓使用者選檔案,那選目錄要使用什麼方式呢?</p>
<p>USE QDialogs</p>
<p>procedure TForm1.cxButton1Click(Sender: TObject);   <br />var    <br />&#160; Dir: WideString;    <br />begin    <br />&#160; if SelectDirectory(&#8217;請選擇目錄&#8217;, 』, Dir) then    <br />&#160; begin    <br />&#160;&#160;&#160; ShowMessage(Dir);    <br />&#160; end;    <br />end;</p>
<p>SelectDirectory(&#8217;請選擇目錄&#8217;, 』, Dir)</p>
<p>第一個參數為提示文字,第二個參數可設定預設目錄,第三個參數為使用者選取目錄後的目錄路徑</p>
<p>可對SelectDirectory按F1查詢使用方式,還有VCL的用法可用,代的參數又不一樣,有興趣的可研究一下。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.infinity.idv.tw/index.php/2011/03/17/delphi-%e4%b8%8b%e8%ae%93%e4%bd%bf%e7%94%a8%e8%80%85%e9%81%b8%e6%93%87%e7%9b%ae%e9%8c%84%e6%96%b9%e5%bc%8f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DELPHI 7 使用ADO元件寫入資料庫強制四捨五入小數到第四位問題</title>
		<link>http://blog.infinity.idv.tw/index.php/2010/12/09/delphi-7-%e4%bd%bf%e7%94%a8ado%e5%85%83%e4%bb%b6%e5%af%ab%e5%85%a5%e8%b3%87%e6%96%99%e5%ba%ab%e5%bc%b7%e5%88%b6%e5%9b%9b%e6%8d%a8%e4%ba%94%e5%85%a5%e5%b0%8f%e6%95%b8%e5%88%b0%e7%ac%ac%e5%9b%9b/</link>
		<comments>http://blog.infinity.idv.tw/index.php/2010/12/09/delphi-7-%e4%bd%bf%e7%94%a8ado%e5%85%83%e4%bb%b6%e5%af%ab%e5%85%a5%e8%b3%87%e6%96%99%e5%ba%ab%e5%bc%b7%e5%88%b6%e5%9b%9b%e6%8d%a8%e4%ba%94%e5%85%a5%e5%b0%8f%e6%95%b8%e5%88%b0%e7%ac%ac%e5%9b%9b/#comments</comments>
		<pubDate>Thu, 09 Dec 2010 10:14:16 +0000</pubDate>
		<dc:creator>Roger Lin</dc:creator>
				<category><![CDATA[DELPHI]]></category>
		<category><![CDATA[資料庫]]></category>
		<category><![CDATA[ADO 小數 第四位 四捨五入]]></category>

		<guid isPermaLink="false">http://blog.infinity.idv.tw/index.php/2010/12/09/delphi-7-%e4%bd%bf%e7%94%a8ado%e5%85%83%e4%bb%b6%e5%af%ab%e5%85%a5%e8%b3%87%e6%96%99%e5%ba%ab%e5%bc%b7%e5%88%b6%e5%9b%9b%e6%8d%a8%e4%ba%94%e5%85%a5%e5%b0%8f%e6%95%b8%e5%88%b0%e7%ac%ac%e5%9b%9b/</guid>
		<description><![CDATA[<p>DELPHI 7 使用ADO元件寫入資料庫強制四捨五入小數到第四位問題</p>
<p>parameters.parambyname(&#8217;tmpprice&#8217;).datatype：=ftFloat;&#160;&#160; &#60;==寫入資料前先將欄位設定成 Float 型態即可解決此問題。</p>
<p>參考:http://jzinfo.javaeye.com/blog/432853</p>

var&#160;&#160; 
&#160;&#160;&#160; adoquery1:Tadoquery;&#160;&#160; 
begin&#160;&#160; 
&#160;&#160;&#160; adoquery1:=Tadoquery.create(nil);&#160;&#160; 
&#160;&#160;&#160; try&#160;&#160; 
&#160;&#160;&#160;&#160;&#160;&#160; if not DM.adonconnection1.connected then&#160;&#160; 
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DM.adoconnection1.connected:=true;&#160;&#160; 
&#160;&#160;&#160;&#160;&#160;&#160; adoquery1.connection:=DM.adoconnection1;&#160;&#160; 
&#160;&#160;&#160;&#160;&#160;&#160; adoquery1.enableBCD:=False;&#160;&#160;&#160;&#160;&#160;&#160; //禁用bcd类型&#160;&#160; 
&#160;&#160;&#160;&#160;&#160;&#160; with adoquery1 do&#160;&#160; 
&#160;&#160;&#160;&#160;&#160;&#160; begin&#160;&#160; 
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; close;&#160;&#160; 
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sql.clear;&#160;&#160; 
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sql.add(&#8217;insert into materialInfo values(:tmppno,:tmpvendor,:tmpdesc,:tmpprice)&#8217;);&#160;&#160; 
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; parameters.parambyname(&#8217;tmppno&#8217;).value:=trim(edit1.text);&#160;&#160; 
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; parameters.parambyname(&#8217;tmpvendor&#8217;).value:=trim(edit2.text);&#160;&#160; 
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; parameters.parambyname(&#8217;tmpdesc&#8217;).value:=trim(edit3.text);&#160;&#160; 
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; parameters.parambyname(&#8217;tmpprice&#8217;).datatype：=ftFloat;&#160;&#160;&#160;&#160;&#160;&#160; //设置下数据类型&#160;&#160; 
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; parameters.parambyname(&#8217;tmpprice&#8217;).value:=trim(edit4.text);&#160;&#160; 
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; execsql;&#160;&#160; 
&#160;&#160;&#160;&#160;&#160;&#160; end;&#160;&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>DELPHI 7 使用ADO元件寫入資料庫強制四捨五入小數到第四位問題</p>
<p>parameters.parambyname(&#8217;tmpprice&#8217;).datatype：=ftFloat;&#160;&#160; &lt;==寫入資料前先將欄位設定成 Float 型態即可解決此問題。</p>
<p>參考:<a title="http://jzinfo.javaeye.com/blog/432853" href="http://jzinfo.javaeye.com/blog/432853">http://jzinfo.javaeye.com/blog/432853</a></p>
<ol>
<li>var&#160;&#160; </li>
<li>&#160;&#160;&#160; adoquery1:Tadoquery;&#160;&#160; </li>
<li>begin&#160;&#160; </li>
<li>&#160;&#160;&#160; adoquery1:=Tadoquery.create(nil);&#160;&#160; </li>
<li>&#160;&#160;&#160; try&#160;&#160; </li>
<li>&#160;&#160;&#160;&#160;&#160;&#160; if not DM.adonconnection1.connected then&#160;&#160; </li>
<li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DM.adoconnection1.connected:=true;&#160;&#160; </li>
<li>&#160;&#160;&#160;&#160;&#160;&#160; adoquery1.connection:=DM.adoconnection1;&#160;&#160; </li>
<li>&#160;&#160;&#160;&#160;&#160;&#160; adoquery1.enableBCD:=False;&#160;&#160;&#160;&#160;&#160;&#160; //禁用bcd类型&#160;&#160; </li>
<li>&#160;&#160;&#160;&#160;&#160;&#160; with adoquery1 do&#160;&#160; </li>
<li>&#160;&#160;&#160;&#160;&#160;&#160; begin&#160;&#160; </li>
<li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; close;&#160;&#160; </li>
<li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sql.clear;&#160;&#160; </li>
<li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sql.add(&#8217;insert into materialInfo values(:tmppno,:tmpvendor,:tmpdesc,:tmpprice)&#8217;);&#160;&#160; </li>
<li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; parameters.parambyname(&#8217;tmppno&#8217;).value:=trim(edit1.text);&#160;&#160; </li>
<li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; parameters.parambyname(&#8217;tmpvendor&#8217;).value:=trim(edit2.text);&#160;&#160; </li>
<li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; parameters.parambyname(&#8217;tmpdesc&#8217;).value:=trim(edit3.text);&#160;&#160; </li>
<li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; parameters.parambyname(&#8217;tmpprice&#8217;).datatype：=ftFloat;&#160;&#160;&#160;&#160;&#160;&#160; //设置下数据类型&#160;&#160; </li>
<li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; parameters.parambyname(&#8217;tmpprice&#8217;).value:=trim(edit4.text);&#160;&#160; </li>
<li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; execsql;&#160;&#160; </li>
<li>&#160;&#160;&#160;&#160;&#160;&#160; end;&#160;&#160; </li>
<li>&#160;&#160;&#160; finally&#160;&#160; </li>
<li>&#160;&#160;&#160;&#160;&#160;&#160;&#160; adoquery1.free;&#160;&#160; </li>
<li>&#160;&#160;&#160; end;&#160;&#160; </li>
<li>end;&#160; </li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.infinity.idv.tw/index.php/2010/12/09/delphi-7-%e4%bd%bf%e7%94%a8ado%e5%85%83%e4%bb%b6%e5%af%ab%e5%85%a5%e8%b3%87%e6%96%99%e5%ba%ab%e5%bc%b7%e5%88%b6%e5%9b%9b%e6%8d%a8%e4%ba%94%e5%85%a5%e5%b0%8f%e6%95%b8%e5%88%b0%e7%ac%ac%e5%9b%9b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DELPHI下使用FileSetDate()函式修改檔案的&#8221;修改日期&#8221;</title>
		<link>http://blog.infinity.idv.tw/index.php/2010/10/11/delphi%e4%b8%8b%e4%bd%bf%e7%94%a8filesetdate%e5%87%bd%e5%bc%8f%e4%bf%ae%e6%94%b9%e6%aa%94%e6%a1%88%e7%9a%84%e4%bf%ae%e6%94%b9%e6%97%a5%e6%9c%9f/</link>
		<comments>http://blog.infinity.idv.tw/index.php/2010/10/11/delphi%e4%b8%8b%e4%bd%bf%e7%94%a8filesetdate%e5%87%bd%e5%bc%8f%e4%bf%ae%e6%94%b9%e6%aa%94%e6%a1%88%e7%9a%84%e4%bf%ae%e6%94%b9%e6%97%a5%e6%9c%9f/#comments</comments>
		<pubDate>Mon, 11 Oct 2010 10:14:39 +0000</pubDate>
		<dc:creator>Roger Lin</dc:creator>
				<category><![CDATA[DELPHI]]></category>
		<category><![CDATA[DELPHI 修改檔案修改日期 FileSetDate]]></category>

		<guid isPermaLink="false">http://blog.infinity.idv.tw/index.php/2010/10/11/delphi%e4%b8%8b%e4%bd%bf%e7%94%a8filesetdate%e5%87%bd%e5%bc%8f%e4%bf%ae%e6%94%b9%e6%aa%94%e6%a1%88%e7%9a%84%e4%bf%ae%e6%94%b9%e6%97%a5%e6%9c%9f/</guid>
		<description><![CDATA[<p>Delphi下使用function FileSetDate(Handle: Integer; Age: Integer): Integer; overload;函式修改檔案的”修改日期”:</p>
<p>參考:http://delphi.ktop.com.tw/board.php?cid=30&#38;fid=70&#38;tid=37667</p>
<p>procedure TForm1.Button1Click(Sender: TObject);   Var    &#160;&#160;&#160; FileHandle : Integer;    &#160;&#160;&#160; Str : String;    begin    &#160;&#160;&#160; FileHandle := FileOpen(&#8217;D:\prog\1.txt&#8217;, fmOpenReadWrite);    &#160;&#160;&#160; if FileHandle = -1 then    &#160;&#160;&#160;&#160;&#160; ShowMessage(&#8217;開啟檔案失敗&#8217;)    [...]]]></description>
			<content:encoded><![CDATA[<p>Delphi下使用function FileSetDate(Handle: Integer; Age: Integer): Integer; overload;函式修改檔案的”修改日期”:</p>
<p>參考:<a title="http://delphi.ktop.com.tw/board.php?cid=30&amp;fid=70&amp;tid=37667" href="http://delphi.ktop.com.tw/board.php?cid=30&amp;fid=70&amp;tid=37667">http://delphi.ktop.com.tw/board.php?cid=30&amp;fid=70&amp;tid=37667</a></p>
<p>procedure TForm1.Button1Click(Sender: TObject);   <br />Var    <br />&#160;&#160;&#160; FileHandle : Integer;    <br />&#160;&#160;&#160; Str : String;    <br />begin    <br />&#160;&#160;&#160; FileHandle := FileOpen(&#8217;D:\prog\1.txt&#8217;, fmOpenReadWrite);    <br />&#160;&#160;&#160; if FileHandle = -1 then    <br />&#160;&#160;&#160;&#160;&#160; ShowMessage(&#8217;開啟檔案失敗&#8217;)    <br />&#160;&#160;&#160; else    <br />&#160;&#160;&#160; begin    <br />&#160;&#160;&#160;&#160;&#160; Str := &#8216;檔案原來日期時間: &#8216;+ DateTimeToStr(FileDateToDateTime(FileGetDate(FileHandle)))+#10#13;    <br />&#160;&#160;&#160;&#160;&#160; if FileSetDate(FileHandle, FileAge(&#8217;D:\prog\AMS.exe&#8217;)) = 0 then    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; Str := Str+DateTimeToStr(FileDateToDateTime(FileAge(&#8217;D:\prog\AMS.exe&#8217;)))    <br />&#160;&#160;&#160;&#160;&#160; else    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; Str := Str+&#8217;新的日期時間設定失敗&#8217;;    <br />&#160;&#160;&#160;&#160;&#160; ShowMessage(Str);    <br />&#160;&#160;&#160; end;    <br />&#160;&#160;&#160; FileClose(FileHandle);    <br />end;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.infinity.idv.tw/index.php/2010/10/11/delphi%e4%b8%8b%e4%bd%bf%e7%94%a8filesetdate%e5%87%bd%e5%bc%8f%e4%bf%ae%e6%94%b9%e6%aa%94%e6%a1%88%e7%9a%84%e4%bf%ae%e6%94%b9%e6%97%a5%e6%9c%9f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DELPHI 完整檔名路徑下取檔名去除路逕與去除附檔名</title>
		<link>http://blog.infinity.idv.tw/index.php/2010/09/10/delphi-%e5%ae%8c%e6%95%b4%e6%aa%94%e5%90%8d%e8%b7%af%e5%be%91%e4%b8%8b%e5%8f%96%e6%aa%94%e5%90%8d%e5%8e%bb%e9%99%a4%e8%b7%af%e9%80%95%e8%88%87%e5%8e%bb%e9%99%a4%e9%99%84%e6%aa%94%e5%90%8d/</link>
		<comments>http://blog.infinity.idv.tw/index.php/2010/09/10/delphi-%e5%ae%8c%e6%95%b4%e6%aa%94%e5%90%8d%e8%b7%af%e5%be%91%e4%b8%8b%e5%8f%96%e6%aa%94%e5%90%8d%e5%8e%bb%e9%99%a4%e8%b7%af%e9%80%95%e8%88%87%e5%8e%bb%e9%99%a4%e9%99%84%e6%aa%94%e5%90%8d/#comments</comments>
		<pubDate>Fri, 10 Sep 2010 08:02:14 +0000</pubDate>
		<dc:creator>Roger Lin</dc:creator>
				<category><![CDATA[DELPHI]]></category>
		<category><![CDATA[取檔名 去除附檔名 去除路徑 DELPHI]]></category>

		<guid isPermaLink="false">http://blog.infinity.idv.tw/index.php/2010/09/10/delphi-%e5%ae%8c%e6%95%b4%e6%aa%94%e5%90%8d%e8%b7%af%e5%be%91%e4%b8%8b%e5%8f%96%e6%aa%94%e5%90%8d%e5%8e%bb%e9%99%a4%e8%b7%af%e9%80%95%e8%88%87%e5%8e%bb%e9%99%a4%e9%99%84%e6%aa%94%e5%90%8d/</guid>
		<description><![CDATA[<p>ExtractFileName(FileName);&#160; //去除檔案的路徑</p>
<p>ChangeFileExt(FileName);&#160;&#160;&#160;&#160; //去除副檔名</p>
]]></description>
			<content:encoded><![CDATA[<p>ExtractFileName(FileName);&#160; //去除檔案的路徑</p>
<p>ChangeFileExt(FileName);&#160;&#160;&#160;&#160; //去除副檔名</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.infinity.idv.tw/index.php/2010/09/10/delphi-%e5%ae%8c%e6%95%b4%e6%aa%94%e5%90%8d%e8%b7%af%e5%be%91%e4%b8%8b%e5%8f%96%e6%aa%94%e5%90%8d%e5%8e%bb%e9%99%a4%e8%b7%af%e9%80%95%e8%88%87%e5%8e%bb%e9%99%a4%e9%99%84%e6%aa%94%e5%90%8d/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DELPHI寫入EXCEL時，寫入速度緩慢問題</title>
		<link>http://blog.infinity.idv.tw/index.php/2010/07/12/delphi%e5%af%ab%e5%85%a5excel%e6%99%82%ef%bc%8c%e5%af%ab%e5%85%a5%e9%80%9f%e5%ba%a6%e7%b7%a9%e6%85%a2%e5%95%8f%e9%a1%8c/</link>
		<comments>http://blog.infinity.idv.tw/index.php/2010/07/12/delphi%e5%af%ab%e5%85%a5excel%e6%99%82%ef%bc%8c%e5%af%ab%e5%85%a5%e9%80%9f%e5%ba%a6%e7%b7%a9%e6%85%a2%e5%95%8f%e9%a1%8c/#comments</comments>
		<pubDate>Mon, 12 Jul 2010 07:46:11 +0000</pubDate>
		<dc:creator>Roger Lin</dc:creator>
				<category><![CDATA[DELPHI]]></category>
		<category><![CDATA[EXCEL]]></category>
		<category><![CDATA[DELPHI EXCEL 寫入資料 速度緩慢 寫入緩慢]]></category>

		<guid isPermaLink="false">http://blog.infinity.idv.tw/index.php/2010/07/12/delphi%e5%af%ab%e5%85%a5excel%e6%99%82%ef%bc%8c%e5%af%ab%e5%85%a5%e9%80%9f%e5%ba%a6%e7%b7%a9%e6%85%a2%e5%95%8f%e9%a1%8c/</guid>
		<description><![CDATA[<p>最近在修改使用者提出 EXCEL 報表欄位，發現有幾支 procedure 轉出 EXCEL 的速度非常龜，而這幾支 procedure 是前輩所留下的產物，跟自己最近寫的轉 EXCEL 報表速度上差很多，以為是卡在SQL查詢，如果查詢條件KEY值給不齊全，有可能因為資料過多，查詢變很慢，但是測試後應該不是SQL查詢的問題，再對照前輩與自己的程式，感覺不出差異，最後看到 DELPHI 內設定EXCEL時前面通常會有一些基本設定，發現了這幾支程式都有設定列印範圍，姑且註解掉試試看，果然&#8230;&#8230;&#8230;&#8230;&#8230;兇手就是它！</p>
<p>PageSetup.PrintArea := &#8216;A:R&#8217;;&#160; //設定列印範圍</p>
<p>建議把它移到資料轉完後，最後在給上這個參數就好了。</p>
]]></description>
			<content:encoded><![CDATA[<p>最近在修改使用者提出 EXCEL 報表欄位，發現有幾支 procedure 轉出 EXCEL 的速度非常龜，而這幾支 procedure 是前輩所留下的產物，跟自己最近寫的轉 EXCEL 報表速度上差很多，以為是卡在SQL查詢，如果查詢條件KEY值給不齊全，有可能因為資料過多，查詢變很慢，但是測試後應該不是SQL查詢的問題，再對照前輩與自己的程式，感覺不出差異，最後看到 DELPHI 內設定EXCEL時前面通常會有一些基本設定，發現了這幾支程式都有設定列印範圍，姑且註解掉試試看，果然&#8230;&#8230;&#8230;&#8230;&#8230;兇手就是它！</p>
<p>PageSetup.PrintArea := &#8216;A:R&#8217;;&#160; //設定列印範圍</p>
<p>建議把它移到資料轉完後，最後在給上這個參數就好了。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.infinity.idv.tw/index.php/2010/07/12/delphi%e5%af%ab%e5%85%a5excel%e6%99%82%ef%bc%8c%e5%af%ab%e5%85%a5%e9%80%9f%e5%ba%a6%e7%b7%a9%e6%85%a2%e5%95%8f%e9%a1%8c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DELPHI 7 下將文字存成UTF8格式</title>
		<link>http://blog.infinity.idv.tw/index.php/2010/06/30/delphi-7-%e4%b8%8b%e5%b0%87%e6%96%87%e5%ad%97%e5%ad%98%e6%88%90utf8%e6%a0%bc%e5%bc%8f/</link>
		<comments>http://blog.infinity.idv.tw/index.php/2010/06/30/delphi-7-%e4%b8%8b%e5%b0%87%e6%96%87%e5%ad%97%e5%ad%98%e6%88%90utf8%e6%a0%bc%e5%bc%8f/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 04:00:53 +0000</pubDate>
		<dc:creator>Roger Lin</dc:creator>
				<category><![CDATA[DELPHI]]></category>
		<category><![CDATA[UTF8 編碼 文字]]></category>

		<guid isPermaLink="false">http://blog.infinity.idv.tw/index.php/2010/06/30/delphi-7-%e4%b8%8b%e5%b0%87%e6%96%87%e5%ad%97%e5%ad%98%e6%88%90utf8%e6%a0%bc%e5%bc%8f/</guid>
		<description><![CDATA[<p>上網找到下面的程式碼，修了一下測試，真的可以耶!!!!最近的程式剛好有UTF8編碼的困擾，使用這方式轉是方便多了，不過還要測試會不會有問題。</p>
<p>討論區：http://delphi.ktop.com.tw/board.php?cid=30&#38;fid=76&#38;tid=89562</p>
<p>procedure TForm1.Button1Click(Sender: TObject);    var     &#160; S:UTF8String;     &#160; F:TextFile;     &#160; TntEdit1: TStringList;     begin     &#160; TntEdit1 := TStringList.Create;     &#160; TntEdit1.Add(&#8217;我是天才我是天才我是天才&#8217;);     &#160; S:=UTF8Encode(TntEdit1.Text);     [...]]]></description>
			<content:encoded><![CDATA[<p>上網找到下面的程式碼，修了一下測試，真的可以耶!!!!最近的程式剛好有UTF8編碼的困擾，使用這方式轉是方便多了，不過還要測試會不會有問題。</p>
<p><a href="http://delphi.ktop.com.tw/board.php?cid=30&amp;fid=76&amp;tid=89562">討論區：http://delphi.ktop.com.tw/board.php?cid=30&amp;fid=76&amp;tid=89562</a></p>
<p>procedure TForm1.Button1Click(Sender: TObject);    <br />var     <br />&#160; S:UTF8String;     <br />&#160; F:TextFile;     <br />&#160; TntEdit1: TStringList;     <br />begin     <br />&#160; TntEdit1 := TStringList.Create;     <br />&#160; TntEdit1.Add(&#8217;我是天才我是天才我是天才&#8217;);     <br />&#160; S:=UTF8Encode(TntEdit1.Text);     <br />&#160; AssignFile(F, &#8216;C:\test.txt&#8217;);     <br />&#160; Rewrite(F);     <br />&#160; Write(F,#$EF+#$BB+#$BF); //UTF8??     <br />&#160; Write(F,S);     <br />&#160; CloseFile(F);     <br />end;</p>
<p>&#160;</p>
<p>結果去開C:\test.txt 來看，真的直接就是UTF8編碼，在XP下看中文也正常，沒有亂碼。</p>
<p><a href="http://blog.infinity.idv.tw/blog-img/DELPHI7UTF8_A8F0/1.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="1" border="0" alt="1" src="http://blog.infinity.idv.tw/blog-img/DELPHI7UTF8_A8F0/1_thumb.jpg" width="609" height="522" /></a></p>
<p>&#160;</p>
<p>&#160; Write(F,#$EF+#$BB+#$BF); 中 #$EF+#$BB+#$BF 的意義</p>
<p>=======================================================================</p>
<p><a href="http://60.248.128.85/bbs/dv_rss.asp?s=xhtml&amp;boardid=63&amp;id=491&amp;page=3">http://60.248.128.85/bbs/dv_rss.asp?s=xhtml&amp;boardid=63&amp;id=491&amp;page=3</a></p>
<p>這是一篇程式員寫給程式員的趣味讀物。所謂趣味是指可以比較輕鬆地瞭解一些原來不清楚的概念，增進知識，類似於打RPG遊戲的升級。整理這篇文章的動機是兩個問題：</p>
<dl>
<dt>問題一： </dt>
<dd>
<p>使用Windows記事本的「另存為」，可以在GBK、Unicode、Unicode big endian和UTF-8這幾種編碼方式間相互轉換。同樣是txt文件，Windows是怎樣辨識編碼方式的呢？</p>
<p><font color="#ff0000">我很早前就發現Unicode、Unicode big endian和UTF-8編碼的txt文件的開頭會多出幾個字元，分別是FF、FE（Unicode）,FE、FF（Unicode big endian）,EF、BB、BF（UTF-8）。但這些標記是基於什麼標準呢？</font></p>
</p>
</dd>
<dt>問題二： </dt>
<dd>最近在網上看到一個ConvertUTF.c，達到了UTF-32、UTF-16和UTF-8這三種編碼方式的相互轉換。對於Unicode(UCS2)、GBK、UTF-8這些編碼方式，我原來就瞭解。但這個程式讓我有些糊塗，想不起來UTF-16和UCS2有什麼關係。</dd>
</dl>
<p>查了查相關資料，總算將這些問題弄清楚了，順帶也瞭解了一些Unicode的細節。寫成一篇文章，送給有過類似疑問的朋友。本文在寫作時盡量做到通俗易懂，但要求讀者知道什麼是字元，什麼是十六進制。</p>
<h5>0、big endian和little endian</h5>
<p>big endian和little endian是CPU處理多字元數的不同方式。例如「漢」字的Unicode編碼是6C49。那麼寫到文件裡時，究竟是將6C寫在前面，還是將49寫在前面？如果將6C寫在前面，就是big endian。還是將49寫在前面，就是little endian。</p>
<p>「endian」這個詞出自《格列佛遊記》。小人國的內戰就源於吃雞蛋時是究竟從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開，由此曾發生過六次叛亂，其中一個皇帝送了命，另一個丟了王位。</p>
<p>我們一般將endian翻譯成「字元序」，將big endian和little endian稱作「大尾」和「小尾」。</p>
<h5>1、字元編碼、內碼，順帶介紹中文字編碼</h5>
<p>字元必須編碼後才能被電腦處理。電腦使用的缺省編碼方式就是電腦的內碼。早期的電腦使用7位的ASCII編碼，為了處理中文字，程式員設計了用於簡體中文的big5和用於繁體中文的big5。</p>
<p>big5(1980年)一共收錄了7445個字元，包括6763個中文字和682個其它符號。中文字區的內碼範圍高字元從B0-F7，低字元從A1-FE，佔用的碼位是72*94=6768。其中有5個空位是D7FA-D7FE。</p>
<p>big5支援的中文字太少。1995年的中文字擴展規範GBK1.0收錄了21886個符號，它分為中文字區和圖形符號區。中文字區包括21003個字元。2000年的GB18030是取代GBK1.0的正式國家標準。該標準收錄了27484個中文字，同時還收錄了藏文、蒙文、維吾爾文等主要的少數民族文字。現在的PC平台必須支援GB18030，對嵌入式產品暫不作要求。所以手機、MP3一般只支援big5。</p>
<p>從ASCII、big5、GBK到GB18030，這些編碼方法是向下兼容的，即同一個字元在這些方案中總是有相同的編碼，後面的標準支援更多的字元。在這些編碼中，英文和中文可以統一地處理。區分中文編碼的方法是高字元的最高位不為0。按照程式員的稱呼，big5、GBK到GB18030都屬於雙字元字元集 (DBCS)。</p>
<p>有的中文Windows的缺省內碼還是GBK，可以透過GB18030升級包升級到GB18030。不過GB18030相對GBK增加的字元，普通人是很難用到的，通常我們還是用GBK指代中文Windows內碼。</p>
<p>這裡還有一些細節：</p>
<ul>
<li>
<p>big5的原文還是區位碼，從區位碼到內碼，需要在高字元和低字元上分別加上A0。</p>
</li>
<li>
<p>在DBCS中，GB內碼的存儲格式始終是big endian，即高位在前。</p>
</li>
<li>
<p>big5的兩個字元的最高位都是1。但符合這個條件的碼位只有128*128=16384個。所以GBK和GB18030的低字元最高位都可能不是1。不過這不影響DBCS字元流的解析：在讀取DBCS字元流時，只要遇到高位為1的字元，就可以將下兩個字元作為一個雙字元編碼，而不用管低字元的高位是什麼。</p>
</li>
</ul>
<h5>2、Unicode、UCS和UTF</h5>
<p>前面提到從ASCII、big5、GBK到GB18030的編碼方法是向下兼容的。而Unicode只與ASCII兼容（更準確地說，是與ISO-8859-1兼容），與GB碼不兼容。例如「漢」字的Unicode編碼是6C49，而GB碼是BABA。</p>
<p>Unicode也是一種字元編碼方法，不過它是由國際組織設計，可以容納全世界所有語言文字的編碼方案。Unicode的學名是&quot;Universal Multiple-Octet Coded Character Set&quot;，簡稱為UCS。UCS可以看作是&quot;Unicode Character Set&quot;的縮寫。</p>
<p>根據維基百科全書(http://zh.wikipedia.org/wiki/)的記載：歷史上存在兩個試圖獨立設計Unicode的組織，即國際標準化組織（ISO）和一個軟體製造商的協會（unicode.org）。ISO開發了ISO 10646項目，Unicode協會開發了Unicode項目。</p>
<p>在1991年前後，雙方都認識到世界不需要兩個不兼容的字元集。於是它們開始合併雙方的工作成果，並為創立一個單一編碼表而協同工作。從Unicode2.0開始，Unicode項目採用了與ISO 10646-1相同的字庫和字碼。</p>
<p>目前兩個項目仍都存在，並獨立地公佈各自的標準。Unicode協會現在的最新版本是2005年的Unicode 4.1.0。ISO的最新標準是10646-3:2003。</p>
<p>UCS規定了怎麼用多個字元表示各種文字。怎樣傳輸這些編碼，是由UTF(UCS Transformation Format)規範規定的，常見的UTF規範包括UTF-8、UTF-7、UTF-16。</p>
<p>IETF的RFC2781和RFC3629以RFC的一貫風格，清晰、明快又不失嚴謹地描述了UTF-16和UTF-8的編碼方法。我總是記不得IETF是Internet Engineering Task Force的縮寫。但IETF負責維護的RFC是Internet上一切規範的基礎。</p>
<h5>3、UCS-2、UCS-4、BMP</h5>
<p>UCS有兩種格式：UCS-2和UCS-4。顧名思義，UCS-2就是用兩個字元編碼，UCS-4就是用4個字元（實際上只用了31位，最高位必須為0）編碼。下面讓我們做一些簡單的數學遊戲：</p>
<p>UCS-2有2^16=65536個碼位，UCS-4有2^31=2147483648個碼位。</p>
<p>UCS-4根據最高位為0的最高字元分成2^7=128個group。每個group再根據次高字元分為256個plane。每個plane根據第3個字元分為256行 (rows)，每行包含256個cells。當然同一行的cells只是最後一個字元不同，其餘都相同。</p>
<p>group 0的plane 0被稱作Basic Multilingual Plane, 即BMP。或者說UCS-4中，高兩個字元為0的碼位被稱作BMP。</p>
<p>將UCS-4的BMP去掉前面的兩個零字元就得到了UCS-2。在UCS-2的兩個字元前加上兩個零字元，就得到了UCS-4的BMP。而目前的UCS-4規範中尚未任何字元被分配在BMP之外。</p>
<h5>4、UTF編碼</h5>
<p>UTF-8就是以8位為單元對UCS進行編碼。從UCS-2到UTF-8的編碼方式如下：</p>
<p>UCS-2編碼(16進制)   <br />UTF-8 字元流(二進制)</p>
<p>0000 &#8211; 007F   <br />0xxxxxxx</p>
<p>0080 &#8211; 07FF   <br />110xxxxx 10xxxxxx</p>
<p>0800 &#8211; FFFF   <br />1110xxxx 10xxxxxx 10xxxxxx</p>
<p>例如「漢」字的Unicode編碼是6C49。6C49在0800-FFFF之間，所以肯定要用3字元模板了：1110xxxx 10xxxxxx 10xxxxxx。將6C49寫成二進制是：0110 110001 001001， 用這個比特流依次代替模板中的x，得到：11100110 10110001 10001001，即E6 B1 89。</p>
<p>讀者可以用記事本測試一下我們的編碼是否正確。</p>
<p>UTF-16以16位為單元對UCS進行編碼。對於小於0&#215;10000的UCS碼，UTF-16編碼就等於UCS碼對應的16位無符號整數。對於不小於0&#215;10000的UCS碼，定義了一個算法。不過由於實際使用的UCS2，或者UCS4的BMP必然小於0&#215;10000，所以就目前而言，可以認為UTF-16和UCS-2基本相同。但UCS-2只是一個編碼方案，UTF-16卻要用於實際的傳輸，所以就不得不考慮字元序的問題。</p>
<h5>5、UTF的字元序和BOM</h5>
<p>UTF-8以字元為編碼單元，沒有字元序的問題。UTF-16以兩個字元為編碼單元，在解釋一個UTF-16文本前，首先要弄清楚每個編碼單元的字元序。例如收到一個「奎」的Unicode編碼是594E，「乙」的Unicode編碼是4E59。如果我們收到UTF-16字元流「594E」，那麼這是「奎」還是「乙」？</p>
<p>Unicode規範中推薦的標記字元順序的方法是BOM。BOM不是「Bill Of Material」的BOM表，而是Byte Order Mark。BOM是一個有點小聰明的想法：</p>
<p>在UCS編碼中有一個叫做&quot;ZERO WIDTH NO-BREAK SPACE&quot;的字元，它的編碼是FEFF。而FFFE在UCS中是不存在的字元，所以不應該出現在實際傳輸中。UCS規範建議我們在傳輸字元流前，先傳輸字元&quot;ZERO WIDTH NO-BREAK SPACE&quot;。</p>
<p>這樣如果接收者收到FEFF，就表明這個字元流是Big-Endian的；如果收到FFFE，就表明這個字元流是Little-Endian的。因此字元&quot;ZERO WIDTH NO-BREAK SPACE&quot;又被稱作BOM。</p>
<p>UTF-8不需要BOM來表明字元順序，但可以用BOM來表明編碼方式。字元&quot;ZERO WIDTH NO-BREAK SPACE&quot;的UTF-8編碼是EF BB BF（讀者可以用我們前面介紹的編碼方法驗證一下）。所以如果接收者收到以EF BB BF開頭的字元流，就知道這是UTF-8編碼了。</p>
<p>Windows就是使用BOM來標記文本文件的編碼方式的。</p>
<h5>6、進一步的參考資料</h5>
<p>本文主要參考的資料是 &quot;Short overview of ISO-IEC 10646 and Unicode&quot; (http://www.nada.kth.se/i18n/ucs/unicode-iso10646-oview.html)。</p>
<p>我還找了兩篇看上去不錯的資料，不過因為我開始的疑問都發現了答案，所以就沒有看：</p>
<ol>
<li>&quot;Understanding Unicode A general introduction to the Unicode Standard&quot; (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;item_id=IWS-Chapter04a) </li>
<li>&quot;Character set encoding basics Understanding character set encodings and legacy encodings&quot; (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;item_id=IWS-Chapter03)</li>
</ol>
<p>我寫過UTF-8、UCS-2、GBK相互轉換的軟體包，包括使用Windows API和不使用Windows API的版本。以後有時間的話，我會整理一下放到我的個人首頁上(http://fmddlmyy.home4u.china.com)。</p>
<p>我是想清楚所有問題後才開始寫這篇文章的，原以為一會兒就能寫好。沒想到考慮措辭和查證細節花費了很長時間，竟然從下午1:30寫到9:00。希望有讀者能從中受益。</p>
<p>=======================================================================</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.infinity.idv.tw/index.php/2010/06/30/delphi-7-%e4%b8%8b%e5%b0%87%e6%96%87%e5%ad%97%e5%ad%98%e6%88%90utf8%e6%a0%bc%e5%bc%8f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

