MS 액세스에서 반올림
VBA 액세스에서 라운드하는 가장 좋은 방법은 무엇입니까?
나의 현재 방식은 엑셀 방식을 사용합니다.
Excel.WorksheetFunction.Round(...
하지만 저는 엑셀에 의존하지 않는 방법을 찾고 있습니다.
VBA 라운드 함수는 뱅커의 반올림을 사용하며, 여기서 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를 반올림합니다.
몇 가지 테스트를 해봤는데 셀 형식과 열 너비 반올림(일반 번호 형식을 사용할 때)에도 .5 올림(대칭 반올림)이 사용되는 것 같습니다.'표시된 대로 정밀도' 플래그는 반올림 자체를 수행하지 않고 셀 형식의 반올림 결과만 사용합니다.
반올림을 위해 Microsoft의 SymArith 함수를 VBA에 구현하려고 했지만 58.55와 같은 숫자를 지정하려고 하면 Fix에 오류가 발생합니다. 58.6 대신 58.5라는 함수입니다.그런 다음 Excel 워크시트 라운드 기능을 다음과 같이 사용할 수 있다는 것을 알게 되었습니다.
어플.라운드(58.55, 1)
이렇게 하면 일부 사용자 지정 기능만큼 빠르지는 않지만 VBA에서 일반 반올림을 수행할 수 있습니다.저는 이것이 질문에서 완전히 원을 이루었다는 것을 알고 있지만, 완전성을 위해 그것을 포함하고 싶었습니다.
승인된 답변에 대해 조금 더 자세히 설명을 수 있습니다.
"라운드 기능은 라운드에서 짝수까지 수행되며, 라운드마다 크기가 다릅니다."
--마이크로소프트
형식은 항상 반올림됩니다.
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
스위스, 특히 보험업계에서는 현금화 여부, 혜택 등에 따라 몇 가지 반올림 규칙을 사용해야 합니다.
저는 현재 이 기능을 사용합니다.
Function roundit(value As Double, precision As Double) As Double
roundit = Int(value / precision + 0.5) * precision
End Function
그것은 잘 작동하는 것처럼 보입니다.
Int와 Fix는 모두 숫자의 정수 부분을 제공하는 유용한 반올림 함수입니다.
Int는 항상 반올림됩니다. - Int(3.5) = 3, Int(-3.5) = -4
항상 0을 향해 고정 - 고정(3.5) = 3, 고정(-3.5) = -3
특히 CInt와 CLng는 숫자를 정수 유형 또는 긴 유형(정수는 -32,768과 32,767 사이, 길이는 -2,147,483,648과 2,147,483,647 사이)으로 강제 적용하는 강제 기능도 있습니다.이들은 둘 다 0에서 0을 반올림하여 가장 가까운 정수를 향해 반올림합니다. 5 - CInt(3.5) = 4, Cint(3.49) = 3, CInt(-3.5) = -4 등.
1 place = INT(number x 10 + .5)/10
3 places = INT(number x 1000 + .5)/1000
등등.VBA가 다른 메모리 공간에서 작동하는 것처럼 보이기 때문에 이와 같은 흐릿한 솔루션이 Excel 기능을 사용하는 것보다 훨씬 빠르다는 것을 종종 발견할 수 있습니다.
예를 들어If A > B Then MaxAB = A Else MaxAB = B
MaxExcel 워크시트 함수 사 배 40 더 니 다 빠 릅 약 을 다 것 보 용하 는
안타깝게도 반올림을 수행할 수 있는 VBA의 기본 함수는 누락되거나 제한되거나 부정확하거나 버그가 있으며 각 함수는 단일 반올림 방법만 처리합니다.장점은 그들이 빠르다는 것이고, 어떤 상황에서는 그것이 중요할 수도 있습니다.
그러나 종종 정밀도는 필수 사항이며, 오늘날 컴퓨터의 속도로 인해 단일 값의 처리가 아닌 약간 느린 처리는 거의 눈치채지 못할 것입니다.아래 링크의 모든 기능은 약 1µs로 실행됩니다.
모든 일반적인 반올림 방법, 모든 값에 대한 모든 데이터 유형의 VBA, 그리고 예기치 않은 값을 반환하지 않는 전체 함수 집합은 다음에서 찾을 수 있습니다.
값을 위로, 아래로, 4/5만큼 또는 유의한 숫자로 반올림(EE)
또는 여기:
값을 위로, 아래로, 4/5만큼 또는 유의한 숫자로 반올림(CodePlex)
GitHub에서만 코드:
일반 반올림 방법은 다음과 같습니다.
0을 향해 음수 값을 반올림하는 옵션을 사용하여 반올림합니다.
0에서 음수 값을 반올림하는 옵션을 사용하여 반올림합니다.
0에서 벗어나거나 짝수로 4/5로 반올림(은행가 반올림)
유의한 숫자의 개수로 반올림
처음 세 함수는 모든 숫자 데이터 유형을 사용할 수 있는 반면 마지막 함수는 통화, 십진수 및 이중의 세 가지 유형으로 존재합니다.
그들은 모두 10, 수백 등으로 반올림될 음수 카운트를 포함하여 지정된 소수점 이하의 카운트를 허용합니다.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
소수점 n자리를 반올림하지 않고 정수 값으로 반올림하는 경우에는 항상 기존의 방법이 있습니다.
return int(var + 0.5)
(소수점 n자리에서도 작동할 수 있지만, 약간 지저분해지기 시작합니다.)
랜스가 이미 유전자 반올림에 대해 언급했습니다.bug
VBA의 구현에서.그래서 저는 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
' -----------------------------------------------------------------------------
VBA.Round(1.23342, 2) // will return 1.23
페니 분할이 원래 분할된 금액만큼 합산되지 않는 문제를 해결하기 위해 사용자 정의 함수를 만들었습니다.
Function PennySplitR(amount As Double, Optional splitRange As Variant, Optional index As Integer = 0, Optional n As Integer = 0, Optional flip As Boolean = False) As Double
' This Excel function takes either a range or an index to calculate how to "evenly" split up dollar amounts
' when each split amount must be in pennies. The amounts might vary by a penny but the total of all the
' splits will add up to the input amount.
' Splits a dollar amount up either over a range or by index
' Example for passing a range: set range $I$18:$K$21 to =PennySplitR($E$15,$I$18:$K$21) where $E$15 is the amount and $I$18:$K$21 is the range
' it is intended that the element calling this function will be in the range
' or to use an index and total items instead of a range: =PennySplitR($E$15,,index,N)
' The flip argument is to swap rows and columns in calculating the index for the element in the range.
' Thanks to: http://stackoverflow.com/questions/5559279/excel-cell-from-which-a-function-is-called for the application.caller.row hint.
Dim evenSplit As Double, spCols As Integer, spRows As Integer
If (index = 0 Or n = 0) Then
spRows = splitRange.Rows.count
spCols = splitRange.Columns.count
n = spCols * spRows
If (flip = False) Then
index = (Application.Caller.Row - splitRange.Cells.Row) * spCols + Application.Caller.Column - splitRange.Cells.Column + 1
Else
index = (Application.Caller.Column - splitRange.Cells.Column) * spRows + Application.Caller.Row - splitRange.Cells.Row + 1
End If
End If
If (n < 1) Then
PennySplitR = 0
Return
Else
evenSplit = amount / n
If (index = 1) Then
PennySplitR = Round(evenSplit, 2)
Else
PennySplitR = Round(evenSplit * index, 2) - Round(evenSplit * (index - 1), 2)
End If
End If
End Function
우리 회사에서는 항상 돈을 모으듯이 저는 다음과 같은 간단한 기능을 사용하여 제 통화를 반올림했습니다.
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
(분명하지 않은 경우 모듈에서 사용)
액세스 2003에서 항상 다음 정수로 반올림하는 쉬운 방법은 다음과 같습니다.
BillWt = IIf([Weight]-Int([Weight])=0,[Weight],Int([Weight])+1)
예:
- [무게] = 5.33; Int([무게]) = 5; 따라서 5.33-5 = 0.33(<>0)이므로, BillWt = 5+1 = 6이 답입니다.
- [무게] = 6.000, Int([무게]) = 6이므로 6.000-6 = 0이므로 BillWt = 6입니다.
Public Function RoundUpDown(value, decimals, updown)
If IsNumeric(value) Then
rValue = Round(value, decimals)
rDec = 10 ^ (-(decimals))
rDif = rValue - value
If updown = "down" Then 'rounding for "down" explicitly.
If rDif > 0 Then ' if the difference is more than 0, it rounded up.
RoundUpDown = rValue - rDec
ElseIf rDif < 0 Then ' if the difference is less than 0, it rounded down.
RoundUpDown = rValue
Else
RoundUpDown = rValue
End If
Else 'rounding for anything thats not "down"
If rDif > 0 Then ' if the difference is more than 0, it rounded up.
RoundUpDown = rValue
ElseIf rDif < 0 Then ' if the difference is less than 0, it rounded down.
RoundUpDown = rValue + rDec
Else
RoundUpDown = rValue
End If
End If
End If
'RoundUpDown(value, decimals, updown) 'where updown is "down" if down. else rounds up. put this in your program.
End Function
언급URL : https://stackoverflow.com/questions/137114/rounding-in-ms-access
'programing' 카테고리의 다른 글
Flask 서버에서 콘솔 메시지 사용 안 함 (0) | 2023.08.10 |
---|---|
좋아요와 좋아요가 반대 결과를 반환하지 않음 (0) | 2023.08.10 |
Jquery에서 키와 값을 모두 배열로 밀어넣는 방법 (0) | 2023.08.10 |
"NS_ERROR_DOM_BAD_URI: 제한된 URI에 대한 액세스가 거부되었습니다." (0) | 2023.08.10 |
다른 사람이 저장 프로시저의 결과를 사용하는 방법 - MariaDB (0) | 2023.08.10 |