возьмите последнюю 4-ю цифру и округлите до трех цифр целого числа в ms access

#ms-access

#ms-access

Вопрос:

Как заменить последнюю цифру на 0 и округлить цифру влево вверх или вниз. Итак, у меня есть длинный список номеров доступа, таких как 1542, 1475, 1680. Я хотел бы округлить их, чтобы они отображали 1540, 1480 и 1680. Я пытался использовать функцию round, но это не работает с целыми числами. Существуют ли какие-либо встроенные функции, использующие источник управления для отображения этих чисел таким образом, или это должна быть функция VBA?

Ответ №1:

Вы можете разделить на 10, затем округлить до 0 десятичных знаков, а затем умножить на 10.

 UPDATE bar
SET foo = CLng(Round(foo/10, 0) * 10)
  

Если вам не нравится «округление банкиров», которое делает Access, проверьте http://www.allenbrowne.com/round.html

Ответ №2:

Я не знаю ни одной встроенной функции для этого, но, возможно, это сработает:

 Dim x as Long
x = Round((1542/10)   0.01) * 10
  

Что это делает:

  1. Временно преобразуйте значение в число с одной десятичной цифрой, сдвинув его вправо на одну цифру после запятой;
  2. Используйте функцию Round для округления этого промежуточного десятичного значения;
  3. В конце добавьте завершающий ноль.

Когда я протестировал это в немедленном окне, оказалось, что числа, заканчивающиеся на «5», округляются в меньшую сторону, и вы хотите, чтобы они округлялись в большую. Чтобы исправить это, вам нужно добавить 0,01 перед округлением, чтобы числа, заканчивающиеся на «5», становились немного больше и поэтому округлялись в большую сторону.

Я знаю, что это не совсем то, что вы, возможно, искали, но это все еще однострочная версия VBA.

Ответ №3:

Функция округления сильно прослушивается.

Из моего проекта VBA.Округление, используйте функцию RoundMid, которая правильно округляет любое значение:

 RoundedBy10 = RoundMid(Value, -1)

1475 -> 1480 
1542 -> 1540 
1680 -> 1680 
  

Функция:

 ' Rounds Value by 4/5 with count of decimals as specified with parameter NumDigitsAfterDecimal.
'
' Rounds to integer if NumDigitsAfterDecimal 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() to prevent bit errors of reals.
'
' Execution time is about 1µs.
'
' 2018-02-09. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function RoundMid( _
    ByVal Value As Variant, _
    Optional ByVal NumDigitsAfterDecimal 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 ^ NumDigitsAfterDecimal)
        
        If Scaling = 0 Then
            ' A very large value for NumDigitsAfterDecimal 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 NumDigitsAfterDecimal 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 NumDigitsAfterDecimal 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