Random Numbers In Excel
This page describes how to work with random numbers in Excel and VBA.
Both Excel and VBA have limited support for random numbers. In Excel, you can use the
RAND worksheet
function to return a random number, D, where 0 <= D < 1. In the Analysis Tool Pack add-in, the is a function named
RANDBETWEEN that will return an random integer between two specified numbers.
VBA has its own random function,
Rnd, which returns a
random number, D, where 0 <= D < 1. Building upon the
RAND and
Rnd functions,
we can devise some useful formulas and functions.
The Excel worksheet function RAND returns a random value D where 0 <= D < 1.
To return a decimal number (including a fractional part after the decimal point) between to numbers, use the following
formula:
=RAND()*(High-Low)+Low
where Low is the smallest value in the desired range and High is
the largest value in the desired range. The formula will return a value between Low and High.
To return an integer (whole number with no fractional portion), use
=TRUNC(RAND()*(High-Low)+Low)
The RAND function is a supported array function so
RAND alone or either of the formulas above can be used in array formulas.
It should be noted that RAND is a volatile function, which means it will be recalculated any time
any calculation is made. This means that the value of the function will change with each calculation. If you want the random number to change
only under certain circumstances, you can use a formula with a circular reference to create a random number that is recalculated only under
certain circumstances.
=IF(ReCalc, RAND()*(High-Low)+Low,C3)
In this formula
C3 is the cell containing the formula, and
RecCalc is a value that
indicates whether to recalculate the random number.
ReCalc can be a function or a cell reference. In either
case, ReCalc should be
TRUE or a non-zero numeric value to cause the formula to be recalculated, or
FALSE or zero to prevent the formula from being recalculated. In order to allow circular references, go to the
Tools menu, choose
Options, then the
Calculation tab. There, check the
Iteration box and set
Maximum Iterations to 1. This formula will recalculate the random number result only when the value of
ReCalc is
TRUE.
VBA provides a function named Rnd that returns a value D where where 0 <= D < 1. To get a random
number (a real number with a decimal portion) within a specified range of values, use code like the following. Change the value of
Low and High to lower and upper limits of the range of allowable values.
Dim Low As Double
Dim High As Double
Low = 11
High = 20
R = (High - Low) * Rnd() + Low
The code above will put in the variable R an integer between 11 and 20. To get an integer (whole number)
between two numbers, use:
Dim Low As Double
Dim High As Double
Low = 11
High = 20
R = Int((High - Low + 1) * Rnd() + Low)
This will put in R a whole number between Low and
High.
The function described in this section,
RandomLongs, will return an array of random Long Integers.
The function has the following declaration.
Public Function RandomLongs(Minimum As Long, Maximum As Long, _
Number As Long, Optional ArrayBase As Long = 1, _
Optional Dummy As Variant) As Variant
This function will return an array of random Long Integers
between the values of Minimum and Maximum. The Number parameter
indicates how many values to return. The ArrayBase parameter indicates the LBound of the resulting array. If
ArrayBase is 0, the function returns an array with bounds (0,Number - 1).
If ArrayBase is 1, the funcion returns an array with bounds (1, Number).
The Dummy parameter is used only when this funciton is called from a worksheet cell (discussed later). If the
function is called from within VBA, the Dummy parameter is ignored. If there is an error in parameter values,
such as Minimum > Maximum or Number less than 1, the function
will return Null. To test whether the result from the function is a valid array, use
the IsArrayAllocated function on the Is Array Allocated page.
It is possible that there will be duplicated values in the result array. If you need unique, non-duplicated values, use the
UniqueRandomLongs function described later on this page.
The code for RandomLongs is shown below:
Public Function RandomLongs(Minimum As Long, Maximum As Long, _
Number As Long, Optional ArrayBase As Long = 1, _
Optional Dummy As Variant) As Variant
Dim SourceArr() As Long
Dim ResultArr() As Long
Dim SourceNdx As Long
Dim ResultNdx As Long
If Minimum > Maximum Then
RandomLongs = Null
Exit Function
End If
If Number > (Maximum - Minimum + 1) Then
RandomLongs = Null
Exit Function
End If
If Number <= 0 Then
RandomLongs = Null
Exit Function
End If
ReDim SourceArr(Minimum To Maximum)
For SourceNdx = Minimum To Maximum
SourceArr(SourceNdx) = SourceNdx
Next SourceNdx
ReDim ResultArr(ArrayBase To (ArrayBase + Number - 1))
Randomize
For ResultNdx = LBound(ResultArr) To UBound(ResultArr)
SourceNdx = Int((Maximum - Minimum + 1) * Rnd + Minimum)
ResultArr(ResultNdx) = SourceArr(SourceNdx)
Next ResultNdx
RandomLongs = ResultArr
End Function
This section describes the UniqueRandomLongs function.
Public Function UniqueRandomLongs(Minimum As Long, Maximum As Long, _
Number As Long, Optional ArrayBase As Long = 1, _
Optional Dummy As Variant) As Variant
This function returns an array of unique, non-duplicated, Long Integers. The Minimum and
Maximum parameters indicate the lower and upper bounds of the values of the numbers. The numbers in the returned
array will always be between Minimum and Maximum (inclusive). The Number parameter
indicates the number of values to return. The ArrayBase parameter indicates the LBound of the result
array. ArrayBase should be either 0 or 1; the default is 1. If ArrayBase is 0, the
result array has bounds of (0, Number -1). If ArrayBase is 1, the result array
has bounds of (1, Number). The Dummy parameter is used only when this function
is called from a worksheet cell (discussed later). If the function is called from within VBA, the Dummy parameter
is ignored. If there is an error in the parameters, such as Minimum > Maximum or
Number less than 1, the function returns Null. To test whether the result from
the function is a valid array, use the IsArrayAllocated function on the Is Array Allocated page.
The code for UniqueRandomLongs is shown below.
Public Function UniqueRandomLongs(Minimum As Long, Maximum As Long, _
Number As Long, Optional ArrayBase As Long = 1, _
Optional Dummy As Variant) As Variant
Dim SourceArr() As Long
Dim ResultArr() As Long
Dim SourceNdx As Long
Dim ResultNdx As Long
Dim TopNdx As Long
Dim Temp As Long
If Minimum > Maximum Then
UniqueRandomLongs = Null
Exit Function
End If
If Number > (Maximum - Minimum + 1) Then
UniqueRandomLongs = Null
Exit Function
End If
If Number <= 0 Then
UniqueRandomLongs = Null
Exit Function
End If
Randomize
ReDim SourceArr(Minimum To Maximum)
ReDim ResultArr(ArrayBase To (ArrayBase + Number - 1))
For SourceNdx = Minimum To Maximum
SourceArr(SourceNdx) = SourceNdx
Next SourceNdx
TopNdx = UBound(SourceArr)
For ResultNdx = LBound(ResultArr) To UBound(ResultArr)
SourceNdx = Int((TopNdx - Minimum + 1) * Rnd + Minimum)
ResultArr(ResultNdx) = SourceArr(SourceNdx)
Temp = SourceArr(SourceNdx)
SourceArr(SourceNdx) = SourceArr(TopNdx)
SourceArr(TopNdx) = Temp
TopNdx = TopNdx - 1
Next ResultNdx
UniqueRandomLongs = ResultArr
End Function
The following code demonstrates using the UniqueRandomLongs function in VBA.
Sub DemoUniqueRandomLongs()
Dim Res As Variant
Dim Min As Long
Dim Max As Long
Dim N As Long
Min = 101
Max = 200
N = 20
Res = UniqueRandomLongs(Minimum:=Min, Maximum:=Max, Number:=N)
If IsArrayAllocated(Res) = False Then
Debug.Print "Error from UniqueRandomLongs."
Else
For N = LBound(Res) To UBound(Res)
Debug.Print Res(N)
Next N
End If
End Sub
Function IsArrayAllocated(V As Variant) As Boolean
On Error Resume Next
IsArrayAllocated = Not (IsError(LBound(V)) And _
IsArray(V)) And (LBound(V) <= UBound(V))
End Function
Both the RandomLongs and the UniqueRandomLongs functions may be used as
Array Formulas on a worksheet. Since these functions return arrays of values, you must array-enter
the functions into a range of cells. The size of this range must be the same as the value of the Number parameter.
For example, select range A1:K10 and type the formula
=UniqueRandomLongs(100,199,10)
and then press CTRL SHIFT ENTER rather than just ENTER.
This will return an array of 10 numbers between 100 and 199 into the range A1:K10. By default, the functions return a horizontal array; that is,
an array that is in one row spanning several columns. If you want the result in a vertical range, a single column spanning several rows, you
must transpose the result array:
=TRANSPOSE(UniqueRandomLongs(100,199,10))
Since these are array formulas, you must select the result range, type the formula, and then press
CTRL SHIFT ENTER rather than just ENTER. If you do this properly, Excel
will display the formula enclosed in curly braces { }.
If you enter the functions as show above, Excel will not recalculate and update the functions and their return values when it does a calculation.
You have two options to control when Excel will recalculate the functions. The first method, which will cause the functions to recalculate
when any calculation is made, is to include NOW() as the final argument to the function. This is the
Dummy parameter described in the VBA section of this page.
=UniqueRandomLongs(100,199,10,NOW())
Because NOW() is a volatile function, it will cause a recalculation of the formula whenever
Excel makes any calculation. The actual value of the NOW() is not used. The sole purpose of
NOW() is to force a calculation.
You can also use the last parameter, the Dummy parameter, to specify a cell that controls
calculation. For example:
=UniqueRandomLongs(100,199,10,C1)
The reference to cell C1 will cause the formula to be updated whenver the value of cell
C1 is changed.
You can also create a function that returns a number of elements in random order and without duplicates from a range of worksheet
cells. The function below does just this. You can call as an array formula with a formula like
=RandsFromRange(A1:A10,5)
where A1:A10 is the list of elements from which to pull the values and 5 is
the number of values to return. Enter the formula in a range with as many cells as you specify to return, and press
CTRL SHIFT ENTER rather than just ENTER. The VBA code is shown below:
Function RandsFromRange(InputRange As Range, GetNum As Long) As Variant
Dim ResultArr() As Variant
Dim SourceArr() As Variant
Dim TopNdx As Long
Dim ResultNdx As Long
Dim SourceNdx As Long
Dim Temp As Variant
If InputRange.Columns.Count > 1 And InputRange.Rows.Count > 1 Then
RandsFromRange = CVErr(xlErrRef)
Exit Function
End If
If GetNum > InputRange.Cells.Count Then
RandsFromRange = CVErr(xlErrValue)
Exit Function
End If
ReDim ResultArr(1 To InputRange.Cells.Count)
SourceArr = InputRange.Value
Randomize
TopNdx = UBound(ResultArr)
For ResultNdx = LBound(ResultArr) To UBound(ResultArr)
SourceNdx = Int(TopNdx * Rnd + 1)
ResultArr(ResultNdx) = SourceArr(SourceNdx, 1)
Temp = SourceArr(SourceNdx, 1)
SourceArr(SourceNdx, 1) = SourceArr(TopNdx, 1)
SourceArr(TopNdx, 1) = Temp
TopNdx = TopNdx - 1
Next ResultNdx
If IsObject(Application.Caller) = True Then
If TypeOf Application.Caller Is Excel.Range Then
If Application.Caller.Columns.Count = 1 Then
RandsFromRange = Application.Transpose(ResultArr)
Else
RandsFromRange = ResultArr
End If
Else
End If
Else
RandsFromRange = ResultArr
End If
End Function
You can download
a bas code module here. You can also download a
complete workbook file with the code and examples.
This page last updated: 11-August-2007