ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 13093|回复: 13

callbyname的一个介绍

[复制链接]

TA的精华主题

TA的得分主题

发表于 2013-5-23 00:36 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:数据类型和基本语句
本帖最后由 liucqa 于 2013-5-23 00:43 编辑

http://laomaspeak.i.sohu.com/blog/view/162980516.htm

CallByName这个函数,真是强大了
收藏到手机    转发   评论
2010-11-21 11:02

http://www.vbgood.com/thread-67406-1-2.html

Visual Basic 语言参考
CallByName 函数

执行对象的方法,或者设置或返回对象的属性。

Public Function CallByName( _
   ByVal ObjectRef As System.Object, _
   ByVal ProcName As String, _
   ByVal UseCallType As CallType, _
   ByVal Args() As Object _
) As Object
参数
ObjectRef
必选。Object。指向公开属性或方法的对象的指针。

ProcName
必选。String。包含对象的属性名或方法名的字符串表达式。

UseCallType
必选。CallType 枚举类型的枚举成员,表示所调用过程的类型。CallType 的值可以是 Method、Get 或 Set。

Args
可选。ParamArray。参数数组,包含要传递给所调用的属性和方法的参数。

异常
异常类型  错误号  条件  
ArgumentException
5
无效 UseCallType 值;必须为 Method、Get 或 Set。


如果正在升级使用无结构错误处理的 Visual Basic 6.0 应用程序,请参见“错误号”一列。(您可以根据 Number 属性(Err 对象)比较错误号。)然而,如果可能,应当考虑用 Visual Basic 的结构化异常处理概述替换这种错误控制。

备注
CallByName 函数在运行时用来获取属性,设置属性或调用方法。

示例
在下面的示例中,第一行使用 CallByName 设置文本框的 Text 属性,第二行检索 Text 属性的值,第三行调用 Move 方法以移动文本框。

Visual Basic

Sub TestCallByName1()
    'Set a property.
    CallByName(TextBox1, "Text", CallType.Set, "New Text")

    'Retrieve the value of a property.
    MsgBox(CallByName(TextBox1, "Text", CallType.Get))

    'Call a method.
    CallByName(TextBox1, "Hide", CallType.Method)
End Sub
下一个示例使用 CallByName 函数调用集合对象的 Add 和 Item 方法。


Public Sub TestCallByName2()
    Dim col As New Collection()

    'Store the string "Item One" in a collection by
    'calling the Add method.
    CallByName(col, "Add", CallType.Method, "Item One")

    'Retrieve the first entry from the collection using the
    'Item property and display it using MsgBox().
    MsgBox(CallByName(col, "Item", CallType.Get, 1))
End Sub
================vb6.0例子======================

CallByName
执行一个对象的方法,或者设置或返回一个对象的属性。

语法

CallByName(object, procedurename, calltype,[arguments()])

CallByName 函数的语法有以下部分:

部分 描述
object 必需的;变体型(对象)。函数将要执行的对象的名称。
procedurename 必需的;变体型(字符串)。一个包含该对象的属性名称或者方法名称的字符串表达式。
calltype 必需的;常数。一个 vbCallType 类型的常数,代表正在被调用的过程的类型。
arguments() 可选的:变体型(数组)。


说明

CallByName 函数用于获取或者设置一个属性,或者在运行时使用一个字符串名称来调用一个方法。

在下面的例子中,第一行使用 CallByName 来设置一个文本框的 MousePointer 属性,第二行得到 MousePointer 属性的值,第三行调用 Move 方法来移动文本框:

CallByName Text1, "MousePointer", vbLet, vbCrosshair
Result = CallByName (Text1, "MousePointer", vbGet)
CallByName Text1, "Move", vbMethod, 100, 100



Option Explicit

Private Sub Command1_Click()
    '设置属性
    CallByName Text1, "Text", VbLet, "New Text"

    '读属性
    MsgBox CallByName(Text1, "Text", VbGet)

    'move方法
    CallByName Text1, "Move", VbMethod, 100, 100, 2000, 500
   
End Sub

Private Sub Command2_Click()
    Dim col As New Collection

    CallByName col, "Add", VbMethod, "Item One"
   
    MsgBox CallByName(col, "Item", VbMethod, 1)

End Sub

==========================意义=========================

    假定您有一个服务器应用程序,MathServer,并且它具有一个新的函数 SquareRoot。该应用程序中有两个 TextBox 控件:Text1 包含要计算的表达式;Text2 用于输入该函数的名称。要对 Text1 中的表达式调用 SquareRoot 函数,您可以在一个命令按钮的 Click 事件中使用下面的代码:

    Private Sub Command1_Click()
       Text1.Text = CallByName(MathServer, Text2.Text, vbMethod, Text1.Text)
    End Sub

    如果用户在 Text1 中输入 "64 / 4",在 Text 2 中输入 "SquareRoot",则上面的代码将调用 SquareRoot 函数(要求一个必需的参数,它是一个包含将要计算的表达式的字符串),并且在 Text1 中返回 "4" (16 或64/4的平方根)。当然,如果用户在 Text2 中输入了一个无效的字符串,或者该字符串包含一个属性名而不是方法名,或者该方法要求附加的必需的参数,那么将会产生一个运行时错误。可以猜到,当您使用 CallByName 来预处理这些或其他的错误时,需要添加强健的错误处理程序代码。

    ====================================================

    我来说一个吧,因为我在为这方面的技术而烦恼
    如果这个函数能解决我的问题的话,那就太好了。


    我们经常会写一些通用的模块函数,
    以便日后能方便的调用,就不需要再写同样的或类似的代码了。
    模块函数一但写好,除非发现函数内部有错误,否则一般是不会再修改这个函数了

    但是,如果模块中有回调函数的话,就不是这么回事了:
    比如“VB 全局热键”一文,连接为 http://www.vbgood.com/viewthread.php?tid=53654
    部分代码如下:
    Public Function Wndproc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        If Msg = WM_HOTKEY Then
            If wParam = idHotKey Then
                Dim lp As taLong, i2 As t2Int
                lp.ll = lParam
                LSet i2 = lp
                If (i2.lWord = Modifiers) And i2.hWord = uVirtKey Then
                    msgbox "你按下了热键哦~"
                End If
            End If
        End If
        Wndproc = CallWindowProc(preWinProc, hwnd, Msg, wParam, lParam)
    End Function

    这个回调函数的红色代码部分,就是可以添加想实现自己功能的部分
    但每次写程序的功能都不一样啊,
    也就是说,每次写一个不同的程序,就要改一下这个模块函数的红色部分
    这样一来,这个模块函数就不具备“通用性”了

    因为我对回调的理解不是很明白,或者说一点都不明白,所以不想每次都来改动这个函数
    如果callbyname好用的话,可以这样写:

      dim A as long ' 定义个模块级别的变量
      If (i2.lWord = Modifiers) And i2.hWord = uVirtKey Then
         select case A
            case 1
               callbyname "Func1"
            case 2
               callbyname "Func2"
          end select
      End If

    这样的话,调用函数时,只要把主调函数的过程名规定为“Func1”,“Func2”就可以了

    不知道我说的,大家能否明白,或是有什么错误
    希望大家能给点意见或建议,谢谢!!!
    callbyname "Func1" ,我只是简化写的,
    因为我还在外面,也没用过这个api函数,也没有机器调试

    至于你说 AddressOf 的问题,我也知道
    我一般都是这样解决的,你看可不可以:

    主调函数为
    Sub Main()
      call MyFunc(byval obj as object, byval index as long)
    End Sub

    在回调函数所在模块,再定义一个模块级别的对象变量
    也就是利用模块级别变量来传递参数
    dim A as long
    dim objControl as object

    Sub MyFunc(byval obj as object, byval index as long)
      A = index
      Set objControl = obj
    End Sub

    这样一来,回调函数就能接受主调函数所传递的参数了
    If (i2.lWord = Modifiers) And i2.hWord = uVirtKey Then
         select case A
            case 1
               callbyname objControl , "Func1"
            case 2
               callbyname objControl , "Func2"
          end select
      End If
    =================================================

    由于 callbyname 限制较多,刚才的思路的确有点问题

    方案是可行的:

    form1 中:

    Public Sub hello()
        Print "sss"
    End Sub

    mod1 中:

    Public Function Wndproc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        If Msg = WM_HOTKEY Then
            If wParam = idHotKey Then
                Dim lp As taLong, i2 As t2Int
                lp.ll = lParam
                LSet i2 = lp
                If (i2.lWord = Modifiers) And i2.hWord = uVirtKey Then
                    CallByName Form1, "hello", VbMethod
                End If
            End If
        End If
        Wndproc = CallWindowProc(preWinProc, hwnd, Msg, wParam, lParam)
    End Function

    ==========================================

    callbyname 不能返回函数的返回值?只能通过byref参数来返回,    貌似这是一个问题。

此外callbyname不能调用公共模块的函数




评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-5-23 00:41 | 显示全部楼层
VBA中CallByName的使用示例
来源:水文工具集 分类:代码, 博客 标签:VBA

VBA中CallByName函数是一个灵活性很强的函数,通过它可以实现通过字符串调用方法以及回调的功能,这里给出一个使用示例,具体应用具体分析并实现。

首先,定义一个类模块,并起名为CMyObject,类实现代码如下:
01.Option Explicit
02.Private MyPropValue As Integer
03.
04.Public Function Multiply(x As Integer, y As Integer) As Integer
05.Multiply = x * y
06.End Function
07.
08.Public Property Get MyProperty() As Variant
09.MyProperty = MyPropValue
10.End Property
11.
12.Public Property Let MyProperty(ByVal vNewValue As Variant)
13.MyPropValue = vNewValue
14.End Property

然后是调用CallByName函数测试,代码如下:
01.Private Sub Test()
02.Dim myclass As New CMyObject
03.Dim sum As Integer
04.Dim prop As Integer
05.
06.' Example of calling a method with CallByName
07.' equivalent to -- sum = myclass.Multiply(12, 12)
08.sum = CallByName(myclass, "Multiply", VbMethod, 12, 12)
09.MsgBox sum
10.
11.' Example of a property let with CallByName
12.' equivalent to -- myclass.MyProperty = 5
13.CallByName myclass, "MyProperty", VbLet, 5
14.
15.' Example of a property get with CallByName
16.' equivalent to -- prop = myclass.MyProperty
17.prop = CallByName(myclass, "MyProperty", VbGet)
18.MsgBox prop
19.End Sub

TA的精华主题

TA的得分主题

发表于 2014-7-25 18:55 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2014-7-25 20:28 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2014-8-16 10:56 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
liucqa 发表于 2013-5-23 00:41
VBA中CallByName的使用示例
来源:水文工具集 分类:代码, 博客 标签:VBA

你好,第一次接触这个CallByName,能再介绍一下这个CallByName吗,我看了下这个例子,只看懂了能通过字符串调用过程,但这个用Application.Run也能实现,请问CallByName还有其他什么好的用法啊

TA的精华主题

TA的得分主题

发表于 2016-8-4 08:44 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
找了半天callbyname实例代码
原来在这里
谢谢楼主

TA的精华主题

TA的得分主题

发表于 2016-8-4 08:57 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2016-8-4 09:49 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 yiyiyicz 于 2016-8-4 09:58 编辑

提供一个刚调通的简单示例代码

类模块,名称为“Ctest”
  1. Public Function aa(a As Integer, b As Integer)
  2.      aa = a + b
  3. End Function
复制代码
【注意】类模块Ctest中的Function,是方法,不是事件。这点很重要

测试程序
  1. <p>Sub test()
  2. Dim Temp As String
  3.          Set ch = New Ctest</p><p>      </p><p>     '  常规的调用类模块中的方法
  4.      ds = ch.aa(1, 2)</p><p>     MsgBox ds
  5.       </p><p>     ' 用CallByName函数来调用,对象名Ctest,方法是aa</p><p>     ' 用中间变量Temp是为了编程方便。如果直接用aa,而不是用"aa",则代码不能通过
  6.      Temp = "aa"
  7.         MsgBox CallByName(ch, Temp, VbMethod, 3, 4)
  8. End Sub</p>
复制代码

点评

学习了,调用类中的方法用字符串变量过渡一下就可通过,以前绕了很大的圈子解决这个问题。  发表于 2018-3-3 11:32

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2016-8-4 10:00 | 显示全部楼层
本帖最后由 yiyiyicz 于 2016-8-4 10:02 编辑
  1. Sub test()
  2. Dim Temp As String
  3.     Set ch = New Ctest
  4.     ds = ch.aa(1, 2)
  5.     MsgBox ds
  6.     Temp = "aa"
  7.     MsgBox CallByName(ch, Temp, VbMethod, 3, 4)
  8. End Sub
复制代码


上面的代码,莫名其妙的出现乱码。看这个代码,清楚

TA的精华主题

TA的得分主题

发表于 2016-11-17 19:44 | 显示全部楼层
非常感谢,这个东西太强大了
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-4-19 19:06 , Processed in 0.047119 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

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