2010-01-30 48 views
8

將VBA中的ProgressBar用戶窗體顯示爲模態或無模式會更好嗎?在VBA中開發進度指標的最佳實踐是什麼?將VBA中的ProgressBar用戶窗體顯示爲模態或無模式會更好嗎?

無模式用戶窗體需要使用Application.Interactive = False,而模態用戶窗體本質上阻止與應用程序的任何交互,直到核心過程完成或被取消。

但是,如果使用Application.Interactive = False,則Esc鍵會中斷代碼執行,因此在用戶窗體和調用過程中都需要使用Application.EnableCancelKey = xlErrorHandler和錯誤處理(Err.Number = 18)。

資源密集型調用過程也可能導致CommandButton_ClickUserForm_Activate事件在無模式用戶窗體中失火。

通常,使用模式用戶窗體的進度指示器看起來更簡單,因爲正在執行的代碼完全包含在用戶窗體模塊中,並且不需要傳遞變量。

但是,使用用於進度指示器的模式UserForms的問題在於,需要進度指示器的每個過程都需要單獨的UserForm模塊,因爲調用過程必須位於UserForm_Activate過程中。

因此,雖然在無模式UserForm中可能有單個可重用的進度指示器,但它將比從多個模式用戶窗體中執行代碼的可靠性要低。

哪種方式更好?

謝謝!

回答

1

我打算關閉這一個,說莫代爾是贏家。我已經嘗試了兩種方式,但最終你會試圖通過無模式的用戶表單來關閉太多的漏洞。莫代爾更加困難,因爲它更嚴格,但它鼓勵你將代碼分解成更小的塊,無論如何,從長遠來看這更好。

3

還有第三種方法,使用Application.StatusBar。 您甚至可以使用U + 25A0和U + 25A1字符序列模擬真正的進度條。

+0

謝謝GSerg的建議,但我曾嘗試過使用它,但Excel 2007停止更新窗口並在應用程序窗口頂部顯示「Not Responding」。 – Kuyenda 2010-01-31 00:41:27

+2

我對office 2007不太瞭解,但是如果你在給'StatusBar'設置一個值之後立即調用DoEvents呢? – GSerg 2010-01-31 01:09:32

+0

嗯,那工作。哇,這是一個不錯的選擇是不是!謝謝GSerg! – Kuyenda 2010-01-31 01:23:17

1

絕對模態。 如果你打算考慮Modeless,你應該在一個單獨的進程外線程上運行它,而不是在Excel.exe主線程上。

1

我認爲最初的話題值得回覆,因爲問題的表述非常好,谷歌首先發現它。

第1 - 理論

的第一件事要說的是,在模塊之間傳遞變量是不難的。

你需要做的唯一的事情就是創建一個單獨的模塊,並把所有的全局變量。然後你將能夠以各種形式,表單,模塊閱讀它們。

第二件事是窗口應該是MODELESS。爲什麼? 答案是保持代碼的流動性,即

  1. 其中執行最常規的過程不位於用戶窗體模塊中的功能
  2. 可以調用帶進度條的窗口來自世界各地和
  3. 常規功能/程序之間的唯一聯繫是全局變量

這是一個很大的優勢是多功能這裏。

第2部分 - 實踐

1)創建模塊「申報」與全局變量:

公共StopForce作爲整數 「這個變量將被用作一個指標,該用戶按下的取消按鈕

公共PCTDone單 「這是已經做

P中的工作% ublic CurrentFile As String '我們想要傳遞給表單的任何其他參數。

2)用按鈕創建表單。在按鈕的OnClick事件應該有,我們指的是全局變量StopForce宣言模塊

Private Sub CommandButton1_Click() 

Declaration.StopForce = 1 
    End Sub 

3)添加一個程序代碼,您更新進度條

Sub UpdateProgressBar(PCTDone_in As Single) 
With UserForm1 
    ' Update the Caption property of the Frame control. 
    .FrameProgress.Caption = Format(PCTDone_in, "0%") 
    ' Widen the Label control. 
    .LabelProgress.Width = PCTDone_in * _ 
     (.FrameProgress.Width) 
    ' Display the current file from global variable 
    .Label1.Caption = Declaration.CurrentFile 
End With 
End Sub 

4)在任何其他模塊中,我們必須具有執行例行程序的功能或程序/子程序:

For i=1 to All_Files 

Declaration.CurrentFile = myFiles (i) 

FormFnc.UpdateProgressBar (i/.Range("C11").Value) 


DoEvents 

If Declaration.StopForce = 1 Then 
    GoTo 3 
End If 

Next i 
+0

請注意,無模式UserForms在Mac OS上看起來完全不起作用 – 2017-05-30 06:04:35

相關問題