在Excel VBA 2016中创建随机化非数值的模块

在Excel VBA 2016中创建随机化非数值的模块,vba,excel,excel-2016,Vba,Excel,Excel 2016,背景:我有一张表格,上面有员工ID行和轮班列(每天两列:上午和下午)。员工说明他们是否可以参加每班。然后,我运行一个模块,该模块生成可以参加每个轮班的所有ID的列表 问题:是否有一个模块可以为每个班次获取潜在与会者列表,并为每个上午班次生成四个随机ID,为每个下午班次生成三个随机ID PM班次不应具有与AM班次相同的ID 图1: 图2:这样就可以了-在可用员工数量上是灵活的(可以是10人,也可以是50人!),但它确实假设了3件事: 员工列表从第3行开始,列表中没有空格 周一至周五C列至L列 第一

背景:我有一张表格,上面有员工ID行和轮班列(每天两列:上午和下午)。员工说明他们是否可以参加每班。然后,我运行一个模块,该模块生成可以参加每个轮班的所有ID的列表

问题:是否有一个模块可以为每个班次获取潜在与会者列表,并为每个上午班次生成四个随机ID,为每个下午班次生成三个随机ID

PM班次不应具有与AM班次相同的ID

图1:


图2:

这样就可以了-在可用员工数量上是灵活的(可以是10人,也可以是50人!),但它确实假设了3件事:

  • 员工列表从第3行开始,列表中没有空格
  • 周一至周五C列至L列
  • 第一行将指示是上午还是下午班次
  • 选项显式

    Sub Work_timetables()
    
    Dim c As Integer, R As Long, iEmployees As Long, ID As String, iField As Integer, bAM As Boolean, lRandomNumber As Long, iNumbersNeeded As Integer, iPicked As Integer
    
    Application.ScreenUpdating = False
    
    c = 3
    R = 2
    iField = 1
    iEmployees = Range("B3:B" & Range("B3").End(xlDown).Row).Rows.Count
    
    Do Until c > 12
        Range("C2:L" & iEmployees + 2).AutoFilter Field:=iField, Criteria1:="Yes"
        Range("B3:B" & Range("B3").End(xlDown).Row).Copy
        Cells(iEmployees + 4, c).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
        Application.CutCopyMode = False
        Range("C2:L" & iEmployees).AutoFilter
        c = c + 1
        iField = iField + 1
    Loop
    
    c = 3
    Start:
    Do Until c > 12
        If c Mod 2 = 0 Then
            bAM = False
            iNumbersNeeded = 3
        End If
        If Not c Mod 2 = 0 Then
            bAM = True
            iNumbersNeeded = 4
        End If
        If (Cells(1048563, c).End(xlUp).Row - (iEmployees + 3)) < iNumbersNeeded Then
            MsgBox "There isn't enough emplooyees available for the " & Cells(2, c).Value & " (" & Cells(1, c).Value & ") shift" & vbNewLine & vbNewLine & "Moving to next shift", vbOKOnly, "Short staffed!"
            c = c + 1
            GoTo Start
        End If
        Do Until iPicked = iNumbersNeeded
    goLoop:
            lRandomNumber = WorksheetFunction.RandBetween(iEmployees + 4, Cells(iEmployees + 4, c).End(xlDown).Row)
            If Trim(Range("B" & lRandomNumber).Value) = "" Then
                Range("B" & lRandomNumber).Value = "Picked"
                Cells(Range("C" & iEmployees + 4).CurrentRegion.Rows.Count + iEmployees + 6 + iPicked, c).Value = Cells(lRandomNumber, c)
                iPicked = iPicked + 1
                Else
                    GoTo goLoop
            End If
        Loop
        Range("B" & iEmployees + 4 & ":B" & Range("C" & iEmployees + 4).CurrentRegion.Rows.Count + iEmployees + 4).ClearContents
        c = c + 1
        iPicked = 0
    Loop
    
    Application.ScreenUpdating = True
    
    End Sub
    
    Sub-Work\u时间表()
    Dim c为整数,R为长,I员工为长,ID为字符串,I字段为整数,bAM为布尔值,lRandomNumber为长,InumbersRequired为整数,I标记为整数
    Application.ScreenUpdating=False
    c=3
    R=2
    i字段=1
    IEEmployees=范围(“B3:B”和范围(“B3”).End(xlDown).Row.Count
    直到c>12
    范围(“C2:L”和“IEEmployees+2”)。自动筛选字段:=i字段,标准1:=是
    范围(“B3:B”和范围(“B3”)。结束(xlDown)。行)。复制
    单元格(IEEmployees+4,c).粘贴特殊粘贴:=xlPasteValues,操作:=xlNone,SkipBlanks:=False,转置:=False
    Application.CutCopyMode=False
    范围(“C2:L”和员工)。自动筛选
    c=c+1
    iField=iField+1
    环
    c=3
    开始:
    直到c>12
    如果c Mod 2=0,则
    bAM=错误
    InumbersRequired=3
    如果结束
    如果不是c Mod 2=0,则
    bAM=真
    InumbersRequired=4
    如果结束
    如果(单元格(1048563,c).End(xlUp).Row-(IEEmployees+3))

    我是VBA的完全初学者,上周听说了,从那时起我一直在看教程。我想把这当成我的工作。我的前任根据最初的表格来分配轮班,我认为这是一个更好的方法。在这最后一步,我已经达到了我的能力极限。我试着用一个“For each x in range”(“C26:C29”)。单元格可以:“然后从列表中随机排列,但我无法得到随机排列的坐标与列表对齐(所有这些都是10-1+1)。这有意义吗?阅读如何在VBA中生成随机数,以及如何使用数组(可以从工作表中的某个范围设置),然后将随机数用作所述数组中的索引,提示还包括检查所使用的随机数,并首先进行检查。但我不尝试生成随机数,我正在尝试对一个非数字数据点样本进行随机化实际上,我的点是,看看数组,你将使用该数字作为索引,即数组(1)=“移位1”、数组(2)=“Shitf2”或数组(1)=“你喜欢什么”数组(2)=“其他什么”,然后我想选择一个随机的,那么我需要什么呢?“然后我运行一个模块,生成可以参加每次轮班的所有ID的列表。”这是什么类型的列表,这将是您的数组。那么我可以问一个更具体的问题吗?我找到了这个模块,我想。有没有办法让它在我生成的ID列表而不是表本身上运行?子随机化器()用于范围内的每个x(“C16:C19”)。单元格随机化所选人员=整数((10-1+1)*Rnd+1)x。值=单元格(2+所选人员,2)。值下一个结束SubI获取错误A004。您介意在运行模块时截图显示表格的格式吗?错误出现在“范围”(“C2:L”和“IEEmployees”)行中。AutoFilter“您使用的是什么版本的excel?”?我的还好。。我已经把截图放在了我的原始答案上。不管怎样,用
    ActiveSheet.AutoFilterMode=False
    替换那一行就行了,谢谢!快速跟进问题:如果有三个ID可用,PM班次不会分配与AM班次相同的ID吗?不,它是根据谁说他们可用于PM班次随机分配的-您希望它为AM员工分配PM班次的优先级,然后分配任何“剩余”吗插槽?在给定的一天中,PM班次的员工不应与AM班次的员工相同。是否有可能将AM员工ID从当天下午轮班的考虑范围中删除?