设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

返回列表 发新帖
查看: 1875|回复: 8
打印 上一主题 下一主题

[模块/函数] 【原创】利用Eval函数,简单实现回调机制

[复制链接]

点击这里给我发消息

跳转到指定楼层
1#
发表于 2015-1-21 10:15:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 盗梦 于 2015-1-21 11:37 编辑

有时候,我们很多代码结构很类似,前后都一样,就中间不一样。
提取不了为一个公共函数直接调用,不得不写成很多重复代码
如果用回调方式就能轻松解决问题
但vb,vba中实现回调要通过一个API函数,十分不方便
最近研究发现,可以利用Eval函数的特性(可以执行文本表达的代码),简单实现回调机制

优点:容易理解和使用
缺点:窗体的函数调用不到
           没有返回值(可以通过公共临时变量得到返回值)
           传递参数不方便
           调用的函数或者过程必须是公共的

附上我研究的几个模型,包括有无参数和返回值

1、示例(无参数,无返回值)
  1. '说明:无参数传递,没返回值
  2. '参数:funcName,函数表达式(字符串)。要调用的函数名,函数名后一定要加括号
  3. '示例:funcEvalEasy("funcTestEasy()")

  4. Public Function funcEvalEasy(funcName As String)
  5.     '其他代码过程
  6.     '...
  7.     '回调函数部分
  8.     MsgBox "开始执行函数" & funcName
  9.     Eval funcName
  10. End Function

  11. Public Function funcTestEasy()
  12.     MsgBox "我是测试函数,用于测试回调"
  13. End Function
复制代码

2、示例(有参数,无返回值)
  1. '说明:有参数传递,没返回值
  2. '参数:funcName,函数表达式(字符串)。要调用的函数名,函数名后一定要加括号

  3. '方法1:在funcName,函数表达式中就写好参数
  4. '示例:funcEvalPara1("funcTestPara(1)")
  5. '特点:较为灵活
  6. Public Function funcEvalPara1(funcName As String)
  7.     '其他代码过程
  8.     '...
  9.     '回调函数部分
  10.     MsgBox "开始执行函数" & funcName
  11.     Eval funcName
  12. End Function

  13. '方法2:在执行回调的函数里面合并一个函数表达式
  14. '示例:funcEvalPara2(1,"funcTestPara")   '为了方便合成函数表达式,就不加括号
  15. '特点:有什么参数,一目了然,就是不灵活
  16. Public Function funcEvalPara2(i As Integer, funcName As String)
  17.     '其他代码过程
  18.     '...
  19.     '回调函数部分
  20.     MsgBox "开始执行函数" & funcName
  21.     Eval funcName & "(" & i & ")"
  22. End Function

  23. Public Function funcTestPara(i As Integer)
  24.     MsgBox "我是测试函数,用于测试回调" & vbCrLf & "你传进来的数字是" & i
  25. End Function

  26. '方法3:利用公共变量传递参数(这个可以参考下面的示例,一样道理,这里就不赘述)
复制代码

3、示例(有返回值)
  1. Public intEvalReturn As Integer '临时变量,用于保存返回值

  2. '说明:有返回值
  3. '参数:funcName,函数表达式(字符串)。要调用的函数名,函数名后一定要加括号
  4. '示例:funcEvalReturn("funcTestReturn(1)")

  5. Public Function funcEvalReturn(funcName As String) As Integer
  6.     '其他代码过程
  7.     '...
  8.     '回调函数部分
  9.     MsgBox "开始执行函数" & funcName
  10.     Eval funcName

  11.     '获取返回值
  12.     MsgBox "返回结果" & intEvalReturn  '弹窗显示
  13.     funcEvalReturn = intEvalReturn    '返回结果
  14. End Function

  15. Public Function funcTestReturn(i As Integer)
  16.     MsgBox "我是测试函数,用于测试回调" & vbCrLf & "你传进来的数字是" & i & vbCrLf & "将执行计算返回一个值"
  17.     '计算
  18.     i = i + 1
  19.     '返回
  20.     intEvalReturn = i
  21. End Function
复制代码

追加更新:
2015-01-21: 多谢todaynew版主告知,Eval本身可以返回值。例如Eval("1+1"),返回2。
                     那就不用像上面那么麻烦。详请见6楼

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 分享淘帖 订阅订阅

点击这里给我发消息

2#
发表于 2015-1-21 10:55:33 | 只看该作者
赞一个! eval的确很方便。但也还有它的短处。如要将 事件的参数 传递过去 还不太方便
3#
发表于 2015-1-21 10:59:08 | 只看该作者
有点类似.net中的委托

点击这里给我发消息

4#
 楼主| 发表于 2015-1-21 11:00:04 | 只看该作者
todaynew 发表于 2015-1-21 10:59
有点类似.net中的委托

就是学了.net,灵光一现

点击这里给我发消息

5#
 楼主| 发表于 2015-1-21 11:02:44 | 只看该作者
tmtony 发表于 2015-1-21 10:55
赞一个! eval的确很方便。但也还有它的短处。如要将 事件的参数 传递过去 还不太方便

是啊,所以一开篇就把优缺点罗列出来了
6#
发表于 2015-1-21 11:18:33 | 只看该作者
本帖最后由 todaynew 于 2015-1-21 11:36 编辑
盗梦 发表于 2015-1-21 11:00
就是学了.net,灵光一现

其实不必设公共变量,Eval是可以返回值的。
Public Function getDate(ByVal y As Integer, ByVal m As Integer, ByVal d As Integer) As Date
    getDate = DateSerial(y, m, d)
End Function


Private Sub 确定_Click()
    Me.日期.Value = Eval("getDate(" & Me.年.Value & "," & Me.月.Value & "," & Me.日.Value & ")")
End Sub








本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

点击这里给我发消息

7#
 楼主| 发表于 2015-1-21 11:19:10 | 只看该作者
todaynew 发表于 2015-1-21 11:18
其实不必设公共变量,Eval是可以返回值的。

我研究一下

点击这里给我发消息

8#
 楼主| 发表于 2015-1-21 11:37:43 | 只看该作者
todaynew 发表于 2015-1-21 11:18
其实不必设公共变量,Eval是可以返回值的。
Public Function getDate(ByVal y As Integer, ByVal m As I ...

确实,我研究不够深入。多谢版主
9#
发表于 2016-1-11 11:15:02 | 只看该作者
MSScriptControl.ScriptControl

其他语言也可以调用这个,实现表达式计算。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-6-5 02:49 , Processed in 0.084720 second(s), 35 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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