【问题标题】:How to round up with excel VBA round()?如何用excel VBA round()四舍五入?
【发布时间】:2013-04-07 16:54:23
【问题描述】:

我有以下数据:

cell(1,1) = 2878.75
cell(1,2) = $31.10
cell(2,1) = $89,529.13

但是,当我尝试使用round(cells(1,1).value*cells(1,2).value),2) 时,结果与cell(2,1) 不匹配。我认为这与舍入问题有关,但我只是想知道是否可以让round() 正常运行。也就是说,对于value > 0.5,向上取整。对于value < 0.5,向下取整?

【问题讨论】:

  • “也就是说,对于 value > 0.5,向上取整。对于 value 实际上,Round 的行为是这样的。问题在于它对value = 0.5 的作用。

标签: excel vba


【解决方案1】:

我的建议等于 Worksheetfunction.RoundUp

Function RoundUp(ByVal Number As Double, Optional ByVal Digits As Integer = 0) As Double
    Dim TempNumber As Double, Mantissa As Double
    
    'If Digits is minor than zero assign to zero.
    If Digits < 0 Then Digits = 0
    
    'Get number for x digits
    TempNumber = Number * (10 ^ Digits)
    
    'Get Mantisa for x digits
    Mantissa = TempNumber - Int(TempNumber)
    
    'If mantisa is not zero, get integer part of TempNumber and increment for 1.
    'If mantisa is zero then we reach the total number of digits of the mantissa of the original number
    If Mantissa <> 0 Then
        RoundUp = (Int(TempNumber) + 1) / (10 ^ Digits)
    Else
        RoundUp = Number
    End If
End Function

【讨论】:

    【解决方案2】:

    这里的答案几乎遍及整个地图,并尝试完成几件不同的事情。我只是将您指向 the answer 我最近给出的讨论强制向上舍入的内容——即根本不向零舍入。这里的答案涵盖了不同类型的四舍五入,例如 ana 的答案是强制四舍五入。

    要清楚,最初的问题是如何“正常四舍五入”——所以,“对于值 > 0.5,向上舍入。对于值

    我链接到的答案讨论了强制四舍五入,您有时也想这样做。 Excel 的普通 ROUND 使用 round-half-up,而其 ROUNDUP 使用 round-away-from-zero。所以这里有两个模仿VBA中ROUNDUP的函数,第二个只取整为整数。

    Function RoundUpVBA(InputDbl As Double, Digits As Integer) As Double
    
        If InputDbl >= O Then
            If InputDbl = Round(InputDbl, Digits) Then RoundUpVBA = InputDbl Else RoundUpVBA = Round(InputDbl + 0.5 / (10 ^ Digits), Digits)
        Else
            If InputDbl = Round(InputDbl, Digits) Then RoundUpVBA = InputDbl Else RoundUpVBA = Round(InputDbl - 0.5 / (10 ^ Digits), Digits)
        End If
    
    End Function
    

    或者:

    Function RoundUpToWhole(InputDbl As Double) As Integer
    
        Dim TruncatedDbl As Double
    
        TruncatedDbl = Fix(InputDbl)
    
        If TruncatedDbl <> InputDbl Then
            If TruncatedDbl >= 0 Then RoundUpToWhole = TruncatedDbl + 1 Else RoundUpToWhole = TruncatedDbl - 1
        Else
            RoundUpToWhole = TruncatedDbl
        End If
    
    End Function
    

    上面的一些答案涵盖了类似的领域,但这里的答案是独立的。我还在我的另一个答案中讨论了一些单行快速而肮脏的方法来总结。

    【讨论】:

      【解决方案3】:

      我觉得以下功能就足够了:

      '
      ' Round Up to the given number of digits
      '
      Function RoundUp(x As Double, digits As Integer) As Double
      
          If x = Round(x, digits) Then
              RoundUp = x
          Else
              RoundUp = Round(x + 0.5 / (10 ^ digits), digits)
          End If
      
      End Function
      

      【讨论】:

        【解决方案4】:

        这对我有用

        Function round_Up_To_Int(n As Double)
            If Math.Round(n) = n Or Math.Round(n) = 0 Then
                round_Up_To_Int = Math.Round(n)
            Else: round_Up_To_Int = Math.Round(n + 0.5)
            End If
        End Function
        

        【讨论】:

        • 能否请您也为您的答案提供一些解释,以便其他用户也可以轻松理解。
        【解决方案5】:

        这是我制作的。它不使用我喜欢的第二个变量。

                Points = Len(Cells(1, i)) * 1.2
                If Round(Points) >= Points Then
                    Points = Round(Points)
                Else: Points = Round(Points) + 1
                End If
        

        【讨论】:

          【解决方案6】:

          如果要四舍五入,请使用半调整。将要四舍五入的数字加 0.5 并使用 INT() 函数。

          答案 = INT(x + 0.5)

          【讨论】:

          • 不适用于已经是整数的数字。例如。 Round(41.0 + 0.5) 将导致 42
          • 在这种情况下:answer = Iif(Int(x) = x, x, Round(x + 0.5)) 使用 Int 检查它是否为圆形
          • @MCL 42 不是正确答案吗?有什么问题?
          • @Ans 不,因为 41 已经是四舍五入,所以答案应该是 41。添加 0.5 只是为了始终向上舍入。
          • 不知道我在想什么。意思是使用 INT() 函数,而不是 Round() 函数。
          【解决方案7】:

          这是一个示例 j 是您要四舍五入的值。

          Dim i As Integer
          Dim ii, j As Double
          
          j = 27.11
          i = (j) ' i is an integer and truncates the decimal
          
          ii = (j) ' ii retains the decimal
          
          If ii - i > 0 Then i = i + 1 
          

          如果余数大于 0,则将其向上取整,简单。在 1.5 时,它会自动舍入为 2,因此它会小于 0。

          【讨论】:

            【解决方案8】:

            使用来自 ShamBhagwat 的函数“RDown”和“RUp”,并创建了另一个返回圆形部分的函数(无需输入“数字”)

            Function RoundDown(a As Double, digits As Integer) As Double
                RoundDown = Int((a + (1 / (10 ^ (digits + 1)))) * (10 ^ digits)) / (10 ^ digits)
            End Function
            
            Function RoundUp(a As Double, digits As Integer) As Double
                RoundUp = RoundDown(a + (5 / (10 ^ (digits + 1))), digits)
            End Function
            
            Function RDownAuto(a As Double) As Double
                Dim i As Integer
                For i = 0 To 17
                    If Abs(a * 10) > WorksheetFunction.Power(10, -(i - 1)) Then
                        If a > 0 Then
                            RDownAuto = RoundDown(a, i)
                        Else
                            RDownAuto = RoundUp(a, i)
                        End If
                    Exit Function
                    End If
                Next
            End Function
            

            输出将是:

            RDownAuto(458.067)=458
            RDownAuto(10.11)=10
            RDownAuto(0.85)=0.8
            RDownAuto(0.0052)=0.005
            RDownAuto(-458.067)=-458
            RDownAuto(-10.11)=-10
            RDownAuto(-0.85)=-0.8
            RDownAuto(-0.0052)=-0.005
            

            【讨论】:

              【解决方案9】:

              我遇到了一个问题,我只需要四舍五入,而这些答案对于我必须如何运行我的代码不起作用,所以我使用了不同的方法。 INT 函数向负数舍入(4.2 变为 4,-4.2 变为 -5) 因此,我将我的函数更改为负数,应用 INT 函数,然后通过在前后乘以 -1 将其返回为正数

              Count = -1 * (int(-1 * x))
              

              【讨论】:

              • x 是您只想四舍五入的变量,count 是您将在代码中进一步使用的结果
              • 我使用代码的方式是确定日历中需要多少页才能在任何给定月份每周有一个页面。该等式基于一个月中的天数以及该月的第一天是什么时候。
              • 为了清楚起见,我将年和月变量分别命名为年和月,因为年和月已经是 VBA 中的函数。 daysinmonth 当然是用前面的公式确定的一个月中有多少天。如果有人感兴趣,这是我使用的代码(可能比需要的括号多,但我不在乎反复试验以减少使用): count = -1 * (Int((-1 * (daysinmonth + (DateSerial(years, months) , 1) - 1))) / 7))
              【解决方案10】:

              Math.Round 使用银行家四舍五入,如果要四舍五入的数字正好在中间,则将四舍五入到最接近的偶数。

              简单的解决方案,使用 Worksheetfunction.Round()。如果它在边缘,那将四舍五入。

              【讨论】:

                【解决方案11】:

                我介绍了两个在vba中使用的自定义库函数,它们将用于舍入double值而不是使用WorkSheetFunction.RoundDown和WorkSheetFunction.RoundUp

                Function RDown(Amount As Double, digits As Integer) As Double
                    RDown = Int((Amount + (1 / (10 ^ (digits + 1)))) * (10 ^ digits)) / (10 ^ digits)
                End Function
                
                Function RUp(Amount As Double, digits As Integer) As Double
                    RUp = RDown(Amount + (5 / (10 ^ (digits + 1))), digits)
                End Function
                

                因此函数 Rdown(2878.75 * 31.1,2) 将返回 899529.12 并且函数 RUp(2878.75 * 31.1,2) 将返回 899529.13 然而 函数 Rdown(2878.75 * 31.1,-3) 将返回 89000 并且函数 RUp(2878.75 * 31.1,-3) 将返回 90000

                【讨论】:

                • 这些功能很棒!
                【解决方案12】:

                我自己有一个解决方法:

                    'G = Maximum amount of characters for width of comment cell
                    G = 100
                    'CommentX
                    If THISWB.Sheets("Source").Cells(i, CommentColumn).Value = "" Then
                        CommentX = ""
                     Else
                        CommentArray = Split(THISWB.Sheets("Source").Cells(i, CommentColumn).Value, Chr(10)) 'splits on alt + enter
                        DeliverableComment = "Available"
                    End If
                                        If CommentX <> "" Then
                
                                            'this loops for each newline in a cell (alt+enter in cell)
                                            For CommentPart = 0 To UBound(CommentArray)
                                            'format comment to max G characters long
                                                LASTSPACE = 0
                                                LASTSPACE2 = 0
                                                    If Len(CommentArray(CommentPart)) > G Then
                
                                                        'find last space in G length character string to make sure the line ends with a whole word and the new line starts with a whole word
                                                        Do Until LASTSPACE2 >= Len(CommentArray(CommentPart))
                                                            If CommentPart = 0 And LASTSPACE2 = 0 And LASTSPACE = 0 Then
                                                                LASTSPACE = WorksheetFunction.Find("þ", WorksheetFunction.Substitute(Left(CommentArray(CommentPart), G), " ", "þ", (Len(Left(CommentArray(CommentPart), G)) - Len(WorksheetFunction.Substitute(Left(CommentArray(CommentPart), G), " ", "")))))
                                                                ActiveCell.AddComment Left(CommentArray(CommentPart), LASTSPACE)
                                                            Else
                                                                If LASTSPACE2 = 0 Then
                                                                   LASTSPACE = WorksheetFunction.Find("þ", WorksheetFunction.Substitute(Left(CommentArray(CommentPart), G), " ", "þ", (Len(Left(CommentArray(CommentPart), G)) - Len(WorksheetFunction.Substitute(Left(CommentArray(CommentPart), G), " ", "")))))
                                                                   ActiveCell.Comment.Text Text:=ActiveCell.Comment.Text & vbNewLine & Left(CommentArray(CommentPart), LASTSPACE)
                                                                Else
                                                                   If Len(Mid(CommentArray(CommentPart), LASTSPACE2)) < G Then
                                                                       LASTSPACE = Len(Mid(CommentArray(CommentPart), LASTSPACE2))
                                                                       ActiveCell.Comment.Text Text:=ActiveCell.Comment.Text & vbNewLine & Mid(CommentArray(CommentPart), LASTSPACE2 - 1, LASTSPACE)
                                                                   Else
                                                                       LASTSPACE = WorksheetFunction.Find("þ", WorksheetFunction.Substitute(Mid(CommentArray(CommentPart), LASTSPACE2, G), " ", "þ", (Len(Mid(CommentArray(CommentPart), LASTSPACE2, G)) - Len(WorksheetFunction.Substitute(Mid(CommentArray(CommentPart), LASTSPACE2, G), " ", "")))))
                                                                       ActiveCell.Comment.Text Text:=ActiveCell.Comment.Text & vbNewLine & Mid(CommentArray(CommentPart), LASTSPACE2 - 1, LASTSPACE)
                                                                   End If
                                                                End If
                                                            End If
                                                            LASTSPACE2 = LASTSPACE + LASTSPACE2 + 1
                                                        Loop
                                                    Else
                                                        If CommentPart = 0 And LASTSPACE2 = 0 And LASTSPACE = 0 Then
                                                          ActiveCell.AddComment CommentArray(CommentPart)
                                                        Else
                                                          ActiveCell.Comment.Text Text:=ActiveCell.Comment.Text & vbNewLine & CommentArray(CommentPart)
                                                        End If
                                                    End If
                
                                            Next CommentPart
                                            ActiveCell.Comment.Shape.TextFrame.AutoSize = True
                
                                        End If
                

                请随时感谢我。对我来说就像一个魅力,自动调整大小功能也有效!

                【讨论】:

                • 这如何回答这个问题?
                【解决方案13】:



                试试这个功能,双舍入就OK了

                '---------------Start -------------
                Function Round_Up(ByVal d As Double) As Integer
                    Dim result As Integer
                    result = Math.Round(d)
                    If result >= d Then
                        Round_Up = result
                    Else
                        Round_Up = result + 1
                    End If
                End Function
                '-----------------End----------------
                

                【讨论】:

                  【解决方案14】:

                  VBA 使用bankers rounding 来尝试补偿总是向上或向下舍入 0.5 的偏差;你可以改为;

                  WorksheetFunction.Round(cells(1,1).value * cells(1,2).value, 2)
                  

                  【讨论】:

                  • 如果我想在 RoundUp 之后选择这个值怎么办? @Alex K
                  【解决方案15】:

                  试试 RoundUp 函数:

                  Dim i As Double
                  
                  i = Application.WorksheetFunction.RoundUp(Cells(1, 1).Value * Cells(1, 2).Value, 2)
                  

                  【讨论】:

                  • -1,OP 要求一个向下舍入值
                  猜你喜欢
                  • 2016-11-24
                  • 1970-01-01
                  • 2023-01-12
                  • 1970-01-01
                  • 2022-11-21
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-11-05
                  相关资源
                  最近更新 更多