2015年2月27日 星期五
2015年2月6日 星期五
用DELPHI產生HTML
大家熟悉的HTML一般都是用UTF-8格式來做存檔格式,可是DELPHI所用的TXT FILE卻都是用ANSI格式,所以在存檔和轉換都會有許多問題,那怎麼做比較好呢?
筆者最近因為工作上的關係,常會用HTML做樣板,然後再用DELPHI把檔案讀進來,做一些轉換,再形成新的HTML供BROWSER讀取,就碰上了格式的問題。
最後的解決方式是用TStringList的LoadFromFile來解決這個問題
舉例如下
function RefreshHTM():String;
var
HTML1,HTML2 :TStrings;
FG : Boolean;
i : Integer;
begin
try
// 宣告二個TString,HTML1承接HTML樣版,HTML2是做轉換後要顯示的HTML結果
HTML1 := TStringList.Create;
HTML2 := TStringList.Create;
try
// 取得樣版的HTML
HTML1 .LoadFromFile('D:\web_root\html\PTL01U05.htm');
for i :=0 to HTML1.Count-1 do
begin
// 逐筆把資料抓入
Ln := HTML1[i];
// 這邊做想要更換的作
// 把更改後的資料加到HTML2中
HTML2.Add(Ln);
end;
Result := HTML2.Text;
finally
//把資料傳出後,把TString Free 掉
HTML1.Free;
HTML2.Free;
end;
end;
筆者最近因為工作上的關係,常會用HTML做樣板,然後再用DELPHI把檔案讀進來,做一些轉換,再形成新的HTML供BROWSER讀取,就碰上了格式的問題。
最後的解決方式是用TStringList的LoadFromFile來解決這個問題
舉例如下
function RefreshHTM():String;
var
HTML1,HTML2 :TStrings;
FG : Boolean;
i : Integer;
begin
try
// 宣告二個TString,HTML1承接HTML樣版,HTML2是做轉換後要顯示的HTML結果
HTML1 := TStringList.Create;
HTML2 := TStringList.Create;
try
// 取得樣版的HTML
HTML1 .LoadFromFile('D:\web_root\html\PTL01U05.htm');
for i :=0 to HTML1.Count-1 do
begin
// 逐筆把資料抓入
Ln := HTML1[i];
// 這邊做想要更換的作
// 把更改後的資料加到HTML2中
HTML2.Add(Ln);
end;
Result := HTML2.Text;
finally
//把資料傳出後,把TString Free 掉
HTML1.Free;
HTML2.Free;
end;
end;
2015年1月19日 星期一
規格乎?程式乎?
每個程式在設計時,都有它要完成的目標,也都有它要完成工作的前提。程式設計師常會接到使用者來電說,程式跑的結果有問題。我相信程式有BUG在所難免,坊間也有一堆關於如何DEBUG,如何防止BUG發生的方法。不過會不會最大的BUG就是人?
很久以前,看到一篇系統上線的文章,其中提到「樹大必有枯枝,人多必有白痴」,其中的白痴就是在諷刺程式設計者的設計軟體理念很奇怪。不過有時候使用者定義的需求也常令程式設計師瞠目結舌,不知道這設計邏輯是如何跑出來的。
感覺BUG不一定存在電腦中,更常存在人的大腦中。不論是程式人員或是使用人員,通常都有一定的思考方式,而當二人的思考方式放在一起時,就會有溝通不良的問題,如果沒有消除彼此的歧見,BUG就是接下來的產物了。每個人心中的「理所當然」或許就是BUG的源頭吧,也許在DEBUG電腦的BUG前,應該先DEBUG一下自己的想法。
最近常聽到使用者的一堆問題,往往都是使用者沒有先瞭解系統的運作方式,才會有「BUG除不盡,春風吹又生」。在除舊佈新的這段時間,我想也該更新一下自己的思考方式了。也許程式人員的第一要務是讓使用者瞭解程式在做什麼,而不是Coding程式。
很久以前,看到一篇系統上線的文章,其中提到「樹大必有枯枝,人多必有白痴」,其中的白痴就是在諷刺程式設計者的設計軟體理念很奇怪。不過有時候使用者定義的需求也常令程式設計師瞠目結舌,不知道這設計邏輯是如何跑出來的。
感覺BUG不一定存在電腦中,更常存在人的大腦中。不論是程式人員或是使用人員,通常都有一定的思考方式,而當二人的思考方式放在一起時,就會有溝通不良的問題,如果沒有消除彼此的歧見,BUG就是接下來的產物了。每個人心中的「理所當然」或許就是BUG的源頭吧,也許在DEBUG電腦的BUG前,應該先DEBUG一下自己的想法。
最近常聽到使用者的一堆問題,往往都是使用者沒有先瞭解系統的運作方式,才會有「BUG除不盡,春風吹又生」。在除舊佈新的這段時間,我想也該更新一下自己的思考方式了。也許程式人員的第一要務是讓使用者瞭解程式在做什麼,而不是Coding程式。
2015年1月5日 星期一
Delphi可以上WEB嗎?
提供一篇還不錯的文章 DELPHI的WEB解決方案 ,在目前大家都熱衷於APP的時候,還有人做Delphi 的WEB解決方案。
大家有空看一下吧,可以讓大家更瞭解在Delphi領域的程式人員在思考什麼,用Delphi開發了那些應用程式。
2014年12月26日 星期五
ClientDataSet在EOF後可以取值嗎?
當我們在一個ClientDataSet取值時,如果該ClientDataSet已經EOF了,那ClientDataSet.FieldByName('KEY').AsString可以取值嗎?
答案是可以,它會是最後一筆的值。所以在做二個ClientDataSet比較時,別忘了在EOF時要做特別判斷,例如給'zzz'這種最大值,否則常會造成誤判,變成另一ClientDataSet的值被忽略了。
2014年12月20日 星期六
合久必分,分久必合
很久以前用DBASE資料庫的時候,當時一個檔案有2M的限制,所以考量到資料量的關係,於是把筆數多的資料,區分為不同類型的檔案。例如料品基本檔就依型態,原料叫ITEM1,一般物料叫ITEM2,半成品叫ITEM3,成品叫ITEM4等等。這樣就可以減少單一TABLE筆數過大的問題。
不過到了SQL,資料庫的容量大大提昇了,用WHERE條件來區分料品型態其實是一件很容易的事。於是為了減少程式碼,就把先前的檔案合併成一個,用一個分類碼來做區分,這樣原先要個別寫四隻程式維護,變成只要寫一隻就行了。
這種方式行之有年,大家也覺得很正常,資料庫大真的很方便,程式不用再像以前一樣考慮TABLE合併的問題。不過筆者最近碰到一個案例,就是前面說的料品檔一分為四的情形。可能是從舊程式資料轉上來,因為資料的關係,沒辦法合併到相同的TABLE,這下要查詢挑選全部的資料就麻煩了。
事實上在很多情況也必須把不同TABLE的資料合併讓操作人員挑選,例如付款時,付款的對象可能是廠商,但如果客戶也會有付款的情形呢?當然有人會在廠商檔建立客戶編號,當作付款對象,不過如果員工也會有付款情形呢?好像這樣加也不是好方法。
這是用SQL資料庫提供的VIEW就很方便了,利用UNION把先前分開的TABLE整合在一起,就可以讓操作人員挑選了
以下就是把客戶檔 G_CUST、廠商檔 P_VEND 和員工檔 PUB_EMP 建立成 v_PUB_ID_HQ
Create View vPUB_ID_HQ AS
Select '1' AS FG_OBJECT,ID_CUST AS ID_HQ,NM_CS,NM_CONTACT,NN_TEL,NN_FAX,AR_MAIL FROM G_CUST
UNION
Select '2' AS FG_OBJECT,ID_VEND AS ID_HQ,NM_CS,NM_CONTACT,NN_TEL,NN_FAX,AR_MAIL FROM P_VEND
UNION
Select '3' AS FG_OBJECT,ID_EMP AS ID_HQ,NM_EMP AS NM_CS,NM_CONTACT,NN_TEL,NULL AS NN_FAX,AR_EMAIL AS AR_MAIL FROM PUB_EMP
這樣以後 SLECT * FROM v_PUB_ID_HQ,就會出現合併的資料,讓使用者挑選了
用WHERE條件把大資料區分成需要的小資料,用UNION把不同TABLE的資料合併成大資料。二種方式讓你設計的資料庫結構更有彈性。
不過到了SQL,資料庫的容量大大提昇了,用WHERE條件來區分料品型態其實是一件很容易的事。於是為了減少程式碼,就把先前的檔案合併成一個,用一個分類碼來做區分,這樣原先要個別寫四隻程式維護,變成只要寫一隻就行了。
這種方式行之有年,大家也覺得很正常,資料庫大真的很方便,程式不用再像以前一樣考慮TABLE合併的問題。不過筆者最近碰到一個案例,就是前面說的料品檔一分為四的情形。可能是從舊程式資料轉上來,因為資料的關係,沒辦法合併到相同的TABLE,這下要查詢挑選全部的資料就麻煩了。
事實上在很多情況也必須把不同TABLE的資料合併讓操作人員挑選,例如付款時,付款的對象可能是廠商,但如果客戶也會有付款的情形呢?當然有人會在廠商檔建立客戶編號,當作付款對象,不過如果員工也會有付款情形呢?好像這樣加也不是好方法。
這是用SQL資料庫提供的VIEW就很方便了,利用UNION把先前分開的TABLE整合在一起,就可以讓操作人員挑選了
以下就是把客戶檔 G_CUST、廠商檔 P_VEND 和員工檔 PUB_EMP 建立成 v_PUB_ID_HQ
Create View vPUB_ID_HQ AS
Select '1' AS FG_OBJECT,ID_CUST AS ID_HQ,NM_CS,NM_CONTACT,NN_TEL,NN_FAX,AR_MAIL FROM G_CUST
UNION
Select '2' AS FG_OBJECT,ID_VEND AS ID_HQ,NM_CS,NM_CONTACT,NN_TEL,NN_FAX,AR_MAIL FROM P_VEND
UNION
Select '3' AS FG_OBJECT,ID_EMP AS ID_HQ,NM_EMP AS NM_CS,NM_CONTACT,NN_TEL,NULL AS NN_FAX,AR_EMAIL AS AR_MAIL FROM PUB_EMP
這樣以後 SLECT * FROM v_PUB_ID_HQ,就會出現合併的資料,讓使用者挑選了
用WHERE條件把大資料區分成需要的小資料,用UNION把不同TABLE的資料合併成大資料。二種方式讓你設計的資料庫結構更有彈性。
2014年12月13日 星期六
欄位資料取得的速度
如果要取得G_CUST的檔案中的AR_DLV欄位,用G_CUST.FieldByName('AR_DLV').AsString和G_CUSTAR_DLV.AsString(直接用欄位取值)那一個比較好?
以前筆者都採用G_CUST.FieldByName('AR_DLV').AsString,主要的原因是1.看起來很直覺2.不用抓欄位設定3.如果欄位或來源有更改不用重抓。
不過最近在做程式大量計算時,發現當資料量一多,檔案的欄位在多年功能變動加大的努力上,也成長了不少,結果速度就有點拖下去了。改用第二種方式後,速度明顯的提升了,原因是用欄位取值是直接取,FieldByName則要跑一下迴圈,判斷是AR_DLV欄位後,才給值,所以雖然FieldByName的彈性大,但是速度就被犧牲了。
所以在設計程式時,也許要考量一下這二種不同的方式,依程式特性來做取捨。提供給Delphi同好做參考。
以前筆者都採用G_CUST.FieldByName('AR_DLV').AsString,主要的原因是1.看起來很直覺2.不用抓欄位設定3.如果欄位或來源有更改不用重抓。
不過最近在做程式大量計算時,發現當資料量一多,檔案的欄位在多年功能變動加大的努力上,也成長了不少,結果速度就有點拖下去了。改用第二種方式後,速度明顯的提升了,原因是用欄位取值是直接取,FieldByName則要跑一下迴圈,判斷是AR_DLV欄位後,才給值,所以雖然FieldByName的彈性大,但是速度就被犧牲了。
所以在設計程式時,也許要考量一下這二種不同的方式,依程式特性來做取捨。提供給Delphi同好做參考。
訂閱:
文章 (Atom)