Download presentation
Presentation is loading. Please wait.
1
第十章 陣列
2
章節預覽 理論與Visual Basic相關基本知識 控制項 10.1 陣列 10.2 動態陣列與靜態陣列 10.3 搜尋與排序
10.1 陣列 10.2 動態陣列與靜態陣列 10.3 搜尋與排序 10.4 控制項陣列 控制項 10.5 清單方塊(ListBox)控制項 10.6 下拉式清單方塊(ComboBox)控制項 10.7 功能表(Menu) 10.8 本章整合應用實例
3
10.1:陣列 陣列(重要的資料結構) 陣列是一種儲存大量同性質資料的良好環境,由於不需要使用不同的變數,以及存取陣列元素的方便性,使得大多數的程式設計都看得到陣列的影子。 『陣列』與數學的「矩陣」非常類似。也就是每一個陣列中的元素都有它的編號。更明確地說,『陣列』是一群資料型態相同的變數,並且在記憶體中會以連續空間來加以存放。 例如,存放每月的營業額,可以使用January、February、、、December等12個數值變數來加以儲存,也可以使用陣列來加以儲存,並且只需要使用同一個陣列變數名稱即可,例如:Month (12)。當我們宣告Month(12)陣列時,Month就是陣列名稱,而在記憶體中則會保留13個連續位置分別存放Month(0)~Month(12)陣列元素。 陣列中每個元件(陣列元素)相當於一個變數,透過索引就可以直接取得陣列的指定元素 例如Month(1)~Month(12)存放12個月份的營業額,要取出8月份的營業額,只要使用Month(8)當做變數名稱即可。因此,使用陣列可以免除大量變數命名的問題,使得程式具有較高的可讀性。
4
10.1:陣列 宣告陣列-Dim敘述 由於陣列佔用較大的記憶體空間,因此『陣列』在使用之前必須先加以宣告,而宣告的目的,則是決定要在主記憶體中保留多少個連續空間給該陣列使用,以及宣告陣列中每一個元素的資料型態。 宣告陣列也是使用Dim敘述,以下是陣列宣告語法 【語法說明】: 1. 陣列名稱:陣列名稱的命名規定與變數命名規定相同,盡量採用有意義的英文字或組合字。 2. 索引:索引決定了該陣列為1維陣列、2維陣列、、、。也決定了每一維數的元素數目。舉例如下: 語法:Dim 陣列名稱 (索引1 [.索引2 [.....]]) [As資料型態] 功能:宣告一維(二維、三維、、)陣列,以及元素的資料型態。
5
10.1:陣列 【範例】:假設我們有12個月的營業額要記錄,您可以使用Month也可以使用Trade(交易)做為陣列名稱,如下宣告1維陣列: Dim Trade (12) As Integer 月份 則Trade(7)代表7月份的營業額。 【範例】:假設我們有兩年的每月營業額要記錄,則可以如下宣告2維陣列: Dim Trade (2 , 12) As Integer 年 月份 則Trade(2,7)代表第2年7月份的營業額。 【範例】:假設我們有兩家公司兩年的每月營業額要記錄,則可以如下宣告3維陣列: Dim score (2 , 2 , 12) As Integer 公司 年 月份 則Trade(1,2,7)代表第1家公司第2年7月份的營業額。
6
10.1:陣列 3. As資料形態 資料型態但對於陣列而言,其重要性遠比變數的資料型態來得重要許多,原因是當您宣告了陣列的資料型態之後,陣列中每一個元素都是使用了該資料型態,因此,假設您宣告了過於大的資料型態(例如:只需要Integer卻使用Long資料型態),而該陣列共有100個元素的話,就浪費了100倍的記憶體空間。因此,慎選陣列的資料型態是非常很重要的。 以下是各種常用的陣列基本資料形態宣告: (1) As Integer:【範例】Dim Trade(12) As Integer (2) As Long:【範例】Dim Trade(12) As Long (3) As Single:【範例】Dim Trade(12) As Single (4) As Double:【範例】Dim Trade(12) As Double (5) As String:【範例】Dim Item(12) As String (6) As Variant:【範例】Dim Item(12) As Variant或Dim Item(12)
7
10.1:陣列 4. 陣列宣告時後,若無設定初始值,則數值陣列的每個元素值為0,字串陣列的每個元素值為『空字串』。自由資料型態陣列的每個元素值為『空值』(Empty)。 5. 和全域變數與區域變數一樣,若在某個程序中宣告的陣列,僅僅該程序才可以使用該陣列;若在表單檔的工作區域(一般程序)宣告時,則所有的程序都可以使用該陣列(共用)。 6. 陣列元素可以和其他變數或其他陣列元素做運算。 【範例】: Trade(0)=Trade(1) +Trade(2)+ 、、、+Trade(12) Trade(0)=Trade(1)*12 Trade(0)=Trade(1) +X Trade(0)=Trade(1) +TEST(2)
8
【範例10-1】:使用陣列存放資料。 4 5 6 7 8~10 11~13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29~30 31~32 33~34 35~36 37 Dim WeekDay(7) As String Private Sub Form_Activate() Dim Temper(7) As Single Temper(1) = 28 : Temper(2) = : Temper(3) = 22 Temper(4) = 24 : Temper(5) = : Temper(6) = 26 Temper(7) = 29 Cls FontSize = 12 Print " 溫度統計" Print "========================" For i = 1 To 7 Print WeekDay(i), Temper(i) Temper(0) = Temper(0) + Temper(i) Next i Temper(0) = Temper(0) / 7 Print WeekDay(0), Temper(0) End Sub Private Sub Form_Load() WeekDay(0) = "本周平均" : WeekDay(1) = "星期一" WeekDay(2) = "星期二" : WeekDay(3) = "星期三" WeekDay(4) = "星期四" : WeekDay(5) = "星期五" WeekDay(6) = "星期六" : WeekDay(7) = "星期日"
9
10.1:陣列 陣列索引的下界與上界 Option Base
Visual Basic的陣列索引內定由0開始,所以宣告A(10),代表一共有11個元素可以使用,即A(0)~A(10),若不習慣,Visual Basic也提供了一些變通方法來改變索引的上下界。 Option Base 宣告陣列前,若先使用Option Base則可以將索引值設定為從1開始。以下是語法: 【語法說明】: 1. 符號『|』有「或」的涵義,亦即您可以宣告Option Base 0或Option Base 1。 2. Option Base敘述必須在表單檔宣告區使用,並且必須置於所有Dim敘述之前。 語法:Option Base {0 | 1} 功能:宣告陣列索引值的下界(Low Bound)為0或1。
10
10.1:陣列 3. 省略Option Base敘述,則預設為Option Base 0。(以0為下界)A(n)的陣列元素為n+1個,如下範例: 陣列元件共四個,分別為A(0)、A(1)、A(2)、A(3)。 4.Option Base 1,則A(n)的陣列有n個(1~n),如下範例、 陣列元件共三個,分別為A(1)、A(2)、A(3)。 Option Base '可省略本行 Dim A(3) Option Base 1 Dim A(3)
11
10.1:陣列 直接宣告陣列索引值下界與上界 除了使用Option Base 0與1做為陣列下界宣告之外,我們也可以直接在使用Dim宣告陣列時,指定陣列的下界與上界。語法如下: 【語法說明】: 1. 索引值的下界~上界範圍可以由 -2,147,483,648~2,147,483,647。 例如:Dim A(-3 TO 2),則陣列元素分別為A(-3)、A(-2)、A(-1)、A(0)、A(1)、A(2)等6個元素。 2. 第二次出現的(下界 TO上界)代表第二維的索引範圍。 語法:Dim陣列名稱(下界To上界[,下界To上界...])[As資料型態] 功能:宣告陣列索引值的範圍(從下界到上界)。
12
10.1:陣列 取得陣列索引的上、下界值 語法:L=LBound(陣列名稱[,維數]) 功能:取得指定陣列某一維的索引下界值。
【範例】:假設二維陣列Dim A(100, 50 To 60),則取出的上下界值如下: LBound(A, 1) 回傳值為0。 (第一維的下界值) LBound(A, 2) 回傳值為50。 (第二維的下界值) UBound(A, 1) 回傳值為100。 (第一維的上界值) UBound(A, 2) 回傳值為60。 (第二維的上界值) 語法:L=LBound(陣列名稱[,維數]) 功能:取得指定陣列某一維的索引下界值。 語法:U=UBound(陣列名稱[,維數]) 功能:取得指定陣列某一維的索引上界值。
13
10.1:陣列 初始與宣告陣列函數-Array 函數
使用Dim來宣告陣列,無法同時設定陣列初始值,不過Visual Basic提供了另一個函數可以同時宣告陣列與設定初始值,那就是Array函數,其語法如下: 【語法說明】: 1. Array函數所宣告的陣列為自由型態的陣列。 2. 引數串列:引述串列將做為元素值,由於是自由型態陣列,因此引數中的元素可以是任一種資料型態,並且不必全部相同。當引數個數超過兩個時,使用逗號『,』來加以間隔。而引數個數同時決定了陣列的大小。舉例如下: 語法:Array(引數串列) 功能:宣告自由資料型態的陣列並且直接將引數串列的值指定為陣列元素的初始值。
14
10.1:陣列 【範例】:使用Array函數宣告rainfall_record陣列,同時設定元素初始值如下:
"新竹"為地名(字串);30為雨量(數值);"3月"為月份(字串)。 Array函數所宣告陣列仍受Option Base影響陣列的下界,上例中,rainfall(1)= "新竹"。 Option Base 1 rainfall_record =Array("新竹",30,"3月")
15
10.1:陣列 【範例10-2】: 使用Array宣告陣列。 4 5 6 7 8 9 10 11 12 13 14 15
Option Base 1 Private Sub Form_Activate() Temper = Array(28, 26.5, 22, 24, 23.8, 26) Cls FontSize = 12 Print " 溫度統計" Print "========================" For i = 1 To 6 Print "星期" & i, Temper(i) Next i End Sub
16
10.1:陣列 For Each ...Next 陣列迴圈 陣列與迴圈息息相關,例如透過一個迴圈可以將一維陣列的每一個元素值讀出或存入新值,也可以利用巢狀迴圈將多維陣列的每一個元素值讀出或存入新值。 例如下列範例將九九乘法之結果存入二維陣列A之中: 也可以透過Visual Basic提供的另一種迴圈敘述For Each…Next來完成與陣列有關的運算。 For Each…Next迴圈,稱之為『陣列迴圈』,它將會依照透過陣列元素件個數,決定迴圈內的敘述區塊要重覆執行的次數,其語法如下: Dim A(1 To 9, 1 To 9) As Integer For I = LBound(A, 1) To UBound(A, 1) For J=LBound(A, 2) To UBound(A, 2) A(I,J)=I*J Next J Next I
17
10.1:陣列 【語法說明】: 1. 變數:資料型態必須為Variant。 2. 陣列的元素個數決定了迴圈內的敘述區塊重覆執行的次數。
語法:For Each變數In陣列名稱 [敘述區段] [Exit For] Next 功能:依照陣列元素的個數,決定重複執行敘述區段的次數。 【語法說明】: 1. 變數:資料型態必須為Variant。 2. 陣列的元素個數決定了迴圈內的敘述區塊重覆執行的次數。 3. 每次重覆迴圈時,變數值會等於陣列元素值,並且會由陣列第一個元素開始,依序指定給該變數。 4. 迴圈執行完畢會繼續執行緊接在Next後的敘述。
18
10.1:陣列 【範例10-3】: 使用For Each…Next迴圈讀出陣列元素值。 4 5 6 7 8 9 10 11 12 13 14
15 16 17 18 19 20 Private Sub Form_Activate() Dim A(1 To 9, 1 To 9) As Integer Dim result As Variant For I = LBound(A, 1) To UBound(A, 1) For J = LBound(A, 2) To UBound(A, 2) A(I, J) = I * J Next J Next I FontSize = 12 Sum = 0 For Each result In A Sum = Sum + 1 Print Format(result, "00 "); If Sum Mod 9 = 0 Then Print Next End Sub
19
10.1:陣列 二維陣列與多維陣列 陣列若具有兩個索引稱為『二維陣列』、具有三個索引稱為『三維陣列』,依此類推。二維陣列的使用十分廣泛(僅次於一維陣列)。您可以將二維陣列以數學之矩陣來加以看待,也就是二維陣列是由列(Row)與行(Column)組合而成。每一個元素恰恰落在特定之某一列的某一行。 『列』就是二維陣列的第一維索引,而『行』則是二維陣列的第二維索引,我們以下圖來解說A(4,3)二維陣列在記憶體中的儲存。
20
10.1:陣列 第一季 第二季 第三季 第四季 A(1,1) A(1,2) A(1,3) A(1,4) A(2,1) A(2,2)
我們可以用二維陣列來表示複雜的資料,例如使用橫列來表示各分公司的營運狀況,直行表示各季的營業額,並事先宣告Option Base 1,使用『1』做為陣列索引下界。則可以如下圖安排整間公司的總體營運狀況。 以上的二維陣列宣告,可以使用列與行來分別代表兩個索引,索引之間則必須以逗號『,』加以分隔,宣告如下: 第一季 第二季 第三季 第四季 A(1,1) A(1,2) A(1,3) A(1,4) A(2,1) A(2,2) A(2,3) A(2,4) A(3,1) A(3,2) A(3,3) A(3,4) 台北總公司(第1列) 新竹園區(第2列) 高雄分公司(第3列) Option Base 1 Dim A(3,4) As Integer
21
10.1:陣列 完整的二維陣列宣告語法如下: 在上面的營運業績範例,A(3,4)陣列共有(3*4)=12個元素,若要取得高雄分公司第3季的營業額,則應該以相對應的索引值來加以取得,也就是A(3,3)。 二維陣列可以使用表格來加以示意,三維陣列則需要使用三度空間圖形加以示意,更多維度的陣列則無法使用幾何圖形來示意,但存取方法也大同小異。 盡量使用1~3維陣列來儲存資料,過多的維數將容易造成程式撰寫不易且維護困難的問題。 語法:Dim 陣列名稱 (索引1,索引2) [As資料型態] 功能:宣告二維陣列,以及元素的資料型態。
22
【範例10-4】:使用二維陣列存放學生的期中考成績
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 Option Base 1 Private Sub Form_Activate() Dim Score(5, 4) As Single Score(1, 1) = 85: Score(1, 2) = 78: Score(1, 3) = 65 Score(2, 1) = 75: Score(2, 2) = 85: Score(2, 3) = 69 Score(3, 1) = 63: Score(3, 2) = 67: Score(3, 3) = 95 Score(4, 1) = 94: Score(4, 2) = 92: Score(4, 3) = 88 Score(5, 1) = 74: Score(5, 2) = 65: Score(5, 3) = 73 FontSize = 10 LoopCount = 0 Print "成績", "計概", "數學", "英文", "平均" Print "===============================================================" Student_Name = Array("鐵雄", "大明", "珍珍", "阿丁", "阿龍") For I = 1 To 5 Print Student_Name(I) & " "; Score(I, 4) = (Score(I, 1) + Score(I, 2) + Score(I, 3)) / 3 For J = 1 To 4 Print Format(Score(I, J), " "); Next J Print Next I End Sub
23
【實作範例10-5】 【實作範例10-5】: 上機實作 使用二維陣列儲存得票數與得票率。 Step1:專案名稱為『p10_05』。
24
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 Option Base 1 Dim PVote(3, 2) As Single Private Sub txtP1_Change() PVote(1, 1) = Val(txtP1.Text) For I = 1 To 3 PVote(I, 2) = 100 * PVote(I, 1) / (PVote(1, 1) + PVote(2, 1) + PVote(3, 1)) Next I lblP1Rate = PVote(1, 2): lblP2Rate = PVote(2, 2): lblP3Rate = PVote(3, 2) End Sub Private Sub txtP2_Change() PVote(2, 1) = Val(txtP2.Text) Private Sub txtP3_Change() PVote(3, 1) = Val(txtP3.Text)
25
10.2:動態陣列與靜態陣列 Visual Basic的陣列其實分為兩種 『動態陣列』與『靜態陣列』的差別在於記憶體的使用狀況
『動態陣列』(Dynamic Array) 『靜態陣列』(Static array) 『動態陣列』與『靜態陣列』的差別在於記憶體的使用狀況 『動態陣列』在程式尚未執行到有關該陣列的宣告之前,並不會配置任何記憶體給該陣列,也就是說,當程式執行到宣告陣列時,才會要求系統配置記憶體空間給動態陣列使用。 『靜態陣列』是程式在載入到記憶體時,同時也要求配置記憶體空間給靜態陣列使用。 因此,動態陣列比較節省記憶體空間的使用率。
26
10.2:動態陣列與靜態陣列 宣告動態陣列有3種方法: Dim敘述:在程序中使用Dim宣告區域陣列
例如:Dim D(100) As Integer。 ReDim敘述:在程序中使用ReDim宣告區域陣列 例如:ReDim D(100) As Integer。 Dim與ReDim敘述:可以先在表單宣告區使用Dim來宣告表單內的空維數『全域陣列』,然後在程序中再以ReDim來宣告陣列的維數與索引之上下界。如下範例: 範例: Dim D() As Integer Private Sub Form_Activate() ReDim D(1 To 10,2 To 50) As Integer End Sub
27
10.2:動態陣列與靜態陣列 宣告靜態陣列有2種方法: 在程序中使用Static來宣告區域陣列
例如:Static S(30) As Integer。 說明: (1) Static宣告語法及使用規則與在程序中的Dim敘述相同 (2) 在程序中,使用Static宣告的陣列,當程式主控權離開程序後,陣列仍然佔用原來的記憶體空間,並且其資料並不會消失,因此,當該程序再次被呼叫可以重覆使用之前在陣列中儲存的資料。 在表單宣告區使用Dim來宣告維數、上下界固定的全域陣列 例如:Dim S(30) As Integer。 在表單宣告區使用Dim宣告的全域靜態陣列,當表單檔被執行時,將一直佔據記憶空間,所以我們可以在所有的程序中,共用陣列中的元素內容。
28
10.2:動態陣列與靜態陣列 【範例10-6】: 比較動態陣列與靜態陣列的差別。 4 5 6 7 8 9 10 11 12 13
Private Sub Form_Click() Dim D(1 To 3) As Integer Static S(1 To 3) As Integer FontSize = 12 For i = 1 To 3 D(i) = D(i) + i S(i) = S(i) + i Print "D(" & i; ")=" & D(i) & " S(" & i & ")=" & S(i) Next i End Sub
29
10.2:動態陣列與靜態陣列 清除陣列-Erase敘述
『動態陣列』於程式執行時,可以使用ReDim敘述重新定義陣列的大小,除此之外,也可以利用Erase敘述來清除陣列。所謂清除陣列,其實就是強迫釋放動態陣列的記憶體空間。 『靜態陣列』也可以使用Erase敘述,但『靜態陣列』使用Erase敘述並不會釋放所佔用的記憶體空間,只會將陣列元素重新設為初始值。Erase語法如下: 1. Erase敘述會將靜態陣列設為初始值,數值靜態陣列的元素初始值為0;字串靜態陣列的元素初始值為空字串。 2. 使用Array函數建立的陣列,遇到Erase敘述會被釋放 語法:Erase陣列名稱 功能: 陣列名稱為動態陣列→釋放記憶體空間。 陣列名稱為靜態陣列→陣列元素被設定為初始值。
30
10.2:動態陣列與靜態陣列 【範例10-7】: 使用Erase敘述清除靜態陣列與動態陣列 5 6 7 8 9 10 11 12 13 14
15 16 17 18 Private Sub Form_Activate() Static S(10) As Integer Dim D(10) As Integer S(10) = 100 D(10) = 100 FontSize = 12 Print "使用Erase前" Print "S(10)=" & S(10) & " D(10)="; D(10) Erase S, D Print "使用Erase後" Print "S(10)=" & S(10) 'Print "D(10)="; D(10) End Sub
31
10.3:搜尋與排序 搜尋與排序是程式設計的一項基本且重要的問題。 『搜尋』(Searching) 『排序』(Sorting)
在一堆資料中,尋找您所想要的資料,例如:在英文字典中找尋某一個單字。 本章將介紹最簡單的『循序搜尋法』與常見的『二分搜尋法』。 『排序』(Sorting) 將一堆雜亂的資料,依照某個鍵值(Key Value)依序排列,方便日後的查詢或使用。 例如:英文字典中每個單字就是已經排序後的結果『從a~z』。 本章將介紹『氣泡排序法』。
32
10.3:搜尋與排序 【氣泡排序法】: 『氣泡排序法』是將相鄰兩個資料一一互相比較,依據比較結果,決定是否互換,由於整個執行過程,有如氣泡逐漸浮上水面,因此命名。 假設我們有24,7,36,2,65要做氣泡排序:
33
10.3:搜尋與排序 氣泡排序演算法 輸入:未排序的資料X(1)~X(n) 輸出:已排序的資料 k←n
Do While k<>0 t←0 For i=1 To k-1 If X(i)>X(i+1) Then X(i)←→ X(i+1) 'X(i)與X(i+1)互換 t←i End If Next i k←t Loop
34
10.3:搜尋與排序 【實例說明】: 若陣列的五個元素資料A(1),A(2),A(3),A(4),A(5)要由小到大排序,則以下是詳細步驟:
第一回合: 相鄰兩個資料相互比較,依照下列步驟,最大值將被放入A(5)中: (1) A(1)和A(2)比較,若A(1)>A(2)則資料互換,否則資料不交換。 (2) A(2)和A(3)比較,若A(2)>A(3)則資料互換,否則資料不交換。 (3) A(3)和A(4)比較,若A(3)>A(4)則資料互換,否則資料不交換。 (4) A(4)和A(5)比較,若A(4)>A(5)則資料互換,否則資料不交換。 很容易可以發現,經過上面四次比較之後,最大的資料一定會被放到A(5)之中,如此稱為『第一回合掃描』。
35
10.3:搜尋與排序 五筆資料使用氣泡排序,需經過四個回合的掃描,共比較(4+3+2+1)=10次。 第二回合:
由於在第一回合時,A(1)~A(5)的最大值已經被放到A(5)了,因此在第二回合掃描時,只需要仿照第一回合,將A(1)~A(4)中最大的值放到A(4)中即可(明顯地,第二回合掃描只需要比較3次)。 第三回合: 由於在第一、二回合時,A(1)~A(5)的最大值及第二大值已經被放到A(5)、A(4)了,因此在第三回合掃描時,只需要仿照第一回合,將A(1)~A(3)中最大的值放到A(3)中即可(明顯地,第三回合掃描只需要比較2次)。 第四回合: 由於在第一、二、三回合時,A(1)~A(5)的最大值、第二大值、第三大值已經被放到A(5)、A(4)、A(3)了,因此在第四回合掃描時,只需要仿照第一回合,將A(1)~A(2)中最大的值放到A(2)中即可(明顯地,第四回合掃描只需要比較1次)。 第五回合: 最後剩下A(1),不必比較就知道A(1)中的值是最小的值。(第五回合可省略) 五筆資料使用氣泡排序,需經過四個回合的掃描,共比較( )=10次。 N筆資料做氣泡排序,需要(N-1)次掃描,共比較(N-1)+(N-2)+(N-3)+… = N(N-1)/2次。 在排序過程中,若有某一回合的掃描沒有交換任何的資料,則代表資料已經提早排序完成,此時可掠過後面尚未掃描的回合。因此N(N-1)/2次比較是最差的狀況。
36
10.3:搜尋與排序 【範例10-8】: 使用氣泡排序法,依小到大排序24,7,36,2,65等5個資料。
37
10.3:搜尋與排序 『循序搜尋』 『二分搜尋法』 【範例10-9】:
一種簡單的搜尋方法,也就是從第一筆資料開始尋找,然後是第二筆資料、、、一直到找到所要的資料或全部資料被找完為止。 假設有N筆資料,則最差需要作N次比較,而平均則需要N/2次比較。 通常在資料量比較少或資料未經排序的狀況下使用『循序搜尋法』。 『二分搜尋法』 效率高 將資料一半一半的切割開來,直到找到資料為止 關於『二分搜尋法』將在本章最後一節中加以說明。 【範例10-9】: 使用循序搜尋法在未排序的資料中,尋找所需要的資料『57』。
38
【範例10-9】 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 Option Base 1 Private Sub Form_Activate() Dim Target As Integer find_flag = False Target = 57 Data = Array(74, 41, 54, 86, 63, 57, 33, 79) FontSize = 12 For i = 1 To UBound(Data) Print "資料" & i & " " & Data(i); If Target = Data(i) Then Print " 找到了" find_flag = True Exit For Else Print " 不是要找的資料" End If Next i If Not (find_flag) Then Print "很抱歉,您要找的資料不在陣列中!" End Sub
39
10.4:控制項陣列 『控制項陣列』可以用來代表類似的控制項集合,並且透過索引值來區別同樣物件名稱中的各個控制項。『控制項陣列』語法如下:
控制項陣列中的每一個控制項元素,由於名稱相同,因此觸發的事件程序將會共用,只不過在觸發的同時,會傳進一個Index參數以示區別。 產生控制項陣列: 【方法一】:複製控制項 【方法二】:將兩個不同名稱的同性質控制項的名稱修正為相同名稱 語法:物件(索引值).Index 功能:取得或設定物件(控制項)陣列中某一個物件元素。
40
10.4:控制項陣列 控制項陣列程式設計 控制項陣列 【實作範例10-10】:
修正範例10-5,使用控制項陣列來取代同性質的控制項,以便於使用迴圈設定控制項的屬性值。 上機實作 Step1:專案名稱為『p10_10』。 Step2:在表單上產生下列控制項並設定屬性。 Step3:編輯下頁程式碼。 Step4:執行程式。 控制項陣列
41
【實作範例10-10】 5 6 7 8 9 10 11 12 13 14 15 Private Sub txtP_Change(Index As Integer) Dim Total, Rate As Single Total = 0 For I = 0 To 2 Total = Total + Val(txtP(I).Text) Next I Rate = 100 * Val(txtP(I).Text) / Total lblPRate(I).Caption = Str(Rate) End Sub
42
10.5:清單方塊(ListBox)控制項 『清單方塊』控制項可以用來製作一連串的選項,使用者可以在清單中選擇所需要的選項。
『清單方塊』控制項允許設定單選與複選。 建立『清單方塊』 2:在表單上拉出清單 方塊控制項大小 1:選取清單 方塊工具
43
10.5:清單方塊(ListBox)控制項 『清單方塊』的常用屬性 屬性 屬性值說明 Columns(欄位個數)
設定清單方塊有幾個水平欄位。 List(Index) (選項內容) 設定清單方塊某一選項的內容。Index:索引值 ListCount(項目總數) 設定清單方塊項目總數。 ListIndex(索引值) 設定清單方塊選定項目的索引值。 Text(預選內容) 設定預選的清單項目內容。 Sorted (排序) 設定清單方塊內的項目是否排序(以字母順序)。 MultiSelect(複選) 設定清單方塊內的選項是否允許複選。
44
10.5:清單方塊(ListBox)控制項 『清單方塊』控制項的常用方法(加入與移除項目)
Addltem:加入一個項目到清單方塊中,語法如下: 【語法說明】:執行AddItem方法後,ListIndex屬性會變成『-1』。 Removeltem:從清單方塊中移除某一個項目,語法如下 使用『清單方塊』設計介面,可以透過ListIndex屬性,取得目前被使用者選定的項目索引值,也可以藉由AddItem方法來增加新的項目。 【語法】:[物件名稱].AddItem項目名稱[,索引值] 【語法】:[物件名稱].RemoveItem 索引值
45
【實作範例10-11】 清單方塊的程式設計 【實作範例10-11】: 使用清單方塊,設計一個售票系統。 上機實作
Step1:專案名稱為『p10_11』。 Step2:在表單上產生下列控制項並設定屬性。 Step3:編輯程式碼。
46
3:重複步驟1~2輸入下一個項目 (每次重覆就可以輸入新的項目)
【實作範例10-11】 【設定項目】:您如果要在編輯介面階段,設定清單的項目(List屬性),則可以依照下列步驟: 1:按下拉鈕 3:重複步驟1~2輸入下一個項目 (每次重覆就可以輸入新的項目) 2:輸入第一個項目
47
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Dim Item(10) As String Dim Price(10) As Integer Dim TotalPrice As Long Private Sub cmdOrder_Click() TotalPrice = TotalPrice + Val(txtSubTotal.Text) txtTotal = Str(TotalPrice) txtQty = "0" txtSubTotal = "0" End Sub Private Sub Form_Load() For I = 0 To 5 Item(I) = lstTicket.List(I) Price(I) = 200 Next I Item(6) = "全部兄弟場次": Price(6) = 200 * 3 * 0.95 Item(7) = "全部興農場次": Price(7) = 200 * 3 * 0.8 Item(8) = "全部統一場次": Price(8) = 200 * 3 * 0.85 Item(9) = "全部中信場次": Price(9) = 200 * 3 * 0.8 Item(10) = "全部場次":: Price(10) = 200 * 6 * 0.7 For I = 6 To 10 lstTicket.AddItem Item(I)
48
【實作範例10-11】 30 31 32 33 34 35 36 37 38 39 40 41 Private Sub lstTicket_Click() SelectItem = lstTicket.ListIndex txtTicket = Item(SelectItem) txtPrice = Str(Price(SelectItem)) txtQty = "0" txtSubTotal = "0" txtTotal = Str(TotalPrice) End Sub Private Sub txtQty_Change() txtSubTotal = Str(Val(txtPrice) * Val(txtQty)) Step4:執行程式。
49
10.6:下拉式清單方塊(ComboBox)控制項
『下拉式清單方塊』控制項與清單方塊非常類似,但在某些狀況下,必須先按下『下拉鈕』,然後才能夠選取清單項目 『下拉式清單方塊』控制項還提供了輸入文字的功能。 建立『下拉式清單方塊』 2:在表單上拉出下拉式 清單方塊控制項大小 1:選取下拉式 清單方塊工具
50
10.6:下拉式清單方塊(ComboBox)控制項
『下拉式清單方塊』的3種型式(style屬性) 『下拉式清單方塊』與『清單方塊』的常用屬性大多相同,但『下拉式清單方塊』另外還多了一個style屬性。 style屬性是用來設定下拉式清單方塊的型式,型式一共有3種: 『組合下拉式』清單方塊(style=0) 程式執行時,「清單方塊」會被隱藏,必須按下拉鈕才會顯示方塊內容。使用者可以在「文字方塊」中直接輸入選項名稱,也可以由拉出「清單方塊」選取項目。 【選取項目】: 【直接輸入項目名稱】:
51
10.6:下拉式清單方塊(ComboBox)控制項
『組合式』清單方塊(style=1) 清單方塊出現在下方(設計介面時請拉大ComboBox高度),使用者可以在「文字方塊」中直接輸入選項名稱,也可以由拉出「清單方塊」選取項目。 【選取項目】: 【直接輸入項目名稱】: 『單純下拉式』清單方塊(style=2) 程式執行時,「清單方塊」會被隱藏,必須按下拉鈕才會顯示方塊內容。使用者無法在「文字方塊」中直接輸入選項名稱,但可以由拉出「清單方塊」選取項目。 【無法直接輸入項目名稱】:
52
【實作範例10-12】 下拉式清單方塊的程式設計 【實作範例10-12】:
由於『組合下拉式』清單方塊允許直接在「文字方塊」中輸入項目,因此我們設計一個統計剩餘票系統,當輸入新的項目時,要求使用者輸入該新項目的總票數。 上機實作 Step1:專案名稱為『p10_12』。 Step2:在表單上產生 控制項並設定屬性。 Step3:編輯下頁 程式碼。 Step4:執行程式。
53
【實作範例10-12】 4 5 6 7 8 9 10 11 12 64 65 66 67 68 69 70 71 72 73 74 75 76 Dim Item(10) As String Dim Price(10) As Integer Dim Stock(10) As Integer Private Sub cboTicket_Click() SelectItem = cboTicket.ListIndex txtPrice = Price(SelectItem) txtStock = Stock(SelectItem) End Sub Private Sub Form_Activate() For i = 0 To 4 Item(i) = cboTicket.List(i) Price(i) = 200 Next i Stock(0) = 2223 Stock(1) = 4323 Stock(2) = 3123 Stock(3) = 1769 Stock(4) = 1374 cmdAddNew.Visible = False cmdCancel.Visible = False
54
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 Private Sub cboTicket_KeyDown(KeyCode As Integer, Shift As Integer) If KeyCode = 13 Then '13是Enter鍵 i = 0 Do While i < cboTicket.ListCount If cboTicket.Text = Item(i) Then txtPrice = Price(i) txtStock = Stock(i) Exit Sub End If i = i + 1 Loop If i = cboTicket.ListCount Then AddNew = MsgBox("您要新增項目" + cboTicket.Text + "嗎?", 33) If AddNew = 1 Then cboTicket.Locked = True cmdAddNew.Visible = True cmdCancel.Visible = True txtPrice.SetFocus txtPrice = "" txtStock = "" Else cboTicket.Text = "" End Sub
55
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 78 79 80 81 82 Private Sub cmdAddNew_Click() cboTicket.Locked = False cboTicket.AddItem cboTicket.Text Item(cboTicket.ListCount - 1) = cboTicket.List(cboTicket.ListCount - 1) Price(cboTicket.ListCount - 1) = Val(txtPrice) Stock(cboTicket.ListCount - 1) = Val(txtStock) cboTicket.SetFocus cmdAddNew.Visible = False cmdCancel.Visible = False End Sub Private Sub cmdCancel_Click() cboTicket.Text = "" txtPrice = "" txtStock = "" Private Sub txtPrice_KeyDown(KeyCode As Integer, Shift As Integer) If KeyCode = 13 Then txtStock.SetFocus End If
56
10.7:功能表(Menu) 功能表 一個簡單的功能表如右圖:
之前所設計的程式都是單一畫面或單一功能的程式,如果想要設計更複雜更完整的程式,則需要設計『功能表』。 一個簡單的功能表如右圖: 【名詞】: 1. 標題:功能表列或(次)功能表 選項的文字。 2. 有效指令/失效指令: 有效指令用實體字顯示, 失效指令用虛體字顯示。 3. 快速鍵:可直接按組合鍵執行選項。 核取記號:該選項的開/關狀態。選取此選項時,核取記號由出現變為消失或由消失變為出現。 箭頭符號:該選項之下尚有次功能表。
57
【實作範例10-13】 【實作範例10-13】: 實作上圖的功能表。詳細規格如下: Step1:專案名稱為『p10_13』。
Step2:建立表單名稱為『f10_13』,屬性Caption為『f10_13』,屬性Appearance設為『0-平面』。
58
【實作範例10-13】 Step3:先選取表單,然後執行【工具/功能表編輯器】指令。將出現如下的功能表編輯器對話方塊。
59
【實作範例10-13】 Step4:設定【格式】功能表與【關於】功能表;請按下列步驟設定。 1:輸入。 3:輸入 5:輸入。 7:輸入
4:按下。 2:出現了格式。 6:出現了關於。
60
【實作範例10-13】 Step5:設定【轉換為大寫】指令;請按下列步驟設定。 4:輸入。(&U)將來會變成(U) 6:輸入
7:選取(設定快捷鍵) 5:出現轉換 為大寫(&U) 3:關於被移往下一個 1:選取關於 2:按下 8:按下 9:被移往下一層
61
【實作範例10-13】 Step6:設定【轉換為小寫】指令;請按下列步驟設定。 2:取消啟用。(這樣就變成失效指令)
62
1:於欄位中輸入『-』 ,將來就會變成分隔線。
【實作範例10-13】 Step7:設定『分隔線』;如下畫面(把分隔線當作指令來設定)。 1:於欄位中輸入『-』 ,將來就會變成分隔線。
63
【實作範例10-13】 Step8:參照前面步驟設定『字型』、『第二條分隔線』、『結束』,結果如圖。 設定
64
【實作範例10-13】 Step9:在『第二條分隔線』前插入【底線】指令,並如下設定。 1:輸入 2:輸入
3:勾選(將來指令前就會出現核選記號)
65
【實作範例10-13】 Step10:設定【粗體】指令;請按下列步驟設定。 4:輸入 6:輸入 5:出現了粗體 2:按下 1:選取底線
3:底線被移往下一個 7:按下 8:被移往下一層
66
【實作範例10-13】 Step11:仿照Step10,設定【斜體】指令,結果如圖,最後按下【確定】鈕即可完成功能表的製作。 2:按下
1:設定
67
【實作範例10-14】 『功能表』 程式設計 【實作範例10-14】: 設計一個透過功能表內所提中的指令進行字型設定的程式。 上機實作
Step1:專案名稱為『p10_14』。 Step2:在表單上產生 控制項並設定屬性。並設定 功能表內的指令選項。 Step3:編輯下頁 程式碼。
68
【實作範例10-14】 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Private Sub Form_Load() If mnuUnderline.Checked Then lblResult.FontUnderline = True Else lblResult.FontUnderline = False End If End Sub Private Sub mnuAbout_Click() Cls Print " 版權所有!!" Private Sub mnuBold_Click() lblResult.FontBold = True Private Sub mnuEnd_Click() End Private Sub mnuItalic_Click() lblResult.FontItalic = True
69
【實作範例10-14】 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 Private Sub mnuLowerCase_Click() lblResult.Caption = LCase(txtSource.Text) mnuLowerCase.Enabled = Fasle mnuUpperCase.Enabled = True End Sub Private Sub mnuUnderline_Click() If mnuUnderline.Checked Then mnuUnderline.Checked = False lblResult.FontUnderline = False Else mnuUnderline.Checked = True lblResult.FontUnderline = True End If Private Sub mnuUpperCase_Click() lblResult.Caption = UCase(txtSource.Text) mnuUpperCase.Enabled = Fasle mnuLowerCase.Enabled = True
70
執行【格式/轉換為大寫】、 【格式/底線】、 【格式/字型/粗體】、 【格式/字型/斜體】指令後。
【實作範例10-14】 Step4:執行程式。 執行【格式/轉換為大寫】、 【格式/底線】、 【格式/字型/粗體】、 【格式/字型/斜體】指令後。
71
10.8:本章整合應用實例 【實作範例10-15】: 上機實作 使用陣列、控制項陣列及清單方塊重新設計範例9-14。
Step1:專案名稱為『p10_15』。 Step2:在表單上產生 控制項並設定屬性。 Step3:編輯程式碼。 Step4:執行程式。
72
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 Dim PVote(0 To 5) As Integer Dim PName(0 To 5) As String Private Sub cmdSta_Click() picSta.Cls PI = For I = 0 To 5 If I <= 2 Then ManVotes = ManVotes + PVote(I) Else WomanVotes = WomanVotes + PVote(I) End If Next I If (ManVotes + WomanVotes) > 0 Then ManRate = Int(ManVotes / (ManVotes + WomanVotes) * 100) WomRate = ManRate lblSexRate(0).Caption = Str(ManRate) & "%" lblSexRate(1).Caption = Str(WomRate) & "%" If ManRate > 0 Then picSta.FillStyle = 5 picSta.FillColor = QBColor(1) picSta.Circle(800, 800),800,QBColor(1),-0.01,-2*PI*ManRate/100 If WomRate > 0 Then picSta.FillStyle = 0 picSta.FillColor = QBColor(0) picSta.Circle(800, 800),800,QBColor(0),-2*PI*ManRate/100,-2*PI MsgBox "請先投票!!" End Sub
73
39 40 41 42 43 44 45 46 47~48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70~71 72 73 74 Private Sub cmdVote_Click() If optSex(0).Value = True Then I = 0 Else I = 3 End If For J = 0 To 2 If lstPerson.Selected(J) = True Then PVote(I) = PVote(I) : lblP(J) = PVote(I) I = I + 1 Next J End Sub Private Sub Form_Load() PName(0) = "老沈": PName(1) = "小章": PName(2) = "大千" PName(3) = "阿琴": PName(4) = "阿霞": PName(5) = "阿華" For I = 0 To 5 PVote(I) = 0 Next I Private Sub optSex_Click(Index As Integer) If Index = 0 Then lstPerson.Clear lstPerson.AddItem (PName(I)) : lblP(J) = PVote(I)
74
【實作範例10-16】 1:先對男性投票, 清單方塊的選項可以複選 2:再對女性投票 3:按下【統計】鈕 4:得票分布圓餅圖
75
【範例10-16】二分搜尋法 【範例10-16】:二分搜尋法。
二分搜尋法比循序搜尋法來得有效率許多,平均只需要做log2N+1次比較即可找到資料。雖然速度比較快,但使用二分搜尋法找尋資料必須先將資料經過排序之後,才可以使用用二分搜尋法。以下是用二分搜尋法的原理及步驟
76
【範例10-16】二分搜尋法 二分搜尋法原理: 先從記錄中央開始搜尋,若該記錄比目標還小,則往大的剩餘另一半搜尋,若記錄比目標還還大,則往小的剩餘另一半搜尋,若相等,則找到資料。重覆此步驟直到找到資料為止,或者發現要搜尋的資料不存在。因此,每次會剩下1/2、1/4、1/8、、、,在第k次比較時,最多只剩下『n/2k』筆記錄未搜尋,在最壞的狀況下,只剩單一記錄n/2k =1,所以k=log2n,所以最多的比較次數為log2n。
77
【範例10-16】二分搜尋法 二分搜尋演算法: 輸入:已排序的資料X(1)~X(n)、要找尋的目標資料K 輸出:目標資料的索引值m
Low←1 Upper←n Do While (Low<=Upper) m←(Low+Upper)/ '計算中間位置 Select Case X(m) Case X(m)>K 'K位於上半部 Upper←m-1 Case X(m)<K 'K位於下半部 Low←m+1 Case X(m)=K '找到了 return m End Select Loop return "找不到"
78
【範例10-16】二分搜尋法 【實例說明】: 8個陣列元素A(1)~A(8)為『33,41,52,54,63,74,79,86』, 尋找目標為52,使用二分搜尋法搜尋,則詳細步驟如下: 1. 計算中間位置為(1+8)/2=4.5取整數為4。 2. A(4)=54>52,所以Upper=4-1=3。 3. 計算中間位置為(1+3)/2=2。 4. A(2)=41<52,所以Lower=2+1=3。 5. 計算中間位置為(3+3)/2=3。 6. A(3)=52,所以找到了。
79
【範例10-16】二分搜尋法 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Option Base 1 Private Sub Form_Activate() X = Array(33, 41, 52, 54, 63, 74, 79, 86) K = 52 '搜尋目標K Low = 1 Upper = 8 FontSize = 14 Print "在X陣列中尋找" & K: Print Do While (Low <= Upper) m = Int((Low + Upper) / 2) '計算中間位置 Print "目前正在比對X(" & m & ")=" & X(m) Select Case X(m) Case Is > K 'K位於上半部 Upper = m - 1 Case Is < K 'K位於下半部 Low = m + 1 Case Is = K '找到了 Print: Print "要找的" & K & "位於X(" & m & ")" Exit Sub End Select Loop Print: Print "找不到" & K End Sub
80
10.9:本章回顧 理論與Visual Basic相關基本知識 控制項 陣列 搜尋與排序 動態陣列與靜態陣列 控制項陣列
清單方塊(ListBox)控制項 下拉式清單方塊(ComboBox)控制項 功能表(Menu)
81
本章習題
Similar presentations