excel - Generate Even Amount of Runs in Left and Right Lanes for Racers
问题描述
I'm working on a spreadsheet for a soap box derby type race that can automatically generate an even amount of runs in the left and right line per racer. It also will randomize who races against who. Currently, I have 6 heats and a button above each one. It pulls from a list of racers with a randomly generated number in the cell next to it using the method shown here: https://www.extendoffice.com/documents/excel/4591-excel-random-selection-no-duplicates.html
This is what the sheet looks like.
[![img][1]][1]
The 'DON'T TOUCH' column is then copied to another sheet and placed in each heat when a button is pressed above that heat. The heat sheet looks like this: ![img][2]
Each time a heat button is clicked, it will copy and paste from the "Randomizer" sheet and since the sheet refreshes each time, it will be randomized on each button click. The following macro runs when a heat button is clicked.
Sub btnHeat1_Click()
On Error Resume Next
Dim xRg As Range
Dim WS As Worksheet
Dim Shp As Shape
Set xRg = Application.Selection
Set WS = ActiveSheet
Set Shp = WS.Shapes("btnHeat1")
Worksheets("Randomizer").Range("E4:E62").Copy
Worksheets("The Race is On").Range("F4:F62").PasteSpecial xlPasteValues
xRg.Select
Shp.Visible = False
End Sub
I need to improve the randomizer so that each racer has an even amount of runs in the left and right lane (3 times each side). I'm not sure how to go about doing this and couldn't find any examples online of a similar situation (drag race heats, golf outings, etc). I thought of recording right and left lane each time a heat button is clicked, but not sure how to implement that into the existing randomizer. Or all the heats need to be generated at once and right and left lanes can represent a 0 and 1 in the randomizer equation.
Any suggestion on how to accomplish this? Thanks!
Edit: Removed images to protect names
解决方案
因此,以下代码应作为您要实现的目标的基础 - 请注意,这目前会在活动表中产生热度,参赛者以数字方式分配;需要进一步的工作以适应您的工作表
它创建了一个参赛者数组,然后依次“移动”数组中的元素一个计算量,以便在全部热量中,每个元素应该平等地出现在每个“热量”数组的前半部分和后半部分。然后将数组分成两半,每一半都是随机的。
因此,它应该生成一个随机配对,其中每个参赛者平等地在右侧或左侧车道,如问题所述......
Sub GenerateHeatData()
Dim Contestants As Long: Contestants = 16
Dim Heats As Long: Heats = 6
Dim CycleLength As Long: CycleLength = WorksheetFunction.Ceiling(Contestants / Heats, 1)
Dim i As Long, j As Long, Arr() As Variant, Left() As Variant, Right() As Variant
Dim BaseArray() As Variant
ReDim BaseArray(Contestants - 1)
For i = 0 To UBound(BaseArray)
BaseArray(i) = i + 1
Next i
Dim BaseHeatArray() As Variant
ReDim BaseHeatArray(Heats - 1)
For i = 0 To UBound(BaseHeatArray)
BaseHeatArray(i) = i + 1
Next i
Call RandomiseArray(BaseHeatArray)
For i = 0 To Heats - 1
Arr = RightShiftArray(BaseArray, CycleLength * CLng(BaseHeatArray(i)))
Left = ExtractArray(Arr, 0, WorksheetFunction.Ceiling(UBound(Arr) / 2, 1))
Right = ExtractArray(Arr, UBound(Left) + 1, UBound(Arr) - UBound(Left))
Call RandomiseArray(Left)
Call RandomiseArray(Right)
For j = 0 To UBound(Left)
ThisWorkbook.ActiveSheet.Cells(j + 1, 3 * i + 1) = CLng(Left(j))
Next j
For j = 0 To UBound(Right)
ThisWorkbook.ActiveSheet.Cells(j + 1, 3 * i + 2) = CLng(Right(j))
Next j
Next i
End Sub
Function RightShiftArray(InArray() As Variant, Shift As Long) As Variant()
Shift = Shift Mod (UBound(InArray) + 1)
If Shift < 1 Then Shift = Shift + UBound(InArray)
Dim TempArr() As Variant: ReDim TempArr(Shift - 1)
Dim i As Long, Arr() As Variant
ReDim Arr(LBound(InArray) To UBound(InArray))
For i = LBound(InArray) To UBound(InArray)
Arr(i) = InArray(i)
Next i
For i = 0 To UBound(TempArr)
TempArr(i) = Arr(UBound(Arr) - Shift + i + 1)
Next i
For i = 0 To UBound(Arr) - Shift
Arr(UBound(Arr) - i) = Arr(UBound(Arr) - i - Shift)
Next i
For i = 0 To UBound(TempArr)
Arr(i) = TempArr(i)
Next i
RightShiftArray = Arr
End Function
Function RandomiseArray(Arr() As Variant)
Dim i As Long, j As Long
Dim Temp As Variant
Randomize
For i = LBound(Arr) To UBound(Arr)
j = CLng(((UBound(Arr) - i) * Rnd) + i)
If i <> j Then
Temp = Arr(i)
Arr(i) = Arr(j)
Arr(j) = Temp
End If
Next i
End Function
Function ExtractArray(InArray() As Variant, First As Long, Length As Long) As Variant()
On Error Resume Next
Dim i As Long, Arr() As Variant
ReDim Arr(Length - 1)
For i = LBound(Arr) To UBound(Arr)
Arr(i) = InArray(First + i)
Next i
ExtractArray = Arr
End Function
* 编辑 - 添加镜像分配 *
Sub GenerateHeatData()
Dim i As Long, j As Long, Left() As Variant, Right() As Variant
Dim Contestants As Long: Contestants = 10
Dim Heats As Long: Heats = 6 ' Heats should be even
Dim BaseArray() As Variant: ReDim BaseArray(Contestants - 1)
For i = 0 To UBound(BaseArray)
BaseArray(i) = i + 1
Next i
For i = 0 To Heats / 2 - 1
Call RandomiseArray(BaseArray)
Left = ExtractArray(BaseArray, 0, WorksheetFunction.Ceiling(UBound(BaseArray) / 2, 1))
Right = ExtractArray(BaseArray, UBound(Left) + 1, UBound(BaseArray) - UBound(Left))
Call RandomiseArray(Left)
For j = 0 To UBound(Left)
ThisWorkbook.ActiveSheet.Cells(j + 1, 3 * i + 1) = CLng(Left(j))
Next j
Call RandomiseArray(Left)
For j = 0 To UBound(Left)
ThisWorkbook.ActiveSheet.Cells(j + 1, 3 * (i + Heats / 2) + 2) = CLng(Left(j))
Next j
Call RandomiseArray(Right)
For j = 0 To UBound(Right)
ThisWorkbook.ActiveSheet.Cells(j + 1, 3 * i + 2) = CLng(Right(j))
Next j
Call RandomiseArray(Right)
For j = 0 To UBound(Right)
ThisWorkbook.ActiveSheet.Cells(j + 1, 3 * (i + Heats / 2) + 1) = CLng(Right(j))
Next j
Next i
End Sub
Function RandomiseArray(Arr() As Variant)
Dim i As Long, j As Long
Dim Temp As Variant
Randomize
For i = LBound(Arr) To UBound(Arr)
j = CLng(((UBound(Arr) - i) * Rnd) + i)
If i <> j Then
Temp = Arr(i)
Arr(i) = Arr(j)
Arr(j) = Temp
End If
Next i
End Function
Function ExtractArray(InArray() As Variant, First As Long, Length As Long) As Variant()
On Error Resume Next
Dim i As Long, Arr() As Variant
ReDim Arr(Length - 1)
For i = LBound(Arr) To UBound(Arr)
Arr(i) = InArray(First + i)
Next i
ExtractArray = Arr
End Function
推荐阅读
- reporting-services - 此代码对字段中没有值的记录给出错误,但对在字段中具有值的记录给出良好的结果
- android - 谷歌对 IBM MobileFirst 应用中心的新限制
- python-3.x - 我怎么能关闭 tqdm_gui?
- java - 使用spring boot创建自定义附加程序以将日志消息输出到文本区域
- python - 需要帮助在国际象棋中移动棋子
- swift - 如何将 SwiftUI 视图设置为 CollectionView 的单元格
- excel - 使用小函数在 excel 2013 中返回两个重复值
- c++ - iOS const char* 到 std::string 并返回缺少第一个字符
- azure-devops - 没有代理注册或您无权查看代理
- html - Angular-Routing 在云中不起作用,但在 localhost