2017-01-24 7 views
1

В настоящее время у меня есть форма, установленная в моей книге. Эта форма содержит кнопку. Нажав на кнопку, я хотел бы назвать Sub, который находится в разделе «ThisWorkbook». Как я мог это сделать?Вызов Sub в форме

Кнопка в виде ...

Sub CommandButton1_Click() 
    Call Main("Test") 
End Sub 

Суб, который должен быть назван в "ThisWorkbook"

Sub Main(DPass As String) 
    msgbox Dpass 
End Sub 

Это даст мне ошибку компиляции из: Sub or Function not defined. Почему это происходит?

+3

Префикс thisworkbook перед вашим подзаголовком. Вызовите ThisWorkbook.Main() – cyboashu

+1

^^, но используя 'Call ThisWorkbook.Main (« Test »)' или, проще говоря, 'ThisWorkbook.Main" Test ". – YowE3K

ответ

4

Существуют два основных типа модулей:

  • "/ Процедурные Стандарт" модули
  • модули класса

"Документ" модули (например, ThisWorkbook, Sheet1 и т.д.) просто специальные типы модулей классов. То же самое для модулей «UserForm», которые в основном представляют собой классы с экземпляром по умолчанию и дизайнером.

Члены модуля класса не существуют во время выполнения; класс - это не что иное, как чертеж для объекта - поэтому вам нужно либо создать объект этого типа (класс определяет тип), либо использовать существующий.

ThisWorkbook является пример категории Workbook; Sheet1 - это экземпляр класса Worksheet. Chart1 - экземпляр класса Chart; UserForm1 - пример класса UserForm. И так далее.

Если вы новый модуль класса и назовите его Class1 и добавьте публичную процедуру к нему:

Public Sub DoSomething() 
    MsgBox "Something!" 
End Sub 

Тогда для того, чтобы вызвать DoSomething вам нужен экземпляр из Class1:

Dim foo As Class1 
Set foo = New Class1 
foo.DoSomething 

Если DoSomething находится в модуле ThisWorkbook, вы можете назвать его, присвоив имя метода объекту, в котором он существует, так как w как уже упоминалось в комментариях, и в другом ответе:

ThisWorkbook.DoSomething 

Если DoSomething реализован в стандартном/процедурный модуль, то нет объекта, процедура существует в глобальном масштабе, и вы можете просто сделать это:

DoSomething 

Однако открытые члены процедурных модулей также подвергаются, как макросов (Public Sub) и пользовательских функций (Public Function), которые вы, возможно, не захотите делать.

Если вам нужен процедурный модуль с открытыми членами, который можно вызывать только из кода VBA (а не нажатием кнопки на листе или путем ввода формулы в ячейке), вы можете указать Option Private Module наверху :

Option Private Module 

Public Sub DoSomething() 
    ' DoSomething is not exposed as a macro, 
    ' but can be called from anywhere in the VBA project. 
End Sub 
+0

Очень хороший ответ с деталью. Это именно то, что я искал. Спасибо за глубину, так как теперь у меня действительно хорошее понимание предмета. – Brad

1

Поместите свой модуль в модуль, а не в эту книгу, если вам не нужно по какой-либо причине, если да, используйте ThisWorkbook.Main "string".

+5

Это должно быть либо «Call ThisWorkbook.Main (« Test »)», либо «ThisWorkbook.Main» Test »' - помещая скобки вокруг параметров для подпрограммы, вызываемой как 'subname (parameters)', является опасной привычкой проникать в - например если бы потребовались два параметра, то использование синтаксиса 'subname (parm1, parm2)' потерпит неудачу. Он часто работает, когда требуется только один параметр, но иногда дает неожиданные результаты (из-за скобок, заставляющих параметр передаваться как 'ByVal' вместо' ByRef'). – YowE3K

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