2016-01-21 38 views
1

长话短说,我工作的地方用时钟的象限来测量时间。例如,1.1是1小时0-15分钟,1.2是1小时15-30分钟,1.3是1小时30-45分钟。没有1.4,因为1.4当然等于2.在UDF中使用Excel的舍入舍入1到0

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

如果你看下面的屏幕截图,你会发现该函数适用于除了最后一周的总列之外的所有列,出于某种原因显示39.4而不是40(两个值在技术上相同,但是由于某种原因,程序不会将.4转换为1)。

http://i.imgur.com/yxOvlkP.png

这里是它的全部代码。这个问题似乎在余数等于1的情况下出现(为了简单起见,只需要输入两个结尾为0.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的ROUNDDOWN功能似乎是四舍五入到0

这意味着,因为它应该下面的行不会将1添加到整数倍:

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

而且,当它不应该(这是.4来自)这条线将返回1,它得到了2.5分:

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

我不确定发生了什么事情,或者为什么excel会将我的余数从1减小到0,如果这确实是问题所在。我很感激任何帮助,如果您需要更多信息,请告诉我们。谢谢!

+0

你的问题是,电脑是二进制和你正在做数字算术。关于39.4的结果,其余的计算为0.399999999999999你需要舍入,或使用十进制算术 –

回答

0

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

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

另请注意,下面的例程仅适用于正数。如果你可以在你的考勤表是具有负数,你应该在的地方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 
+0

这是完美的。非常感谢! –

0

使用Fix试试这个代码:

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