เมื่อโค้ดยาวและแมโคร VBA ใช้เวลาทำงานหลายวินาที Excel อาจดูเหมือนค้าง (Frozen) หรือไม่ตอบสนอง (Unresponsive) แม้โค้ดจะทำงานถูกต้อง ผู้ใช้ก็อาจคิดว่าเวิร์กบุ๊กค้าง เพราะไม่มีอะไรเกิดขึ้นบนหน้าจอ วิธีง่ายๆ เพื่อหลีกเลี่ยงปัญหานี้คือ แสดงข้อความแบบเรียลไทม์ (Live Message) ในแถบสถานะ (Status Bar) ของ Excel ขณะที่แมโครทำงาน
ในบทช่วยสอนนี้ เราจะแสดงวิธีแสดงข้อความความคืบหน้าขณะ VBA ทำงาน คุณไม่ต้องการ UserForm หรือแถบความคืบหน้าแบบกราฟิก ในหลายกรณี Application.StatusBar เพียงพอแล้ว
ทำไมต้องใช้ Application.StatusBar?
Excel มีแถบสถานะ (Status Bar) ในตัว ที่ด้านล่างของหน้าต่างโปรแกรม VBA สามารถแทนที่ข้อความปกติในบริเวณนั้นด้วยข้อความกำหนดเองได้ชั่วคราว
นั่นหมายความว่าแมโครของคุณสามารถแสดงการอัปเดตได้ เช่น:
- กำลังประมวลผลแถว 10 จาก 100
- กำลังนำเข้าข้อมูล…
- กำลังเขียนสูตร…
- เสร็จแล้ว 65%
สิ่งนี้มีประโยชน์เมื่อคุณต้องการให้ผู้ใช้รู้ว่าแมโครยังทำงานอยู่ แต่ไม่ต้องทำงานเพิ่มเติมในการสร้างแถบความคืบหน้าแบบกราฟิกเต็มรูปแบบ คุณยังสามารถทำให้ข้อความมีข้อมูลมากขึ้นด้วยการแสดงจำนวนแถวหรือเปอร์เซ็นต์ แต่ยังคงเป็นโซลูชันที่ข้อความเท่านั้น (Text-based)
ไวยากรณ์พื้นฐาน (Basic Syntax):
เพื่อแสดงข้อความในแถบสถานะของ Excel ให้ใช้:
Application.StatusBar = "Processing..."
เมื่อแมโครเสร็จสิ้น ให้รีเซ็ตแถบสถานะด้วย:
Application.StatusBar = False
การตั้งค่า Application.StatusBar = False จะคืนการควบคุมแถบสถานะให้ Excel อนุญาตให้แสดงข้อความเริ่มต้นอีกครั้ง อย่าไม่ทำขั้นตอนนี้เลย
ตัวอย่างพื้นฐาน: ข้อความความคืบหน้าผ่านๆ
นี่คือรูปแบบพื้นฐานที่สุดพร้อมข้อความความคืบหน้าผ่านๆ ในแถบสถานะ จะแสดง "Running report... please wait"
Sub SimpleStatusBar()
Application.StatusBar = "Running report... please wait"
' Simulate work
Dim i As Long
For i = 1 To 50000
' Your processing here
Next i
Application.StatusBar = False ' Restore the status bar
MsgBox "Done!"
End Sub
นี่ทำงานได้ แต่แสดงข้อความคงที่เพียงอย่างเดียว บอกผู้ใช้ว่าแมโครกำลังทำงาน แต่ไม่แสดงความคืบหน้าจริง
แสดงความคืบหน้าแบบเรียลไทม์ในลูป (Loop)
ในแมโครจริงส่วนใหญ่ คุณประมวลผลแถว เซลล์ ไฟล์ หรือเรคคอร์ดทีละรายการ นั่นทำให้ง่ายที่จะอัปเดตแถบสถานะตามความคืบหน้าของลูป
Sub ShowLoopProgress()
Dim i As Long
Dim lastRow As Long
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
For i = 2 To lastRow
' Simple action
Cells(i, "K").Value = "Processed"
' Update progress message
Application.StatusBar = "Processing row " & (i - 1) & " of " & lastRow
DoEvents
Next i
Application.StatusBar = False
MsgBox "Task completed!"
End Sub
- DoEvents อนุญาตให้ Excel รีเฟรชหน้าจอและตอบสนองขณะแมโครทำงาน
- โดยไม่มีมัน แถบสถานะอาจไม่อัปเดตมองเห็นได้จนกว่าแมโครจะจบ โดยเฉพาะในลูปที่ยาว
- อย่าใช้ DoEvents มากเกินไปในลูปที่ใหญ่มาก ยกเว้นจำเป็น เพราะอาจทำให้การทำงานช้าลงเล็กน้อย
ที่ด้านล่าง แถบสถานะจะแสดง "Processing row 90 of 101"
เพิ่มข้อความเปอร์เซ็นต์
คุณสามารถปรับแต่งข้อความความคืบหน้าให้รวมเปอร์เซ็นต์ได้ คุณเพียงต้องคำนวณเปอร์เซ็นต์และรวมไว้ในข้อความแถบสถานะ
Sub ShowPercentageProgress()
Dim i As Long
Dim lastRow As Long
Dim percentDone As Double
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
For i = 2 To lastRow
' Simple action
Cells(i, "K").Value = "Processed"
' Update progress message
percentDone = (i - 1) / (lastRow - 1)
Application.StatusBar = "Processing row " & (i - 1) & " of " & (lastRow - 1) & _
" (" & Format(percentDone, "0%") & ")"
DoEvents
Next i
Application.StatusBar = False
MsgBox "Task completed!"
End Sub
โค้ดนี้สร้างการอัปเดตสถานะที่ชัดเจนให้ผู้ใช้ แสดง "Processing row 14 of 100 (14%)"
ตัวอย่างกับงานสูตรง่ายๆ
ลองสำรวจตัวอย่างเชิงปฏิบัติที่ดำเนินการเวิร์กชีท (Worksheet Action) รุ่นนี้เขียนสูตรยอดขายง่ายๆ ในคอลัมน์
Sub ShowProgressWithFormula()
Dim i As Long
Dim lastRow As Long
Dim percentDone As Double
lastRow = Cells(Rows.Count, "H").End(xlUp).Row
For i = 2 To lastRow
' Simple action
Cells(i, "K").Formula = "=H" & i & "*I" & i
' Update progress message
percentDone = (i - 1) / (lastRow - 1)
Application.StatusBar = "Writing formulas... " & _
"Row " & (i - 1) & " of " & (lastRow - 1) & _
" (" & Format(percentDone, "0%") & ")"
DoEvents
Next i
Application.StatusBar = False
MsgBox "Formulas added in column K!"
End Sub
นี่เป็นตัวอย่างง่าย แต่สะท้อนประเภทงานเวิร์กชีทที่ผู้ใช้หลายคนทำอยู่ดี
"แถบความคืบหน้าข้อความ" แบบจำลอง (Fake Progress Bar)
Application.StatusBar ไม่สามารถสร้างแถบความคืบหน้าแบบกราฟิกจริงได้ อย่างไรก็ตาม คุณสามารถจำลองได้โดยการสร้างแถบจากตัวอักษร (Characters)
Sub StatusBarWithTextProgressBar()
Dim i As Long
Dim lastRow As Long
Dim percentDone As Double
Dim barLength As Integer
Dim filledBars As Integer
Dim progressBar As String
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
barLength = 20
For i = 2 To lastRow
Cells(i, "K").Value = "Processed"
percentDone = (i - 1) / (lastRow - 1)
filledBars = Int(percentDone * barLength)
progressBar = String(filledBars, "|") & String(barLength - filledBars, ".")
Application.StatusBar = "Progress: [" & progressBar & "] " & _
Format(percentDone, "0%")
DoEvents
Next i
Application.StatusBar = False
MsgBox "Completed!"
End Sub
ทุกครั้งที่คุณรัน VBA แถบสถานะจะแสดงประมาณนี้:
Progress: [||||||||||.........] 67%
นี่ยังเป็นแค่ข้อความ แต่ให้ความรู้สึกภาพความคืบหน้าที่ชัดเจนกว่า
แนวทางปฏิบัติที่ดี: รีเซ็ตแถบสถานะเสมอ
ข้อผิดพลาดที่พบบ่อยที่สุดคือ ลืมคืนค่าแถบสถานะท้ายแมโคร หากคุณไม่ใช้ Application.StatusBar = False Excel อาจยังคงแสดงข้อความกำหนดเองของคุณ แม้แมโครจบแล้ว รูปแบบที่ปลอดภัยกว่าใช้การจัดการข้อผิดพลาดง่ายๆ เพื่อให้แถบสถานะรีเซ็ตแม้จะมีข้อผิดพลาดเกิดขึ้น
Sub SafeStatusMessage()
Dim i As Long
Dim lastRow As Long
Dim percentDone As Double
On Error GoTo CleanUp
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
For i = 2 To lastRow
Cells(i, "K").Value = "Processed"
percentDone = (i - 1) / (lastRow - 1)
Application.StatusBar = "Processing row " & (i - 1) & " of " & (lastRow - 1) & _
" (" & Format(percentDone, "0%") & ")"
DoEvents
Next i
MsgBox "Task completed!"
CleanUp:
Application.StatusBar = False
If Err.Number <> 0 Then
MsgBox "Error: " & Err.Description
End If
End Sub
รูปแบบนี้เหมาะสมสำหรับการใช้งานจริงมากกว่า
เคล็ดลับสำหรับข้อความสถานะที่ดีกว่า
ข้อความแถบสถานะที่ดีควรสั้นและเฉพาะเจาะจง รักษาข้อความให้กระชับและมีประโยชน์ ตัวอย่างที่ดี ได้แก่:
- Importing sales data…
- Checking duplicates…
- Formatting worksheet…
- Processing record 45 of 200…
- Finalizing report…
พยายามทำให้ข้อความตรงกับงานที่กำลังดำเนินการจริง นี่ทำให้แมโครรู้สึกมืออาชีพและน่าไว้วิ้วาสมากขึ้น
รูปแบบที่พร้อมใช้งานและนำกลับมาใช้ซ้ำได้
คุณสามารถนำรูปแบบนี้ไปใช้ซ้ำในแมโครเกือบทุกตัวได้ เพียงคัดลอกโค้ดนี้และวางตรรกะของคุณที่ต้องการ
Sub MyMacro()
On Error GoTo CleanUp
Dim i As Long
Dim total As Long
total = 100
For i = 1 To total
Application.StatusBar = "Processing item " & i & " of " & total
DoEvents
' Your code here
Next i
CleanUp:
Application.StatusBar = False
End Sub
สรุป
โดยการปฏิบัติตามบทช่วยสอนนี้ คุณสามารถแสดงข้อความความคืบหน้าขณะ VBA ทำงานได้อย่างง่ายดาย หากคุณต้องการแสดงให้ผู้ใช้เห็นว่าแมโคร VBA ยังทำงานอยู่ Application.StatusBar เป็นหนึ่งในเครื่องมือที่ง่ายที่สุดที่มีอยู่ มันไม่ใช่แถบความคืบหน้าเต็มรูปแบบ แต่เพียงพอในหลายกรณี วิธีนี้ง่ายต่อการนำไปใช้ น่าเชื่อถือ ต้องการโค้ดน้อย และปรับปรุงประสบการณ์ผู้ใช้ขณะดำเนินการ VBA ที่ใช้เวลานานมาก ลองทดสอบในแมโครของคุณเองโดยวางการอัปเดตสถานะภายในลูปหลัก — ใช้เพียงไม่กี่บรรทัดของโค้ดเท่านั้น
Get FREE Advanced Excel Exercises with Solutions!