ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

VBA中的回调函数如何处理

[复制链接]

TA的精华主题

TA的得分主题

发表于 2021-4-14 15:38 | 显示全部楼层 |阅读模式
最近因为需要用到一个表达式计算的功能,所以自己花了一些精力完成了,但目前遇到的问题想请教下各位大佬。
第一:回调函数目前是通过事件来完成的,但因为通过事件就限定了使用场景只能在窗体的对象模块中使用,不能在公共模块中使用。所以想知道有没有什么办法处理回调函数。
目前我是这样做的如下图。
企业微信截图_16183851496429.png

在窗体初始的时候添加函数及常量

Private Sub UserForm_Initialize()
    iRow = 2
    Set F = New cFormulan
    '添加常量
    Call F.AddUserConstant("Pi", "3.1415926535897932385")
    Call F.AddUserConstant("true", "1")
    Call F.AddUserConstant("false", "0")
    Call F.AddUserConstant("亿", "100000000")

    '添加函数
    Call F.AddUserFunction("abs", 1)
    Call F.AddUserFunction("sqr", 1)
    Call F.AddUserFunction("sqrt", 1)
    Call F.AddUserFunction("round", 2)
    Call F.AddUserFunction("left", 2)
    Call F.AddUserFunction("right", 2)
    Call F.AddUserFunction("sin", 1)
End Sub


通过事件处理变量及函数,虽然目前来看是没有什么问题,也比较容易扩展函数功能。目前唯一遗憾的想知道有没有回调函数可以避开使用事件。

Private Sub F_FunctionCallback(ByVal fName As String, ByVal Args As Variant, ByVal aIndex As Long, result As Variant)
    Select Case fName
        Case "ABS"
            result = Abs(Args(aIndex))
        Case "RIGHT"
            result = Right(Args(aIndex), Args(aIndex + 1))
        Case "LEFT"
            result = Left(Args(aIndex), Args(aIndex + 1))
        Case "SQR", "SQRT"
            result = VBA.Sqr(Args(aIndex))
        Case "ROUND"
            If Args(aIndex + 1) > 0 Then
                result = Round(Args(aIndex), Args(aIndex + 1))
            Else
                result = Round(Args(aIndex) * 10 ^ (Args(aIndex + 1)), 0) * 10 ^ Abs(Args(aIndex + 1))
            End If
        Case "SIN"
            result = Sin(Args(aIndex))
    End Select
End Sub

Private Sub F_SetVariableVal(ByVal vName As Variant, vVal As Variant)
    Select Case vName
        Case "i"
            vVal = i
            Sheet1.Cells(iRow, 4).value = i
        Case "j"
            vVal = J
            Sheet1.Cells(iRow, 5).value = J
        Case "X" '
            vVal = Round(Rnd() * (100 - 1) + 1, 2)
            Sheet1.Cells(iRow, 6).value = vVal
        Case "Y"
            vVal = Round(Rnd() * (100 - 1) + 1, 2)
            Sheet1.Cells(iRow, 7).value = vVal
    End Select
    Debug.Print vName, vVal
End Sub


第二:效率问题,本来想提升效率,想用内存操作业操作数据,想着即可节约空间又可提高效率,结果发现CopyMemory 反而效率更慢,不知道那位大佬知道是什么原因,最后没办法只好改为了字符串组合,为了性能牺牲空间了。
Sub storedbl(ByVal s As String, value As Variant)
    Dim v As Currency
    Dim iOffset As Long
    Dim T As Currency
    Dim SS As String
    s = s & value & ChrW(0)
    'iOffset = LenB(s)
    'SS = String$(LenB(v) / 2, 100)
    'CopyMemory StrPtr(SS) + iOffset, StrPtr(SS), 8
End Sub

企业微信截图_20210414153713.png

希望能得到帮助,谢谢!

TA的精华主题

TA的得分主题

发表于 2021-4-14 21:33 | 显示全部楼层
自己添加函数?为什么不利用Excel的内置函数公式进行计算。

“我们不生产水,我们只是大自然的搬运工”。使用正则表达式,把计算式中的特定字符进行转换和清洗过滤,然后借用Excel强大的函数公式及名称定义的功能,拥有无穷的扩展能力。

请参考我的帖子:
单元格小工具之九——工程量计算式 求值与字体格式化
http://club.excelhome.net/thread-1517833-1-1.html
(出处: ExcelHome技术论坛)

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-4-14 22:01 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
ggmmlol 发表于 2021-4-14 21:33
自己添加函数?为什么不利用Excel的内置函数公式进行计算。

“我们不生产水,我们只是大自然的搬运工” ...

应用场景不一样,有时候需要从很多其它外部得到数据,并对它些数据计算处理,所以需要用到表达式计算。如果不用表达式,用内置函数,那就得把所有数据读取到数据表中,再写公式这样运算量太大了。并不是我想要的。

TA的精华主题

TA的得分主题

发表于 2021-4-15 08:06 | 显示全部楼层
你既然强调应用场景,却不上附件,别人谁能了解你的应用场景?
你自己认为只有自定义回调函数才是最好的解决办法,在我看来,这也许是根本的方向错误。
就求助方式来说,你不上附件,做为一个新人,不了解附件在求助中的关键作用,可以理解。但是,在被提示上附件之后,如果你仍坚持所谓的通用函数不需要用附件测试,我赌一包82年的辣条,你不可能得到满意的解答!

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-4-15 08:57 | 显示全部楼层
ggmmlol 发表于 2021-4-15 08:06
你既然强调应用场景,却不上附件,别人谁能了解你的应用场景?
你自己认为只有自定义回调函数才是最好的解 ...

谢谢你的回复,其实也知道可能根本没有答案,毕竟VBA有很多局限,在别的编程语言中回调函数真的是非常基础的,但VBA以我的认知只能用事件来实现。另外说到的第二个问题内存操作,同样的代码copymemory在VB中则效率很高,在VBA中则效率非常低,这也是让我困惑的地方。如果操作内存能高效也可以补VBA很多短板,特别是自己构造数据结构这些特殊需求的场景。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

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

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

GMT+8, 2024-4-19 12:43 , Processed in 0.040795 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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