2016-08-03 60 views
1

我正在制定一個計劃,確定誰要去做飯,誰和一些朋友一起做菜。 我列出「A」列中列出的參與者的姓名,並使用CountIf來查看特定人員出現在日程安排中的次數,以使每個人都公平。該代碼挑選2個隨機人員做飯,2個做菜以確保他們不一樣。然後將這些名稱放入我在工作表中定義的日程表中。 我目前的代碼看起來像這樣,並且工作到目前爲止。在Excel中使用VBA制定計劃

Private Sub cookplan() 
last_row = Range("A1").End(xlDown).Row 
Dim awesome() 
Dim index1 As Integer 
Dim index2 As Integer 
Dim cook1 As String 
Dim cook2 As String 
Dim dish1 As String 
Dim dish2 As String 
ReDim awesome(last_row - 1, 0) 
For i = 0 To last_row - 1 
    awesome(i, 0) = Range("A" & i + 1) 
Next 

For i = 1 To 5 
     index1 = Int((last_row - 1 - 0 + 1) * Rnd + 0) 
     cook1 = awesome(index1, 0) 
     Cells(i * 2, 6).Value = cook1 

     Do 
      index2 = Int((last_row - 1 - 0 + 1) * Rnd + 0) 
      cook2 = awesome(index2, 0) 
      Cells(i * 2, 7).Value = cook2 
     Loop While cook2 = cook1 

     Do 
      index1 = Int((last_row - 1 - 0 + 1) * Rnd + 0) 
      dish1 = awesome(index1, 0) 
     Loop While dish1 = cook1 Or dish1 = cook2 

     Do 
      index2 = Int((last_row - 1 - 0 + 1) * Rnd + 0) 
      dish2 = awesome(index2, 0) 
     Loop While dish2 = cook1 Or dish2 = cook2 Or dish2 = dish1 

     Cells(i * 2, 8).Value = dish1 
     Cells(i * 2, 9).Value = dish2 
Next 
End Sub 

有沒有辦法讓名字出現最大和最小次數?就像現在一樣,當我運行代碼並查看CountIf結果時,2或3次似乎是相當數量的。

UPDATE

我現在已經得到了代碼,旨在工作。每個人都需要至少一種烹飪和美食,所以現在編碼看起來就像這樣。我知道這是不是很漂亮,但它能夠完成任務:)

Private Sub cookplan() 
last_row = Range("A1").End(xlDown).Row 
Dim awesome() 
Dim index As Integer 
Dim cook1 As String 
Dim cook2 As String 
Dim dish1 As String 
Dim dish2 As String 
Dim counter1 As Integer 
Dim counter2 As Integer 
ReDim awesome(last_row - 2, 0) 
For i = 0 To last_row - 2 
    awesome(i, 0) = Range("A" & i + 2) 
Next 
Do 
    For i = 1 To 5 
     Do 
      index = Int((last_row - 2 - 0 + 1) * Rnd + 0) 
      cook1 = awesome(index, 0) 
      Cells(i * 2, 6).Value = cook1 
     Loop While Cells(index + 2, 2) > 2 Or Cells(index + 2, 3) > 2 
     Do 
      index = Int((last_row - 2 - 0 + 1) * Rnd + 0) 
      cook2 = awesome(index, 0) 
      Cells(i * 2, 7).Value = cook2 
     Loop While Cells(index + 2, 2) > 2 Or Cells(index + 2, 3) > 2 Or cook2 = cook1 
     Do 
      index = Int((last_row - 2 - 0 + 1) * Rnd + 0) 
      dish1 = awesome(index, 0) 
      Cells(i * 2, 8).Value = dish1 
     Loop While Cells(index + 2, 2) > 2 Or Cells(index + 2, 3) > 2 Or dish1 = cook1 Or dish1 = cook2 
     Do 
      index = Int((last_row - 2 - 0 + 1) * Rnd + 0) 
      dish2 = awesome(index, 0) 
      Cells(i * 2, 9).Value = dish2 
     Loop While Cells(index + 2, 2) > 2 Or Cells(index + 2, 3) > 2 Or dish2 = cook1 Or dish2 = cook2 Or dish2 = dish1 
    Next 
    counter1 = 0 
    counter2 = 0 
    For i = 2 To last_row 
     If Cells(i, 2).Value = 0 Then 
      counter1 = counter1 + 1 
     End If 
     If Cells(i, 3).Value = 0 Then 
      counter2 = counter2 + 1 
     End If 
    Next 
Loop While counter1 > 0 Or counter2 > 0 
End Sub 
+0

當你隨機的東西,日之後沒有辦法排除已經出現的價值的外觀。唯一合理的解決方案是檢查已經出現最大次數的人,如果是,重新運行隨機獲得新名字。 – FDavidov

+0

Acalally,你可以使用解算器而不是vba。它是一個內置的插件,旨在解決場景。網上有足夠的教程。 –

+0

您也可以刪除/縮小可用名稱的列表,一旦名稱被使用了最長時間。一本字典對此很好。 –

回答

0

,你可以用隨機生成的separte功能,即檢查工作,如果選擇的名稱已經被使用了兩次。如果爲false,則返回名稱。如果爲true,則函數會自行調用(因此會生成一個新名稱),直到找到符合條件的名稱。

更新請注意,這是某種形式的僞代碼,這是不打算工作

在你的子cookplan,您添加功能,每次的名字,你需要一個新的名字

cook1 = GetName() 

在End Sub插入一個名爲的GetName新的Funktion(或任何你想要的)

Function GetName() As String 

    'Determine your name here 
    If CountForDeterminedName > 2 Then 

     'Call Function Again to find another Name 
     GetName = GetName() 

    Else 

     GetName = DeterminedName 

    End If 

End Function 
+0

這將如何編碼? –

+0

你最初的評論讓我想到了一個解決方案。不那麼流暢,但它是一些東西。看到我的文章中的更新:)並感謝你 –