2013-04-04 161 views
3

我有一個朋友在Excel中使用VBA項目。這個項目有很多表單彈出,並在電子表格被使用時執行各種功能。其中一些有複雜的Form_Initialize方法依賴於其他已經存在的東西(當項目按預期使用時,這不是問題)。訪問沒有窗體實例的VBA用戶窗體控件

我們試圖在應用程序內的每個表單上打印出每個控件的名稱。我們的問題是VBA.UserForms集合只包含已經實例化的表單,我們不能在沒有執行它們的Form_Initialize方法的情況下實例化所有表單。

例如:

For Each f In VBA.UserForms 
    Debug.Print f.Name 
    Debug.Print "----------------------" 

    For Each c In f.Controls 
     Debug.Print c.Name 
    Next c 
Next f 

什麼都不做,如果沒有形式已經使用/加載。此代碼:

For Each c in frmConfig.Controls 
    Debug.Print c.Name 
Next c 

首先執行frmConfig.Form_Initialize(),然後通過形式印刷自己的名字上的控制迴路。這個崩潰,因爲在這個表單可用之前需要發生的事情還沒有發生。

是否有可能獲得窗體上的控件的名稱沒有實例化窗體(避免執行frmConfig.Form_Initialize())?

任何幫助非常感謝!

+1

+ 1美麗的問題..迫使我思考了一段時間:) – 2013-04-04 11:39:58

+0

你有沒有想過具有第二(可選)構造函數初始化? – 2013-04-04 11:40:20

+0

@mehow:是的,這已經被考慮過了,但是這是我們想要做的一次性工作,將ctor邏輯轉換爲不同的函數幾乎與在設計視圖中打開表單並記下所有控件名稱一樣耗時手動... – 2013-04-04 11:48:44

回答

2

這是你正在嘗試?

Option Explicit 

Sub FindObjects() 
    Dim vbc As VBIDE.VBComponent 
    Dim frm As Object 
    Dim Ctrl As MSForms.Control 

    For Each vbc In ThisWorkbook.VBProject.VBComponents 
     If vbc.Type = vbext_ct_MSForm Then 
      With VBA.UserForms 
       On Error Resume Next 
       Set frm = .Add(vbc.Name) 
       Debug.Print "Found userform :" & vbc.Name 
       If Err.Number = 0 Then 
        For Each Ctrl In frm.Controls 
         Debug.Print "Controls in Userform " & vbc.Name & _ 
         " - " & Ctrl.Name 
        Next Ctrl 
       End If 
       On Error Go To 0 
      End With 
     End If 
    Next vbc 
End Sub 

IMP

  1. 設置參考到Microsoft Visual Basic for Applications擴展
  2. 在Excel選項中,設置 「信任對VBA項目對象模型」

屏幕截圖

enter image description here

隨訪

由於這是一次性的事情,這樣做

  1. 打開VBA項目
  2. CTRL + ˚F
  3. 做如圖所示在下面的屏幕截圖中,然後運行碼。
  4. 關閉文件不保存,一旦你已經得到了你所需要的

enter image description here

+0

添加一個'Private Sub UserForm_Initialize'方法,其中包含'Debug.Print「Hello」'給你的一個表單,你會發現它出現在你的輸出中:(但是,無論如何感謝!! – 2013-04-04 11:47:18

+0

I只是注意到你在上面提到這是一次性的事情,這是否正確?如果是,那麼我可能會爲你解決一個問題... – 2013-04-04 11:58:37

+0

是啊 - 當然是... – 2013-04-04 12:02:42