2010年12月2日 星期四

[C#] 將二進位資料寫入資料庫

這兩天在研究如何對資料庫操作二進位的資料
最基本的應用就是把圖片存進資料庫,而不是只存圖片路徑
以撰寫應用程式的層面來看
大致上就是
1.「將已存在於電腦上的圖片讀入pictureBox」
2.「將該圖片寫入資料庫」
3.「從資料庫讀出圖片至pictureBox」
這三個主要的動作
在Access上是使用OLE物件為該圖片欄位的資料型態
而Oracle則是Blob

第一個算是控制項操作基礎也沒啥好講的了
2跟3倒是費了我不少時間,尤其是在Oracle方 Orz
圖片寫入資料庫的流程概念:
1.將圖片轉存為記憶體串流
2.將記憶體串流轉為byte陣列
(此步驟是因為有一些特別的圖片格式無法直接轉成byte陣列)
3.將byte陣列寫入資料庫

從資料庫讀出圖片就是反向:
1.從資料庫將圖片讀出存放在byte陣列
2.將byte陣列轉換為記憶體串流
3.把記憶體串流做為pictureBox的顯示圖片

再來就來看看實做的Code吧
假設今天Access資料庫為test.mdb,img資料表
有兩個欄位,id與pics
先看寫入資料庫的部份
MemoryStream st = new MemoryStream();
pBox.Image.Save(st, pBox.Image.RawFormat);
byte[] by = st.ToArray();
string strDbConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Application.StartupPath + "\\test.mdb";
OleDbConnection OdbConn = new OleDbConnection(strDbConn);
OdbConn.Open();
OleDbCommand OdbCmd = new OleDbCommand("update img set pics = ? where id = 1", OdbConn);
OleDbParameter parameter = new OleDbParameter("pics", System.Data.OleDb.OleDbType.Binary);
parameter.Size = by.Length;
parameter.Value = by;
OdbCmd.Parameters.Add(parameter);
OdbCmd.ExecuteNonQuery();
OdbCmd.Dispose();
OdbConn.Close();
OdbConn.Dispose();

再來是從資料庫讀出圖片
string strDbConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Application.StartupPath + "\\test.mdb";
OleDbConnection OdbConn = new OleDbConnection(strDbConn);
OdbConn.Open();
OleDbCommand OdbCmd = new OleDbCommand("select pics from img where id = 1", OdbConn);
byte[] by = (byte[])OdbCmd.ExecuteScalar();
MemoryStream st = new MemoryStream(by, 0, by.Length);
pBox.Image = Image.FromStream(st);
OdbCmd.Dispose();
OdbConn.Close();
OdbConn.Dispose();

Oracle的部份雖然有實作成功
不過跟我所找到的一些國外的文件在做法上有差異
等我把他搞清楚整個機制再來po

2010年11月25日 星期四

[VB] 作業 - 購物機

購物機?大概吧,管他的
反正就是一個從課本範例去改的程式
這種作業對出題老師而言應該算是很輕鬆
不用自己想題目,還可以稍加變更多加條件進去

完成圖大概如下


這種題目其實只有一個重點
那就是要記得把計算總價另外寫副程式
然後不管是更改數量、更改選取與否或是更改運送法
都直接call副程式去運算就好了

撰寫上的差異大概就是
你要手動把每個事件分開寫
還是把所有同類事件寫一起
例如所有的TextChange只寫一個事件
分開寫跟一起寫其實差異不大
只不過一起寫看起來比較省字、比較高明
(但是原始碼是自己在看的,高不高明意義好像也不大
省字卻又不一定快,因為分開寫可以複製貼上再小小改過即可)
反正就是....見仁見智吧
只是,當今天有動態控制項或是控制項超多的時候
如果只會一個個分開寫大概會死人吧

剩下的....沒了
這種基礎程式沒啥難度可言

2010年11月18日 星期四

[C#] 作業 - 點餐機

題目跟之前的一樣
不過這次改用C#來認真寫了一下

C#版本多了甜點跟飲料單點功能
而且利用dataGridView加上comboBox
讓更改已經點了的菜單更加簡單也合理化
(之前VB版要改一個人就要所有人全部重點)

至於結帳明細
我是覺得內容列表出已經出來了
其實也就是一種結帳明細了
何況題目本來就是舉例一種做法
沒有強制規定一定要用○○○xN的方法來做
我覺得像這樣直接用表格做更好看也方便

完成圖兩張~

2010年11月8日 星期一

[C#] 限制textBox只能輸入數字

這個其實在學校教程式設計的時候常不會去講到
在入門來講,textBox當輸入介面是必然的事
不過當你辛苦的寫了一個簡單的四則運算程式後
你發現你只要不小心打了一個不是數字的字進textBox就會出錯
這是多麼令人傷心啊(咦?)

好啦,這不是重點
其實程式設計就是這樣
要先將會使用的人想成是電腦白癡之外
還要假設他們看不懂中文
明明就叫你輸入數字了,你偏要打英文甚至是中文字進去是怎樣 XD
所以寫程式的人就要在這種小細節用心 囧rz
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
    if ((int)e.KeyChar < 48 | (int)e.KeyChar > 57)
    {
        e.Handled = true;
    }
}
這樣就可以讓該textBox無法輸入數字以外的字
不過問題來了
你會發現連Backspace也不能用了
對寫程式的人來說覺得沒差
不過竟然發現了就改進一下吧 XD
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (((int)e.KeyChar < 48 | (int)e.KeyChar > 57) & (int)e.KeyChar!=8)
    {
        e.Handled = true;
    }
}

2010年11月3日 星期三

[VB] 跟IIf說再見~

VB.Net在VS2005有個函數叫IIf
簡單舉例用法如下:
Dim age As Integer = 18
MsgBox(IIf(age >= 18, "可看限制級", "不可看限制級"))
此例即是輸出判斷式為真的"可看限制級"

不過IIf其實在VS2008是不建議使用的
建議改以效率較佳的If替代
因為IIf不論判斷式為真或假,皆會去運算後面的兩個內容
這樣除了效率較差,亦有可能會產生錯誤
而If則只運算符合判斷式的內容
舉個例子最快~
Dim a As Integer = 4
Dim b As Integer = 0
MsgBox(If(True, a, a \ b))
Dim a As Integer = 4
Dim b As Integer = 0
MsgBox(IIf(True, a, a \ b))
前者用If,因為判斷式為true,所以不會去運算後面的 4 \ 0
而IIf即便為true,也一樣會去運算 4 \ 0而導致發生錯誤

[VB] 作業 - 點餐機

-----------題目開始:分隔線-----------
玖何呷特惠套餐:
A.義式蕃茄義大利麵 298元
B.雲泰辣炒河粉 229元
C.墨魚海鮮焗麵 239元
D.烏骨雞湯煲飯 319元
E.韓式泡菜豬排拌鍋飯 359元

是否加點甜品?
A.草莓慕斯 +20元 (原價45元)
B.黑森林蛋糕 +15元 (原價42元)
C.法式千層派 +25元 (原價50元)

套餐點麵(A、C)甜品原價計算

飲料:+30元
A.薰衣草奶茶
B.薄荷清茶
C.拿鐵抹茶 +10元
D.曼特寧咖啡 +5元

若加點甜品,飲料可折抵10元
若甜品與飲料都未點,則不可折抵10元

1.可重覆點餐 (點菜機上需加上份數)
2.五人同行一人免費 (點菜機上需可輸入人數,點的套餐裡最便宜的免費,甜品飲料原價)
3.同一套餐第二人點,第二份可打9折(點的份數為偶數第二份才能打折)
4.消費滿2000元加送一道沙拉(每個人都有但只能單選一種:A.陽光沙拉、B.水果沙拉、C.洋芋沙拉)
5.顯示點餐明細與金額EX:烏骨雞湯煲飯3份、草莓慕斯1份、薄荷清茶2杯,合計1030元)
6.顯示欲找金額(點菜機上需輸入顧客付的金額,並顯示應找金額
EX:輸入1100元,應找70元-->應找50元1個、10元2個
不需要找的面額不可顯示,注意應找金額不可有小數點)
7.請在程式中加入一個迴圈判斷
-----------題目結束:分隔線-----------

這學期去上資工的網頁程設
沒教Asp.Net也就算了,VB.Net還從頭教起,又淺到不行
每週出一個作業,總算在上週出了一個算是有難度的作業
不過這個作業的難度在於....題目的邏輯很奇怪

就真實生活面來說:
‧說是套餐卻所有東西都要加錢,有這種套餐嗎?
‧五人同行一人免費(套餐免費) ,但如果五個人只點一套套餐呢?
‧那十人同行呢? 是兩套免費嗎?

就程設面來說:
‧因套餐跟附加的要綁在一起才能決定價格,所以這個可重覆點餐的要求就很怪
‧甜點折價非固定額,難搞 XD

好啦,雖然說題目出得相當不好寫
但是你知道,寫程式就是這樣子
客人要啥程式 ,就算是不合理也要自己想辦法寫出來
所以就當做是給自己的磨練吧

因為我一直在VB跟C#間切來切去(學校上課寫VB,但是我生活上用C#)
老實說常常被有差異的一些語法搞到很煩
所以這個程式就先以能交再說,自己設計一些簡單的條件
讓這支程式能比較合理化也比較好寫
期中考完有空再來寫功能上更加完善的C#版本

本程式在不違反題目條件以外的自行設定條件:
‧有低消,一人最少需點一套套餐,讓五人同行一餐免費合理化
‧除套餐外不提供單點甜點與飲料(這是為了方便自己寫程式 XD)

最後寫出來的程式....
首先要先來個操作說明文件 XD
再來就是實際運作的情況啦

還多弄了一個以套餐分類顯示明細的功能
也可以方便自己Debug用....

2010年8月22日 星期日

新Blog啟動

因為公司會擋Pixnet,所以申請一個沒被擋到的
來發一些PC維修上的文章&其他Blah Blah
頭香已經被另一位作者搶去了 Q_Q
有空的話應該也會把我發的文章同步轉去Pixnet,以上

首篇

測試O_O