iT邦幫忙

0

亂數不重複

  • 分享至 

  • xImage

網路上看到高手寫下此程式碼:
https://www.jobforum.tw/discussTopic.asp?cat=skill&id=32703

在 c1 欄位輸入函式 =50*RAND()

在 D1 輸入 =COUNT(A:A)

進入VBA 創立一個 巨集

把以下資料貼上 執行巨集 就 OK了(邏輯 每次產生一個亂數數字 比對是否重複 重複則產生新數字)
For i = 1 To 50
10
Cells(i, 1).Value = Int(Cells(1, 3).Value)
If i >= 2 Then
cnt = Cells(1, 4).Value
For j = 1 To cnt - 1
val1 = Cells(cnt, 1).Value
val2 = Cells(j, 1).Value
If val1 = val2 Then GoTo 10
Next j
End If
Next i
可是實際操作時在(A:A)的欄位上還是會出現重複的數字,如何修改才真正不會出現重複的數字呢?

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

5
japhenchen
iT邦超人 1 級 ‧ 2019-06-17 09:59:59
最佳解答

Sub bag()

Dim mybag As New Collection ' 宣告一個放球的袋子,類型是Collection集合

For i = 1 To 49
    mybag.Add (i)  ' 依序放入1到49的號碼球
Next
        
c = 1 ' 我要顯示的列碼,從第1列開始

While mybag.Count > 0  ' 直到mybag裡的球被抽完為止
    R = Int(mybag.Count * Rnd()) + 1 ' R 就是包包裡的球數*0~1之間的隨機數,集合跟陣列一樣,元素從1開始
    Cells(c, 1).Value = mybag.Item(R) ' 按c值在相對的列上填入球號
    mybag.Remove (R) ' 抽到的球就不要放回袋子(集合)裡了,直接拿掉
    c = c + 1 ' 加一列,下一球就從下一列開始填格子
Wend

' 如果你想玩樂透彩,就把while 改成 for x = 1 to 6只抽6次即可

End Sub

看更多先前的回應...收起先前的回應...

https://ithelp.ithome.com.tw/upload/images/20190617/20117954mfUtqbaMda.jpg

這個方法也是之前有人回答的法官抽撲克牌的方法,大同小異,在C#、PYTHON裡我也會這個方法做大型亂數處理(LIST)

小魚 iT邦大師 1 級 ‧ 2019-06-17 11:41:48 檢舉

抽撲克牌的方式算是蠻常見,
也不會有多餘的判斷,
使用原本那種方式運氣不好的話會多花很多時間...
C#裡面有已經寫好的函式,
直接呼叫一行就解決了.

VB/VBA真的不好用,想要達成這些集合的事,還要做集合項目的新增移除,一些在其他語言裡一兩行可以達成的事(LAMBDA),在VBA裡連迴圈都要一個一個來,是蠻不好閱讀的

0
小魚
iT邦大師 1 級 ‧ 2019-06-17 08:07:43

我實測過沒有重複啊...

看更多先前的回應...收起先前的回應...
小魚 iT邦大師 1 級 ‧ 2019-06-17 08:15:00 檢舉

有另外一種做法是發撲克牌的做法.

no1kent iT邦新手 5 級 ‧ 2019-06-17 09:34:25 檢舉

有時候就會重複不知道為什麼?那有辦法避免0跑出來嗎https://ithelp.ithome.com.tw/upload/images/20190617/201182509XMmvO8jFo.png

/images/emoticon/emoticon04.gif 放錯格子了

小魚 iT邦大師 1 級 ‧ 2019-06-17 10:01:27 檢舉

以這種寫法,
0跑出來是正常的,
這部分你要自己思考...

正常來說如果A欄整個是空的應該不會重複...

我要發表回答

立即登入回答