VB.NET If Then Else 筆記(基礎篇)
If Then Else 是 VB.NET 中最常用的條件判斷語法。只要程式需要依照資料狀態走不同流程,例如檢查輸入、判斷資格、分級顯示、提示錯誤或切換狀態,就會用到條件判斷。
If Then Else 的核心不是把條件堆在一起,而是讓程式流程清楚分流。條件成立時走一段,不成立時走另一段;若條件很多,則由上往下依序檢查,第一個成立的分支會先被執行。
先理解 If Then Else 在做什麼
If Then Else:依照條件式的結果是 True 或 False,決定接下來要執行哪一段程式碼。條件式通常來自比較運算、布林變數或多個條件組合。
條件判斷的核心觀念
- If:開始檢查第一個條件。
- Then:條件成立時執行後方或下方程式區塊。
- ElseIf:前面條件不成立時,繼續檢查下一個條件。
- Else:前面所有條件都不成立時,執行預設處理。
- End If:結束多行條件判斷區塊。
| 寫法 | 用途 | 適合情境 |
|---|---|---|
| 單一 If | 條件成立才做事。 | 只有成立時需要處理。 |
| If...Else | 成立與不成立各有處理。 | 結果只有兩種方向。 |
| If...ElseIf...Else | 多個條件依序分流。 | 分級、狀態、門檻判斷。 |
| 巢狀 If | 條件成立後再細分。 | 先通過第一層檢查,才需要第二層判斷。 |
基本寫法與條件順序
單一條件
If stockCount = 0 Then
LabelStatus.Text = "目前缺貨"
End If
雙分支條件
If amount >= 500D Then
LabelStatus.Text = "符合折抵門檻"
Else
LabelStatus.Text = "尚未達到折抵門檻"
End If
多重條件
If score >= 90 Then
LabelStatus.Text = "等級:A"
ElseIf score >= 80 Then
LabelStatus.Text = "等級:B"
ElseIf score >= 70 Then
LabelStatus.Text = "等級:C"
Else
LabelStatus.Text = "等級:待加強"
End If
條件順序很重要
ElseIf 會由上往下檢查。若先寫較寬鬆條件,再寫較嚴格條件,後面的嚴格分支可能永遠不會被執行。例如分數判斷應先檢查 >= 90,再檢查 >= 80。
單一條件與雙分支判斷
場景一:自習室座位開放判斷
這個範例用剩餘座位數判斷是否仍可入場。輸入有效數字後,若剩餘座位大於 0,就顯示可入場;否則顯示已額滿。
需要的主控項
TextBoxSeatLeft:輸入剩餘座位數。ButtonCheckSeat:檢查座位狀態。LabelSeatStatus:顯示判斷結果。
範例程式碼
Public Class Form1
Private Sub ButtonCheckSeat_Click(sender As Object, e As EventArgs) Handles ButtonCheckSeat.Click
Dim seatLeft As Integer
If Not Integer.TryParse(TextBoxSeatLeft.Text.Trim(), seatLeft) Then
LabelSeatStatus.Text = "座位數格式錯誤"
Return
End If
If seatLeft < 0 Then
LabelSeatStatus.Text = "座位數不可小於 0"
Return
End If
If seatLeft > 0 Then
LabelSeatStatus.Text = "自習室狀態:可入場"
Else
LabelSeatStatus.Text = "自習室狀態:已額滿"
End If
End Sub
End Class
邏輯解析
- 先用
Integer.TryParse檢查輸入是否能轉成整數。 - 負數不符合座位數意義,因此先用
Return結束流程。 - 有效資料才進入主要判斷,流程會比較清楚。
多重條件與分級判斷
場景二:包裹重量級距判斷
包裹重量可依級距分成輕量、標準、加重與超重。這種互斥分級很適合使用 If...ElseIf...Else,並且從特殊或較高門檻開始判斷。
需要的主控項
TextBoxPackageWeight:輸入包裹重量,單位公斤。ButtonCheckPackage:檢查包裹級距。LabelPackageLevel:顯示級距。LabelPackageFee:顯示處理費。
範例程式碼
Public Class Form1
Private Sub ButtonCheckPackage_Click(sender As Object, e As EventArgs) Handles ButtonCheckPackage.Click
Dim weight As Decimal
If Not Decimal.TryParse(TextBoxPackageWeight.Text.Trim(), weight) Then
LabelPackageLevel.Text = "重量格式錯誤"
LabelPackageFee.Text = String.Empty
Return
End If
If weight <= 0D Then
LabelPackageLevel.Text = "重量必須大於 0"
LabelPackageFee.Text = String.Empty
Return
End If
If weight > 20D Then
LabelPackageLevel.Text = "包裹級距:超重件"
LabelPackageFee.Text = "處理費:300 元"
ElseIf weight > 10D Then
LabelPackageLevel.Text = "包裹級距:加重件"
LabelPackageFee.Text = "處理費:180 元"
ElseIf weight > 3D Then
LabelPackageLevel.Text = "包裹級距:標準件"
LabelPackageFee.Text = "處理費:90 元"
Else
LabelPackageLevel.Text = "包裹級距:輕量件"
LabelPackageFee.Text = "處理費:50 元"
End If
End Sub
End Class
邏輯解析
- 重量級距會互相排斥,因此只會進入其中一個分支。
- 先判斷
> 20,再判斷> 10,可避免高重量被低門檻先攔截。 Else放最後,代表所有前面條件都不符合時的預設結果。
條件組合:AndAlso、OrElse、Not
| 運算子 | 意思 | 常見用途 |
|---|---|---|
| AndAlso | 兩個條件都成立才成立。 | 資格檢查、格式檢查、範圍判斷。 |
| OrElse | 任一條件成立即可。 | 多種通過條件、多種例外情況。 |
| Not | 反轉布林結果。 | 不是空白、尚未勾選、尚未完成。 |
短路判斷:AndAlso 與 OrElse 會在結果已經確定時停止檢查後面的條件。一般條件流程建議優先使用這兩個短路版本。
場景三:手作課程報名資格
這個範例同時檢查姓名、年齡、同意條款與是否具備優先資格。一般報名需要姓名、年齡達標且同意條款;若是內部邀請碼,則可直接通過資格檢查。
需要的主控項
TextBoxSignupName:輸入報名名稱。TextBoxSignupAge:輸入年齡。CheckBoxAgreeRule:是否同意活動規範。CheckBoxInviteCode:是否具備邀請碼。ButtonCheckSignup:檢查資格。LabelSignupStatus:顯示結果。
範例程式碼
Public Class Form1
Private Sub ButtonCheckSignup_Click(sender As Object, e As EventArgs) Handles ButtonCheckSignup.Click
Dim age As Integer
If Not Integer.TryParse(TextBoxSignupAge.Text.Trim(), age) Then
LabelSignupStatus.Text = "年齡格式錯誤"
Return
End If
Dim hasName As Boolean = Not String.IsNullOrWhiteSpace(TextBoxSignupName.Text)
Dim ageValid As Boolean = age >= 12
Dim ruleAccepted As Boolean = CheckBoxAgreeRule.Checked
Dim hasInviteCode As Boolean = CheckBoxInviteCode.Checked
Dim normalQualified As Boolean = hasName AndAlso ageValid AndAlso ruleAccepted
Dim canSignup As Boolean = normalQualified OrElse hasInviteCode
If canSignup Then
LabelSignupStatus.Text = "報名資格:通過"
Else
LabelSignupStatus.Text = "報名資格:未通過"
End If
End Sub
End Class
邏輯解析
Not String.IsNullOrWhiteSpace(...)用來判斷名稱不是空白。AndAlso表示一般資格中的每一項都要成立。OrElse表示一般資格成立或具備邀請碼,任一條件成立即可。- 複雜條件先拆成布林變數,可讀性會比直接塞進
If更好。
巢狀 If 與提前結束
巢狀 If:一個 If 區塊裡面再放另一個 If。適合「第一層成立後,才需要檢查第二層」的情境。若只是單純多個分級,通常用 ElseIf 會更清楚。
場景四:倉庫領料流程檢查
領料流程需要先確認料號存在,再確認庫存是否足夠,最後確認是否需要主管覆核。這種流程有明顯先後順序,適合使用提前結束降低巢狀層數。
需要的主控項
TextBoxPartNo:輸入料號。TextBoxRequestQty:輸入領料數量。CheckBoxManagerApproved:是否已主管覆核。ButtonCheckMaterial:檢查領料流程。LabelMaterialStatus:顯示結果。
範例程式碼
Public Class Form1
Private Sub ButtonCheckMaterial_Click(sender As Object, e As EventArgs) Handles ButtonCheckMaterial.Click
Dim partNo As String = TextBoxPartNo.Text.Trim().ToUpper()
Dim requestQty As Integer
If partNo = String.Empty Then
LabelMaterialStatus.Text = "請輸入料號"
Return
End If
If Not Integer.TryParse(TextBoxRequestQty.Text.Trim(), requestQty) OrElse requestQty <= 0 Then
LabelMaterialStatus.Text = "領料數量格式錯誤"
Return
End If
Dim partExists As Boolean = (partNo = "P-A100" OrElse partNo = "P-B200")
If Not partExists Then
LabelMaterialStatus.Text = "料號不存在"
Return
End If
Dim stockQty As Integer
If partNo = "P-A100" Then
stockQty = 30
Else
stockQty = 8
End If
If requestQty > stockQty Then
LabelMaterialStatus.Text = "庫存不足,目前庫存:" & stockQty.ToString()
Return
End If
If requestQty > 10 AndAlso Not CheckBoxManagerApproved.Checked Then
LabelMaterialStatus.Text = "超過 10 件,需要主管覆核"
Return
End If
LabelMaterialStatus.Text = "領料檢查通過"
End Sub
End Class
邏輯解析
- 前面的條件不通過時直接
Return,可避免後面邏輯繼續執行。 - 這種寫法可以減少多層巢狀,讓主要通過流程留在下方。
- 條件有明顯先後依賴時,先檢查基礎條件,再檢查細節條件。
多個獨立判斷
場景五:飲料訂單摘要判斷
有些判斷不是同一組分支,而是多個獨立面向。例如付款狀態、訂單金額級距、是否需要提醒補庫存,彼此可以分開寫成不同 If 區塊。
需要的主控項
TextBoxOrderAmount:輸入訂單金額。TextBoxCupCount:輸入杯數。CheckBoxPaid:是否已付款。ButtonReviewDrinkOrder:檢查訂單。LabelPayStatus:顯示付款狀態。LabelOrderLevel:顯示訂單級距。LabelPrepareHint:顯示備料提醒。
範例程式碼
Public Class Form1
Private Sub ButtonReviewDrinkOrder_Click(sender As Object, e As EventArgs) Handles ButtonReviewDrinkOrder.Click
Dim amount As Decimal
Dim cupCount As Integer
If Not Decimal.TryParse(TextBoxOrderAmount.Text.Trim(), amount) OrElse amount <= 0D Then
LabelPayStatus.Text = "訂單金額格式錯誤"
LabelOrderLevel.Text = String.Empty
LabelPrepareHint.Text = String.Empty
Return
End If
If Not Integer.TryParse(TextBoxCupCount.Text.Trim(), cupCount) OrElse cupCount <= 0 Then
LabelPayStatus.Text = "杯數格式錯誤"
LabelOrderLevel.Text = String.Empty
LabelPrepareHint.Text = String.Empty
Return
End If
If CheckBoxPaid.Checked Then
LabelPayStatus.Text = "付款狀態:已付款"
Else
LabelPayStatus.Text = "付款狀態:待付款"
End If
If amount >= 1500D Then
LabelOrderLevel.Text = "訂單級距:大型訂單"
ElseIf amount >= 500D Then
LabelOrderLevel.Text = "訂單級距:一般訂單"
Else
LabelOrderLevel.Text = "訂單級距:小額訂單"
End If
If cupCount >= 20 Then
LabelPrepareHint.Text = "備料提醒:需要提前分杯"
Else
LabelPrepareHint.Text = "備料提醒:一般流程"
End If
End Sub
End Class
邏輯解析
- 付款、金額級距與備料提醒是三個不同判斷面向。
- 不同面向分成不同
If區塊,會比硬塞成一大串ElseIf更清楚。 ElseIf適合互斥分支;多個獨立結果則適合多段If。
綜合應用:圖書借閱檢查面板
場景六:借閱規則與提示訊息
這個範例整合輸入驗證、條件順序、布林組合、多重條件與多個獨立判斷。流程先確認輸入格式,再判斷是否可借閱,最後依借閱天數與冊數顯示提示。
需要的主控項
TextBoxBookCount:輸入借閱冊數。TextBoxBorrowDays:輸入借閱天數。CheckBoxHasOverdue:是否有逾期未還。CheckBoxIsMember:是否為有效會員。ButtonCheckBorrowRule:檢查借閱規則。LabelBorrowStatus:顯示可否借閱。LabelBorrowLevel:顯示借閱量級。LabelBorrowHint:顯示提醒。
範例程式碼
Public Class Form1
Private Sub ButtonCheckBorrowRule_Click(sender As Object, e As EventArgs) Handles ButtonCheckBorrowRule.Click
Dim bookCount As Integer
Dim borrowDays As Integer
LabelBorrowStatus.Text = String.Empty
LabelBorrowLevel.Text = String.Empty
LabelBorrowHint.Text = String.Empty
If Not Integer.TryParse(TextBoxBookCount.Text.Trim(), bookCount) OrElse bookCount <= 0 Then
LabelBorrowStatus.Text = "借閱冊數格式錯誤"
Return
End If
If Not Integer.TryParse(TextBoxBorrowDays.Text.Trim(), borrowDays) OrElse borrowDays <= 0 Then
LabelBorrowStatus.Text = "借閱天數格式錯誤"
Return
End If
Dim isMember As Boolean = CheckBoxIsMember.Checked
Dim hasOverdue As Boolean = CheckBoxHasOverdue.Checked
Dim countAllowed As Boolean = bookCount <= 8
Dim daysAllowed As Boolean = borrowDays <= 30
Dim canBorrow As Boolean = isMember AndAlso Not hasOverdue AndAlso countAllowed AndAlso daysAllowed
If canBorrow Then
LabelBorrowStatus.Text = "借閱狀態:可借閱"
Else
LabelBorrowStatus.Text = "借閱狀態:不可借閱"
End If
If bookCount >= 6 Then
LabelBorrowLevel.Text = "借閱量級:大量借閱"
ElseIf bookCount >= 3 Then
LabelBorrowLevel.Text = "借閱量級:一般借閱"
Else
LabelBorrowLevel.Text = "借閱量級:少量借閱"
End If
If Not isMember Then
LabelBorrowHint.Text = "提醒:會員狀態未啟用"
ElseIf hasOverdue Then
LabelBorrowHint.Text = "提醒:需先歸還逾期書籍"
ElseIf Not countAllowed Then
LabelBorrowHint.Text = "提醒:借閱冊數不可超過 8 本"
ElseIf Not daysAllowed Then
LabelBorrowHint.Text = "提醒:借閱天數不可超過 30 天"
Else
LabelBorrowHint.Text = "提醒:請於期限內歸還"
End If
End Sub
End Class
整合重點
- 格式錯誤與無效數值先處理,避免後續判斷使用錯誤資料。
canBorrow把主要借閱資格整理成一個布林變數。- 借閱狀態、借閱量級與提醒訊息是不同面向,因此分段判斷。
- 提醒訊息使用
ElseIf,讓最需要處理的原因只顯示一個。
實務判斷與常見誤區
常見問題整理
- 條件順序錯誤:分級判斷應先寫較特殊或較嚴格的條件。
- 沒有先驗證輸入:文字框內容應先轉型成功,再進入數值比較。
- 巢狀太深:多層判斷會讓流程難以閱讀,可用提前結束降低層數。
- 把不同面向硬寫成同一串 ElseIf:互斥結果適合
ElseIf,獨立結果應拆成多段If。 - 條件式太長:可先拆成有意義的布林變數,再放入
If。 - 忽略短路判斷:一般條件組合建議優先使用
AndAlso與OrElse。
| 需求 | 建議寫法 | 原因 |
|---|---|---|
| 只有成立時要處理 | 單一 If |
不需要寫多餘的 Else。 |
| 兩種結果擇一 | If...Else |
成立與不成立各有清楚流程。 |
| 互斥分級 | If...ElseIf...Else |
由上往下找到第一個成立分支。 |
| 前置檢查失敗就停止 | If ... Then Return |
減少巢狀層數,讓主要流程更清楚。 |
| 多個條件同時判斷 | AndAlso、OrElse、Not |
可組合多個布林條件。 |
重點整理
If Then Else用來依條件結果分流程式流程。If後方條件必須能得到True或False。ElseIf會由上往下依序檢查,第一個成立分支會被執行。- 分級判斷通常要先寫較嚴格或較特殊的條件。
- 輸入資料應先驗證格式,再進入條件比較。
AndAlso、OrElse與Not可用來組合布林條件。- 巢狀判斷不宜過深,可用提前結束讓流程更清楚。
- 互斥結果適合
ElseIf;不同面向的結果應拆成多個獨立If區塊。