Giúp Tính Tổ Hợp bằng VB (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

Takehi_JP

Thành viên hoạt động
Tham gia
31/12/11
Bài viết
183
Được thích
9
Giới tính
Nữ
Chào các bạn, các bạn có thể giúp mình tính tổ hợp như trong bảng tính mình gữi kèm theo, bằng VBA được không ?
với số lượng con số hàng và cột ít, thì có một tham khảo trong forum, nhưng mình không hiểu lắm, với lại, mình muốn cho kết quả nằm riêng ra bảng tính khác,
hoặc cột khác để tiện hơn.
và có thể thay đổi số cột, hoặc số hàng một cách linh hoạt.

Xin Chân Thành Cảm ơn !
 

File đính kèm

Chào các bạn, các bạn có thể giúp mình tính tổ hợp như trong bảng tính mình gữi kèm theo, bằng VBA được không ?
với số lượng con số hàng và cột ít, thì có một tham khảo trong forum, nhưng mình không hiểu lắm, với lại, mình muốn cho kết quả nằm riêng ra bảng tính khác,
hoặc cột khác để tiện hơn.
và có thể thay đổi số cột, hoặc số hàng một cách linh hoạt.

Xin Chân Thành Cảm ơn !

đề bài không rõ lắm, tui diễn đạt lại thế này không biết có đúng không:

giả sử có 5 range trên các cột: [A1:A19], [B1:B35], [C1:C32], [D1:D12], [E1:E42]
yêu cầu: liệt kê tất cả các range dạng [Ai, Bj, Ck, Dm, En] ???

không hiểu đề, không dám có ý kiến.
 
Upvote 0
đúng là vậy đó jact, tks bạn nhiều, có thể giúp mình giải đáp phép toàn này không ?
 
Upvote 0
Chào các bạn, các bạn có thể giúp mình tính tổ hợp như trong bảng tính mình gữi kèm theo, bằng VBA được không ?
với số lượng con số hàng và cột ít, thì có một tham khảo trong forum, nhưng mình không hiểu lắm, với lại, mình muốn cho kết quả nằm riêng ra bảng tính khác,
hoặc cột khác để tiện hơn.
và có thể thay đổi số cột, hoặc số hàng một cách linh hoạt.

Xin Chân Thành Cảm ơn !

Có 5 cột dữ liệu A, B, C, D, E với số phần tử trong mỗi cột lần lượt là 19, 35, 32, 12, 42
Như vậy số nhóm có dạng AiBjCkDsEr là 19*35*32*12*42 = 10725120

Bạn định liệt kê ra ở đâu vậy? Bạn lấy sheet nào để có hơn 10 triệu dòng???

Cũng không khai báo được mảng nào có số dòng lớn như thế.
 
Upvote 0
đúng là vậy đó jact, tks bạn nhiều, có thể giúp mình giải đáp phép toàn này không ?
Bạn đọc và trả lời bài số 4 của anh Siwtom !
Mình hỏi thêm vấn đề này nữa :
hầu hết các bài toán liệt kê tổ hợp đều là dạng liệt kê tổ hợp tối ưu : tức là luôn có điều kiện biên ví dụ : tìm tổng nhỏ nhất,...!
Vậy :
* Bạn liệt kê tổ hợp để làm gì ??? --> chỉ để xem cho biết, cho vui mắt ??
Nếu vậy mình có ví dụ code cho vui, ( mình liệt kê từ ô A3 cho đến ô D9 chẳng hạn )
Mã:
Option Explicit
Public Result, Arr, str$
'---------------------------------------------------
Sub Try(ByVal i As Long)
    Dim j&, item
        For j = 1 To UBound(Arr, 1)
            If Len(Arr(j, i)) Then
                Result(i) = Arr(j, i)
                If i = UBound(Arr, 2) Then
                    For Each item In Result
                        str = str & item & vbTab
                    Next
                        str = Trim(str) & vbCrLf
                Else
                    Try i + 1
                End If
            End If
        Next
End Sub
'---------------------------------------------------------------------
Sub GPE()
    str = vbNullString
    Arr = range("A3:D9")
    ReDim Result(1 To UBound(Arr, 2))
    Try 1
    MsgBox str
End Sub

copy code trên vào file excel bạn đính kèm, chạy Sub GPE()
 
Upvote 0
đúng là vậy đó jact, tks bạn nhiều, có thể giúp mình giải đáp phép toàn này không ?

Thôi, nếu bạn hungpecc1 đã dùng đệ quy thì ta thử cách khác không đệ quy nhé.
Ta test cho mảng A3:E19, tức kết quả sẽ có 17*17*17*12*17 = 1002252 (hơn 1 triệu) kết quả
------------
Mã:
Private Declare Function GetTickCount Lib "kernel32.dll" () As Long

Function Combination(Arr(), result()) As Boolean
'    Arr là mảng chứa dữ liệu, không nhất thiết các ôđều có dữ liệu. Vd. mảng 3x3 với các dòng là
'    dòng 1: A1, B1, C1
'    dòng 2: A2 , B2, C2
'    dòng 3: <trống>, B3, <trống>
'    Điều kiện bắt buộc mà mảng phải thỏa: Trong mỗi cột các ôcó dữ liệu phải liên tục bắt đầu từ ôđầu tiên. Mỗi cột phải có ít nhất 1 ôdữ liệu
'    result là mảng chứa kêt quả trả về.
'    Nếu mảng có k cột và gọi s(k) là số ôcó dữ liệu trong cột k thì mảng trả về có s(1)*s(2)*...*s(k) dòng
'    Với vd. ở trên thì có 12 dòng kết quả
'    A1 , B1, C1
'    A1 , B1, C2
'    A1 , B2, C1
'    A1 , B2, C2
'    A1 , B3, C1
'    A1 , B3, C2
'    A2 , B1, C1
'    A2 , B1, C2
'    A2 , B2, C1
'    A2 , B2, C2
'    A2 , B3, C1
'    A2 , B3, C2
'    Nếu cột nào đó không có dữ liệu thì hàm trả về FALSE và không có kết quả trả về trong mảng result

Dim tmp(), index(), k As Long, r As Long, c As Long, count As Long
    tmp = Arr
'    dong 1 cua mang index ghi so phan tu trong moi cot
    ReDim index(1 To 2, 1 To UBound(tmp, 2))
    count = 1
    For c = UBound(tmp, 2) To 1 Step -1
        If c = UBound(tmp, 2) Then
            index(2, c) = 1
        Else
            index(2, c) = index(1, c + 1) * index(2, c + 1)
        End If
        For r = UBound(tmp) To 1 Step -1
            If tmp(r, c) <> "" Then
                index(1, c) = r
                count = count * r
                Exit For
            End If
        Next
        If r = 0 Then GoTo end_
    Next

'   xác định các kết quả    
    ReDim result(1 To count, 1 To UBound(tmp, 2))
    For r = 1 To count
        For c = 1 To UBound(result, 2)
            k = (r - 1) \ index(2, c)
            k = (k Mod index(1, c)) + 1
            result(r, c) = tmp(k, c)
        Next
    Next
    Combination = True
end_:
End Function

Sub test()
Dim Arr(), result(), t As Double
    t = GetTickCount
    Arr = Range("A3:E19")
    If Combination(Arr, result) Then
        Debug.Print (GetTickCount - t) / 1000
        Range("H3").Resize(UBound(result), UBound(result, 2)).Value = result
    End If
End Sub
 
Upvote 0
đúng là vậy đó jact, tks bạn nhiều, có thể giúp mình giải đáp phép toàn này không ?
@qtnbphi: siwtom đã trả lời rồi, tui không viết thêm gì về code nữa.
nếu bạn vẫn cố mà list hết ra, 1 sheet không đủ thì dùng nhiều sheet (excel >= 2007 có hơn 1 triệu dòng), trong trường hợp này phải dùng đến cỡ 10 sheet. bạn lỡ thêm cột thêm dòng vào thì e là chờ đến tết công gô mới xong. lỡ xài máy dell (không có phím break) thì chỉ còn nước tắt máy.
ở trên có bạn hỏi rồi, nhưng tui cũng hỏi lại: bạn liệt kê ra để ngắm chơi a? phải có điều kiện gì đó để hạn chế số lượng tổ hợp chứ.
 
Upvote 0
@qtnbphi:
Bạn jack_nt đề nghị dùng nhiều sheet khi số dòng cực lớn.

Muốn liệt kê 10 triệu dòng thì ngoài việc dùng nhiều sheet còn có vấn đề của mảng - Array.

Vì không thể khai báo Array với hơn 1 triệu "gì gì đó" dòng được (???).
Với số dòng quá lớn thì chỉ còn nước khai báo max Array, vd. 1 triệu dòng, rồi trong vòng For khi Array đã "đầy" thì "đập" xuống sheet rồi lại nạp Array từ đầu. Cứ thế cho đến dữ liệu cuối cùng.
 
Upvote 0
lý do ở đây không phải là mình làm để chơi, mình cũng có tìm hiểu biết là excel có giới hạn số hàng cột
2007 thì 65536 hàng
còn 2010 thì 1triệu mấy giống đó , mình quên rồi.
còn về bài viết, là vì mình cầy tổ hợp một list các hạng mục công việc, với điều kiện là nằm ở cột A,B, còn. nằm trong việc quản lý công việc của nhân viên đang làm những hạng mục công việc nào trong công ty mình
dựa vào list tổ hợp được, mình sẽ tính được .
Copy cũng được, nhưng hởi phiền, và lâu, nên mình nghĩ tới việc nhờ mọi người giúp viết code, để sau còn sài tiếp cho những công việc khác không chừng.

tks các bạn rất nhiều nhé, đã trả lời cho mình rất nhiều ý kiến hay.
 
Upvote 0

Bài viết mới nhất

Back
Top Bottom