excel表格名称的秘密( 二 )


对于这些属于应用程序的隐藏的名称 , 关闭所有工作簿和加载项不会销毁它们 。它们仅能通过对SET.NAME(如果没有第二个参数)明确的调用或者通过退出并重启Excel被销毁 。在这种情况下 , 这些名称能被用作一种Excel的环境变量 。
它们是完全隐藏的 。当一个受保护的加载项使用这个隐藏的名称空间时 , 新的名称不能被任何其它的VBA模块读取 , 也不能被用户读取 , 除非他们知道它们的身份证书 。没有方法“列出”定义在隐藏命名空间中的名称 。
这些名称无须与标准的隐藏名称(工作簿或工作表名称的.Visible属性已设置为False)混淆 。标准的工作簿级的名称决不会真正的被隐藏 , 因为它们能通过使用Application.Names集合的任何VBA程序来获取和修改 , 如下面的代码所示:
Dim CName As Name
For Each CName In Workbooks(“WB1.xlsm”).Names
If CName.Hidden Then
MsgBox CName.Name & ” 被删除”
CName.Delete
End If
Next CName
上面的代码 , 在工作簿WB1.xlsm的所有名称中循环 , 并删除它们中隐藏的名称 。然而 , 这些代码不能发现存储在隐藏名称空间中的名称 , 因为这些名称不属于Application.Names集合 。因此 , 它们被保护以反对任何恶意的访问或修改 。
在VBA中访问隐藏的名称空间
创建一个隐藏的名称
下面的语句创建一个包含字符串“OK”的名为Test的隐藏的名称:
Application.ExecuteExcel4Macro”SET.NAME(“”Test””,””OK””)”
获取一个隐藏名称的内容
下面的语句获取名称“Test”所代表的内容:
TestVal = Application.ExecuteExcel4Macro(“Test”)
只是使用名称本身作为ExecuteExcel4Macro的参数 。
删除一个隐藏的名称
下面的语句删除名称“Test”:
Application.ExecuteExcel4Macro”SET.NAME(“”Test””)”
忽略了SET.NAME的第二个参数 。
在工作表中访问隐藏的名称空间
在工作表中也可以直接访问隐藏的名称 , 必须使用SET.NAME和EVALUATE与CALL()和API函数Excel4组合在一起 。函数SET.NAME和EVALUATE的编号分别是88和257 。
创建一个隐藏的名称
下面创建一个包含字符串“OK”的名为Test的隐藏的名称:
=CALL(“Xlcall32″,”Excel4″,”2JRJRR#”,88,,2,”Test”,”OK”)
获取一个隐藏名称的内容
下面获取名为“Test”的名称的内容:
=CALL(“Xlcall32″,”Excel4″,”2JRJR#”,257,,1,”Test”)
删除一个隐藏名称
下面删除名称“Test”:
=CALL(“Xlcall32″,”Excel4″,”2JRJRR#”,88,,1,”Test”)
在工作表公式中直接定义和删除名称是可能的 , 因为SET.NAME不是一个命令而是一个宏函数 。
在宏工作表中能以相同的方式使用隐藏的名称 , 除了不需要给类型字符串添加数字标志外 。
示例
下面的代码演示了在受保护的VBA加载项中隐藏的名称空间的可能的用途 。
它限制用户在相同的Excel会话中执行加载项主过程超过3次 。没有在一个模块级的变量中存储允许剩余执行的计数器 , 也没有将其存储在依赖加载项的名称中 , 而是存储在这个隐藏的命名空间中 。
使用名称空间阻止用户中断保护 , 修复了传统方法的下列缺点:
像所有变量一样 , 存储在VBA中的计数器可以在VBE中手工清除 。

推荐阅读