|
不久前,我遇到一个朋友,他说看到了一个Access短视频,里面有个函数,可以实时显示计算结果。我很奇怪,为什么会写这样的函数。他说,人最大的烦恼,就是不能随时实现愿望。如果什么愿望都能像这个函数一样,随时实现,你说多开心。这个函数本来打算发给你,现在看起来,我们得一起研究了。
- Function Calculate(s As String) As Long
- Dim ops() As Long
- ReDim ops(0)
- ops(0) = 1
- Dim sign As Long
- sign = 1
- Dim ret As Long
- ret = 0
-
- Dim n As Long
- n = Len(s)
- Dim i As Long
- i = 1
-
- Do While i <= n
- Select Case Mid(s, i, 1)
-
- Case " "
- i = i + 1
- Case "+"
- sign = ops(UBound(ops))
- i = i + 1
- Case "-"
- sign = -ops(UBound(ops))
- i = i + 1
- Case "("
- ReDim Preserve ops(UBound(ops) + 1)
- ops(UBound(ops)) = sign
- i = i + 1
- Case ")"
- ReDim Preserve ops(UBound(ops) - 1)
- i = i + 1
- Case Else
- Dim num As Long
- num = 0
- Do While i <= n And IsNumeric(Mid(s, i, 1))
- num = num * 10 + CLng(Mid(s, i, 1))
- i = i + 1
- Loop
- ret = ret + sign * num
- End Select
- Loop
- Calculate = ret
- End Function
复制代码 我看了一眼,虽然可以实时显示,但还是太复杂了。我很奇怪,为什么博主不用eval函数,而是非要使用数组?
关于eval函数,很久以前写过一个帖子,用于计算学杂费之类:
http://www.office-cn.net/thread-108898-1-1.html
在我看来,使用eval函数应该会更简单些。另外,考虑到只有加减法,根据加减法结合律,小括号对加减运算没任何影响,所以干脆去掉小括号的判定,于是有了这个简单版本:
- Function StrtoLong(ByVal strExpress As String) As Long
- Dim strResult As String
- '如果最后一个字符是运算符,剔除
- If InStr(1, "+-*/^", Right(strExpress, 1)) Then
- strResult = Left(strExpress, Len(strExpress) - 1)
-
- Else
- strResult = strExpress
- End If
- StrtoLong = Eval(strResult)
- End Function
复制代码 写完这个,后来想想,既然非要使用小括号,那不如把乘、除和幂方也加上吧,便有了一个进阶版。
这里就不贴代码了。有需要的版友可以自行下载附件。
需要说明的是:
- 三个窗体都没有进行错误处理,使用时请确保输入字符为指定的字符。否则会出错,导致Access”假死“(目前我遇到的是这个情况)。
- 进阶版虽然支持小括号运算,但暂时还不能处理嵌套小括号的问题。这是因为需要使用正则表达式来提取小括号内部的表达式,再进行处理,可能需要用到递归算法,处理完毕后再拼接回去,过程相对复杂。而且一旦存在多个嵌套小括号的情况,复杂度将成倍增加。因此暂时不加上。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|