A family of Microsoft spreadsheet software with tools for analyzing, charting, and communicating data.
a button in excel, to generate a new sheet that provides 5 random rows for work competed on any given day, (Users will enter date as confirmation of task completion in column 17 and then their name in column 18.)
I want to generate data based on name and date.
Up to this point I can follow you, but all the following is not comprehensible.
Copy the code below into a new regular module, you can run it from anywhere you like.
Run it a few times, have a look at the output. If you're not satisfied come back and tell me how the output should look like.
Andreas.
Option Explicit
Sub GenerateRandomSample()
Dim sDate As String, sName As String
Dim dDate As Date
Dim Data, Possible, This
Dim i As Long, j As Long
Dim Ws As Worksheet
'Get a valid user input
Do
sDate = InputBox("Enter date", "Generate Random Sample")
If sDate = "" Then Exit Sub
If Not IsDate(sDate) Then Beep
Loop Until IsDate(sDate)
dDate = sDate
sName = InputBox("Enter name", "Generate Random Sample")
If sName = "" Then Exit Sub
'Read in all data
Data = Sheets("Customer Accounts").Range("A1").CurrentRegion.Value
'Initialize
Possible = Array()
j = -1
'Collect all row numbers that are possible
For i = 2 To UBound(Data)
If (Data(i, 17) = dDate) And (Data(i, 18) = sName) Then
j = j + 1
ReDim Preserve Possible(0 To j)
Possible(j) = i
End If
Next
'Found any?
If j < 0 Then
MsgBox "No match found for " & dDate & " - " & sName, vbExclamation, "Generate Random Sample"
Exit Sub
End If
'More than 5?
If j > 4 Then
'Get 5 random rows of the possible rows
Randomize
ReDim This(0 To 4)
For i = 0 To 4
This(i) = Possible(RandomUnique(0, j, i = 0))
Next
Else
'Just this
This = Possible
End If
'Copy the rows to the top
For i = 0 To UBound(This)
For j = 1 To UBound(Data, 2)
Data(i + 2, j) = Data(This(i), j)
Next
Next
'Output
Set Ws = Worksheets.Add(After:=Sheets(Sheets.Count))
Ws.Range("A1").Resize(UBound(This) + 2, UBound(Data, 2)).Value = Data
End Sub
Private Function RandomUnique(ByVal Lo As Long, ByVal Hi As Long, _
Optional Reset As Boolean = False) As Long
Static Dict As Object 'Dictionary
'Init dictionary if necessary
If Dict Is Nothing Then Set Dict = CreateObject("Scripting.Dictionary")
'Remove all used numbers if forced from outside
If Reset Then Dict.RemoveAll
Do
'Get a random number
RandomUnique = Int((Hi - Lo + 1) * Rnd) + Lo
'Already used?
Loop Until Not Dict.Exists(RandomUnique)
'Remember it
Dict.Add RandomUnique, 0
'Automatic reset if all numbers used
If Dict.Count > Hi - Lo Then Dict.RemoveAll
End Function