Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> ซอฟต์แวร์ >> Office

ทำให้ Excel ตอบสนอง: แสดงข้อความความคืบหน้าแบบเรียลไทม์ขณะ VBA ทำงาน

ทำให้ Excel ตอบสนอง: แสดงข้อความความคืบหน้าแบบเรียลไทม์ขณะ VBA ทำงาน

เมื่อโค้ดยาวและแมโคร 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"

ทำให้ Excel ตอบสนอง: แสดงข้อความความคืบหน้าแบบเรียลไทม์ขณะ VBA ทำงาน

เพิ่มข้อความเปอร์เซ็นต์

คุณสามารถปรับแต่งข้อความความคืบหน้าให้รวมเปอร์เซ็นต์ได้ คุณเพียงต้องคำนวณเปอร์เซ็นต์และรวมไว้ในข้อความแถบสถานะ

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%)"

ทำให้ Excel ตอบสนอง: แสดงข้อความความคืบหน้าแบบเรียลไทม์ขณะ VBA ทำงาน

ตัวอย่างกับงานสูตรง่ายๆ

ลองสำรวจตัวอย่างเชิงปฏิบัติที่ดำเนินการเวิร์กชีท (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%

นี่ยังเป็นแค่ข้อความ แต่ให้ความรู้สึกภาพความคืบหน้าที่ชัดเจนกว่า

ทำให้ Excel ตอบสนอง: แสดงข้อความความคืบหน้าแบบเรียลไทม์ขณะ VBA ทำงาน

แนวทางปฏิบัติที่ดี: รีเซ็ตแถบสถานะเสมอ

ข้อผิดพลาดที่พบบ่อยที่สุดคือ ลืมคืนค่าแถบสถานะท้ายแมโคร หากคุณไม่ใช้ 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!