使用 VBA 的名称管理器 - 宏调用与函数调用给出不同的响应

Name Manager using VBA - Macro vs. Function Call Gives Different Response

我有一个 XLA 用于进行计算,我想在名称管理器中创建变量以用于这些计算。我想检查那些命名为 ranged 的​​是否已经存在,如果不存在则让用户为它们赋值。我有一个 Sub() 用于设置名称管理器 - 下面的示例 - :

Public Sub SetNames()
On Error Resume Next
   IsRangeName = CheckName("test")

If IsRangeName = Empty Then
   Application.ThisWorkbook.Names.Add Name:="test", RefersTo:=0
End If

End Sub

如果我进入 "Macro" 菜单和 运行 SetNames 例程,它会工作并在名称管理器中设置 test = 0。

但是,我想做的是 运行 通过一个函数,并允许该函数使用名称管理器中的变量(如果它们存在),如果它们不存在,则将这些值设置为通过子例程在名称管理器中设置初始值。

当我尝试运行以下代码时,名称管理器中从未设置值:

Sub Function1()
   Call SetNames()

   -Do Other Things-

End Function

所有名称都声明为全局变量。

目的是让用户安装插件,并在第一次使用插件调用函数时设置名称管理器,以初始化名称或允许用户设置初始值。我不希望用户通过宏功能区选项并执行子例程来初始化名称管理器名称。

如有任何帮助,我们将不胜感激。

不确定你的脚本中的 "CheckName" 是什么 - 你没有提供它.. 但是,我通过以下方式让它工作:

1) 注释掉 On Error Resume Next - 这允许您看到 CheckNames 失败。

2) 用循环替换 CheckNames 以循环抛出定义的名称,寻找我们的名称。

3) 将您的 "function" 定义从 "sub" 更改为 "function"。

测试一下,运行没问题。 如果 "test" 名称不存在,则设置它。手动更改为另一个值,再次运行,不要碰它。

  Public Sub SetNames()
  'On Error Resume Next
    For i = 1 To Application.ThisWorkbook.Names.Count
      If Application.ThisWorkbook.Names(i).Name = "test" Then
         IsRangeName = True
         Exit For
      End If
    Next i

  If Not IsRangeName Then
     Application.ThisWorkbook.Names.Add Name:="test", RefersTo:=1
  End If

  End Sub

  Function Function1()
     Call SetNames

     '-Do Other Things-

  End Function

似乎 在我的快速测试中有效,但您应该确保它在您的最终用例中执行。这是对 UDF 能够更新工作簿的限制的破解,因此它不在 "normal" 用法范围内。

Sub SetNameIfMissing(swb As String)

    Dim r As Name, wb As Workbook
    Set wb = Workbooks(swb)
    On Error Resume Next
    Set r = wb.Names("test")
    On Error GoTo 0

    If r Is Nothing Then
        Debug.Print "adding name..."
        wb.Names.Add "test", 99
    Else
        Debug.Print "already added"
    End If

End Sub


Function SetIt(v)

    Dim wb
    wb = Application.Caller.Parent.Parent.Name

    'using Evaluate gets around the UDF restriction
    Application.Caller.Parent.Evaluate "SetNameIfMissing(""" & wb & """)"

    SetIt = "OK" 'or whatever return value is useful...

End Function