Reputation: 765
I'm trying to calculate how many layers a commodity will be stacked in. I have a variable quantity (iQty
), a given width for the loadbed (dRTW
), a width per unit for the commodity (dWidth
) and a quantity per layer (iLayerQty
).
The quantity per layer is calculated as iLayerQty = Int(dRTW/dWidth)
Now I need to divide the total quantity by the quantity per layer and round up. In an Excel formula it would be easy, but I'm trying to avoid WorksheetFunction calls to minimise A1/R1C1 confusion. At the moment I'm approximating it with this:
(Number of layers) = ((Int(iQty / iLayerQty) + 1)
And that works fine most of the time - except when the numbers give an integer (a cargo width of 0.5 m, for instance, fitting onto a 2.5 m rolltrailer). In those instances, of course, adding the one ruins the result.
Is there any handy way of tweaking that formula to get a better upward rounding?
Upvotes: 10
Views: 37921
Reputation: 1
This is my Ceiling in VBA:
Function Ceiling(ByVal Number As Double, ByVal Significance As Double) As Double
Dim intVal As Long
Dim delta As Double
Dim RoundValue As Double
Dim PreReturn As Double
If Significance = 0 Then
RoundValue = 1
Else
RoundValue = 1 / Significance
End If
Number = Number * RoundValue
intVal = CLng(Number)
delta = intVal - Number
If delta < 0 Then
PreReturn = intVal + 1
Else
PreReturn = intVal
End If
Ceiling = PreReturn / RoundValue
End Function
Upvotes: 0
Reputation: 1
These are the functions I put together for this purpose.
Function RoundUp(ByVal value As Double) as Integer
Dim intVal As Integer
Dim delta As Double
intVal = CInt(value)
delta = intVal - value
If delta < 0 Then
RoundUp = intVal + 1
Else
RoundUp = intVal
End If
End Function
Function RoundDown(ByVal value As Double) as Integer
Dim intVal As Integer
Dim delta As Double
intVal = CInt(value)
delta = intVal - value
If delta <= 0 Then
RoundDown = intVal
ElseIf delta > 0 Then
RoundDown = intVal - 1
End If
End Function
Upvotes: 0
Reputation: 2695
I use -int(-x)
to get the ceiling.
?-int(-1.1) ' get ceil(1.1)
2
?-int(1.1) ' get ceil(-1.1)
-1
?-int(-5) ' get ceil(5)
5
Upvotes: 12
Reputation:
If using a WorksheetFunction object to access a ROUNDUP or CEILING function is off the table then the same can be accomplished with some maths.
Number of layers = Int(iQty / iLayerQty) - CBool(Int(iQty / iLayerQty) <> Round(iQty / iLayerQty, 14))
A VBA True is the equivalent of (-1) when used mathematically. The VBA Round is there to avoid 15 digit floating point errors.
Upvotes: 7
Reputation: 5921
I don't see any reason to avoid WorksheetFunction
; I don't see any confusion here.
Number_of_layers = WorksheetFunction.RoundUp(iQty / iLayerQty, 0)
You could also roll your own function:
Function RoundUp(ByVal Value As Double)
If Int(Value) = Value Then
RoundUp = Value
Else
RoundUp = Int(Value) + 1
End If
End Function
Call it like this:
Number_of_layers = RoundUp(iQty / iLayerQty)
Upvotes: 20