[Excel] MS Access, VBA에서 라운드하는 법


Answers

허용되는 답변을 조금 확장하려면 다음을 수행하십시오.

"라운드 기능은 라운드에서 짝수로 수행됩니다. 라운드와 크게 다르다."
- Microsoft

형식은 항상 반올림됩니다.

  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

ACC2000 : 원하는 수만큼 숫자를 반올림하거나 올림하는 방법 : http://support.microsoft.com/kb/209996

라운드 기능 : http://msdn2.microsoft.com/en-us/library/se6f2zfx.aspx

사용자 지정 반올림 절차를 구현하는 방법 : http://support.microsoft.com/kb/196652

Question

VBA 액세스에서 가장 좋은 방법은 무엇입니까?

내 현재 메서드는 Excel 메서드를 사용합니다.

Excel.WorksheetFunction.Round(...

그러나 Excel에 의존하지 않는 방법을 찾고 있습니다.




Int와 Fix는 모두 숫자의 정수 부분을 제공하는 유용한 반올림 함수입니다.

Int는 항상 반올림합니다. Int (3.5) = 3, Int (-3.5) = -4

Fix는 항상 0으로 반올림 됨 - Fix (3.5) = 3, Fix (-3.5) = -3

정수 타입이나 긴 타입 (정수는 -32,768 ~ 32,767 사이, longs는 -2,147,483,648과 2,147,483,647 사이)으로 강요하려고하는 CInt와 CLng 같은 강압 함수도 있습니다. 이 둘은 가장 가까운 정수로 반올림하여 .5 - CInt (3.5) = 4, Cint (3.49) = 3, CInt (-3.5) = -4 등의 0에서 반올림합니다.




나는 다음과 같은 단순한 함수를 사용하여 우리 회사에서 항상 통화 를 둥글게했습니다.

Function RoundUp(Number As Variant)
   RoundUp = Int(-100 * Number) / -100
   If Round(Number, 2) = Number Then RoundUp = Number
End Function

그러나 이것은 항상 소수점 이하 2 자릿수로 반올림되며 오류 일 수도 있습니다.

음수라도 반올림합니다 (-1.011은 -1.01이고 1.011은 1.02가됩니다)

반올림 (또는 음수로 아래로) 옵션을 추가로 제공하려면이 함수를 사용할 있습니다.

Function RoundUp(Number As Variant, Optional RoundDownIfNegative As Boolean = False)
On Error GoTo err
If Number = 0 Then
err:
    RoundUp = 0
ElseIf RoundDownIfNegative And Number < 0 Then
    RoundUp = -1 * Int(-100 * (-1 * Number)) / -100
Else
    RoundUp = Int(-100 * Number) / -100
End If
If Round(Number, 2) = Number Then RoundUp = Number
End Function

(명백하지 않은 경우 모듈에서 사용됨)




정수 값으로 반올림하는 것에 대해 말하면 (소수점 이하 자릿수로 반올림하지 않음), 항상 오래된 학교 방식이 있습니다.

return int(var + 0.5)

(당신은 n 소수점 이하 자리에도이 작업을 할 수 있지만 조금 지저분 해지기 시작합니다)




VBA.Round(1.23342, 2) // will return 1.23



불행히도 반올림을 수행 할 수있는 VBA의 네이티브 함수는 누락되거나 제한적이거나 부정확하거나 버그가 있으며 각각 단일 반올림 메서드 만 처리합니다. 위쪽은 그들이 빠르다는 것이고, 그것은 상황에 따라 중요 할 수도 있습니다.

그러나 종종 정밀도가 필수적이며 오늘날 컴퓨터의 속도로 볼 때 처리 속도가 약간 느려지는 것은 아니며 사실 단일 값을 처리하지는 못합니다. 아래 링크의 모든 기능은 약 1 μs에서 실행됩니다.

모든 일반적인 반올림 메소드, VBA의 모든 데이터 유형, 모든 값, 예기치 않은 값을 반환하지 않는 함수의 전체 집합은 다음에서 찾을 수 있습니다.

반올림 값을 4/5, 또는 유효 숫자로 반올림 (EE)

또는 여기 :

4/5 또는 유효 숫자로 반올림 값 반올림 (CodePlex)

GitHub에서만 코드 :

VBA.Round

그들은 정상적인 반올림 방법을 다룹니다.

  • 반올림하여 음수 값을 0으로 반올림하는 옵션 사용

  • 반올림하여 0에서 음수 값을 반올림하는 옵션 포함

  • 0에서 또는 심지어 짝수 (Banker 's Rounding)에서 4/5로 반올림

  • 유효 숫자로 반올림

처음 세 함수는 모든 숫자 데이터 형식을 허용하지만 마지막 함수는 Currency, Decimal 및 Double의 세 가지 유형으로 각각 존재합니다.

그들은 모두 소수점 이하의 지정된 수를 허용합니다 - 수십, 수백 등의 반올림을하는 음의 수를 포함합니다. Variant가 반환 유형 인 경우에는 이해할 수없는 입력에 대해 Null이 반환됩니다.

테스트 및 검증을위한 테스트 모듈도 포함되어 있습니다.

일반적인 4/5 반올림에 대한 예가 여기에 있습니다. 미묘한 세부 사항과 CDec 이 비트 오류를 ​​피하는 데 사용되는 방법에 대한 인라인 주석을 연구하십시오.

' Common constants.
'
Public Const Base10     As Double = 10

' Rounds Value by 4/5 with count of decimals as specified with parameter NumDigitsAfterDecimals.
'
' Rounds to integer if NumDigitsAfterDecimals is zero.
'
' Rounds correctly Value until max/min value limited by a Scaling of 10
' raised to the power of (the number of decimals).
'
' Uses CDec() for correcting bit errors of reals.
'
' Execution time is about 1µs.
'
Public Function RoundMid( _
    ByVal Value As Variant, _
    Optional ByVal NumDigitsAfterDecimals As Long, _
    Optional ByVal MidwayRoundingToEven As Boolean) _
    As Variant

    Dim Scaling     As Variant
    Dim Half        As Variant
    Dim ScaledValue As Variant
    Dim ReturnValue As Variant

    ' Only round if Value is numeric and ReturnValue can be different from zero.
    If Not IsNumeric(Value) Then
        ' Nothing to do.
        ReturnValue = Null
    ElseIf Value = 0 Then
        ' Nothing to round.
        ' Return Value as is.
        ReturnValue = Value
    Else
        Scaling = CDec(Base10 ^ NumDigitsAfterDecimals)

        If Scaling = 0 Then
            ' A very large value for Digits has minimized scaling.
            ' Return Value as is.
            ReturnValue = Value
        ElseIf MidwayRoundingToEven Then
            ' Banker's rounding.
            If Scaling = 1 Then
                ReturnValue = Round(Value)
            Else
                ' First try with conversion to Decimal to avoid bit errors for some reals like 32.675.
                ' Very large values for NumDigitsAfterDecimals can cause an out-of-range error 
                ' when dividing.
                On Error Resume Next
                ScaledValue = Round(CDec(Value) * Scaling)
                ReturnValue = ScaledValue / Scaling
                If Err.Number <> 0 Then
                    ' Decimal overflow.
                    ' Round Value without conversion to Decimal.
                    ReturnValue = Round(Value * Scaling) / Scaling
                End If
            End If
        Else
            ' Standard 4/5 rounding.
            ' Very large values for NumDigitsAfterDecimals can cause an out-of-range error 
            ' when dividing.
            On Error Resume Next
            Half = CDec(0.5)
            If Value > 0 Then
                ScaledValue = Int(CDec(Value) * Scaling + Half)
            Else
                ScaledValue = -Int(-CDec(Value) * Scaling + Half)
            End If
            ReturnValue = ScaledValue / Scaling
            If Err.Number <> 0 Then
                ' Decimal overflow.
                ' Round Value without conversion to Decimal.
                Half = CDbl(0.5)
                If Value > 0 Then
                    ScaledValue = Int(Value * Scaling + Half)
                Else
                    ScaledValue = -Int(-Value * Scaling + Half)
                End If
                ReturnValue = ScaledValue / Scaling
            End If
        End If
        If Err.Number <> 0 Then
            ' Rounding failed because values are near one of the boundaries of type Double.
            ' Return value as is.
            ReturnValue = Value
        End If
    End If

    RoundMid = ReturnValue

End Function