5

我有一个要从各种模块调用的函数。在 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

模块“主要”

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

不想这样做,还是我这样做?

Call SheetExists.Name("mySheet")

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

4

4 回答 4

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. 右键单击项目并选择插入模块。重复此 4 次以获得 4 个模块。
  4. 按 F4 打开属性窗口(如果尚未打开)
  5. 将您的模块名称更改为以下内容:CallMe、CallMeAgain、CallMeBack、Validation 重命名模块
  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 中运行代码。您应该看到以下消息框: 在此处输入图像描述

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

我从 Tim Williams ( https://stackoverflow.com/a/6688482/138938 ) 那里得到了 SheetExists 函数并一直使用它。

于 2012-07-12T20:11:45.580 回答
1

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

于 2013-01-07T13:35:39.470 回答
1

另外,如果你碰巧用下划线命名你的子,VBA 不喜欢它。

“Subroutine_Name”不起作用,但是

“子程序名称”将起作用。

于 2013-10-17T17:07:36.800 回答
0

问题是excel没有明确说明函数具有全局范围。

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

看来,只要模块名称与任何其他函数名称不相似,excel VB 将允许您从任何其他模块调用函数,从而有效地为所有函数提供全局范围......?!?这与大多数编程语言非常不同,因为通常您调用模块(或类).function() 而不仅仅是 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

模块“任何其他模块”

SheetExists("mysheet")

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

于 2012-07-13T15:27:55.890 回答