Chọn 10 Tên Ngẫu Nhiên Từ Danh Sách 20 Tên

Chọn 10 Tên Ngẫu Nhiên Từ Danh Sách 20 Tên

Published Time: Mon, 06 Apr 2026 14:04:41 GMT

Nội Dung Bài Viết

Chào các anh chị. Cho em hỏi bài toán như sau

Cho 1 danh sách gồm 20 cái tên khác nhau, yêu cầu nhấc ra 1 tổ hợp gồm 10 tên ngẫu nhiên trong danh sách 20 tên đó, sao cho không có cái tên nào trong cùng 1 tổ hợp bị trùng nhau. Kết quả nằm trong 1 cell và các tên ngăn nhau bằng dấu trừ.

Nhờ anh chị cho em xin công thức ạ. Em xin cảm ơn nhiều!

Các Phản Hồi và Giải Pháp

Phản Hồi #2

=RANDBETWEEN(A1,A2) &"-"& RANDBETWEEN(A3,A4)&"-"& RANDBETWEEN(A5,A6)&"-"& RANDBETWEEN(A7,A8)&"-"& RANDBETWEEN(A9,A10)&.....

Đơn giản quá nhỉ

Phản Hồi #3

Chào các anh chị. Cho em hỏi bài toán như sau

Cho 1 danh sách gồm 20 cái tên khác nhau, yêu cầu nhấc ra 1 tổ hợp gồm 10 tên ngẫu nhiên trong danh sách 20 tên đó, sao cho không có cái tên nào trong cùng 1 tổ hợp bị trùng nhau. Kết quả nằm trong 1 cell và các tên ngăn nhau bằng dấu trừ.

Nhờ anh chị cho em xin công thức ạ. Em xin cảm ơn nhiều!

Bạn thử code này:

Mã:

Sub a() Dim arr, num As Long, key, str As String arr = [A1:A20] With CreateObject("Scripting.dictionary") Do While .Count < 10 Randomize num = Int(Rnd() * 20) + 1 If Not .exists(num) Then .Add num, arr(num, 1) Loop str = Join(.items(), " - ") End With [c1].Value = str End Sub

Lần chỉnh sửa cuối: 23/1/19

Phản Hồi #4

Chào các anh chị. Cho em hỏi bài toán như sau

Cho 1 danh sách gồm 20 cái tên khác nhau, yêu cầu nhấc ra 1 tổ hợp gồm 10 tên ngẫu nhiên trong danh sách 20 tên đó, sao cho không có cái tên nào trong cùng 1 tổ hợp bị trùng nhau. Kết quả nằm trong 1 cell và các tên ngăn nhau bằng dấu trừ.

Nhờ anh chị cho em xin công thức ạ. Em xin cảm ơn nhiều!

Nếu không nối chuỗi có thể dùng công thức này:

=INDEX($A$1:$A$20,SMALL(IF(COUNTIF($E$1:E1,$A$1:$A$20)=0,ROW($1:$20)),RANDBETWEEN(1,21-COLUMN(A1))))

Bấm Ctrl+Shift+Enter rồi kéo sang phải.

Phản Hồi #5

Bạn thử code này:

Mã:

Sub a() Dim arr, num As Long, key, str As String arr = [A1:A20] With CreateObject("Scripting.dictionary") Do While .Count < 10 Randomize num = Int(Rnd() * 20) + 1 If Not .exists(num) Then .Add num, "" Loop For Each key In .keys() str = str & IIf(str = "", "", " - ") & arr(key, 1) Next End With [c1].Value = str End Sub

Thử dùng Join cho đẹp

Phản Hồi #6

Thử dùng Join cho đẹp

Đã sữa, thanks bạn!

Phản Hồi #7

Chào các anh chị. Cho em hỏi bài toán như sau

Cho 1 danh sách gồm 20 cái tên khác nhau, yêu cầu nhấc ra 1 tổ hợp gồm 10 tên ngẫu nhiên trong danh sách 20 tên đó, sao cho không có cái tên nào trong cùng 1 tổ hợp bị trùng nhau. Kết quả nằm trong 1 cell và các tên ngăn nhau bằng dấu trừ.

Nhờ anh chị cho em xin công thức ạ. Em xin cảm ơn nhiều!

Dùng hàm tự tạo

Mã:

Function GPE(ByVal Rng As Range, ByVal n As Long) Dim Str As String, tmp As String, m As Long, i As Long, j As Long m = Rng.Rows.Count Str = "- " & Join(Application.Transpose(Rng), " - ") & " -" Randomize For i = 1 To m - n num = Int(Rnd() * (m + 1 - i)) + 1 tmp = Replace(Str, "-", "#", 1, num) j = InStrRev(tmp, "#") Str = Replace(Str, Mid(tmp, j + 1, InStr(1, tmp, "-") - j), "") Next i GPE = Mid(Str, 3, Len(Str) - 4) End Function

Phản Hồi #8

Sao bạn không hỏi thêm tổ hợp.

Nếu hoán vị 20 cái tên vào 10 vị vị trí khác nhau thì thành bài toán tổ hợp.

Phản Hồi #9

Cảm ơn anh @HieuCD và @excel_lv1.5 nhiều ạ. Đúng là chỉ có VBA mới giải quyết được mà em thì chưa thạo.

Theo như em nhớ hồi lớp 11 học thì đây gọi tổ hợp chập 10 của 20, tức là có tối đa 184756 cell kết quả có thể được tạo ra.

=> Do đó em muốn khi kéo ô B1 xuống bên dưới nhiều nhiều nữa thì sẽ xuất ra 1 loạt tổ hợp nhấc 10 phần tử ngẫu nhiên không lặp lại trong số 20 phần tử cho trước ở cột A ạ. Mong anh cho em xin giải pháp, em cảm ơn nhiều ạ!

Phản Hồi #10

Vấn đề này có ít nhất là 3 cách giải quyết:

  1. cách dễ nhất, và nếu là bài tập thì chính là cách mà Thầy/Cô đòi hỏi: đặt một hàm Rand() vào cột kế bên, sort, lấy ra 10 cái.
  2. dùng công thức khủng: tôn chỉ của tôi là công thức khủng chỉ dùng để vận động đầu óc giải đố mẹo. Vì vậy toi khong tiếp thêm.
  3. dùng hàm tự tạo. Thuật toán lấy k phần tử ngẫu nhiên trong n phần tử đã được giải nhiều lần ở diễn đàn này rồi.

Chú: thuật toán ở bài #3 giản dị nhưng nếu (n-k)/n là số rất nhỏ, tức là k gần bằng n thì khả năng chạm số càng lúc càng cao và theo lý thuyết, bài toán có thể chạy vòng đi vòng lại khá lâu. Yêu cầu bài này (n-k)/n = 0,5 là số tương đối chấp nhận.

Phản Hồi #11

Vấn đề này có ít nhất là 3 cách giải quyết:
  1. cách dễ nhất, và nếu là bài tập thì chính là cách mà Thầy/Cô đòi hỏi: đặt một hàm Rand() vào cột kế bên, sort, lấy ra 10 cái.
  2. dùng công thức khủng: tôn chỉ của tôi là công thức khủng chỉ dùng để vận động đầu óc giải đố mẹo. Vì vậy toi khong tiếp thêm.
  3. dùng hàm tự tạo. Thuật toán lấy k phần tử ngẫu nhiên trong n phần tử đã được giải nhiều lần ở diễn đàn này rồi.

Chú: thuật toán ở bài #3 giản dị nhưng nếu (n-k)/n là số rất nhỏ, tức là k gần bằng n thì khả năng chạm số càng lúc càng cao và theo lý thuyết, bài toán có thể chạy vòng đi vòng lại khá lâu. Yêu cầu bài này (n-k)/n = 0,5 là số tương đối chấp nhận.

Lỗi tại em chưa hỏi hết ý ngay từ đầu ạ, em muốn render ra 1 loạt kết quả theo cách kéo B1 xuống dưới thì có thể tạo thêm các tổ hợp mới. Nên em nhờ các anh chị giúp em phần công thức để chạy ạ

Cảm ơn anh @@HieuCD và @@excel_lv1.5 nhiều ạ. Đúng là chỉ có VBA mới giải quyết được mà em thì chưa thạo.

Theo như em nhớ hồi lớp 11 học thì đây gọi tổ hợp chập 10 của 20, tức là có tối đa 184756 cell kết quả có thể được tạo ra.

=> Do đó em muốn khi kéo ô B1 xuống bên dưới nhiều nhiều nữa thì sẽ xuất ra 1 loạt tổ hợp nhấc 10 phần tử ngẫu nhiên không lặp lại trong số 20 phần tử cho trước ở cột A ạ. Mong anh cho em xin giải pháp, em cảm ơn nhiều ạ!

Phản Hồi #12

Tôi đã nói là thuật toán tạo tổ hợp đã từng được bàn cặn kẽ ở diễn đàn này. Chịu khó tìm.

Số lớn thì khó chứ 30 phần tử trở xuống thì tương đối dễ.

Phản Hồi #13

Tôi đã nói là thuật toán tạo tổ hợp đã từng được bàn cặn kẽ ở diễn đàn này. Chịu khó tìm.

Số lớn thì khó chứ 30 phần tử trở xuống thì tương đối dễ.

thực ra là em muốn nhờ mọi người cho xin 1 công thức/code để sau nhập nhiều phần tử cho trước hơn, có thể tới 50 phần tử cung cấp sẵn và nhấc ra 10 phần tử ạ

Phản Hồi #14

Cảm ơn anh @HieuCD và @excel_lv1.5 nhiều ạ. Đúng là chỉ có VBA mới giải quyết được mà em thì chưa thạo.

Theo như em nhớ hồi lớp 11 học thì đây gọi tổ hợp chập 10 của 20, tức là có tối đa 184756 cell kết quả có thể được tạo ra.

=> Do đó em muốn khi kéo ô B1 xuống bên dưới nhiều nhiều nữa thì sẽ xuất ra 1 loạt tổ hợp nhấc 10 phần tử ngẫu nhiên không lặp lại trong số 20 phần tử cho trước ở cột A ạ. Mong anh cho em xin giải pháp, em cảm ơn nhiều ạ!

Thử code này, show tối đa số dòng của excel trong một cột thôi, thay đổi ô B1 để thay đổi số tổ hợp!

Mã:

Sub combin() Dim i As Long, j As Long, n As Long, m As Long, arr, darr, result, str As String If [g1] <> "" Then Range("G1").CurrentRegion.Clear arr = Range("A1:A" & [A100000].End(xlUp).Row): m = UBound(arr): n = [b1] ReDim darr(1 To WorksheetFunction.combin(UBound(arr), n), 1 To n + 2) For i = 1 To UBound(darr, 2) - 2 darr(1, i + 1) = i Next i For i = 2 To UBound(darr) For j = 2 To UBound(darr, 2) - 1 darr(i, j) = IIf(darr(i - 1, j) = m + j - n - 1, CDbl(darr(i, j - 1)) + 1, _ IIf(darr(i - 1, j + 1) = m + j - n Or CDbl(darr(i - 1, j + 1)) = 0,
Tin liên quan