2013-04-04 6 views
3

У меня есть друг с проектом VBA в Excel. В этом проекте много Форм, которые всплывают и выполняют различные функции во время использования электронной таблицы. Некоторые из них имеют сложные методы 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 Прекрасный вопрос .. заставил меня думать, какое-то время :) –

+0

вы думали о втором (по желанию) конструктор для инициализации? – 2013-04-04 11:40:20

+0

@mehow: Да, это было рассмотрено, но это одноразовое, что мы хотим сделать, и переключение логики ctor на другую функцию почти так же трудоемко, как просто открытие форм в режиме проектирования и запись всех контрольных имен вручную ... –

ответ

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 для расширяемости приложений
  2. В настройках Excel, установите "Trust Доступ к VBA проекта объектной модели"

Вырезка экрана

enter image description here

Followup

Поскольку это один раз вещь, сделать это

  1. Open VBA Project
  2. Нажмите CTRL + F
  3. Поступай, как показано на скриншоте ниже, а затем запустите код.
  4. Закройте файл без сохранения, как только вы получили то, что вам нужно

enter image description here

+0

Добавьте 'Private Sub UserForm_Initialize' метод, содержащий' Debug.Print 'Привет "' в одну из ваших форм, и вы увидите, что она появляется в вашем выходе :(Но спасибо в любом случае !! –

+0

I просто заметил, что вы упомянули выше, что это одно время. Правильно ли это? Если да, то у меня может быть решение для вас ... –

+0

Да, конечно ... –

Смежные вопросы