//
// 將長字串拆解成數行,中間用 CR+LF 分開
// Crystal Report 9 以後適用
//
StringVar s := {要拆解的欄位}; // 要拆解的字串
StringVar output := ''; // 輸出字串
NumberVar CharsInALine := 20; // 一行幾個字
NumberVar currLength := 0;
while Length(s) > 0 do
(
// 這只是很粗略的判斷,假定使用者只會輸入半形英數字跟中文字,
// 不會使用半形的特殊符號,如半形日文假名
if AscW(s) > 256 then
(
currLength := currLength + 2; // 中文字,長度 + 2
)
else
(
currLength := currLength + 1; // 文數字,長度 + 1
);
output := output + s[1];
if currLength >= CharsInALine then
(
output := output + Chr(13) + Chr(10);
currLength := 0;
);
s := Mid(s, 2);
);
output;
2011年12月15日 星期四
Crystal Report 9 以後適用的“拆解長字串成多行”函數
2011年10月9日 星期日
用 NPOI 在 Excel 工作表中畫斜線
程式碼如下:
using NPOI; using NPOI.SS.UserModel; using NPOI.HSSF.UserModel; …… // 於工作表上建立 HSSFPatriarch,注意!一張工作表只可以建立一個 HSSFPatriarch HSSFPatriarch p = sheet1.CreateDrawingPatriarch() as HSSFPatriarch;
// new HSSFClientAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2) // 就是從 (col1, row1) 儲存格的 (dx1, dy1) 點 // 到 (col2, row2) 儲存格的 (dx2, dy2) 點建立一個繪圖物件的涵蓋範圍 HSSFClientAnchor a = new HSSFClientAnchor(0, 0, 0, 0, 0, 0, 1, 1); // 建立一個 HSSFSimpleShape 繪圖物件,範圍是 a,物件會充滿整個範圍 HSSFSimpleShape s = p.CreateSimpleShape(a); s.ShapeType = HSSFSimpleShape.OBJECT_TYPE_LINE; // 設定線條類型為線條 s.LineStyle = HSSFSimpleShape.LINESTYLE_SOLID; // 設定為實線 s.LineWidth = 1; // 限定線條寬度為 1
2011年9月15日 星期四
dbExpress 啟動交易時,出現「與異動管理員建立連線的要求遭到拒絶」訊息的 Trouble Shotting
前天收到同事傳來的一封郵件,裡面提到他有一個挑單畫面,挑單之前會先修改數量然後再挑單 (修改的數量不需要更新回資料庫)。挑單確定之後,根據挑選到的資料去異動另外一個資料表。可是,當異動另外一個資料表時,發生了「與異動管理員建立連線的要求遭到拒絶」的錯誤訊息。
原先我以為是 MSDTC 服務沒有啟動,請他確定是否有啟動,同事說已經啟動了仍然發生錯誤,接下來同事貼了他的程式碼,說是在啟動交易時發生的錯誤訊息。
於是我想到是不是因為挑單畫面的「修改數量」產生了擱置的異動,使得接下來的交易啟動時,因為有擱置的異動而無法啟動?
在說明如何修改之前,先說明一下挑單畫面的結構。
挑單畫面的組成很簡單,一個 PageControl,第一頁是挑單畫面,第二頁是查詢畫面。進入挑單時切到第一頁,可以預先傳入條件查詢出可供挑單的資料,也可以手動切換到第二頁自行查詢出供挑單的資料。查詢是使用 SQLQuery + DataSetProvider + ClientDataSet,以 TDBGrid 顯示資料。
我的想法是:如果能避免產生「擱置的異動」,就不會阻擋到接下來的交易了。
於是做了這樣的修改:
- 清除畫面上 ClientDataSet 的 ProviderName 屬性
- ClientDataSet.Open 之前,設定 ProviderName 屬性,讓 ClientDataSet 可以接到後面的資料來源,把資料收進來
- ClientDataSet.Open 之後,清除 ProviderName 屬性,使 ClientDataSet 做出的所有異動與後面的資料來源隔離開來
經過這樣的修改,這個問題就解決了。在此提供給大家做個參考。
2011年6月18日 星期六
改善 ASP.Net Menu 控制項點擊有效區域太小的問題
使用過 ASP.Net Menu 控制項的朋友都會發現這個問題:點擊有效區域 (也就是會變成手型游標的區域) 僅限於功能表的文字部份,但是 Hover 的效果卻及於功能表項目的全部。導致「雖然看到功能表項目變色了,但是點擊無效,必須游標變成手型才可以」,而讓使用者有不好的操作體驗。
如何解決這個問題?靠一點 css 的輔助就可以了。
將以下的 css 加入您的 css 檔
a.menu
{ display:block; width:100%; height:100%; padding-top:8px; } a.menu:hover { background-color: Gray; }
然後設定 Menu 控制項的 StaticMenuItemStyle 以及 DynamicMenuItemStyle 的 CssClass="menu"
a.menu 中的 padding-top:8px,以及 a.menu:hover 需要依照實際狀況做調整
這樣套用之後,功能表的點擊有效區域就可以括及功能表項目的全部範圍了
2011年6月6日 星期一
Delphi ListBox 顯示多欄文字
- 設定 ListBox.TabWidth,單位是 Dialog Base Unit (DBU),以定寬字來說,英數字寬是 4 DBU,中文字寬是 8 DBU,所以每一欄 20 個英數字寬度的話,TabWidth 就要設定為 80
不用管一個 DBU 合多少 Pt,DBU 是相對單位,會跟著字的大小而變化的
- Items.Add 時,要分欄的地方,插入 Tab 字元,可以用 #9 或是 ^I 例如:
Items.Add('0001'#9'這是品名'); 或是 Items.Add('0001'^I'這是品名');
- 沒辦法各欄設定不同寬度,所以 TabWidth 請設定大一點,或是最長的欄放最後
如果一定要各欄不同寬度顯示,請改用 TListView
2011年6月2日 星期四
Delphi + PostgreSQL 處理 bytea 欄位的注意事項
設定 PostgreSQL ODBC 時,要把圖中的「bytea as LO」選項勾起來,這樣使用 bytea 欄位型態就會被判別成 TBlobField,而不是 TVarBytesField
如此一來,就可以使用 TBlobField.LoadFromFile() 跟 SaveToFile() 來存入與讀取 bytea 欄位的內容了
若讀取時只想使用 TImage 顯示,不想存檔也可以 (以 JPG 圖檔為例子)
uses jpeg; // 支援 JPEG 圖檔
var blob: TStream;
blob := ADODataSet1.CreateBlobStream(BlobField, bmRead);
try
blob.Seek(0, soFromBeginning);
Image1.Picture.Graphic := TJPEGImage.Create;
Image1.Picture.Graphic.LoadFromStream(blob);
finally
blob.Free
end;
2011年5月12日 星期四
XMLHttpRequest 的應用:灌垃圾資料給釣魚網站
今天有一個許久未聯絡的同學忽然間丟MSN水球給我,第一時間的直覺就是詐騙,要買遊戲儲值卡的。果不其然,聊不到兩句就開始問我有沒有空,可不可以幫他買卡等等,我用幾個爛藉口推掉之後,他留下一個超連結就離線了。
點擊超連結,果然出現一個很像 Windows Live 登入的網頁,做得十分粗糙,連 Title 都沒有改,還是“Untitled Document”,唉~~要騙人帳號也搞像一點嘛!於是我就拿出了我之前寫的小程式,一個 html 檔案,填入了一些資料,開始向那個釣魚網站灌垃圾資料
這隻程式很簡單,就是使用 XMLHttpRequest 對釣魚網站 POST 假資料,假資料當然是使用亂數產生,主要的部份是這樣子的:
//產生一個XMLHttpRequest物件
function initRequest()
{
var A=null;
try
{
A = new ActiveXObject("Msxml2.XMLHTTP")
}
catch(e)
{
try
{
A = new ActiveXObject("Microsoft.XMLHTTP")
}
catch(oc)
{
A = null
}
}
if (!A && typeof XMLHttpRequest != "undefined")
{
A = new XMLHttpRequest()
}
if (!A && window.createRequest)
{
try
{
A = window.createRequest();
} catch (e)
{
A = null;
}
}
return A
}
//取亂數帳號密碼,塞入釣魚網頁
function DoBurst()
{
try
{
// 宣告變數
username = "";
password = "";
// 取得輸入資料
actionUrl = document.getElementById("actionUrl").value;
usernameId = document.getElementById("usernameId").value;
passwordId = document.getElementById("passwordId").value;
// 取亂數拼湊假的帳號跟密碼
c = Math.floor(Math.random() * 8) + 5;
for (n=0; n < c; n++)
{
username += charSet.charAt(Math.floor(Math.random() * charSet.length));
}
username += document.getElementById("usernameSuffix").value;
c = Math.floor(Math.random() * 8) + 5;
for (n=0; n < c; n++)
{
password += charSet.charAt(Math.floor(Math.random() * charSet.length));
}// submit
url = actionUrl + "?" + usernameId + "=" + username + "&" + passwordId+ "=" + password;
if (typeof XmlHttp == "undefined")
{
XmlHttp = initRequest();
}
XmlHttp.open("POST", url, true);
XmlHttp.onreadystatechange = ShowResult;
XmlHttp.send("");
// 計數器累加,並更新畫面
i++;
document.getElementById("sendTimes").innerText = i;
}
catch(e)
{
}
}
然後使用 interval 定時重複執行,就這樣簡單!
2011年3月9日 星期三
2011年1月30日 星期日
Ubuntu Server 10.10 安裝 ASP.Net 網站伺服器的步驟
一、安裝 mono 以及 xsp
sudo apt-get install mono-gmcs
sudo apt-get install mono-xsp2
sudo apt-get install mono-apache-server2
sudo apt-get install libapache2-mod-mono
sudo a2enmod mod_mono
二、修改 /etc/apache2/mods-enabled/mod_mono.conf
成為以下這樣:
===== 從這裡開始 =====
AddType application/x-asp-net .aspx .ashx .asmx .ascx .asax .config .axd
DirectoryIndex index.aspx
DirectoryIndex Default.aspx
DirectoryIndex default.aspx
MonoAutoApplication enabled
MonoServerPath "/usr/bin/mod-mono-server2"
Include /etc/mono-server2/mono-server2-hosts.conf
===== 到這裡結束 =====
三、重新啟動 apache2
sudo /etc/init.d/apache2 restart
若要讓 Visual Studio 跟 MonoDevelop 共用網站專案的話
要使用「ASP.Net 應用程式」開發,不可以使用「ASP.Net 網站」開發
這樣平常就可以使用 Visual Studio 開發,要部署到 Ubuntu Server 時,再用 MonoDevelop 編譯一次就好