Visit my Youtube Channel
Create a Randomized Dataset [Excel VBA]
Note: This webpage is designed to accompany the Youtube video posted above. The video offers detailed explanation on all topics; while this webpage will serve as a repository for the code presented in the video.
Macro file can be downloaded from Github here.
In this project, we are going to look at how to create a rich dataset at the push of a button using the Random function in VBA.
While the use-case of this project might be rather specific, there are a lot of creative data manipulation tricks showcased here, that might be worth your while.
We will be mainly, using dictionary, custom function, Chr function and the Random function.
Premise
We want to create a dataset of 5000 open or unpaid invoices from the past 2 years. There are some rules that we want to follow. But, for the most part, we are going to use the Random function in some form to help generate each field.
The Random Function
As per the Microsoft docs’ page, The Rnd function returns a value less than 1 but greater than or equal to zero.
More accurately though, we usually get a decimal number between 0 and 1. And occasionally, we will get 0.
Code to use the vanilla Rnd function.
Sub checkRandomFunction()
Debug.Print Rnd()
End Sub
We can use this to generate valid random numbers. But, for a more realistic scenario, lets bound this number within certain limits. Let’s restrict the lower bound to 10000 and upper bound to 19999. The formula to do this is:
Int(LowerBound + Rnd * (UpperBound – LowerBound + 1))
Lets, replace the Lower Bound with 10000 and the Upper Bound with 19999
Sub checkRandomFunction()
Debug.Print Int(10000 + Rnd * (19999 - 10000 + 1))
End Sub
Awesome. We are actually, going to use this exact code, when we generate our invoice numbers.
Let’s now, generate random Upper Case alphabets that we will use in our alpha numeric strings.
For this, we need the (character) Chr Function. This function returns a character associated with a certain code. For the full list of codes, lets go to the Microsoft docs page.
Uppercase alphabets start from code 65 through to 90.
So, our lower bound will be 65 and upper bound will be 90.
Let’s feed this into our function.
Sub checkRandomFunction()
Debug.Print Chr(Int(65 + Rnd * (90 - 65 + 1)))
End Sub
Works well. And that’s all the basics that we need to know.
Below is the full code for the module presented in the above Youtube video.
Main Code
Sub GenerateRandomData()
wsUpInv.Range("A2:I" & wsUpInv.Rows.Count).Clear
wsUpInv.Columns("A").NumberFormat = "dd-mm-yyyy"
wsUpInv.Columns("B:F").NumberFormat = "General"
wsUpInv.Columns("G").NumberFormat = "@"
wsUpInv.Columns("H:I").NumberFormat = "General"
Dim RandomNumber As Long, RandomValue As String
Dim initialDate As Date
initialDate = DateAdd("d", -730, Date)
Dim dicInvCRM As Object
Set dicInvCRM = CreateObject("Scripting.Dictionary")
Dim uniqueCRM As Boolean
Dim lrow As Long
lrow = wsRndList.Cells(wsRndList.Cells.Rows.Count, 1).End(xlUp).Row
Dim arrStore() As Variant
arrStore = wsRndList.Range("A2:A" & lrow).Value
Dim dicInvERP As Object
Set dicInvERP = CreateObject("Scripting.Dictionary")
Dim UniqueERP As Boolean
Dim arrSource() As Variant
lrow = wsRndList.Cells(wsRndList.Cells.Rows.Count, 2).End(xlUp).Row
arrSource = wsRndList.Range("B2:B" & lrow).Value
Dim arrCRMRef() As Variant
lrow = wsRndList.Cells(wsRndList.Cells.Rows.Count, 3).End(xlUp).Row
arrCRMRef = wsRndList.Range("C2:C" & lrow).Value
Dim i As Long
For i = 2 To 5001
' Col1 = Date
wsUpInv.Range("A" & i).Value = DateAdd("d", GetRandomNumber(0, 730), initialDate)
' Col2 = CRM Invoice Number
Do Until uniqueCRM = True
RandomNumber = GetRandomNumber(10000, 19999)
If Not dicInvCRM.exists(RandomNumber) Then
dicInvCRM.Add RandomNumber, 0
wsUpInv.Range("B" & i).Value = RandomNumber
uniqueCRM = True
End If
Loop
uniqueCRM = False
' Col3 = Store Name
RandomNumber = GetRandomNumber(LBound(arrStore), UBound(arrStore))
wsUpInv.Range("C" & i).Value = arrStore(RandomNumber, 1)
' Col4 =Customer Code
' CX-00001234
wsUpInv.Range("D" & i).Value = "CX-0000" & GetRandomNumber(1000, 9999)
' Col5 =Invoice Amount
wsUpInv.Range("E" & i).Value = GetRandomNumber(5000, 20000)
' Col6 = Open Amount
wsUpInv.Range("F" & i).Value = GetRandomNumber(1, wsUpInv.Range("E" & i).Value)
' Col7 =ERP Invoice Number
Do Until UniqueERP = True
RandomValue = CreateAlphaNumericString(8)
If Not dicInvERP.exists(RandomValue) Then
dicInvERP.Add RandomValue, 0
wsUpInv.Range("G" & i).Value = RandomValue
UniqueERP = True
End If
Loop
UniqueERP = False
' Col 8 = Source
RandomNumber = GetRandomNumber(LBound(arrSource), UBound(arrSource))
wsUpInv.Range("H" & i).Value = arrSource(RandomNumber, 1)
' Col 9 = CRM Reference Code
RandomNumber = GetRandomNumber(LBound(arrCRMRef), UBound(arrCRMRef))
wsUpInv.Range("I" & i).Value = arrCRMRef(RandomNumber, 1)
Next i
wsUpInv.Columns("A:I").AutoFit
End Sub
Supporting Functions
Below are the two supporting functions that are referenced by the above code.
Random Number Generator
Function GetRandomNumber(fLowerBound As Long, fUpperBound As Long)
GetRandomNumber = Int(fLowerBound + Rnd * (fUpperBound - fLowerBound + 1))
End Function
Create a Alpha Numeric String
Function CreateAlphaNumericString(stringLen As Long)
Dim i As Long
Dim alphaOrNumeric As Long, singleString As String, fullString As String
For i = 1 To stringLen
alphaOrNumeric = GetRandomNumber(1, 2)
Select Case alphaOrNumeric
Case 1
'generates 1-digit string from 0-9
singleString = CStr(GetRandomNumber(0, 9))
Case 2
'generates A-Z
singleString = Chr(GetRandomNumber(65, 90))
End Select
fullString = fullString & singleString
Next i
CreateAlphaNumericString = fullString
End Function