2016-01-21 72 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