如何在MS Access,VBA中四舍五入
在VBA Access中四舍五入的最佳方法是什么?
我目前的方法是利用Excel方法
Excel.WorksheetFunction.Round(...
但是我正在寻找一种不依赖Excel的方法。
解决方案
Int和Fix都是有用的舍入函数,它们为我们提供数字的整数部分。
Int总是四舍五入Int(3.5)= 3,Int(-3.5)= -4
Fix总是四舍五入到Fix(3.5)= 3,Fix(-3.5)= -3
还有强制功能,尤其是CInt和CLng,它们试图将数字强制转换为整数类型或者长整型(整数介于-32,768和32,767之间,长整数介于-2,147,483,648和2,147,483,647之间)。这些都将舍入到最接近的整数,从.5 CInt(3.5)= 4的Cint(3.49)= 3,CInt(-3.5)= -4的零开始舍入。
VBA.Round(1.23342, 2) // will return 1.23
请注意,VBA舍入功能使用Banker的舍入,将0.5舍入为偶数,如下所示:
Round (12.55, 1) would return 12.6 (rounds up) Round (12.65, 1) would return 12.6 (rounds down) Round (12.75, 1) would return 12.8 (rounds up)
而Excel工作表函数会四舍五入,因此总是四舍五入。
我已经做过一些测试,它看起来像.5向上舍入(对称舍入)也用于单元格格式,也用于列宽舍入(使用"通用数字"格式时)。 "显示的精度"标志似乎没有进行任何舍入,它仅使用单元格格式的舍入结果。
我试图在VBA中从Microsoft实现Microsoft的SymArith函数,但是在尝试给它提供58.55之类的数字时,发现Fix有一个错误。该函数给出的结果是58.5而不是58.6. 然后,我终于发现我们可以使用Excel Worksheet Round函数,如下所示:
Application.Round(58.55, 1)
这将使我们可以在VBA中进行常规舍入,尽管它可能不如某些自定义函数那么快。我意识到问题已经解决了整个问题,但是为了完整起见,我想将其包括在内。
如果我们要四舍五入为整数值(而不是四舍五入为小数点后n位),则总有一种旧的方法:
return int(var + 0.5)
(我们也可以将其用于n个小数位,但开始变得有点混乱)
1 place = INT(number x 10 + .5)/10 3 places = INT(number x 1000 + .5)/1000
我们经常会发现,显然这样的笨拙解决方案比使用Excel函数要快得多,因为VBA似乎在不同的内存空间中运行。
例如:"如果A> B,则MaxAB = A,否则MaxAB = B"比使用ExcelWorksheetFunction.Max快40倍。
在瑞士以及参与保险业的人,我们必须使用一些取整规则,具体取决于它是否会退出市场,是否获得利益等。
我目前正在使用该功能
Function roundit(value As Double, precision As Double) As Double roundit = Int(value / precision + 0.5) * precision End Function
这似乎工作正常
在接受的答案上稍微扩展一下:
"取整功能执行的取整为偶数,这与取整到较大的取数不同。"
- 微软
格式总是四舍五入。
Debug.Print Round(19.955, 2) 'Answer: 19.95 Debug.Print Format(19.955, "#.00") 'Answer: 19.96
ACC2000:使用浮点数时的舍入错误:http://support.microsoft.com/kb/210423
ACC 2000:如何通过所需的增量向上或者向下舍入一个数字:http://support.microsoft.com/kb/209996
圆形函数:http://msdn2.microsoft.com/en-us/library/se6f2zfx.aspx
如何实施自定义舍入过程:http://support.microsoft.com/kb/196652
Lance已经在VBA的实现中提到了继承取整bug
。
因此,我需要在VB6应用程序中使用真正的舍入功能。
这是我正在使用的一个。它基于我在网上找到的评论中指出的一种。
' ----------------------------------------------------------------------------- ' RoundPenny ' ' Description: ' rounds currency amount to nearest penny ' ' Arguments: ' strCurrency - string representation of currency value ' ' Dependencies: ' ' Notes: ' based on RoundNear found here: ' http://advisor.com/doc/08884 ' ' History: ' 04/14/2005 - WSR : created ' Function RoundPenny(ByVal strCurrency As String) As Currency Dim mnyDollars As Variant Dim decCents As Variant Dim decRight As Variant Dim lngDecPos As Long 1 On Error GoTo RoundPenny_Error ' find decimal point 2 lngDecPos = InStr(1, strCurrency, ".") ' if there is a decimal point 3 If lngDecPos > 0 Then ' take everything before decimal as dollars 4 mnyDollars = CCur(Mid(strCurrency, 1, lngDecPos - 1)) ' get amount after decimal point and multiply by 100 so cents is before decimal point 5 decRight = CDec(CDec(Mid(strCurrency, lngDecPos)) / 0.01) ' get cents by getting integer portion 6 decCents = Int(decRight) ' get leftover 7 decRight = CDec(decRight - decCents) ' if leftover is equal to or above round threshold 8 If decRight >= 0.5 Then 9 RoundPenny = mnyDollars + ((decCents + 1) * 0.01) ' if leftover is less than round threshold 10 Else 11 RoundPenny = mnyDollars + (decCents * 0.01) 12 End If ' if there is no decimal point 13 Else ' return it 14 RoundPenny = CCur(strCurrency) 15 End If 16 Exit Function RoundPenny_Error: 17 Select Case Err.Number Case 6 18 Err.Raise vbObjectError + 334, c_strComponent & ".RoundPenny", "Number '" & strCurrency & "' is too big to represent as a currency value." 19 Case Else 20 DisplayError c_strComponent, "RoundPenny" 21 End Select End Function ' -----------------------------------------------------------------------------
这是在Access 2003中始终四舍五入到下一个整数的简单方法:
BillWt = IIf([Weight]-Int([Weight])=0,[Weight],Int([Weight])+1)
例如:
- [重量] = 5.33; Int([Weight])= 5;因此5.33-5 = 0.33(<> 0),因此答案是BillWt = 5 + 1 = 6.
- [Weight] = 6.000,Int([Weight])= 6,所以6.000-6 = 0,所以答案是BillWt = 6.