从两个不同的VBA(excel)模块调用子功能/模块

时间:2012-07-12 19:11:39

标签: excel-vba vba excel

我有一个我想从各种模块调用的函数。什么是VB(excel)中最好的方法。

模块“SheetExists”

Function Name(SheetName As String) As Boolean
' returns TRUE if the sheet exists in the active workbook
    SheetExists = False
    On Error GoTo NoSuchSheet
    If Len(Sheets(SheetName).Name) > 0 Then
        SheetExists = True
        Exit Function
    End If
NoSuchSheet:
End Function

模块“Main”

If Not SheetExists.Name("mySheet") Then
    'do this
Else
    ' else do this
End If

不要想要这样做或者我?

Call SheetExists.Name("mySheet")

这是从另一个模块调用函数的唯一方法吗?我是否必须将其声明为公共函数或其他什么?

4 个答案:

答案 0 :(得分:8)

不,你不必这样做,你可以从任何地方调用你的功能。

试试这个:

将此代码放入Module1:

Sub TestSheetExists()
    If SheetExists("Sheet1") Then
        MsgBox "I exist!"
    End If
End Sub

这在Module2中:

Function SheetExists(shtName As String, Optional wb As Workbook) As Boolean
    Dim sht As Worksheet

     If wb Is Nothing Then Set wb = ThisWorkbook
     On Error Resume Next
     Set sht = wb.Sheets(shtName)
     On Error GoTo 0
     SheetExists = Not sht Is Nothing
 End Function

显然,你可以使用你想要的模块名称。


编辑:我看到来自不同模块的呼叫仍然无效。请严格按照以下步骤设置可帮助您了解问题的测试工作簿。

  1. 创建新的Excel工作簿
  2. 打开VBA编辑器(Alt-F11)
  3. 右键单击项目并选择插入模块。重复这个4x以获得4个模块。
  4. 按F4打开属性窗口(如果尚未打开)
  5. 将模块名称更改为以下内容:CallMe,CallMeAgain,CallMeBack,验证 Renamed modules
  6. 在验证模块中,粘贴以下函数:

    Function SheetExists(shtName As String, Optional wb As Workbook) As Boolean
        Dim sht As Worksheet
    
         If wb Is Nothing Then Set wb = ThisWorkbook
         On Error Resume Next
         Set sht = wb.Sheets(shtName)
         On Error GoTo 0
         SheetExists = Not sht Is Nothing
    End Function
    
  7. 将此子句粘贴到CallMe:

    Sub TestSheetExistsFromCallMe()
        If SheetExists("Sheet1") Then
            MsgBox "I exist, and I was called from CallMe!"
        End If
    End Sub
    
  8. 将其粘贴到CallMeBack中:

    Sub TestSheetExistsFromCallMeBack()
        If SheetExists("Sheet1") Then
            MsgBox "I exist, and I was called from CallMeBack!"
        End If
    End Sub
    
  9. 将其粘贴到CallMeAgain中:

    Sub TestSheetExistsFromCallMeAgain()
        If SheetExists("Sheet1") Then
            MsgBox "I exist, and I was called from CallMeAgain!"
        End If
    End Sub
    
  10. 按F5键从CallMe中运行代码。您应该看到以下消息框: enter image description here

  11. 从3个“呼叫”模块中的任何一个运行代码,您应该会看到相应的消息框。

  12. 我从Tim Williams(https://stackoverflow.com/a/6688482/138938)获得了SheetExists功能,并且一直使用它。

答案 1 :(得分:1)

在类模块中声明的函数必须以类名开头,例如class.function。在普通模块中声明的函数具有一般范围。

答案 2 :(得分:1)

另外,如果你恰好用下划线命名你的sub,VBA不喜欢它。

“Subroutine_Name”无效,但

“SubroutineName”将起作用。

答案 3 :(得分:0)

问题在于excel并不清楚函数是否具有全局范围。

AND模块名称不能与函数名称相同(显然)。

看来excel VB会让你从任何其他模块调用一个函数,只要模块名称与任何其他函数名称不相似,有效地赋予所有函数全局范围......?!?这与大多数编程语言非常不同,因为通常你调用模块(或类).function()而不是函数()。 excel中的所有函数是否都具有全局范围?那有点不同......

模块“SheetChecker”(名称不能等于函数名)

Function SheetExists(SheetName As String) As Boolean
' returns TRUE if the sheet exists in the active workbook
    SheetExists = False
    On Error GoTo NoSuchSheet
    If Len(Sheets(SheetName).Name) > 0 Then
        SheetExists = True
        Exit Function
    End If
NoSuchSheet:
End Function

模块“anyOtherModule”

SheetExists("mysheet")

注意模块中声明的函数(子块的外部)在VB Excel中具有全局范围(似乎)。