循環結構
循環結構允許重複執行一行或數行程式碼。 VisualBasic支援的循環結構有:
1.Do...Loop
2.For...Next
3.ForEach...Next
Do...Loop
用Do迴圈重複執行一語句塊,且重複次數不定。 Do...Loop語句有幾種演變形式,但每種都會計算數值條件以決定是否繼續執行。如同If...Thencondition必須是數值或值為True(非零)或False(零)的表達式。在下面的Do...Loop循環中,只要condition為True就執行statements。
DoWhilecondition
statements
Loop
當VisualBasic執行這個Do迴圈時會先測試condition。如果condition為False(零),則跳過所有語句。如果condition為True(非零),則VisualBasic執行語句,然後退回到DoWhile語句再測試條件。
因此,只要condition為True或非零,循環可以隨意執行多少次。如果condition一開始便為False,則不會執行語句。例如,以下程序將計算某一目標字串在另一字串中出現的次數,只要發現目標字串就執行循環:
FunctionCountStrings(longstring,target)
Dimposition,count
position=1
DoWhileInStr(position,longstring,target)
position=InStr(position,longstring,target)_
1
count=count 1
Loop
CountStrings=count
EndFunction
如果目標字串未出現在另一個字串中,則InStr傳回0,而且不再執行循環。
Do...Loop語句的另一種演進形式是先執行語句,然後在每次執行後測試condition。這種形式保證statements至少執行一次:
Do
statements
LoopWhilecondition
其它兩種演變形式類似於前兩個,所不同的是,只要condition為False而不是True,它們就會執行循環。
For...Next000
在不知道迴圈內需要執行多少次語句時,宜用Do迴圈。但是,在知道要執行多少次時,則最好使用For...Next循環。與Do迴圈不同,For迴圈使用一個叫做計數器的變量,每重複一次迴圈之後,計數器變數的值就會增加或減少。 For迴圈的語法如下:
Forcounter=startToend[Stepincrement]
statements
Next[counter]
參數Counter、Start、end和increment都是數值型的。
注意increment參數可正可負。如果increment為正,則Start必須小於等於end,否則無法執行循環內的語句。如果increment為負,則Start必須大於等於end,這樣才能執行循環體。如果沒有設定Step,則increment缺省值為1。
執行For迴圈時,VisualBasic
1.設定counter等於start。
2.測試counter是否大於end。若是的話,則VisualBasic退出循環。 (若increment為負,則VisualBasic測試counter是否小於end。)
3.執行語句。
4.counter增加一,或增加increment(如果已指定的話)。
5.重複步驟2到步驟4。
以下程式碼列印所有有效的螢幕字體名稱:
PRivateSubForm_Click()
DimIAsInteger
Fori=0ToScreen.FontCount
PrintScreen.Fonts(i)
Next
EndSub
在VCR範例應用程式中,HighlightButton流程使用For...Next循環,一步步經過VCR窗體的控制項集合,並顯示適當的Shape控制項:
SubHighlightButton(MyControlAsVariant)
DimiAsInteger
Fori=0TofrmVCR.Controls.Count-1
IfTypeOffrmVCR.Controls(i)IsShapeThen
IffrmVCR.Controls(i).Name=MyControlThen
frmVCR.Controls(i).Visible=True
Else
frmVCR.Controls(i).Visible=False
EndIf
EndIf
Next
EndSub
ForEach...Next
ForEach...Next循環與For...Next循環類似,但它對數組或物件集合中的每個元素重複一組語句,而不是重複語句一定的次數。如果不知道一個集合有多少元素,ForEach...Next循環非常有用。
ForEach...Next循環的語法如下:
ForEachelementIngroup
statements
Nextelementt
例如,下面的子程序打開Biblio.mdb,把每個表的名字加到列錶框中。
SubListTableDefs()
DimobjDbAsDatabase
DimMyTableDefasTableDef
SetobjDb=OpenDatabase(c:/vb/biblio.mdb,_
True,False)
ForEachMyTableDefInobjDb.TableDefs()
List1.AddItemMyTableDef.Name
NextMyTableDef
EndSub
記得使用ForEach...Next時的幾點限制:
1.對集合,element只能是Variant變量,或一般的Object變量,或“物件瀏覽器”中列出的物件。
2.對數組,element只能是Variant變數。
3.ForEach...Next不能與使用者自訂類型的陣列一起使用,因為Variant不可能包含使用者自訂類型。
使用控制結構
嵌套控制結構可以將控制結構放入另一個控制結構之內(例如在For...Next循環中的If...Then塊)。一個控制結構內部包含另一個控制結構叫做nest(嵌套)。在VisualBasic中,控制結構的嵌套層數沒有限制。依一般習慣,為了使判定結構和循環結構更具可讀性,總是用縮排方式書寫判定結構或循環的正文部分。
例如,下面的過程要把印表機和螢幕共有的字型名稱全部列印出來:
PrivateSubForm_Click()
DimSFont,PFont
ForEachSFontInScreen.Fonts()
ForEachPFontInPrinter.Fonts()
IfSFont=PFontThen
PrintSFont
EndIf
NextPFont
NextSFont
EndSub
注意,第一個Next關閉了內層的For循環,而最後一個For關閉了外層的For循環。同樣,在巢狀的If語句中,EndIf語句會自動與最靠近的前一個If語句配對。嵌套的Do...Loop結構的工作方式也是一樣的,最內圈的Loop語句與最內圈的Do語句相符。
退出控制結構
用Exit語句可以直接退出For迴圈、Do迴圈、子程序或函數過程。 Exit語句的語法很簡單:ExitFor在For迴圈中出現的次數沒有限制,ExitDo在Do迴圈中出現的次數也沒有限制。
Forcounter=startToend
[Stepincrement]
[statementblock]
[ExitFor]
[statementblock]
Next[counter[,counter][,...]]
Do[{While|Until}condition]
[statementblock]
[ExitDo]
[statementblock]
Loop
ExitDo語句可以在Do循環語法的所有版本中使用。
ExitFor和ExitDo非常有用,因為它有時適於立即退出循環,而且不再執行循環中的任何進一步迭代或語句。例如,在前面的列印畫面和印表機共有字體的例子中,程式不斷將印表機字體和給定的螢幕字體作比較,甚至在已經找到了一個相符的打字機字體後還在繼續尋找。對這個函數有一個效率更高的改進版,在此,只要找到相符的字體後就立即退出循環:
PrivateSubForm_Click()
DimSFont,PFont
ForEachSFontInScreen.Fonts()
ForEachPFontInPrinter.Fonts()
IfSFont=PFontThen
PrintSfont
ExitFor '退出內圈循環。
EndIf
NextPFont
NextSFont
EndSub
如同此例所顯示的,Exit語句幾乎總是出現在If語句或SelectCase語句內部,而If語句或SelectCase語句則在迴圈內嵌套。
用Exit語句中斷迴圈時,計數器變數的值會因退出迴圈的方式而不同:
1.完成循環時,計數器的值等於上限值加上步進值。
2.提前退出循環時,計數器變數保持其值,並遵從有關取值範圍的一般規則。
3.在集合之外疊代時,如果計數器變數為Object類型,則其值為Nothing;如果計數器變數為Variant類型,則其值為Empty。
退出子過程或函數過程
也可從控制結構內部退出過程。 ExitSub和ExitFunction的語法,和上一節「退出控制結構」的ExitFor和ExitDo相似。 ExitSub可以出現在子過程主體內的任何地方,出現的次數隨需要而定。
當過程已完成每個任務並可直接返回時,ExitSub和ExitFunction是非常有用的。例如,如果想改動前面的例子,使得對查找到的印表機和螢幕的共有字體,只列印其中的第一個,則可用ExitSub:
PrivateSubForm_Click()
DimSFont,PFont
ForEachSFontInScreen.Fonts()
ForEachPFontInPrinter.Fonts()
IfSFont=PFontThen
PrintSfont
ExitSub '退出過程。
EndIf
NextPFont
NextSFont
EndSub
->