2012-07-25 67 views
0

我從SolidWorks運行VBA宏。表單加倍作爲兩種類型文檔的輸入。在UserForm.Initialize子例程中,我將根據打開的文檔類型更改UserForm的名稱Caption。每當我這樣做時,程序會重新運行UserForm.Initialize,當它完成後,它會從它離開的位置繼續運行,實際運行兩次。VBA UserForm在更改時運行兩次.Caption

有沒有人知道解決這個奇怪的行爲?我試圖把FormName.Caption命令放到它自己的Sub中,但結果是一樣的。

非常感謝。

+1

初始化事件不應該發生兩次。你是否已經通過代碼來確保.caption更新導致重複? 您可以隨時將標題更改移至激活事件。從技術上講,這意味着它會顯示錯誤的標題,但是它會改變的時間幾乎是難以區分的。 – 2012-07-25 17:37:05

+0

@DanielCook但是,這不會導致*更*重新運行的代碼? (即每次表單被激活/點擊打開和關閉) – Gaffi 2012-07-25 17:46:25

+0

是的,它肯定會。但是,如果您將標題存儲到初始化事件期間確定的用戶表單的專用字符串,它幾乎不會有任何開銷。但是我真的只是提到一些可能沒有解決問題的方法。這就是爲什麼我沒有把它列爲答案。 :-) – 2012-07-25 17:48:54

回答

5

我無法複製該問題,但我不知道SolidWorks是什麼,因此可能與它有關。也許你可以發佈一個顯示Initialize被調用兩次的組合示例。

我的猜測是它與自動實例化變量有關。當您使用UserForm1時,您正在實例化名爲UserForm1的對象變量指向一個對象,也稱爲UserForm1。這與在Dim語句中使用New關鍵字類似。你從來沒有定義UserForm1(變量),但是VBA確實並且第一次使用它時,它會自動實例化。

在userforms類模塊內部工作時,應該嘗試使用Me關鍵字(除了具有用戶界面元素外,userforms與其他對象類相似)。在初始化事件,說

Me.Caption = "blah" 

,而不是

UserForm1.Caption = "blah" 

這可能是(只是一個理論,我不能證明),其時設置的標誌說:「我指向一個真實的實例「不是在您更改Caption屬性時設置的,而是通過使用自動實例化變量UserForm1來強制另一個實例化。

更好的是,不要使用自動實例化變量,儘管它們很方便(並且不要在Dim語句中使用New關鍵字)。您可以控制何時創建和銷燬變量,這是最佳做法。事情是這樣的一個標準模塊中

Sub uftst() 

    Dim uf As UserForm1 

    Set uf = New UserForm1 'you control instantiation here 

    'Now you can change properties before you show it 
    uf.Caption = "blech" 
    uf.Show 

    Set uf = Nothing 'overkill, but you control destruction here 

End Sub 

注意,如果ShowModal屬性設置爲False,代碼將繼續執行,因此,如果運行無模式不破壞變量。

+0

+1是完全正確的。我不喜歡迷你Markdown格式,所以我發佈了一個新的答案,只是爲了展示如何複製這個問題。 – 2012-07-26 03:19:51

+0

真棒,這工作的魅力。並感謝您提供更多信息! – 2012-07-27 08:16:12

1

正如迪克所說,你應該能夠通過確保使用me.caption而不是Userform1.caption來停止行爲。

這裏有一種方法可以複製的問題,對於那些誰是好奇:

創建一個用戶窗體(Userform1),請確保您設置的ShowModal爲false,否則您將無法看到這一點。

在模塊中添加以下內容:

Option Explicit 
Sub ShowUserForm() 
    Dim uf As UserForm1 
    Set uf = New UserForm1 
End Sub 

在UserForm1列出了下面的代碼:

Option Explicit 
Private Sub UserForm_Initialize() 
    UserForm1.Caption = "I'm UserForm1!" 'This will call the Initialize method of Userform1 not Me. 
    Me.Caption = "I'm Me!" 
    Me.Show 
End Sub 

運行ShowUserForm。您現在有兩個具有不同標題的用戶表單。順便說一句,如果你有一個像我顯示的Initialize方法,向ShowUserForm中添加Set uf = Nothing子實際上不能關閉任何一種形式。