使用 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
我有一个 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