【问题标题】:Select items from list从列表中选择项目
【发布时间】:2016-03-27 20:58:48
【问题描述】:

问题:

以下格式有 N 名足球运动员,表格将显示每 11 名球员的组合。

每个 11 人的阵容必须遵循以下限制。

它应该能够选择玩家作为“核心”,这意味着他们将出现在 100% 的输出阵容中。

输入:

  A               B       C        D                 E
Name          Position  Team     Salary     Core Player? 1="Yes",0="No"
Darron Gibson   M        EVE    6500000              0
Riyad Mahrez    M        LEI    11700000             0
Andrej Kramaric F        LEI    6900000              0
Sadio Mané      M        SOT    12600000             0
Victor Anichebe F        WBA    5300000              1
Serge Gnabry    M        WBA    6300000              0
Dimitri Payet   M        WHM    13500000             0
Juan Mata       M        MUN    10700000             0
  .
  .
  .so on there is list of players

每个团队的限制条件:

Maximum Salary  100000000   Allowed per team

'These are the maximum and minimum no. of players for a position per team   
Position    Min   Max   
  G          1    1
  D          3    4
  M          3    5
  F          1    3

'there can be maximum no. of four players from a single team
' e.g. MUN (manchester united)          
Maximum Number of Players from one team     4   
Total number of players     11            'Total no. of players per team

输出示例:

    Player 1    Player 2    Player 3    Player 4    Player 5    Player 6    Player 7    Player 8    Player 9    Player 10   Player 11
    Player 1    Player 2    Player 3    Player 4    Player 5    Player 6    Player 7    Player 8    Player 9    Player 10   Player 12
    Player 1    Player 2    Player 3    Player 4    Player 5    Player 6    Player 7    Player 8    Player 9    Player 10   Player 13
    Player 1    Player 2    Player 3    Player 4    Player 5    Player 6    Player 7    Player 8    Player 9    Player 10   Player 14
.
.
.
.

'Update: Players can be repeated in another teams but no match for full line up is allowed 

 Like this is not allowed

Player 1    Player 2    Player 3    Player 4    Player 5    Player 6    Player 7    Player 8    Player 9    Player 10   Player 11
Player 1    Player 3    Player 2    Player 5    Player 4    Player 6    Player 7    Player 8    Player 9    Player 10   Player 11

Attached File

我的想法是首先放置它们,然后检查约束,因为它们被选择的顺序并不重要,并在满足条件之前使它们正确,但这在每个阶段都会变得复杂。

我尝试过的(不完整):

Option Explicit
Sub Teams()
Dim wi, wo, wt, ws As Worksheet
Dim i, j, l, d, m, ct, c, a, b, r As Long
Dim TotalG, TotalD, TotalM, TotalF, TotalSal, Sal, SalLeft, MaxTeam As Long
Dim Team, Pos, Name As String
Dim FinalRowI, FinalRowO As Long
Dim Drng As Range
Dim Mrng As Range

Set wi = Sheet1
Set wo = Sheet2
Set wt = Sheet3
Set ws = Sheet4

FinalRowI = wi.Range("A900000").End(xlUp).Row

TotalG = 0
TotalD = 0
TotalM = 0
TotalF = 0
Sal = 0
SalLeft = 0
TotalSal = wi.Range("H14").Value

    For i = 2 To FinalRowI

        Name = Trim(wi.Range("A" & i).Text)
        Pos = Trim(wi.Range("B" & i).Text)
        Team = Trim(wi.Range("C" & i).Text)
        Sal = wi.Range("D" & i).Value

        Select Case Pos

        Case "G"
            TotalG = TotalG + 1

        Case "D"
            TotalD = TotalD + 1

        Case "M"
            TotalM = TotalM + 1

        Case "F"
            TotalF = TotalF + 1

        Case Else
        End Select
    Next i

    MaxTeam = (WorksheetFunction.Min(CInt(TotalD), CInt(TotalM))) / 3

    MaxTeam = (WorksheetFunction.Min(CInt(MaxTeam), CInt(TotalG), CInt(TotalF)))

    MsgBox "MaxTeam " & MaxTeam
    MsgBox "G " & TotalG
    MsgBox "D " & TotalD
    MsgBox "M " & TotalM
    MsgBox "F " & TotalF

        m = 0
        d = 0
        c = 1
        ct = 1
        a = 1
        r = 1

        l = 3
        b = 6

        'Place all the Min Goalkeepers,Forwards, Mid, Defenders
        For i = 2 To FinalRowI

            Name = Trim(wi.Range("A" & i).Text)
            Pos = Trim(wi.Range("B" & i).Text)
            Team = Trim(wi.Range("C" & i).Text)
            Sal = wi.Range("D" & i).Value

            Select Case Pos

            Case "G"

                If ct <= MaxTeam Then
                    wo.Range("A" & ct) = Name
                    wt.Range("A" & ct) = Team
                    ws.Range("A" & ct) = Sal
                    ct = ct + 1
                Else: End If

            Case "D"

                If d <= 3 * MaxTeam And r <= MaxTeam Then
                    wo.Cells(r, l) = Name
                    wt.Cells(r, l) = Team
                    ws.Cells(r, l) = Sal
                        d = d + 1
                        If d Mod 3 = 0 Then
                            r = r + 1
                            l = 3
                        Else
                            l = l + 1
                        End If
                Else: End If

            Case "M"

                If m <= 3 * MaxTeam And a <= MaxTeam Then
                    wo.Cells(a, b) = Name
                    wt.Cells(a, b) = Team
                    ws.Cells(a, b) = Sal
                    m = m + 1
                        If m Mod 3 = 0 Then
                            a = a + 1
                            b = 6
                        Else
                            b = b + 1
                        End If
                Else: End If

            Case "F"

                If c <= MaxTeam Then
                    wo.Range("B" & c) = Name
                    wt.Range("B" & c) = Team
                    ws.Range("B" & c) = Sal
                    c = c + 1
                Else: End If

            Case Else
            End Select
        Next i

     Set Drng = wo.Range(Cells(1, 3), Cells(MaxTeam, 5))
     Set Mrng = wo.Range(Cells(1, 6), Cells(MaxTeam, 8))

        m = 8
        d = 8
        c = 0
        ct = 0
        a = 1
        b = 1

        l = 3
        b = 6

'For Rest of three Places
    For i = 2 To FinalRow

        Name = Trim(wi.Range("A" & i).Text)
        Pos = Trim(wi.Range("B" & i).Text)
        Team = Trim(wi.Range("C" & i).Text)
        Sal = wi.Range("D" & i).Value

        Select Case Pos

        Case "G"

        Case "D"
            For Each c In Drng

            Next j

        Case "M"

        Case "F"

        Case Else
        End Select
    Next i

End Sub

【问题讨论】:

  • 您有几个编译错误需要修复。您的代码仅输出 8 列而不是 11 列(这是所有位置的最小值),因此您需要再添加 3 个玩家。您的示例下载文件没有标记为“核心”,但我不明白您上面的评论,即“核心”将出现在所有阵容中 - 这是否意味着每一行都会有一个或多个“核心”?
  • @WayneG.Dunn 谢谢,是的,它有错误,因为它尚未完成,因为在将最低要求的球员放入团队后,我很困惑如何继续。 Core 表示相对于非核心玩家,玩家在被选中的优先级最高,只能取 1 和 0 两个值,因此必须将所有核心玩家放在团队中
  • @WayneG.Dunn 你能帮我吗?或者至少指导我如何解决这个问题?
  • 我会看看你的代码,看看我是否能提供帮助。但首先,我想 100% 准确地理解你想要做什么。你说'...吐出每一个 11 人的球员组合',你知道那会是多少个组合吗?!?!试试这个网站,看看你是否真的是这个意思:stattrek.com/online-calculator/combinations-permutations.aspx
  • 感谢您查看它,因此根据限制,最大可能的团队只能是最少 =MIN(TotalGoalkeepers ,(Total Defenders/3),(TotalMidField PLayers/3),TotalForwards),因为这是组建团队的最低要求,还有其他限制,例如每个团队允许的总薪水以及从团队等中选出的最大数量的玩家。

标签: algorithm vba excel combinations


【解决方案1】:

考虑一个 SQL 解决方案,该解决方案运行 11 位玩家序列的随机迭代,并验证每次迭代是否满足所有要求的条件。 MS Access 与其 Office 兄弟 MS Excel 配合得很好,这可能是一个可行的解决方案。此外,任何 RDMS 都可以在存储过程中运行。以下是事件的顺序和所需的对象。这里是MS Access accdb app,没有任何可供您测试的选择。

表格

首先,创建一个决赛桌SoccerPicks 来容纳所有 11 个成员团队,这些团队将在应用程序的生命周期内增长。它用于下面的 VBA 模块调用的追加查询,每次循环迭代插入一个成功验证的团队记录。

交叉连接查询

其次,创建一个randomizedCross Join Query(返回选择集的所有可能组合),但每 11 个玩家表选择一名玩家并条件位置(G、D、M、F)计数。在FROM 子句中,前四个对应于四个核心球员,这些人将出现在每个团队中。复制他们的派生表以获取更多信息,或者在设置其他 7 个时删除并复制随机派生表。

SELECT Player1, Player2, Player3, Player4, Player5, Player6, 
       Player7, Player8, Player9, Player10, Player11, 

       (t1.Salary + t2.Salary + t3.Salary + t4.Salary + t5.Salary + t6.Salary +
        t7.Salary + t8.Salary + t9.Salary + t10.Salary + t11.Salary) AS TeamSalary, 
       IIF(t1.Position = 'G', 1, 0) + IIF(t2.Position = 'G', 1, 0) +
       IIF(t3.Position = 'G', 1, 0) + IIF(t4.Position = 'G', 1, 0) + 
       IIF(t5.Position = 'G', 1, 0) + IIF(t6.Position = 'G', 1, 0) + 
       IIF(t7.Position = 'G', 1, 0) + IIF(t8.Position = 'G', 1, 0) + 
       IIF(t9.Position = 'G', 1, 0) + IIF(t10.Position = 'G', 1, 0) +
       IIF(t11.Position = 'G', 1, 0) AS GPosition, 

       IIF(t1.Position = 'D', 1, 0) + IIF(t2.Position = 'D', 1, 0) +
       IIF(t3.Position = 'D', 1, 0) + IIF(t4.Position = 'D', 1, 0) + 
       IIF(t5.Position = 'D', 1, 0) + IIF(t6.Position = 'D', 1, 0) +
       IIF(t7.Position = 'D', 1, 0) + IIF(t8.Position = 'D', 1, 0) + 
       IIF(t9.Position = 'D', 1, 0) + IIF(t10.Position = 'D', 1, 0) + 
       IIF(t11.Position = 'D', 1, 0) AS DPosition, 

       IIF(t1.Position = 'M', 1, 0) + IIF(t2.Position = 'M', 1, 0) +
       IIF(t3.Position = 'M', 1, 0) + IIF(t4.Position = 'M', 1, 0) +
       IIF(t5.Position = 'M', 1, 0) + IIF(t6.Position = 'M', 1, 0) +
       IIF(t7.Position = 'M', 1, 0) + IIF(t8.Position = 'M', 1, 0) + 
       IIF(t9.Position = 'M', 1, 0) + IIF(t10.Position = 'M', 1, 0) +
       IIF(t11.Position = 'M', 1, 0) AS MPosition, 

       IIF(t1.Position = 'F', 1, 0) + IIF(t2.Position = 'F', 1, 0) +
       IIF(t3.Position = 'F', 1, 0) + IIF(t4.Position = 'F', 1, 0) +
       IIF(t5.Position = 'F', 1, 0) + IIF(t6.Position = 'F', 1, 0) +
       IIF(t7.Position = 'F', 1, 0) + IIF(t8.Position = 'F', 1, 0) + 
       IIF(t9.Position = 'F', 1, 0) + IIF(t10.Position = 'F', 1, 0) +
       IIF(t11.Position = 'F', 1, 0) AS FPosition

FROM 
    (SELECT PlayerName as Player1, Position, Team, Salary    
     FROM Soccer 
     WHERE [Core Player] = True AND
           (SELECT Count(*) FROM Soccer sub 
            WHERE sub.ID <= Soccer.ID  
            AND sub.[Core Player] = True 
            AND Soccer.[Core Player] = True) = 1)  AS t1, 

    (SELECT PlayerName as Player2, Position, Team, Salary
     FROM Soccer 
     WHERE [Core Player] = True AND
           (SELECT Count(*) FROM Soccer sub 
            WHERE sub.ID <= Soccer.ID  
            AND sub.[Core Player] = True 
            AND Soccer.[Core Player] = True) = 2)  AS t2, 

    (SELECT PlayerName as Player3, Position, Team, Salary    
     FROM Soccer  
     WHERE [Core Player] = True AND
           (SELECT Count(*) FROM Soccer sub 
            WHERE sub.ID <= Soccer.ID  
            AND sub.[Core Player] = True 
            AND Soccer.[Core Player] = True) = 3)  AS t3, 

    (SELECT PlayerName as Player4, Position, Team, Salary
     FROM Soccer 
     WHERE [Core Player] = True AND
           (SELECT Count(*) FROM Soccer sub 
            WHERE sub.ID <= Soccer.ID  
            AND sub.[Core Player] = True 
            AND Soccer.[Core Player] = True) = 4)  AS t4, 

    (SELECT TOP 1 PlayerName AS Player5, Position, Team, Salary 
     FROM Soccer ORDER BY Rnd(ID))  AS t5, 

    (SELECT TOP 1 PlayerName AS Player6, Position, Team, Salary 
     FROM Soccer ORDER BY Rnd(ID))  AS t6, 

    (SELECT TOP 1 PlayerName AS Player7, Position, Team, Salary 
     FROM Soccer ORDER BY Rnd(ID))  AS t7, 

    (SELECT TOP 1 PlayerName AS Player8, Position, Team, Salary 
     FROM Soccer ORDER BY Rnd(ID))  AS t8, 

    (SELECT TOP 1 PlayerName AS Player9, Position, Team, Salary 
     FROM Soccer ORDER BY Rnd(ID))  AS t9, 

    (SELECT TOP 1 PlayerName AS Player10, Position, Team, Salary
     FROM Soccer ORDER BY Rnd(ID))  AS t10,

    (SELECT TOP 1 PlayerName AS Player11, Position, Team, Salary 
     FROM Soccer ORDER BY Rnd(ID))  AS t11

WHERE 

   IIF(t1.Position = 'G', 1, 0) + IIF(t2.Position = 'G', 1, 0) +
   IIF(t3.Position = 'G', 1, 0) + IIF(t4.Position = 'G', 1, 0) + 
   IIF(t5.Position = 'G', 1, 0) + IIF(t6.Position = 'G', 1, 0) + 
   IIF(t7.Position = 'G', 1, 0) + IIF(t8.Position = 'G', 1, 0) + 
   IIF(t9.Position = 'G', 1, 0) + IIF(t10.Position = 'G', 1, 0) +
   IIF(t11.Position = 'G', 1, 0) = 1 

AND
   IIF(t1.Position = 'D', 1, 0) + IIF(t2.Position = 'D', 1, 0) +
   IIF(t3.Position = 'D', 1, 0) + IIF(t4.Position = 'D', 1, 0) + 
   IIF(t5.Position = 'D', 1, 0) + IIF(t6.Position = 'D', 1, 0) +
   IIF(t7.Position = 'D', 1, 0) + IIF(t8.Position = 'D', 1, 0) + 
   IIF(t9.Position = 'D', 1, 0) + IIF(t10.Position = 'D', 1, 0) + 
   IIF(t11.Position = 'D', 1, 0) BETWEEN 3 AND 4

AND 
   IIF(t1.Position = 'M', 1, 0) + IIF(t2.Position = 'M', 1, 0) +
   IIF(t3.Position = 'M', 1, 0) + IIF(t4.Position = 'M', 1, 0) +
   IIF(t5.Position = 'M', 1, 0) + IIF(t6.Position = 'M', 1, 0) +
   IIF(t7.Position = 'M', 1, 0) + IIF(t8.Position = 'M', 1, 0) + 
   IIF(t9.Position = 'M', 1, 0) + IIF(t10.Position = 'M', 1, 0) +
   IIF(t11.Position = 'M', 1, 0) BETWEEN 3 AND 5

AND
   IIF(t1.Position = 'F', 1, 0) + IIF(t2.Position = 'F', 1, 0) +
   IIF(t3.Position = 'F', 1, 0) + IIF(t4.Position = 'F', 1, 0) +
   IIF(t5.Position = 'F', 1, 0) + IIF(t6.Position = 'F', 1, 0) +
   IIF(t7.Position = 'F', 1, 0) + IIF(t8.Position = 'F', 1, 0) + 
   IIF(t9.Position = 'F', 1, 0) + IIF(t10.Position = 'F', 1, 0) +
   IIF(t11.Position = 'F', 1, 0) BETWEEN 1 AND 3

AND 
  (t1.Salary + t2.Salary + t3.Salary + t4.Salary + t5.Salary + t6.Salary + 
   t7.Salary + t8.Salary + t9.Salary + t10.Salary + t11.Salary) <= 100000000;

VBA 模块

接下来是运行追加和删除查询的 VBA 模块(以删除不符合其他约束的失败记录)。注意 for 循环 50 次迭代。根据需要增加,知道有 11 名玩家的选择集相当多。需要迭代,因为上述查询可能会根据随机抽取和WHERE 逻辑条件返回零。注意:前两个删除查询需要一个联合查询来堆叠上述第一个查询中的所有球员,以更好地汇总球队人数、球员人数和球队工资总和。请参阅附加的应用程序。

Public Function IteratePicks()
    Dim db As Database
    Dim i As Integer

    Set db = CurrentDb

    For i = 1 To 50
        db.Execute "INSERT INTO SoccerPicks SELECT * FROM SoccerTeamPicksQ", dbFailOnError

        ' DELETING TEAMS WITH DUPLICATE PLAYERS
        db.Execute "DELETE FROM SoccerPicks" _
                    & " WHERE SoccerPicks.ID IN" _
                    & " (SELECT ID" _
                    & "  FROM (SELECT SoccerPicksUnionQ.ID, SoccerPicksUnionQ.Player, Count(*) AS PlayerCount" _
                    & "       FROM SoccerPicksUnionQ " _
                    & "  GROUP BY SoccerPicksUnionQ.ID, SoccerPicksUnionQ.Player" _
                    & "  HAVING Count(*) > 1) AS dT);", dbFailOnError    

        ' DELETING TEAMS WITH TEAM PLAYER COUNT > 4
        db.Execute "DELETE FROM SoccerPicks" _
                    & " WHERE SoccerPicks.ID IN" _
                    & " (SELECT ID AS MaxID" _
                    & "  FROM (SELECT SoccerPicksUnionQ.ID, SoccerPicksUnionQ.Team, Count(*) AS TeamCount" _
                    & "       FROM SoccerPicksUnionQ" _
                    & "       GROUP BY SoccerPicksUnionQ.ID, SoccerPicksUnionQ.Team)  AS dT" _
                    & "  GROUP BY ID" _
                    & "  HAVING Max(TeamCount) >= 4);", dbFailOnError

        ' DELETING TEAMS WITH SAME PLAYERS (I.E. SAME SALARY)
        db.Execute "DELETE FROM SoccerPicks" _
                    & " WHERE ID IN" _
                    & " (SELECT ID AS MaxID" _
                    & "  FROM SoccerPicks" _
                    & "  WHERE TeamSalary IN" _
                    & "         (SELECT sub.TeamSalary" _
                    & "         FROM SoccerPicks sub" _
                    & "         WHERE sub.ID < SoccerPicks.ID));", dbFailOnError
    Next i

    Set db = Nothing


    MsgBox "Successfully completed!", vbInformation
End Function

【讨论】:

    【解决方案2】:

    我已在 Dropbox 中放置了一个新版本(截至 2015 年 12 月 30 日@美国东部标准时间晚上 7:00) https://www.dropbox.com/s/dvobwcpctolk18y/Permutations_REV3.xlsm?dl=0

    ** 注意!!由于大小限制,下面的代码不完整!我必须删除 7,000 多个字符,因此您需要使用 Dropbox 代码。

    请注意,我添加了几张新表来解释该过程: “数学”用于表示允许多少个团队组合。 “限制”跟踪球员来自的球队的名称。 “原始”是您的原始“输入”表 - 更易于复制/粘贴以进行测试。

    此解决方案尝试通过使用团队位置和球员可用性的各种组合来最大化团队数量。

    据我了解,“核心”球员将首先被选中,但不会在团队之间重复。如果不正确,我可以调整。

    以下是使用的代码,但我建议你抢Dropbox版本:

    Option Explicit
    
    Dim WSi, WSo, WSt, WSs, WSl, WSm As Worksheet
    Dim iGLow   As Integer
    Dim iGHigh  As Integer
    Dim iDLow   As Integer
    Dim iDHigh  As Integer
    Dim iMLow   As Integer
    Dim iMHigh  As Integer
    Dim iFLow   As Integer
    Dim iFHigh  As Integer
    Dim iCol    As Integer
    Dim iGoalies, iMidfield, iForward, iDefense As Integer
    Dim iGoaliesA, iMidfieldA, iForwardA, iDefenseA As Integer
    Dim iCoreG, iCoreD, iCoreF, iCoreM As Integer
    Dim iPlayers    As Integer
    Dim iTeams      As Integer
    Dim iRow        As Integer
    Dim iTeamL      As Integer
    Dim FSW         As Boolean
    Dim FinalRowI   As Long
    Dim lMaxSal     As Long
    Dim iTeamRow    As Integer
    Dim iGMin, IGMax   As Integer
    Dim iDMin, IDMax   As Integer
    Dim iFMin, IFMax   As Integer
    Dim iMMin, IMMax   As Integer
    Dim sCores      As String
    Const cGoal = 13
    Const cFwd = 15
    Const cFwd2 = 18
    Const cDef = 14
    Const cDef2 = 17
    Const cMid = 16
    Const cMid2 = 19
    Const cGA = 22
    Const cDA = 23
    Const cFA = 24
    Const cMA = 25
    Const cTTL = 20
    
    Sub Teams()
    Dim i   As Integer
    Dim iT  As Integer
    Dim i2  As Integer
    Dim iGOAL, iFWD, iMID, iDEF As Integer
    
        On Error GoTo Error_Trap
    
        FSW = True
    
        If HouseKeeping = False Then
            MsgBox "Due to problems described earlier, this program will halt now. Please correct all problems.", vbOKOnly, "Program Halt"
            Exit Sub
        End If
    
        WSi.Activate
    
        For iTeamRow = 2 To iTeams + 1
            DoEvents
            iCol = 1            ' Initialize the Output Column number starting position
            sCores = ""         ' Use this to track CORE players per team
    
            iGOAL = 0: iFWD = 0: iMID = 0: iDEF = 0
    
            If iTeamRow Mod 10 = 0 Then
                If ArrangeInputList = True Then
                    MsgBox "Problem with number of players by position."
                End If
            End If
    
            If iGoaliesA > 0 Then
                iRow = FindAnyRow("G", iGLow, iGHigh)
                If iRow = 0 Then
                    Debug.Print "Unable to make any more teams."
                    WSo.Rows(iTeamRow).Delete
                    GoTo Finish_Up
                End If
                iGoaliesA = iGoaliesA - 1       ' Decrease count of available by position...
                iGOAL = iGOAL + 1
            Else
                Debug.Print "Bail out!"
                GoTo Finish_Up
            End If
    
            For i = 1 To WSm.Cells(2 + iTeamRow, cDef) + WSm.Cells(2 + iTeamRow, cDef2)
                iCol = iCol + 1
                iRow = FindAnyRow("D", iDLow, iDHigh)
                If iRow = 0 Then
                    Debug.Print "Unable to make any more teams."
                    WSo.Rows(iTeamRow).Delete
                    GoTo Finish_Up
                End If
                iDefenseA = iDefenseA - 1      ' Decrease count of available by position...
                iDEF = iDEF + 1
            Next i
    
            For i = 1 To WSm.Cells(2 + iTeamRow, cFwd) + WSm.Cells(2 + iTeamRow, cFwd2)
                iCol = iCol + 1
                iRow = FindAnyRow("F", iFLow, iFHigh)
                If iRow = 0 Then
                    Debug.Print "Unable to make any more teams."
                    WSo.Rows(iTeamRow).Delete
                    GoTo Finish_Up
                End If
                iForwardA = iForwardA - 1      ' Decrease count of available by position...
                iFWD = iFWD + 1
            Next i
    
            For i = 1 To WSm.Cells(2 + iTeamRow, cMid) + WSm.Cells(2 + iTeamRow, cMid2)
                iCol = iCol + 1
                iRow = FindAnyRow("M", iMLow, iMHigh)
                If iRow = 0 Then
                    Debug.Print "Unable to make any more teams."
                    WSo.Rows(iTeamRow).Delete
                    WSt.Rows(iTeamRow).Delete
                    WSs.Rows(iTeamRow).Delete
                    GoTo Finish_Up
                End If
                iMidfieldA = iMidfieldA - 1      ' Decrease count of available by position...
                iMID = iMID + 1
            Next i
    
            ' Save Count by Position
            WSo.Cells(iTeamRow, 12) = iGOAL
            WSo.Cells(iTeamRow, 13) = iFWD
            WSo.Cells(iTeamRow, 14) = iDEF
            WSo.Cells(iTeamRow, 15) = iMID
    
            If (iGOAL <> 1) Or (iFWD > 3) Or (iMID > 5) Or (iDEF > 4) Then
                Debug.Print "Team composition exceeds limits: " & vbCrLf & _
                "Goalies = " & iGOAL & vbTab & "Forwards = " & iFWD & vbTab & "Midfielders = " & iMID & vbTab & "Defenders = " & iDEF
                MsgBox "Team composition exceeds limits: " & vbCrLf & _
                "Goalies = " & iGOAL & vbTab & "Forwards = " & iFWD & vbTab & "Midfielders = " & iMID & vbTab & "Defenders = " & iDEF
            End If
            If (iGOAL + iFWD + iMID + iDEF <> 11) Then
                Debug.Print "Team composition not enough players limits: " & vbCrLf & _
                "Goalies = " & iGOAL & vbTab & "Forwards = " & iFWD & vbTab & "Midfielders = " & iMID & vbTab & "Defenders = " & iDEF
                MsgBox "Team composition exceeds limits: " & vbCrLf & _
                "Goalies = " & iGOAL & vbTab & "Forwards = " & iFWD & vbTab & "Midfielders = " & iMID & vbTab & "Defenders = " & iDEF
            End If
    
            DoEvents
        Next iTeamRow
    
    
    Finish_Up:
    
        WSt.Activate
        Range("M2").Select
        ActiveCell = "=COUNTIF($A2:$K2,M$1)"        '"=SUM(RC[-11]:RC[-1])"
        Range("M2").Select
        Selection.Copy
        Range("M2:AA" & Int(iTeams)).Select
        ActiveSheet.Paste
    
        ' Add Conditional Formatting to turn team count to yellow if > 4 players
        Cells.FormatConditions.Delete
        Selection.FormatConditions.Add Type:=xlExpression, Formula1:= _
            "=AND(OR(M2>4),M2<>"""")"
        Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
        With Selection.FormatConditions(1).Interior
            .PatternColorIndex = xlAutomatic
            .Color = 65535
            .TintAndShade = 0
        End With
        Selection.FormatConditions(1).StopIfTrue = False
        Range("M2").Select
        Selection.Copy
        Range("M2:Z31").Select
        ActiveSheet.Paste
        Range("Q3").Select
        Application.CutCopyMode = False
    
    Audit_Checks:
    
    Dim sPlayer1    As String
    Dim sPlayer2    As String
    Dim sPosition   As String
    Dim iRow1       As Integer
    Dim iRow2       As Integer
    Dim Rng1        As Range
    Dim Rng2        As Range
    Dim rCell       As Range
    Dim iCol1       As Integer
    Dim iCol2       As Integer
    Dim iC1         As Integer
    Dim iR1         As Integer
    Dim sTeam       As String
    
        If WSs.Cells(iTeamRow, 12) > lMaxSal Then
            Debug.Print "Team Salary = " & WSs.Cells(iTeamRow, 12)
            MsgBox "Team Salary of: " & WSs.Cells(iRow, 12) & " exceeds Limit of: " & lMaxSal
        End If
    
        ' Find first team with > 4 players from same team...
        For Each rCell In WSt.Range("M2:AD" & iTeams + 1).Cells
            If rCell.Value > 4 Then
                'firstValue = rCell.Value
                iC1 = rCell.Column
                iR1 = rCell.Row
                For i = 2 To iTeams         ' Find a row with less than 4 playes for this team...
                    If WSt.Cells(i, iC1) < 4 Then        ' If < 4, then we have a swap!
                        iRow2 = i
                        Debug.Print "Team #" & i - 1; " has only " & WSt.Cells(i, iC1) & " players from Team '" & WSt.Cells(1, iC1) & "'"
                        sTeam = WSt.Cells(1, iC1)
                        ' Now find a player to swap (must be same position also)
                        For i2 = 2 To 11
                            If WSt.Cells(iR1, i2) = WSt.Cells(1, iC1) Then
                                iRow1 = iR1
                                iCol1 = i2
                                sPlayer1 = WSo.Cells(iR1, i2)                 ' Get Players name & position
                                sPosition = Right(sPlayer1, 3)
                                sPlayer1 = Left(sPlayer1, Len(sPlayer1) - 4)
                                Exit For
                            End If
                        Next i2
                        ' Now we need to find same position in the other team
                        ' iRow2 contains Target Row
                        For i2 = 2 To 11
                            If InStr(1, WSo.Cells(iRow2, i2), sPosition) > 0 And WSt.Cells(iRow2, i2) <> sTeam Then
                                iCol2 = i2
                                sPlayer2 = WSo.Cells(iRow2, i2)
                                sPlayer2 = Left(sPlayer2, Len(sPlayer2) - 4)
    
                                Set Rng1 = WSo.Cells(iRow1, iCol1)
                                Set Rng2 = WSo.Cells(iRow2, iCol2)
    
                                If SwapPlayers(sPlayer1, Rng1, sPlayer2, Rng2) = False Then
                                    MsgBox "Failed to swap players: " & sPlayer1 & " with " & sPlayer2
                                End If
                                GoTo Audit_Checks
                            End If
                        Next i2
                    End If
                Next i
            End If
        Next
    
    End_Of_Time:
    
        Debug.Print "----------------END OF TEAMS---------------------"
        Debug.Print "Remaining: " & vbCrLf & _
                    "Goalies  : " & iGoaliesA & vbTab & "(Need 1)" & vbCrLf & _
                    "Forwards : " & iForwardA & vbTab & "(Need 1)" & vbCrLf & _
                    "Defense  : " & iDefenseA & vbTab & "(Need 3)" & vbCrLf & _
                    "Midfield : " & iMidfieldA & vbTab & "(Need 3)" & vbCrLf
    
        Exit Sub
    
    Error_Trap:
        Debug.Print Err.Number & vbTab & Err.Description & vbCrLf & "In: Teams"
        MsgBox Err.Number & vbTab & Err.Description & vbCrLf & "In: Teams"
        Resume
    
    End Sub
    
    Function FindAnyRow(sPosition As String, iLow As Integer, iHigh As Integer) As Integer
    ' This function will receive the low and high row number for players by a position
    ' it will generate a random row number within that range, and if player not
    ' previously selected (X in 'selected' column), then will use that row #.
    ' As more players are taken from a range, the random number may spend too much time
    ' trying to find an unselected player in that range. If so, re-sort the list to exclude
    ' players that have already been selected.
    
    Dim i       As Integer
    Dim iTries  As Integer
    Dim iRow    As Integer
    Dim FindRow     As Range
    Dim iCLow       As Integer
    Dim iTaken      As Integer
    
        On Error GoTo Error_Trap
    
        'Debug.Print "FindAnyRow: Pos=" & sPosition & vbTab & iLow & vbTab & iHigh
    
        If iHigh - iLow < 0 Then
            Debug.Print "How is this going to work?" & vbTab & iLow & vbTab & iHigh
            FindAnyRow = 0
            Exit Function
        End If
    
        ' First let's check if we have a CORE player for this position
        ' Future change: once all core players have been assigned, bypass this code...
        iCLow = iLow    ' Set low limit of rows to search for CORE
        Do
            DoEvents
    
            ' Having problems with 'Find' logic, so just use the K.I.S.S. method for now!
            For iRow = iCLow To iHigh
                If WSi.Range("E" & iRow) = 1 Then
                    If InStr(1, sCores, WSi.Range("A" & iRow) & ",") = 0 Then
                        sCores = sCores & WSi.Range("A" & iRow) & ","        ' Add player to this team
                        FindAnyRow = iRow           ' Return the row #
                        'Debug.Print "Found CORE '" & sPosition & "' in row: " & iRow
                        WSo.Cells(iTeamRow, iCol) = WSi.Range("A" & iRow) & " (" & sPosition & ")"
                        WSt.Cells(iTeamRow, iCol) = WSi.Range("C" & iRow)
                        WSs.Cells(iTeamRow, iCol) = WSi.Range("D" & iRow)
                        ' If a CORE player - never mark as SELECTED. Thus will appear in every team
                        'WSi.Range("F" & iRow) = "X"
                        Exit Function
                    End If
                End If
            Next iRow
            Exit Do
        Loop
    
        ' Didn't find a CORE player, so let's find any player for this position!
        iTries = 0
        Do
            DoEvents
            iTries = iTries + 1         ' Count # times we have tried to find available player.
            If iTries > 21 Then         ' If more than 5, resort the list!
                ' ONE time during testing, the list was re-sorted, but then still failed to find a player.
                ' Just in case....
                iTaken = 0
                If iHigh - iLow <= 2 Then
                    For i = iLow To iHigh
                        If WSi.Range("E" & i) = 1 Or WSi.Range("F" & iRow) <> "X" Then
                            iTaken = iTaken + 1
                        End If
                    Next i
                End If
                If iTaken >= iHigh - iLow Then
                    ' We have reached the limit on player combinations
                    FindAnyRow = 0
                    Exit Function
                Else
                    MsgBox "Random / resort not working!!"
                End If
            ElseIf iTries > 15 Then
                If ArrangeInputList = True Then
                    Debug.Print "Problem with number of players by position."
                    FindAnyRow = 0
                    Exit Function
                End If
            End If
            DoEvents
            iRow = Int((iHigh - iLow + 1) * Rnd + iLow)    ' Get random number between low & high row
            'Check if already selected
            If WSi.Range("F" & iRow) = " " And WSi.Range("E" & iRow) <> 1 Then
                FindAnyRow = iRow           ' Return the row #
                WSo.Cells(iTeamRow, iCol) = WSi.Range("A" & iRow) & " (" & sPosition & ")"
                WSt.Cells(iTeamRow, iCol) = WSi.Range("C" & iRow)
                WSs.Cells(iTeamRow, iCol) = WSi.Range("D" & iRow)
                ' Don't mark a CORE by accident
                If WSi.Range("E" & iRow) <> 1 Then
                    WSi.Range("F" & iRow) = "X"
                Else
                    'Debug.Print "Prevented marking player by mistake."
                End If
                Exit Do                  ' Exit the loop
            End If
        Loop
    
        Exit Function
    
    Error_Trap:
        Debug.Print Err.Number & vbTab & Err.Description & vbCrLf & "In: FindAnyRow"
        MsgBox Err.Number & vbTab & Err.Description & vbCrLf & "In: FindAnyRow"
        Resume
    
    End Function
    
    Function ArrangeInputList() As Boolean
    ' Sort the list of players by 'selected' column, then by position.
    Dim blnStop As Boolean
    
        On Error GoTo Error_Trap
        blnStop = False
        WSi.Activate
        Columns("A:F").Select
        ActiveWorkbook.Worksheets("Input").Sort.SortFields.Clear
        ActiveWorkbook.Worksheets("Input").Sort.SortFields.Add Key:=Range("F2:F342") _
            , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        ActiveWorkbook.Worksheets("Input").Sort.SortFields.Add Key:=Range("B2:B342") _
            , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        With ActiveWorkbook.Worksheets("Input").Sort
            .SetRange Range("A1:F342")
            .Header = xlYes
            .MatchCase = False
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
        End With
    
        ' Now get the starting row for each position.
        WSi.Activate
        ' Range of Defense...
        iDLow = Range("B:B").Find(What:="D", After:=Range("B1")).Row
        ' Range of Forwards...
        iFLow = Range("B:B").Find(What:="F", After:=Range("B1")).Row
        ' Range of Goalies...
        iGLow = Range("B:B").Find(What:="G", After:=Range("B1")).Row
        ' Range of Midfielders...
        iMLow = Range("B:B").Find(What:="M", After:=Range("B1")).Row
    
        ' Calculate the ending row per position. Note: Can't search for MAX because prior 'selected'
        ' will still appear at the bottom of the list!
        iDHigh = iFLow - 1
        iFHigh = iGLow - 1
        iGHigh = iMLow - 1
    
        ' The last group (Midfielders) needs some help!
        If FSW = True Then
            ' First time thru, this will be the last row for midfielders.
            FSW = False
            iMHigh = iPlayers
        Else
            ' Any other time thru, this will be the last row before a 'selected' flag.
            iMHigh = Range("F:F").Find(What:="X", After:=Range("F1")).Row
        End If
    
        ' Check validity
        If iGHigh < iGLow Then
            Debug.Print "WHAT>>>"
            blnStop = True
        End If
        If iDHigh < iDLow Then
            Debug.Print "WHAT>>>"
            blnStop = True
        End If
        If iFHigh < iFLow Then
            Debug.Print "WHAT>>>"
            blnStop = True
        End If
        If iMHigh < iMLow Then
            Debug.Print "WHAT>>>"
            blnStop = True
        End If
    
    
        ' Count new total # players by position...
        iDefense = iDHigh - iDLow + 1
        iForward = iFHigh - iFLow + 1
        iGoalies = iGHigh - iGLow + 1
        iMidfield = iMHigh - iMLow + 1
    
        ' Calculate new total # players AVAILABLE by position...
        iDefenseA = iDHigh - iDLow + 1
        iForwardA = iFHigh - iFLow + 1
        iGoaliesA = iGHigh - iGLow + 1
        iMidfieldA = iMHigh - iMLow + 1
    
    '    Debug.Print "Goalies Avail:   " & iGoaliesA
    '    Debug.Print "Defenders Avail: " & iDefenseA
    '    Debug.Print "Forwards Avail:  " & iForwardA
    '    Debug.Print "Midfielders Avail: " & iMidfieldA
    
        Exit Function
    
    Error_Trap:
        Debug.Print Err.Number & vbTab & Err.Description & vbCrLf & "In: ArrangeInputList"
        MsgBox Err.Number & vbTab & Err.Description & vbCrLf & "In: ArrangeInputList"
        Resume
    
    End Function
    
    Function SwapPlayers(sName1 As String, iRng1 As Range, sName2 As String, iRng2 As Range) As Boolean
    ' This routine will remove the selected player from their prior team and swap with another player.
    Dim i       As Integer
    Dim iRow1    As Integer
    Dim iCol1    As Integer
    Dim iRow2    As Integer
    Dim iCol2    As Integer
    Dim FindRow     As Integer
    Dim rFound      As Range
    Dim sName       As String
    Dim iLen        As Integer
    Dim lSalary1    As Long
    Dim lSalary2    As Long
    Dim sTeam1      As String
    Dim sTeam2      As String
    Dim sN1         As String
    Dim sN2         As String
    
        On Error GoTo Error_Trap
    
        Debug.Print iRng1.Address & vbTab & iRng1.Row & "/" & iRng1.Column
        Debug.Print iRng2.Address & vbTab & iRng2.Row & "/" & iRng2.Column
    
        ' Find first player
        With WSi
            Set rFound = .Range("A2:A" & FinalRowI).Find(What:=sName1, LookIn:=xlValues)
        End With
        If Not rFound Is Nothing Then
            iRow1 = rFound.Row
        Else
            ' Impossible?
            MsgBox "Unable to find player: " & sName1
        End If
    
        ' Find second player
        With WSi
            Set rFound = .Range("A2:A" & FinalRowI).Find(What:=sName2, LookIn:=xlValues)
        End With
        If Not rFound Is Nothing Then
            iRow2 = rFound.Row
        Else
            ' Impossible?
            MsgBox "Unable to find player: " & sName1
        End If
    
        ' Get Salary and Team names
        sTeam1 = WSi.Cells(iRow1, 3)
        sTeam2 = WSi.Cells(iRow2, 3)
        lSalary1 = WSi.Cells(iRow1, 4)
        lSalary2 = WSi.Cells(iRow2, 4)
        sN1 = WSo.Cells(iRng1.Row, iRng1.Column)
        sN2 = WSo.Cells(iRng2.Row, iRng2.Column)
    
        ' Make the swap
        Debug.Print "Swap: " & sName1 & vbTab & sTeam1 & vbTab & lSalary1 & vbTab & "in RC:" & ""
        Debug.Print "With: " & sName2 & vbTab & sTeam2 & vbTab & lSalary2 & vbTab & "in RC:" & ""
        'Debug.Print WSo.Cells(iRng1.Row, iRng1.Column) & vbTab & WSt.Cells(iRng1.Row, iRng1.Column) & vbTab & WSs.Cells(iRng1.Row, iRng1.Column)
        'Debug.Print WSo.Cells(iRng2.Row, iRng2.Column) & vbTab & WSt.Cells(iRng2.Row, iRng2.Column) & vbTab & WSs.Cells(iRng2.Row, iRng2.Column)
    
        WSo.Cells(iRng1.Row, iRng1.Column) = sN2
        WSo.Cells(iRng2.Row, iRng2.Column) = sN1
    
        WSt.Cells(iRng1.Row, iRng1.Column) = sTeam2
        WSt.Cells(iRng2.Row, iRng2.Column) = sTeam1
    
        WSs.Cells(iRng1.Row, iRng1.Column) = lSalary2
        WSs.Cells(iRng2.Row, iRng2.Column) = lSalary1
    
        SwapPlayers = True
    
        Exit Function
    
    Error_Trap:
        Debug.Print Err.Number & vbTab & Err.Description & vbCrLf & "In: SwapPlayer"
        MsgBox Err.Number & vbTab & Err.Description & vbCrLf & "In: SwapPlayer"
        Exit Function
    
    End Function
    
    Function HouseKeeping() As Boolean
    ' General setup code to:
    ' - Clear sheet contents
    ' - Get Team Names
    ' - Calculate makeup of teams by positions (Math worksheet)
    
    Dim i           As Integer
    Dim i2          As Integer
    Dim iSum        As Integer
    Dim blnFail     As Boolean
    Dim iHalf       As Integer
    Dim iCtr        As Integer
    Dim bSkipBalance    As Boolean
    
        On Error GoTo Error_Trap
    
        blnFail = False    ' Set default to 'FAIL' mode - if good exit, change to pass
    
        Set WSi = Sheet1
        Set WSo = Sheet2
        Set WSt = Sheet3
        Set WSs = Sheet4
        Set WSl = Sheet5
        Set WSm = Sheet8
    
        Sheet2.Cells.ClearContents
        Sheet3.Cells.ClearContents
        Sheet4.Cells.ClearContents
        Sheet5.Cells.ClearContents
    
        iGMin = WSi.Cells(17, 8):     IGMax = WSi.Cells(17, 9)
        iDMin = WSi.Cells(18, 8):     IDMax = WSi.Cells(18, 9)
        iFMin = WSi.Cells(19, 8):     IFMax = WSi.Cells(19, 9)
        iMMin = WSi.Cells(20, 8):     IMMax = WSi.Cells(20, 9)
    
        WSo.Cells(1, 1) = "Goalie"
        WSo.Cells(1, 2) = "2"
        WSo.Cells(1, 3) = "3"
        WSo.Cells(1, 4) = "4"
        WSo.Cells(1, 12) = "# G"
        WSo.Cells(1, 13) = "# D"
        WSo.Cells(1, 14) = "# F"
        WSo.Cells(1, 15) = "# M"
    
        ' Get last row, which is # Players +1
        FinalRowI = WSi.Cells.Find(What:="*", After:=Range("A1"), SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
        iPlayers = FinalRowI - 1
    
        ' Clear 'Selected' column - used to indicate a player has been assigned a team
        WSi.Activate
        Range("F2").Select
        ActiveCell.Value = " "      ' need one space for sort to work properly
        Range("F2").Select
        Selection.Copy
        Range("F3:F" & FinalRowI).Select
        ActiveSheet.Paste
    
        ' Setup Math worksheet...
        WSm.Activate
    
        ' Count Players by position. Place in Math worksheet
        WSm.Cells(4, 4) = Application.WorksheetFunction.CountIf(Workbooks(1).Sheets(1).Range("B2:B" & FinalRowI), "G")
        WSm.Cells(5, 4) = Application.WorksheetFunction.CountIf(Workbooks(1).Sheets(1).Range("B2:B" & FinalRowI), "D")
        WSm.Cells(6, 4) = Application.WorksheetFunction.CountIf(Workbooks(1).Sheets(1).Range("B2:B" & FinalRowI), "F")
        WSm.Cells(7, 4) = Application.WorksheetFunction.CountIf(Workbooks(1).Sheets(1).Range("B2:B" & FinalRowI), "M")
    
        ' In theory, this is the max number of teams
        iTeams = FinalRowI / 11
    
        ' Do we have enough Goalies to make teams?
        If WSm.Cells(4, 4) < iTeams Then
            iTeams = WSm.Cells(4, 4)
        End If
    
        ' Get # Core players
        iCoreG = 0: iCoreD = 0: iCoreF = 0: iCoreM = 0:
    
        For i = 2 To FinalRowI
            If WSi.Cells(i, 5) = 1 Then
                If WSi.Cells(i, 2) = "G" Then
                    iCoreG = iCoreG + 1
                ElseIf WSi.Cells(i, 2) = "D" Then
                    iCoreD = iCoreD + 1
                ElseIf WSi.Cells(i, 2) = "F" Then
                    iCoreF = iCoreF + 1
                ElseIf WSi.Cells(i, 2) = "M" Then
                    iCoreM = iCoreM + 1
                End If
            End If
        Next i
    
    
        ' Clear Map of team composition
        WSm.Range("L4:Y300").Select
        Application.CutCopyMode = False
        Selection.ClearContents
    
        i = 0
    
        ' Loop as long as we can build a team....
        Do
            bSkipBalance = False
    
            i = i + 1
            WSm.Cells(3 + i, cTTL).FormulaR1C1 = "=SUM(RC[-7]:RC[-1])"    ' Add formula to sum count of players on team
    
            If iCoreG = 0 Then
                WSm.Cells(3 + i, cGA).FormulaR1C1 = "=R[-1]C-RC[-9]"     ' Goalie Remainder
            Else
                WSm.Cells(3 + i, cGA).FormulaR1C1 = "=R[-1]C"            ' No limit on goalie
            End If
    
            If iCoreD = 0 Then
                WSm.Cells(3 + i, cDA).FormulaR1C1 = "=R[-1]C-RC[-9]-RC[-6]"                  ' Defender Remainder
            Else
                WSm.Cells(3 + i, cDA).FormulaR1C1 = "=R[-1]C-RC[-9]-RC[-6]+" & iCoreD        ' Defender Remainder
            End If
    
            If iCoreF = 0 Then
                WSm.Cells(3 + i, cFA).FormulaR1C1 = "=R[-1]C-RC[-9]-RC[-6]"                  ' Forward Remainder
            Else
                WSm.Cells(3 + i, cFA).FormulaR1C1 = "=R[-1]C-RC[-9]-RC[-6]+" & iCoreF        ' Forward Remainder
            End If
    
            If iCoreM = 0 Then
                WSm.Cells(3 + i, cMA).FormulaR1C1 = "=R[-1]C-RC[-9]-RC[-6]"                  ' Midfielder Remainder
            Else
                WSm.Cells(3 + i, cMA).FormulaR1C1 = "=R[-1]C-RC[-9]-RC[-6]+" & iCoreM        ' Midfielder Remainder
    
            End If
    
            WSm.Cells(3 + i, 12) = i        ' Set map of positions
            WSm.Cells(3 + i, cGoal) = 1
            WSm.Cells(3 + i, cDef) = 3
            WSm.Cells(3 + i, cFwd) = 1
            WSm.Cells(3 + i, cMid) = 3
    
            ' If we have Excess Defenders, use them (can ONLY use ONE more!!)
            If WSm.Cells(3 + i, 12) > WSm.Cells(3 + i, cDA) Then    ' was WSm.Cells(5, 9)
                WSm.Cells(3 + i, cDef2) = 0
            Else
                WSm.Cells(3 + i, cDef2) = 1
            End If
    

    【讨论】:

    • 我认为您非常接近最终输出,我们可以根据我们得到的输出执行组合,同时牢记约束。请查看更新输出格式。
    • 在测试期间,我从未遇到过薪水> $$$;代码阻止 > 4 名来自同一团队的玩家,并符合位置的 min-max;给定每个位置的 # 名球员,代码还计算和构建可以组成的最大团队数; CORE 玩家首先被选中(但在团队中是唯一的);如果您有 1 个 CORE 前锋,那么每个团队中都应该出现同一个人吗?
    • 是的,如果一名球员是核心球员,那么他必须出现在每个阵容中。使用这个逻辑,不会有任何两名守门员作为核心,因为这样就不会有任何可能的球队,对于前锋和其他位置的球员也是如此。
    • 顺便说一句,当我运行 Teams 宏时,它给了我错误:1004 Method 'Range' of object '_Global' failed In: HouseKeeping
    • 这里肯定需要明确CORE,因为您之前说过“我的意思是核心球员必须被安排在任何一个团队中”。注意“一个团队”部分。 @EEM 早些时候问过允许多少核心,但我没有看到任何定义。你能有4个核心防守者吗?如果是这样,为什么要列出任何其他防御者,因为它们永远不会被使用?了解您遇到错误的代码行以及您在错误之前对数据做了什么会很有帮助。您使用的是哪个版本的 Excel?
    猜你喜欢
    • 1970-01-01
    • 2012-04-04
    • 2015-03-12
    • 1970-01-01
    • 2012-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多