2013-10-09 78 views
4

我正在尋找一種更好的方法來禁用在Excel工作簿中觸發的ActiveX事件(儘管這將適用於具有ActiveX對象的所有Office應用程序)。如何防止在VBA中觸發ActiveX事件?

希望類似於Application.EnableEvents = false的東西,雖然這不適用於ActiveX。

在下面的例子中,使用全局布爾值是微不足道的,但是我有很多用於ActiveX對象的事件處理程序,對於我可以普遍適用的用於臨時禁用ActiveX事件的東西來說,這將非常容易。我真的不想爲這些方法中的每一個添加一個if/exit子語句。

爲了說明這個問題,在工作表上創建一個ActiveX組合框,並添加以下到板模塊

Public initializingContent As Boolean 
Private Sub intializeAllActiveXContent() 

    'this doesn't apply to activeX events :'(
    Application.EnableEvents = False 

    'this could work but is not really elegant 
    'change this to false to show my problem in 
    'the intermediate window (called not once but twice) 
    initializingContent = True 

    ComboBoxTest.Clear 

    ComboBoxTest.AddItem ("item1") 
    ComboBoxTest.AddItem ("item2") 
    ComboBoxTest.AddItem ("item3") 

    'select the top value in the box 
    ComboBoxTest.value = "item1" 

    initializingContent = False 

    Application.EnableEvents = True 

    End Sub 

Private Sub ComboBoxTest_Change() 
    'I really don't want to have to wrap EVERY single ActiveX method 
    'with something like this for a whole variety of reasons... 
    If initializingContent Then Exit Sub 

    Debug.Print "do stuff I don't want to happen when intializeAllActiveXContent() runs " & _ 
     "but I do when user changes box" 
     End Sub 
+0

+ 1好問題!你讓我想了一會兒:) –

+0

我的代碼是一個Excel的例子。 MS Word/PowerPoint的邏輯保持不變。不確定關於MS Access/Project/Outlook。 –

回答

4

爲什麼不禁止呢?這樣你不必擔心他們的個人代碼。

試試這個

Sub DisableActiveXControls() 
    Dim ws As Worksheet 
    Dim OLEobj As OLEObject 

    Set ws = ThisWorkbook.Sheets("Sheet1") 

    With ws 
     For Each OLEobj In ws.OLEObjects 

     If TypeOf OLEobj.Object Is MSForms.ComboBox Then 
      OLEobj.Enabled = False 
     End If 
     Next OLEobj 
    End With 
End Sub 

前/後的截圖:

enter image description here

隨訪自評:

也變成了這個打破^ h在組合在一起的對象上,但我可以取消組合對象(我猜,它們不再位於「Sheet1.OLEobjects」中)。我還是不太喜歡這個,因爲它依賴於這個事實,並且有時候我想要將對象分組.. - - enderland 17分鐘前

要禁用組中的ActiveX控件,不需要將它們解組。使用此代碼。以下代碼將禁用組中的組合框。

Sub Disable_ActiveX_Controls_In_A_Group() 
    Dim shp As Shape, indvShp As Shape 
    Dim OLEobj As OLEObject 
    Dim ws As Worksheet 

    Set ws = ThisWorkbook.Sheets("Sheet1") 

    For Each shp In ws.Shapes 
     If shp.Type = msoGroup Then 
      For Each indvShp In shp.GroupItems 
       Set objOLE = indvShp.OLEFormat.Object 

       If objOLE.progID = "Forms.ComboBox.1" Then _ 
       objOLE.Enabled = False 
      Next 
     End If 
    Next 
End Sub 
+0

嗯。所以這是一個有趣的方法,但不幸的是我有一些對象不是組合框,它們有可變的啓用/禁用狀態 - 我可能會構建一個所有名字的字典並恢復它,但這看起來有點愚蠢。有沒有簡單的方法來檢查一個OLEobject是否是一個組合框? Typename()和.Type都返回相同的(?)。我發誓我之前做過這個,但我不記得如何... – enderland

+0

+1與我的編輯 - 「如果TypeOf OLEobj.Object是MSForms.ComboBox」。同樣的結果是,這打破了分組在一起的對象的核心,但我可以取消組合對象(我猜它們不再是「Sheet1.OLEobjects」)。我仍然不太喜歡這個,因爲它依賴於這個事實,並且有時我會想要將對象分組。 – enderland

+0

我正在用該行代碼編輯它:P,然後我看到了您的編輯。事實上,我正在給你一個鏈接到我的另一個帖子[這裏](http://www.vbforums.com/showthread.php?505132-RESOLVED-Iterating-Through-Controls&p=3113117&viewfull=1#post3113117) –

1

在搜索相似問題時遇到此帖子。我決定在這裏發佈的答案不適合我的情況,並提出了其他的東西。我的方法在這裏也可能有用。

在我的工作簿中,我有一組20個(Activex)複選框。這些基本上過濾/關閉了20個產品類別以包含在報告中。只要通過調用CheckBox_Click例程中的路由,每次更改其中一個複選框時都會運行一個例程。

然後,我也有一個組合框,選擇這些複選框的各種。麻煩的是,當20個複選框中的每一個被組合框代碼選擇(未)時,計算例程被觸發。

我想要的只是在組合框的末尾運行計算程序ONCE,但如果手動更改單個複選框,它仍然有效。

我的解決方案 - 在隱藏工作表上的某個單元格中放入TRUE/FALSE代碼,在某處它不會干擾。

然後CheckBox_Click代碼變爲(每個20個複選框):

Private Sub CheckBox6_Click() 
If (Sheets("Data").Range("G60")) Then 
    Call RangeFind 
End If 
End Sub 

組合框代碼修改此相同的細胞,適當地:

Private Sub ComboBox28_Change() 

Sheets("Data").Range("G60").Value = False 
Select Case Sheets("Data").Range("F50").Value 
    Case "1" 

    CheckBox1.Value = False 
    CheckBox2.Value = False 
    CheckBox3.Value = False 

.... 

End Select 

' This turns the checkboxes back on 
Sheets("Data").Range("G60").Value = True 

' This now actually calls the calculation ONCE 
Call RangeFind 

ActiveSheet.Range("A1").Activate 

End Sub 

乾杯,

邁克爾

1

我知道這真的很舊。但任何看起來這個(首先擊中谷歌)可能想要一個簡單的答案:

假設你有一個私人小組ActiveXControl_Change()在Application.EnableEvents = False期間被調用,你希望它跳過這個只是去:

Private Sub ActiveXControl_Change() 
If Application.EnableEvents = True Then 
'enter you code here 

End If 
End Sub 
相關問題