找回密码
 新建账号

VBA 调用保存在变量中的函数或对象方法和属性

[复制链接]
大郎 发表于 2025-7-17 13:24 | 显示全部楼层 |阅读模式
VBA 中使用指定的名称来调用一个函数,或者更准确地说,使用名称调用一个宏,因为宏包含函数和 Sub,或使用名称调用一个对象的方法,或者读取、设置一个对象的属性值,是很有必要的,直接手动写死能够实现,也很容易实现,但有些时候要调用的函数、方法或属性是一个字符串,或者来自于另外一个变量,这种情况下就需要动态实现了。

这要分两种情况。

如果要调用的是一个对象的方法,或者是要读取或设置一个对象的属性值,可以使用 VBA 的 CallByName() 内部函数。CallByName 的参数如下。
  1. CallByName (Object, Name, Type, [Args()])
复制代码
VBA 官方文档说 CallByName 支持命名参数,实际上这是严重的误导,VBA 内部函数不支持命名参数,对象的方法和自定义函数支持命名参数,但有 ParamArray 参数的自定义函数不支持命名参数。
Object 是目标对象,即从这个对象调用方法或者是要读取或设置属性值,比如 Range("A1")。
Name 是要调用的方法的名称,或者要读取或设置值的属性的名称,如 End,此时它表示的是 Range.End。
Type 调用类型,值是 vbGet vbLet vbSet vbMethod 之一,vbGet vbLet vbSet 用于对象属性,vbGet 读取对象的的属性值,vbLet 设置普通类型的属性值,VbSet 设置对象类型的属性值,vbMethod 用于调用对象方法。
Args() 不是一个参数,而是指可以继续指定 0 个或更多的参数,这些参数将传给要调用的对象方法或属性,作为它们的参数。

CallByName 用法举例
  1. CallByName(Cells(Rows.Count, "A"), "End", VbGet, xlUp).Select
复制代码
以上示例调用 Range.End 属性,将 xlUp 传递给 Range.End,最终实现选中 A 列最后一个已使用的单元格。

如果要调用的是一个自定义函数或 Sub,可以使用 Application.Run() 实现,它的参数如下。
  1. Application.Run(Macro, Arg1, Arg2, ..., Arg30)
复制代码
Macro 要调用的函数或 Sub 的名称,官方文档将这个参数名标注为 MacroName,这是错误的,实际的参数名是 Macro。
Arg1 ... Arg30 都是可选参数,用来继续指定 0 个或最多 30 个的参数,这些参数将传给要调用的函数或 Sub,作为它们的参数。
和 CallByName 不同,Application.Run 支持命名参数,比如 Macro 参数可以使用 Macro:="Greet" 的形式传递,命名参数可以不按顺序写。
  1. Option Explicit
  2. Function Greet(Name As String)
  3.     MsgBox "你好," & Name & "。"
  4. End Function
  5. Sub WXC()
  6.     Application.Run "Greet", "吴先成"
  7. End Sub
复制代码
运行 WXC 后会弹出“你好,吴先成。”
需要特别注意的是,Application.Run 不能调用 VBA 内部函数, VBA 内部函数实际上是 VBA 对象的成员方法,但并不能使用 CallByName 调用,这是 VBA 众多脑残缺陷中的一个。

手机版|轻松e站

GMT+8, 2025-7-18 02:20

快速回复 返回顶部 返回列表