Competition random draw format

Sly_1980

New Member
Joined
Mar 10, 2011
Messages
4
Hi all

I do not know if this is possible, I've seen some similar solutions to what I require but not exactly what I need. What I would like is this:
*competition random player draw for starting positions
*the drawn names should not be repeated
*the name, once drawn, should appear on the starting grid in the position in which it was drawn
Here are the unknowns:
*player names
*total number of players (as this is a competion where people enter as they wish)
Is there any way of drawing up the document and then just filling in the player names and total number of starting players once it becomes known? If this is possible, can the starting grid automatically adjust to the total number of players inputted?

Regards,

Sly
 

Excel Facts

Why are there 1,048,576 rows in Excel?
The Excel team increased the size of the grid in 2007. There are 2^20 rows and 2^14 columns for a total of 17 billion cells.
Assuming the names are in column A starting from A2 and that column B is empty, the following code will allocate grid positions randomly:-
Code:
Option Explicit
 
Sub JiggleNames()
 
  Dim ws As Worksheet
  Dim iRow As Long
 
  Set ws = ThisWorkbook.Sheets("Sheet1")
  iRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
 
  Application.ScreenUpdating = False

  ws.Range("B2") = "=RAND()"
  ws.Range("B2").AutoFill Destination:=Range("B2:B" & CStr(iRow))
  With ws.Sort
    .SortFields.Clear
    .SortFields.Add Key:=Range("B2:B" & CStr(iRow)), SortOn:=xlSortOnValues, _
                    Order:=xlAscending, DataOption:=xlSortNormal
    .SetRange Range("A2:B" & CStr(iRow))
    .Header = xlNo
    .MatchCase = False
    .Orientation = xlTopToBottom
    .SortMethod = xlPinYin
    .Apply
  End With
 
  Do Until iRow = 1
    ws.Cells(iRow, 2) = iRow - 1
    iRow = iRow - 1
  Loop
  ws.Cells(iRow, 2) = "Grid Position"
 
  Application.ScreenUpdating = True
 
End Sub
Is that what you mean?
 
Last edited:
Upvote 0
Hi Ruddles

I should have explained more. Basically, I want input the names as the people enter, once the time has passed for the entries, I will now have a list of names which could be say, 20 long. I now want to be able to press a button and it will randomly draw a name, as the names are drawn, it will place these in the order they were drawn, e.g, Jon Smith may be drawn first, he would then go into position 1, the cell that his name appears in should be auto formatted to have a border. Jane Smith may be drawn next, she would fall into position 2. Here comes the hard part, all players names are drawn and put into position, with the correct cell formatting, is it possible to get excel to auto-format the rest of the cells for the format of the competition? For example, the winner between player 1 & 2 should play the winner between player 3 & 4, of course the system does not have any way of knowing who wins each match but what I'm asking is that once all the names are in place, the rest of the adjacent cells format until the final match so that names of winners may be manually entered until the final. I would also like auto text to appear above each round to have text such as 'best of 3' or 'best of 4' for each successive round.

Hope you can help

Regards,

Sly
 
Upvote 0
Okay, I'm following you know: you want a chart like a knock-out competition so if there are 9-16 names there are four rounds, 17-32 names there are five rounds, 33-64 names, six rounds, etc, and each pair of names leads to a box double the size that you copy the winner's name to - yes?

Try this code. You have to start with a worksheet with just the names in column A from A2 downwards. A1 can say "Competitor's name" or somesuch but the rest of the sheet should be empty with no boxes or merged cells in it (although the macro does try to cope with those).

Start with just a few names to test the code and make sure it works, especially around the 'break points' where one competitor more or less changes the number of rounds.

Code:
[FONT=Courier New][SIZE=1]Option Explicit[/SIZE][/FONT]
[FONT=Courier New][SIZE=1][/SIZE][/FONT] 
[FONT=Courier New][SIZE=1]Sub MakeGrid()[/SIZE][/FONT]
[FONT=Courier New][SIZE=1][/SIZE][/FONT] 
[FONT=Courier New][SIZE=1]  Dim ws As Worksheet
  Dim iLastRow As Long
  Dim iRow As Long
  Dim iCol As Long
  Dim iRound As Integer
  Dim iStep As Integer
  
  Set ws = ThisWorkbook.Sheets("Sheet1")
  iLastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
  
  Application.ScreenUpdating = False
     
  ws.Cells.MergeCells = False
  
  ws.Range("B2") = "=RAND()"
  ws.Range("B2").AutoFill Destination:=Range("B2:B" & CStr(iLastRow))
  With ws.Sort
    .SortFields.Clear
    .SortFields.Add Key:=Range("B2:B" & CStr(iLastRow)), SortOn:=xlSortOnValues, _
                    Order:=xlAscending, DataOption:=xlSortNormal
    .SetRange Range("A2:B" & CStr(iLastRow))
    .Header = xlNo
    .MatchCase = False
    .Orientation = xlTopToBottom
    .SortMethod = xlPinYin
    .Apply
  End With
  ws.Range("B2:B" & CStr(iLastRow)).ClearContents
  
  iCol = Int(WorksheetFunction.Log(iLastRow - 2, 2) + 1)
  iRow = 2 ^ iCol
  
  ws.Range("A1").Copy
  ws.Cells(1, 2).Resize(1, iCol).PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False[/SIZE][/FONT]
[FONT=Courier New][SIZE=1]  With ws.Cells(1, 2).Resize(1, iCol)
    .Borders(xlEdgeLeft).LineStyle = xlContinuous
    .Borders(xlEdgeTop).LineStyle = xlContinuous
    .Borders(xlEdgeBottom).LineStyle = xlContinuous
    .Borders(xlEdgeRight).LineStyle = xlContinuous
    .Borders(xlInsideVertical).LineStyle = xlContinuous
    .Borders(xlInsideHorizontal).LineStyle = xlContinuous
    .HorizontalAlignment = xlCenter
    .VerticalAlignment = xlCenter
  End With
  
  With ws.Range("A2:A" & CStr(iRow + 1))
    .Borders(xlEdgeLeft).LineStyle = xlContinuous
    .Borders(xlEdgeTop).LineStyle = xlContinuous
    .Borders(xlEdgeBottom).LineStyle = xlContinuous
    .Borders(xlEdgeRight).LineStyle = xlContinuous
    .Borders(xlInsideVertical).LineStyle = xlContinuous
    .Borders(xlInsideHorizontal).LineStyle = xlContinuous
    .HorizontalAlignment = xlCenter
    .VerticalAlignment = xlCenter
  End With
  
  For iRound = 1 To iCol
    ws.Cells(1, iRound + 1) = "Round " & CStr(iRound)
    For iStep = 2 To iRow Step (2 ^ iRound)
      With ws.Cells(iStep, iRound + 1).Resize(2 ^ iRound, 1)
        .Borders(xlEdgeLeft).LineStyle = xlContinuous
        .Borders(xlEdgeTop).LineStyle = xlContinuous
        .Borders(xlEdgeBottom).LineStyle = xlContinuous
        .Borders(xlEdgeRight).LineStyle = xlContinuous
        .Borders(xlInsideVertical).LineStyle = xlNone
        .Borders(xlInsideHorizontal).LineStyle = xlNone
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
        .MergeCells = False
        .Merge
      End With
    Next iStep
  Next iRound
  
  Application.ScreenUpdating = True
  
End Sub[/SIZE][/FONT]

Is that what you're trying to achieve?
 
Upvote 0
Hi Ruddles

Thanks for the reply, it works! However, one last question, instead of the list randomly generating at once, I'd like to enter the names (complete the list) and it should randomly draw the names one at a time from the completed list of names and enter it onto the starting grid (one name/press of the button). I am not sure if this is possible, I do not even know where to begin understanding this VB code.

Regards,

Sly
 
Upvote 0
Try this:-
Code:
[FONT=Courier New][SIZE=1]Option Explicit[/SIZE][/FONT]
[FONT=Courier New][SIZE=1][/SIZE][/FONT] 
[FONT=Courier New][SIZE=1]Sub MakeGrid()[/SIZE][/FONT]
[FONT=Courier New][SIZE=1][/SIZE][/FONT] 
[FONT=Courier New][SIZE=1]  Dim ws As Worksheet
  Dim iLastRow As Long
  Dim iRow As Long
  Dim iCol As Long
  Dim iRound As Integer
  Dim iStep As Integer
  
[COLOR=green]  ' set up a reference to the correct worksheet and count how many competitors
[/COLOR]  Set ws = ThisWorkbook.Sheets("Sheet1")
  iLastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
  
  Application.ScreenUpdating = False
     
[COLOR=green]  ' make sure there are no merged cells
[/COLOR]  ws.Columns("B").MergeCells = False
  
[COLOR=green]  ' fill column B with random numbers and hide all the competitors' names
[/COLOR]  ws.Range("B2") = "=RAND()"
  ws.Range("B2").AutoFill Destination:=Range("B2:B" & CStr(iLastRow))
  ws.Range("A2:A" & CStr(iLastRow)).Font.Color = vbWhite
[COLOR=green]  ' sort the competitors using the randomly-generated numbers as the sort key
[/COLOR]  With ws.Sort
    .SortFields.Clear
    .SortFields.Add Key:=Range("B2:B" & CStr(iLastRow)), SortOn:=xlSortOnValues, _
                    Order:=xlAscending, DataOption:=xlSortNormal
    .SetRange Range("A2:B" & CStr(iLastRow))
    .Header = xlNo
    .MatchCase = False
    .Orientation = xlTopToBottom
    .SortMethod = xlPinYin
    .Apply
  End With
[COLOR=green]  ' delete the random numbers as we don't need them any more
[/COLOR]  ws.Range("B2:B" & CStr(iLastRow)).ClearContents
  
[COLOR=green]  ' the LOG(2) function converts the number of competitors into the number of rounds
  ' required to complete a knock-out competition
[/COLOR]  iCol = WorksheetFunction.Log(iLastRow - 1, 2)
[COLOR=green]  ' the number of rounds to the power of 2 gives us the size of the grid
[/COLOR]  iRow = 2 ^ iCol
  
[COLOR=green]  ' whatever format the user has chosen for the column A heading, copy that to all of
  ' the columns we're using
[/COLOR]  ws.Range("A1").Copy
  ws.Cells(1, 2).Resize(1, iCol).PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
    SkipBlanks:=False, Transpose:=False[/SIZE][/FONT]
[FONT=Courier New][SIZE=1]  ' place borders around the column headers
  With ws.Cells(1, 2).Resize(1, iCol)
    .Borders(xlEdgeLeft).LineStyle = xlContinuous
    .Borders(xlEdgeTop).LineStyle = xlContinuous
    .Borders(xlEdgeBottom).LineStyle = xlContinuous
    .Borders(xlEdgeRight).LineStyle = xlContinuous
    .Borders(xlInsideVertical).LineStyle = xlContinuous
    .Borders(xlInsideHorizontal).LineStyle = xlContinuous
    .HorizontalAlignment = xlCenter
    .VerticalAlignment = xlCenter
  End With
  
[COLOR=green]  ' we use 2 to the power of the round number to decide how many cells are going to be[/COLOR][/SIZE][/FONT]
[FONT=Courier New][SIZE=1][COLOR=green]  ' merged to contain the name of the winner of the previous round, i.e. in round 2 the[/COLOR][/SIZE][/FONT]
[FONT=Courier New][SIZE=1][COLOR=green]  ' boxes are 2^1 = 2 cells, in round 3 the boxes are 2^2 = 4 cells, etc
[/COLOR]  For iRound = 0 To iCol
    ws.Cells(1, iRound + 1) = "Round " & CStr(iRound + 1)
    For iStep = 2 To iRow Step (2 ^ iRound)
      With ws.Cells(iStep, iRound + 1).Resize(2 ^ iRound, 1)
        .Borders(xlEdgeLeft).LineStyle = xlContinuous
        .Borders(xlEdgeTop).LineStyle = xlContinuous
        .Borders(xlEdgeBottom).LineStyle = xlContinuous
        .Borders(xlEdgeRight).LineStyle = xlContinuous
        .Borders(xlInsideVertical).LineStyle = xlNone
        .Borders(xlInsideHorizontal).LineStyle = xlNone
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
        .MergeCells = False
        .Merge
      End With
    Next iStep
  Next iRound
  ws.Cells(1, iCol) = "Semi-Final"
  ws.Cells(1, iCol + 1) = "Final"
  ws.Range("A1").Select
  
  Application.ScreenUpdating = True
  
  [COLOR=green]' ready to display the results of the draw
[/COLOR]  
  MsgBox "There are " & CStr(iLastRow - 1) & " competitors" & Space(10) & vbCrLf & vbCrLf _
       & "Click OK to start draw . . ." & Space(10), vbOKOnly + vbInformation
  
  For iStep = 2 To iLastRow
    [COLOR=green]' keep the current worksheet row visible on the screen
[/COLOR]    ActiveWindow.ScrollRow = IIf(iStep <= 20, 1, iStep - 20)
    ws.Cells(iStep, 1).Font.Color = vbBlack
    If iStep Mod 2 = 0 Then
     [COLOR=green] ' it's a 'home' competitor but the 'away' cells below it is empty, so it's a 'bye'
[/COLOR]      If IsEmpty(ws.Cells(iStep + 1, 1)) Then
        MsgBox ws.Cells(iStep, 1).Value & " gets a bye in the first round" & Space(10), _
               vbOKOnly + vbInformation
      Else
        [COLOR=green]' it's a 'home' competitor and the 'away' cells has a name in it
[/COLOR]        MsgBox ws.Cells(iStep, 1).Value & " will be playing . . ." & Space(10), _
               vbOKOnly + vbInformation
      End If
    Else
     [COLOR=green] ' it's an 'away' competitor
[/COLOR]      MsgBox ". . . " & ws.Cells(iStep, 1).Value & Space(10), _
             vbOKOnly + vbInformation
    End If
  Next iStep
  
  ActiveWindow.ScrollRow = 1
  MsgBox "All competitors allocated" & Space(10), vbOKOnly + vbInformation
  
End Sub[/SIZE][/FONT]
 
Upvote 0
Ruddles

Brilliant! Thank you!

You are a true master. I wish I could use VB the way you can but nevertheless, thank you again....

Best regards,

Sly
 
Upvote 0
Try this:-
Code:
[FONT=Courier New][SIZE=1]Option Explicit[/SIZE][/FONT]
 
[FONT=Courier New][SIZE=1]Sub MakeGrid()[/SIZE][/FONT]
 
[FONT=Courier New][SIZE=1]  Dim ws As Worksheet
  Dim iLastRow As Long
  Dim iRow As Long
  Dim iCol As Long
  Dim iRound As Integer
  Dim iStep As Integer
  
[COLOR=green]  ' set up a reference to the correct worksheet and count how many competitors
[/COLOR]  Set ws = ThisWorkbook.Sheets("Sheet1")
  iLastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
  
  Application.ScreenUpdating = False
     
[COLOR=green]  ' make sure there are no merged cells
[/COLOR]  ws.Columns("B").MergeCells = False
  
[COLOR=green]  ' fill column B with random numbers and hide all the competitors' names
[/COLOR]  ws.Range("B2") = "=RAND()"
  ws.Range("B2").AutoFill Destination:=Range("B2:B" & CStr(iLastRow))
  ws.Range("A2:A" & CStr(iLastRow)).Font.Color = vbWhite
[COLOR=green]  ' sort the competitors using the randomly-generated numbers as the sort key
[/COLOR]  With ws.Sort
    .SortFields.Clear
    .SortFields.Add Key:=Range("B2:B" & CStr(iLastRow)), SortOn:=xlSortOnValues, _
                    Order:=xlAscending, DataOption:=xlSortNormal
    .SetRange Range("A2:B" & CStr(iLastRow))
    .Header = xlNo
    .MatchCase = False
    .Orientation = xlTopToBottom
    .SortMethod = xlPinYin
    .Apply
  End With
[COLOR=green]  ' delete the random numbers as we don't need them any more
[/COLOR]  ws.Range("B2:B" & CStr(iLastRow)).ClearContents
  
[COLOR=green]  ' the LOG(2) function converts the number of competitors into the number of rounds
  ' required to complete a knock-out competition
[/COLOR]  iCol = WorksheetFunction.Log(iLastRow - 1, 2)
[COLOR=green]  ' the number of rounds to the power of 2 gives us the size of the grid
[/COLOR]  iRow = 2 ^ iCol
  
[COLOR=green]  ' whatever format the user has chosen for the column A heading, copy that to all of
  ' the columns we're using
[/COLOR]  ws.Range("A1").Copy
  ws.Cells(1, 2).Resize(1, iCol).PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
    SkipBlanks:=False, Transpose:=False[/SIZE][/FONT]
[FONT=Courier New][SIZE=1]  ' place borders around the column headers
  With ws.Cells(1, 2).Resize(1, iCol)
    .Borders(xlEdgeLeft).LineStyle = xlContinuous
    .Borders(xlEdgeTop).LineStyle = xlContinuous
    .Borders(xlEdgeBottom).LineStyle = xlContinuous
    .Borders(xlEdgeRight).LineStyle = xlContinuous
    .Borders(xlInsideVertical).LineStyle = xlContinuous
    .Borders(xlInsideHorizontal).LineStyle = xlContinuous
    .HorizontalAlignment = xlCenter
    .VerticalAlignment = xlCenter
  End With
  
[COLOR=green]  ' we use 2 to the power of the round number to decide how many cells are going to be[/COLOR][/SIZE][/FONT]
[FONT=Courier New][SIZE=1][COLOR=green]  ' merged to contain the name of the winner of the previous round, i.e. in round 2 the[/COLOR][/SIZE][/FONT]
[FONT=Courier New][SIZE=1][COLOR=green]  ' boxes are 2^1 = 2 cells, in round 3 the boxes are 2^2 = 4 cells, etc
[/COLOR]  For iRound = 0 To iCol
    ws.Cells(1, iRound + 1) = "Round " & CStr(iRound + 1)
    For iStep = 2 To iRow Step (2 ^ iRound)
      With ws.Cells(iStep, iRound + 1).Resize(2 ^ iRound, 1)
        .Borders(xlEdgeLeft).LineStyle = xlContinuous
        .Borders(xlEdgeTop).LineStyle = xlContinuous
        .Borders(xlEdgeBottom).LineStyle = xlContinuous
        .Borders(xlEdgeRight).LineStyle = xlContinuous
        .Borders(xlInsideVertical).LineStyle = xlNone
        .Borders(xlInsideHorizontal).LineStyle = xlNone
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
        .MergeCells = False
        .Merge
      End With
    Next iStep
  Next iRound
  ws.Cells(1, iCol) = "Semi-Final"
  ws.Cells(1, iCol + 1) = "Final"
  ws.Range("A1").Select
  
  Application.ScreenUpdating = True
  
  [COLOR=green]' ready to display the results of the draw
[/COLOR]  
  MsgBox "There are " & CStr(iLastRow - 1) & " competitors" & Space(10) & vbCrLf & vbCrLf _
       & "Click OK to start draw . . ." & Space(10), vbOKOnly + vbInformation
  
  For iStep = 2 To iLastRow
    [COLOR=green]' keep the current worksheet row visible on the screen
[/COLOR]    ActiveWindow.ScrollRow = IIf(iStep <= 20, 1, iStep - 20)
    ws.Cells(iStep, 1).Font.Color = vbBlack
    If iStep Mod 2 = 0 Then
     [COLOR=green] ' it's a 'home' competitor but the 'away' cells below it is empty, so it's a 'bye'
[/COLOR]      If IsEmpty(ws.Cells(iStep + 1, 1)) Then
        MsgBox ws.Cells(iStep, 1).Value & " gets a bye in the first round" & Space(10), _
               vbOKOnly + vbInformation
      Else
        [COLOR=green]' it's a 'home' competitor and the 'away' cells has a name in it
[/COLOR]        MsgBox ws.Cells(iStep, 1).Value & " will be playing . . ." & Space(10), _
               vbOKOnly + vbInformation
      End If
    Else
     [COLOR=green] ' it's an 'away' competitor
[/COLOR]      MsgBox ". . . " & ws.Cells(iStep, 1).Value & Space(10), _
             vbOKOnly + vbInformation
    End If
  Next iStep
  
  ActiveWindow.ScrollRow = 1
  MsgBox "All competitors allocated" & Space(10), vbOKOnly + vbInformation
  
End Sub[/SIZE][/FONT]

I've spent ages trying to do this and Googling for an example, Ruddles. Your final example almost hits the mark but I've run it with various numbers of 'competitors' and although it works out the correct grid it doesn't allocate byes in the right way. E.g. If 17 competitors roll up to play the grid will need to accommodate 32 in round 1 but only 2 competitors will play round 1 the other 15 will get a bye through to round 2.

I'm praying you're still involved with this list.

TIA

John
 
Upvote 0
This was a while ago and it's not fresh in my mind. I'll take a look at it later tonight, maybe tomorrow.
 
Upvote 0

Forum statistics

Threads
1,224,550
Messages
6,179,462
Members
452,915
Latest member
hannnahheileen

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top