Tìm nhóm số với số cột lớn nhất (1 người xem)

Liên hệ QC

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

Sơn Mã

Thành viên hoạt động
Tham gia
30/12/16
Bài viết
114
Được thích
2
Mình có một nan đề sau làm rất lâu rồi mà chưa có phương án giải quyết: dữ liệu ở sheet(DULIEU) gồm có 100 cột: số liệu trong các cột là những số trong khoảng từ 00 đến 99. Mình cần chọn ra 5 nhóm số càng nhiều số càng tốt như sau:
Yêu cầu: với mỗi một nhóm số:
1/ Trong mỗi cột chỉ được chọn 1 số.
2/ Bắt đầu Chọn từ cột 1 đầu tiên rồi lần lượt chọn đến các cột tiếp theo (không được chọn nhảy bỏ qua cột).
3/ Các số được chọn trong các cột không được trùng lặp lại. (Ví dụ cột 1 chọn số 03 thì các cột tiếp theo không được chọn số 03 nữa)
4/ Tìm phương án chọn sao cho số cột được chọn là nhiều nhất: từ cột 1 đến cột n (Với n là lớn nhất có thể (n=< 100)).
5/ Chọn ra 5 phương án để có 5 nhóm số với số cột là lớn nhất có thể.
6/ Kết quả chọn: dán sang sheet(KETQUA) và dán vào dòng 2 ( nhóm số cột lớn nhất), dòng 3 (nhóm số cột lớn thứ 2), dòng 4 (nhóm số cột lớn thứ 3), dòng 5 (nhóm số cột lớn thứ 4), dòng 6 (nhóm số cột lớn thứ 5) vào số cột tương ứng.
Mong các bạn và GPE giúp đỡ. Xin trân trọng cảm ơn!
 

File đính kèm

Mình có một nan đề sau làm rất lâu rồi mà chưa có phương án giải quyết: dữ liệu ở sheet(DULIEU) gồm có 100 cột: số liệu trong các cột là những số trong khoảng từ 00 đến 99. Mình cần chọn ra 5 nhóm số càng nhiều số càng tốt như sau:
Yêu cầu: với mỗi một nhóm số:
1/ Trong mỗi cột chỉ được chọn 1 số.
2/ Bắt đầu Chọn từ cột 1 đầu tiên rồi lần lượt chọn đến các cột tiếp theo (không được chọn nhảy bỏ qua cột).
3/ Các số được chọn trong các cột không được trùng lặp lại. (Ví dụ cột 1 chọn số 03 thì các cột tiếp theo không được chọn số 03 nữa)
4/ Tìm phương án chọn sao cho số cột được chọn là nhiều nhất: từ cột 1 đến cột n (Với n là lớn nhất có thể (n=< 100)).
5/ Chọn ra 5 phương án để có 5 nhóm số với số cột là lớn nhất có thể.
6/ Kết quả chọn: dán sang sheet(KETQUA) và dán vào dòng 2 ( nhóm số cột lớn nhất), dòng 3 (nhóm số cột lớn thứ 2), dòng 4 (nhóm số cột lớn thứ 3), dòng 5 (nhóm số cột lớn thứ 4), dòng 6 (nhóm số cột lớn thứ 5) vào số cột tương ứng.
Mong các bạn và GPE giúp đỡ. Xin trân trọng cảm ơn!
Có bạn nào xem giúp đỡ mình với ạ? Có chỗ nào không rõ mình xin trình bày lại. Xin cảm ơn rất nhiều!
 
1/ Trong mỗi cột chỉ được chọn 1 số.
2/ Bắt đầu Chọn từ cột 1 đầu tiên rồi lần lượt chọn đến các cột tiếp theo (không được chọn nhảy bỏ qua cột).
3/ Các số được chọn trong các cột không được trùng lặp lại. (Ví dụ cột 1 chọn số 03 thì các cột tiếp theo không được chọn số 03 nữa)
4/ Tìm phương án chọn sao cho số cột được chọn là nhiều nhất: từ cột 1 đến cột n (Với n là lớn nhất có thể (n=< 100)).
5/ Chọn ra 5 phương án để có 5 nhóm số với số cột là lớn nhất có thể.
6/ Kết quả chọn: dán sang sheet(KETQUA) và dán vào dòng 2 ( nhóm số cột lớn nhất), dòng 3 (nhóm số cột lớn thứ 2), dòng 4 (nhóm số cột lớn thứ 3), dòng 5 (nhóm số cột lớn thứ 4), dòng 6 (nhóm số cột lớn thứ 5) vào số cột tương ứng.
Theo 3; 4; 5 + suy luận thì thấy: với 1 nhóm, số cột được chọn nhiều nhất là = 5
 
Theo 3; 4; 5 + suy luận thì thấy: với 1 nhóm, số cột được chọn nhiều nhất là = 5
Cảm ơn bạn đã quan tâm!
Mình xin lấy ví dụ 1 trường hợp chọn ngẫu nhiên: cột 1: 03; cột 2: 10; cột 3: 13; cột 4: 11; cột 5: 14; cột 6: 04; ..v.v.v như vậy số cột ở đây đã lớn hơn 5 và các số được chọn không bị trùng lặp.
 
Mình có một nan đề sau làm rất lâu rồi mà chưa có phương án giải quyết: dữ liệu ở sheet(DULIEU) gồm có 100 cột: số liệu trong các cột là những số trong khoảng từ 00 đến 99. Mình cần chọn ra 5 nhóm số càng nhiều số càng tốt như sau:
Yêu cầu: với mỗi một nhóm số:
1/ Trong mỗi cột chỉ được chọn 1 số.
2/ Bắt đầu Chọn từ cột 1 đầu tiên rồi lần lượt chọn đến các cột tiếp theo (không được chọn nhảy bỏ qua cột).
3/ Các số được chọn trong các cột không được trùng lặp lại. (Ví dụ cột 1 chọn số 03 thì các cột tiếp theo không được chọn số 03 nữa)
4/ Tìm phương án chọn sao cho số cột được chọn là nhiều nhất: từ cột 1 đến cột n (Với n là lớn nhất có thể (n=< 100)).
5/ Chọn ra 5 phương án để có 5 nhóm số với số cột là lớn nhất có thể.
6/ Kết quả chọn: dán sang sheet(KETQUA) và dán vào dòng 2 ( nhóm số cột lớn nhất), dòng 3 (nhóm số cột lớn thứ 2), dòng 4 (nhóm số cột lớn thứ 3), dòng 5 (nhóm số cột lớn thứ 4), dòng 6 (nhóm số cột lớn thứ 5) vào số cột tương ứng.
Mong các bạn và GPE giúp đỡ. Xin trân trọng cảm ơn!
chép code vào Module
trước khi đi ngũ, chạy code , sáng dậy hi vọng có kết quả
nếu máy yếu thì đừng hi vọng
Mã:
Sub HoanVi()
Dim Arr(), Darr(), Kq(), LT(), i As Integer, S As Integer, j As Integer, C As Integer, k As Integer, dem As Long
S = Sheets("DULIEU").UsedRange.Rows.Count - 1
C = 100
Darr = Sheets("DULIEU").Range("A2", Sheets("DULIEU").Cells(S + 1, C)).Value
ReDim Kq(1 To 5, 1 To C + 1)
ReDim Arr(1 To 4, 1 To C)
For j = 1 To C
    For i = 1 To S
        If Darr(i, j) = "" Then
            Arr(2, j) = i - 1   'so dong cot j
            Exit For
        End If
    Next i
    dk = dk & "z" & Arr(2, j)
Next j
For j = 1 To C
    Arr(1, j) = Darr(1, j):    Arr(3, j) = 1 'thu tu dòng lan truoc, cot j
Next j
i = 2
LT = LoaiTrung(Arr(), C)
Kq = ChonDong(LT, C, Kq, i)
Do
    Arr(4, C) = (Arr(3, C) Mod Arr(2, C)) + 1
    Arr(1, C) = Darr(Arr(4, C), C)
    For j = C - 1 To 1 Step -1
        For k = C To j + 1 Step -1
            If Arr(2, k) <> Arr(3, k) Then
                Arr(4, j) = Arr(3, j)
                GoTo Tiep
            End If
        Next k
        Arr(4, j) = (Arr(3, j) Mod Arr(2, j)) + 1
        Arr(1, j) = Darr(Arr(4, j), j)
Tiep:
    Next j
    For j = 1 To C
        Arr(3, j) = Arr(4, j)
    Next j
    i = i + 1
    If i > 7 Then i = 7
    LT = LoaiTrung(Arr(), C)
    Kq = ChonDong(LT, C, Kq, i)
    tmp = ""
    For j = 1 To C
        tmp = tmp & "z" & Arr(3, j)
    Next j
    dem = dem + 1  '2 dong lenh thoat khoi Sub khi khai báo so vong lap dem
    If dem = 30000 Then GoTo thoat     ' so vong lap gioi han dem = ?
Loop Until tmp = dk
thoat:
Sheets("KETQUA").Range("A2").Resize(5, C + 1) = Kq
End Sub

Function ChonDong(ST(), C As Integer, Kq(), i As Integer)
Dim Sarr(), k As Integer
Sarr = Kq
If i <= 6 Then
    For j = 1 To C + 1
        Sarr(i - 1, j) = ST(1, j)
    Next j
Else
    For k = 1 To 5
        If ST(1, C + 1) > Sarr(k, C + 1) Then
            For j = 1 To C + 1
                Sarr(k, j) = ST(1, j)
            Next j
            Exit For
        End If
    Next k
End If
ChonDong = Sarr
End Function

Function LoaiTrung(Arr(), C As Integer)
Dim Sarr(), Dic As Object, j As Integer
ReDim Sarr(1 To 1, 1 To C + 1)
Set Dic = CreateObject("scripting.dictionary")
For j = 1 To C
    If Not Dic.exists(Arr(1, j)) Then
        Dic.Add Arr(1, j), ""
        Sarr(1, j) = Arr(1, j)
        Sarr(1, C + 1) = Sarr(1, C + 1) + 1
    End If
Next j
Set Dic = Nothing
LoaiTrung = Sarr
End Function
 
Trước khi đi ngũ, chạy code sau, sáng dậy hi vọng có kết quả
nếu máy yếu thì đừng hi vọng
Mã:
Sub HoanVi()
Dim Arr(), Darr(), Kq(), LT(), i As Integer, S As Integer, j As Integer, C As Integer, k As Integer, dem As Long
S = Sheets("DULIEU").UsedRange.Rows.Count - 1
C = 100
Darr = Sheets("DULIEU").Range("A2", Sheets("DULIEU").Cells(S + 1, C)).Value
ReDim Kq(1 To 5, 1 To C + 1)
ReDim Arr(1 To 4, 1 To C)
For j = 1 To C
    For i = 1 To S
        If Darr(i, j) = "" Then
            Arr(2, j) = i - 1   'so dong cot j
            Exit For
        End If
    Next i
    dk = dk & "z" & Arr(2, j)
Next j
For j = 1 To C
    Arr(1, j) = Darr(1, j):    Arr(3, j) = 1 'thu tu dòng lan truoc, cot j
Next j
i = 2
LT = LoaiTrung(Arr(), C)
Kq = ChonDong(LT, C, Kq, i)
Do
    Arr(4, C) = (Arr(3, C) Mod Arr(2, C)) + 1
    Arr(1, C) = Darr(Arr(4, C), C)
    For j = C - 1 To 1 Step -1
        For k = C To j + 1 Step -1
            If Arr(2, k) <> Arr(3, k) Then
                Arr(4, j) = Arr(3, j)
                GoTo Tiep
            End If
        Next k
        Arr(4, j) = (Arr(3, j) Mod Arr(2, j)) + 1
        Arr(1, j) = Darr(Arr(4, j), j)
Tiep:
    Next j
    For j = 1 To C
        Arr(3, j) = Arr(4, j)
    Next j
    i = i + 1
    If i > 7 Then i = 7
    LT = LoaiTrung(Arr(), C)
    Kq = ChonDong(LT, C, Kq, i)
    tmp = ""
    For j = 1 To C
        tmp = tmp & "z" & Arr(3, j)
    Next j
    dem = dem + 1  '2 dong lenh thoat khoi Sub khi khai báo so vong lap dem
    If dem = 30000 Then GoTo thoat     ' so vong lap gioi han dem = ?
Loop Until tmp = dk
thoat:
Sheets("KETQUA").Range("A2").Resize(5, C + 1) = Kq
End Sub
Function ChonDong(ST(), C As Integer, Kq(), i As Integer)
Dim Sarr(), k As Integer
Sarr = Kq
If i <= 6 Then
    For j = 1 To C + 1
        Sarr(i - 1, j) = ST(1, j)
    Next j
Else
    For k = 1 To 5
        If ST(1, C + 1) > Sarr(k, C + 1) Then
            For j = 1 To C + 1
                Sarr(k, j) = ST(1, j)
            Next j
            Exit For
        End If
    Next k
End If
ChonDong = Sarr
End Function
Function LoaiTrung(Arr(), C As Integer)
Dim Sarr(), Dic As Object, j As Integer
ReDim Sarr(1 To 1, 1 To C + 1)
Set Dic = CreateObject("scripting.dictionary")
For j = 1 To C
    If Not Dic.exists(Arr(1, j)) Then
        Dic.Add Arr(1, j), ""
        Sarr(1, j) = Arr(1, j)
        Sarr(1, C + 1) = Sarr(1, C + 1) + 1
    End If
Next j
Set Dic = Nothing
LoaiTrung = Sarr
End Function
Dạ, cảm ơn bạn nhiều quá. Mình chạy luôn xem sao ạ!
 

File đính kèm

Sau khi mình chạy khoảng 3 phút thì có kết quả như thế này ạ! Không được như yêu cầu đưa ra, mong bạn xem giúp ạ! Xin cảm ơn rất nhiều!

Vậy thì chạy thử Sub này coi sao, Cột CW là số đếm các ô liên tiếp không trùng, Cột CX ghi số dòng của dữ liệu.
PHP:
Public Sub GPE()
Dim Sarr(), Darr(), tArr(), Tem As String
Dim i As Long, j As Long, k As Long, N As Long, MaxN As Long, C As Long, R As Long, jI As Long
With Sheets("DULIEU")
    Sarr = .Range("A1").CurrentRegion.Value
    R = UBound(Sarr): C = UBound(Sarr, 2)
End With
ReDim Darr(1 To R, 1 To C + 2)
ReDim tArr(1 To R, 1 To 1)
For i = 2 To R
    Tem = "": N = 0: MaxN = 0
    For j = 1 To C
        If InStr(Tem, Sarr(i, j) & "#") = 0 Then
            N = N + 1
            Tem = Tem & Sarr(i, j) & "#"
        Else
            If MaxN < N Then
                MaxN = N
                For jI = j - N - 1 To 1 Step -1
                    Sarr(i, jI) = Empty
                Next jI
            End If
            Tem = "": N = 0
        End If
    Next j
    tArr(i, 1) = MaxN
Next i
With Sheets("KETQUA")
    .Range("CX1").Resize(R) = tArr
    MaxN = Application.WorksheetFunction.Large(Range("CX2").Resize(R), 5)
For i = 2 To R
    If tArr(i, 1) >= MaxN Then
        k = k + 1
        For j = 1 To C
            If Sarr(i, j) <> Empty Then
                For jI = j To j + tArr(i, 1) - 1
                    Darr(k, jI) = Sarr(i, jI)
                Next jI
                Exit For
            End If
        Next j
        Darr(k, C + 1) = tArr(i, 1)
        Darr(k, C + 2) = i
    End If
Next i
    .Range("A2:CX1000").ClearContents
    .Range("A2").Resize(k, C + 2) = Darr
    .Range("A2").Resize(k, C + 2).Sort Key1:=.Range("CW2"), Order1:=xlDescending
End With
End Sub
 

File đính kèm

Vậy thì chạy thử Sub này coi sao, Cột CW là số đếm các ô liên tiếp không trùng, Cột CX ghi số dòng của dữ liệu.
PHP:
Public Sub GPE()
Dim Sarr(), Darr(), tArr(), Tem As String
Dim i As Long, j As Long, k As Long, N As Long, MaxN As Long, C As Long, R As Long, jI As Long
With Sheets("DULIEU")
    Sarr = .Range("A1").CurrentRegion.Value
    R = UBound(Sarr): C = UBound(Sarr, 2)
End With
ReDim Darr(1 To R, 1 To C + 2)
ReDim tArr(1 To R, 1 To 1)
For i = 2 To R
    Tem = "": N = 0: MaxN = 0
    For j = 1 To C
        If InStr(Tem, Sarr(i, j) & "#") = 0 Then
            N = N + 1
            Tem = Tem & Sarr(i, j) & "#"
        Else
            If MaxN < N Then
                MaxN = N
                For jI = j - N - 1 To 1 Step -1
                    Sarr(i, jI) = Empty
                Next jI
            End If
            Tem = "": N = 0
        End If
    Next j
    tArr(i, 1) = MaxN
Next i
With Sheets("KETQUA")
    .Range("CX1").Resize(R) = tArr
    MaxN = Application.WorksheetFunction.Large(Range("CX2").Resize(R), 5)
For i = 2 To R
    If tArr(i, 1) >= MaxN Then
        k = k + 1
        For j = 1 To C
            If Sarr(i, j) <> Empty Then
                For jI = j To j + tArr(i, 1) - 1
                    Darr(k, jI) = Sarr(i, jI)
                Next jI
                Exit For
            End If
        Next j
        Darr(k, C + 1) = tArr(i, 1)
        Darr(k, C + 2) = i
    End If
Next i
    .Range("A2:CX1000").ClearContents
    .Range("A2").Resize(k, C + 2) = Darr
    .Range("A2").Resize(k, C + 2).Sort Key1:=.Range("CW2"), Order1:=xlDescending
End With
End Sub
Dạ cảm ơn bạn ạ! Bạn ơi, bạn xem giúp ạ. Yêu cầu không phải là tìm ra số ô liên tiếp lớn nhất trong cùng 1 dòng ạ.
- Yêu cầu ở đây là tìm ra nhóm dữ liệu lớn nhất không trùng lặp: xuất phát từ cột 1 rồi lần lượt các cột tiếp theo, dữ liệu không bắt buộc phải ở trong cùng 1 dòng. (Giống như trò chơi: nối các dữ liệu từ cột 1 lần lượt đến các cột tiếp theo mà đường nối đi qua dữ liệu ở các cột không được trùng lặp)
 
Dạ cảm ơn bạn ạ! Bạn ơi, bạn xem giúp ạ. Yêu cầu không phải là tìm ra số ô liên tiếp lớn nhất trong cùng 1 dòng ạ.
- Yêu cầu ở đây là tìm ra nhóm dữ liệu lớn nhất không trùng lặp: xuất phát từ cột 1 rồi lần lượt các cột tiếp theo, dữ liệu không bắt buộc phải ở trong cùng 1 dòng. (Giống như trò chơi: nối các dữ liệu từ cột 1 lần lượt đến các cột tiếp theo mà đường nối đi qua dữ liệu ở các cột không được trùng lặp)

Chưa hiểu lắm. Chờ mò để hiểu đã.
Kết quả chỉ xét trên cùng 1 dòng không có dữ liệu trùng hay xét trong từng cột cũng không trùng? Hay cả bảng kết quả không có dữ liệu trùng?
 

File đính kèm

Lần chỉnh sửa cuối:
Chưa hiểu lắm. Chờ mò để hiểu đã.
Hình như là thề này:
Lựa lấy cột A 1 số, tới cột B 1 số....tới cột thứ 100 (cột nào hổng chọn được thì bỏ qua), tạo thành một nhóm có số số hạng nhiều nhất (nhỏ hơn hoặc bằng 100) và không trùng
Sau đó tìm nhiều thứ 2, 3, 4, 5
Nếu đúng thế thì bài này....khó "thấy bà"
Híc
 
Lần chỉnh sửa cuối:
Hình như là thề này:
Lựa lấy cột A 1 số, tới cột B 1 số....tới cột thứ 100 (cột nào hổng chọn được thì bỏ qua), tạo thành một nhóm có số số hạng nhiều nhất (nhỏ hơn hoặc bằng 100) và không trùng
Sau đó tìm nhiều thứ 2, 3, 4, 5
Nếu đúng thế thì bài này....khó "thấy bà"
Híc
Dạ đúng rồi ạ. Nên đây là một nan đề ạ. Rất mong được sự giúp đỡ của GPE ạ!
 
Chưa hiểu lắm. Chờ mò để hiểu đã.
Kết quả chỉ xét trên cùng 1 dòng không có dữ liệu trùng hay xét trong từng cột cũng không trùng? Hay cả bảng kết quả không có dữ liệu trùng?
Dạ, đúng như bạn làm rồi đó ạ. Mình đang kiểm tra lại ạ! Xin cảm ơn nhiều quá.
Bạn ơi, cho mình hỏi thêm chút ạ. Nếu muốn tăng thêm kết quả, không phải 5 nhóm nữa mà là 10 nhóm thì làm thế nào ạ? Xin cảm ơn rất nhiều!
 
Lần chỉnh sửa cuối:
Sau khi mình chạy khoảng 3 phút thì có kết quả như thế này ạ! Không được như yêu cầu đưa ra, mong bạn xem giúp ạ! Xin cảm ơn rất nhiều!
chỉ chạy 3 phút, làm sao ra được kết quả, chỉ mới duyệt qua 30000 khả năng thôi, còn số khả năng còn lại chưa xét rất lớn, chạy nguyên một đêm mới hi vọng xét hết
 
Thầy Ba Tê chú í: Thầy Cò Già fát biểu sai 1 mệnh đề:

Mình có một nan đề sau làm rất lâu rồi mà chưa có phương án giải quyết: dữ liệu ở sheet(DULIEU) gồm có 100 cột: số liệu trong các cột là những số trong khoảng từ 00 đến 99. Mình cần chọn ra 5 nhóm số càng nhiều số càng tốt như sau:
Yêu cầu: với mỗi một nhóm số:
1/ Trong mỗi cột chỉ được chọn 1 số.
2/ Bắt đầu Chọn từ cột 1 đầu tiên rồi lần lượt chọn đến các cột tiếp theo (không được chọn nhảy bỏ qua cột).
3/ Các số được chọn trong các cột không được trùng lặp lại. (Ví dụ cột 1 chọn số 03 thì các cột tiếp theo không được chọn số 03 nữa)
4/ Tìm phương án chọn sao cho số cột được chọn là nhiều nhất: từ cột 1 đến cột n (Với n là lớn nhất có thể (n=< 100)).
5/ Chọn ra 5 phương án để có 5 nhóm số với số cột là lớn nhất có thể.
6/ Kết quả chọn: dán sang sheet(KETQUA) và dán vào dòng 2 ( nhóm số cột lớn nhất), dòng 3 (nhóm số cột lớn thứ 2), dòng 4 (nhóm số cột lớn thứ 3), dòng 5 (nhóm số cột lớn thứ 4), dòng 6 (nhóm số cột lớn thứ 5) vào số cột tương ứng.

%#^#$ %#^#$ %#^#$ -=.,, -=.,, -=.,, -+*/ -+*/ -+*/
 
chỉ chạy 3 phút, làm sao ra được kết quả, chỉ mới duyệt qua 30000 khả năng thôi, còn số khả năng còn lại chưa xét rất lớn, chạy nguyên một đêm mới hi vọng xét hết
bạn bỏ 2 dòng ghi chú lệnh đếm, để duyệt qua tất cả khả năng
 
bạn bỏ 2 dòng ghi chú lệnh đếm, để duyệt qua tất cả khả năng
Vâng bạn ơi. Cụ Thể là xoá bỏ đi cả 2 dòng này đi đúng không ạ:
dem = dem + 1 '2 dong lenh thoat khoi Sub khi khai báo so vong lap dem If dem = 30000 Then GoTo thoat ' so vong lap gioi han dem = ?
 
Mình có í tưởng này:

Trong bảng có 100 số với tần suất xuất hiện khác nhau.
Cái nào ít xuất hiện nhất thì nên chọn.

Cụ thể các bước fải trãi qua, theo mình như sau"

1./ Lập bảng thống kê tần suất xuất hiện các con số từ 0..99
2./ Copy lần lượt từng cột ra 1 chổ trống trãi; & dùng hàm VLOOKUP() để gắn tần suất của các số trong cột đang trích xuất
3./ Xếp theo thứ tự tăng dần của tần suất;
4./ Sau khi xếp ta lại copy cột này bỏ lại CSDL
5./ Tiến hành chọn chuỗi lần lượt qua từng cột;
Trong mỗi cột, nếu giá trị trên trùng thì ta dò tiếp ngay giá trị dưới nó (trong cột)
 
Vâng bạn ơi. Cụ Thể là xoá bỏ đi cả 2 dòng này đi đúng không ạ:
dem = dem + 1 '2 dong lenh thoat khoi Sub khi khai báo so vong lap dem If dem = 30000 Then GoTo thoat ' so vong lap gioi han dem = ?
đúng rồi bạn nhập nháy đơn trước dòng 2 dòng lệnh để nó không thực thi
'dem = dem + 1 '2 dong lenh thoat khoi Sub khi khai báo so vong lap dem
'If dem = 30000 Then GoTo thoat ' so vong lap gioi han dem = ?
code chạy rất lâu, khi ra kết quả sẽ chính xác
còn bạn muốn chạy nhanh hơn thì dùng code sau, nhưng không đảm bảo đúng 100%, có thể bỏ sót một số khả năng số cột chọn lớn hơn
Mã:
Sub Loc_Cot()
Dim Dic As Object, Arr(), Darr(), Kq(), i As Integer, S As Integer, j As Integer
Dim C As Integer, k As Integer, dong As Integer, dkq As Integer, jk As Integer
Set Dic = CreateObject("scripting.dictionary")
S = Sheets("DULIEU").UsedRange.Rows.Count - 1
C = 100
dkq = 6 'khai báo so dòng ket qua theo ý
Darr = Sheets("DULIEU").Range("A2", Sheets("DULIEU").Cells(S + 1, C)).Value
ReDim Arr(1 To 2, 1 To C + 1):  ReDim Kq(1 To dkq, 1 To C + 1)
For j = 1 To C
    [COLOR=#ff0000]Arr(2, j) = S[/COLOR]
    For i = 1 To S
        If Darr(i, j) = "" Then
            Arr(2, j) = i - 1:       Exit For
        End If
    Next i
Next j
For k = 1 To 100
    For i = 1 To Arr(2, k)
        Dic.RemoveAll:    Arr(1, C + 1) = 0
        Dic.Add Darr(i, k), ""
        Arr(1, k) = Darr(i, k)
        Arr(1, C + 1) = Arr(1, C + 1) + 1
        For jk = 2 To 100
            j = jk:            If jk = k Then j = 1
            For n = 1 To Arr(2, j)
                If Not Dic.exists(Darr(n, j)) Then
                    Dic.Add Darr(n, j), ""
                    Arr(1, j) = Darr(n, j)
                    Arr(1, C + 1) = Arr(1, C + 1) + 1
                    Exit For
                End If
            Next n
        Next jk
        dong = dong + 1: If dong > dkq + 1 Then dong = dkq + 1
        Kq = ChonDong(Arr, C, Kq, dong, dkq)
    Next i
Next k
Sheets("KETQUA").Range("A2").Resize(dkq, C + 1) = Kq
Set Dic = Nothing
End Sub

Function ChonDong(ST(), C As Integer, Kq(), i As Integer, dkq)
Dim Sarr(), k As Integer
Sarr = Kq
If i <= dkq Then
    For j = 1 To C + 1
        Sarr(i, j) = ST(1, j)
    Next j
Else
    For k = 1 To dkq
        If ST(1, C + 1) > Sarr(k, C + 1) Then
            For j = 1 To C + 1
                Sarr(k, j) = ST(1, j)
            Next j
            Exit For
        End If
    Next k
End If
ChonDong = Sarr
End Function
 
Lần chỉnh sửa cuối:
code thiếu 1 dòng lệnh màu đỏ bạn chỉnh lại
Mã:
Sub Loc_Cot()
Dim Dic As Object, Arr(), Darr(), Kq(), i As Integer, S As Integer, j As Integer
Dim C As Integer, k As Integer, dong As Integer, dkq As Integer, jk As Integer
Set Dic = CreateObject("scripting.dictionary")
S = Sheets("DULIEU").UsedRange.Rows.Count - 1
C = 100
dkq = 6 'khai báo so dòng ket qua theo ý
Darr = Sheets("DULIEU").Range("A2", Sheets("DULIEU").Cells(S + 1, C)).Value
ReDim Arr(1 To 2, 1 To C + 1):  ReDim Kq(1 To dkq, 1 To C + 1)
For j = 1 To C
     [COLOR=#FF0000]Arr(2, j) = S[/COLOR]
    For i = 1 To S[COLOR=#ff0000]        [/COLOR]
        If Darr(i, j) = "" Then
            Arr(2, j) = i - 1:       Exit For
        End If
    Next i
Next j
For k = 1 To C
    For i = 1 To Arr(2, k)
        Dic.RemoveAll:    Arr(1, C + 1) = 0
        Dic.Add Darr(i, k), ""
        Arr(1, k) = Darr(i, k)
        Arr(1, C + 1) = Arr(1, C + 1) + 1
        For jk = 2 To 100
            j = jk:            If jk = k Then j = 1
            For n = 1 To Arr(2, j)
                If Not Dic.exists(Darr(n, j)) Then
                    Dic.Add Darr(n, j), ""
                    Arr(1, j) = Darr(n, j)
                    Arr(1, C + 1) = Arr(1, C + 1) + 1
                    Exit For
                End If
            Next n
        Next jk
        dong = dong + 1: If dong > dkq + 1 Then dong = dkq + 1
        Kq = ChonDong(Arr, C, Kq, dong, dkq)
    Next i
Next k
Sheets("KETQUA").Range("A2").Resize(dkq, C + 1) = Kq
Set Dic = Nothing
End Sub
Function ChonDong(ST(), C As Integer, Kq(), i As Integer, dkq)
Dim Sarr(), k As Integer
Sarr = Kq
If i <= dkq Then
    For j = 1 To C + 1
        Sarr(i, j) = ST(1, j)
    Next j
Else
    For k = 1 To dkq
        If ST(1, C + 1) > Sarr(k, C + 1) Then
            For j = 1 To C + 1
                Sarr(k, j) = ST(1, j)
            Next j
            Exit For
        End If
    Next k
End If
ChonDong = Sarr
End Function
 
Lần chỉnh sửa cuối:
Dạ, đúng như bạn làm rồi đó ạ. Mình đang kiểm tra lại ạ! Xin cảm ơn nhiều quá.
Bạn ơi, cho mình hỏi thêm chút ạ. Nếu muốn tăng thêm kết quả, không phải 5 nhóm nữa mà là 10 nhóm thì làm thế nào ạ? Xin cảm ơn rất nhiều!

Nguyên tắc: Vị trí nào trong mỗi cột đã được lấy vào 1 nhóm nào đó thì ở nhóm khác không lấy vị trí đó nữa.
Bạn thay đổi số dòng (Tôi có ghi chú trong Sub), 10 dòng thì thay 5 bằng số 10.
Kiểm tra kết quả rồi "la lên" nhé. Im ru chẳng biết đúng sai mà lần.
PHP:
Public Sub GPE()
Dim Dic As Object, sArr(), dArr(), tArr(), Tem As String, DK As Boolean
Dim I As Long, J As Long, K As Long, N As Long, MaxN As Long, C As Long, R As Long, Col As Long
Set Dic = CreateObject("Scripting.Dictionary")
With Sheets("DULIEU")
    sArr = .Range("A1").CurrentRegion.Value
    R = UBound(sArr): C = UBound(sArr, 2)
End With
ReDim dArr(1 To R * C, 1 To C + 2)
ReDim tArr(1 To R, 1 To C + 1)
For I = 2 To R
    K = K + 1
    Col = 0
    Dic.RemoveAll
    For J = 1 To C
        DK = False
        For N = 2 To R
            If sArr(N, J) <> Empty Then
                Tem = sArr(N, J)
                If Not Dic.Exists(Tem) Then
                    Dic.Add Tem, ""
                    Col = Col + 1
                    tArr(K, Col) = Tem
                    sArr(N, J) = Empty              '<----------------Xoa vi tri da lay'
                    DK = True
                    Exit For
                End If
            End If
        Next N
        If DK = False Then Exit For
    Next J
    tArr(K, 101) = Col
Next I
With Sheets("KETQUA")
    .Range("A2").Resize(100, 101).ClearContents
    .Range("A2").Resize(K, 101) = tArr
    .Range("A2").Resize(K, 101).Sort Key1:=.Range("CW2"), Order1:=xlDescending
    .Range("A2").Offset(5).Resize(K, 101).ClearContents '<--------Thay so 5 thanh so 10'
End With
Set Dic = Nothing
End Sub
 
Lần chỉnh sửa cuối:
Nguyên tắc: Vị trí nào trong mỗi cột đã được lấy vào 1 nhóm nào đó thì ở nhóm khác không lấy vị trí đó nữa.
Bạn thay đổi số dòng (Tôi có ghi chú trong Sub), 10 dòng thì thay 5 bằng số 10.
Kiểm tra kết quả rồi "la lên" nhé. Im ru chẳng biết đúng sai mà lần.
PHP:
Public Sub GPE()
Dim Dic As Object, sArr(), dArr(), tArr(), Tem As String, DK As Boolean
Dim I As Long, J As Long, K As Long, N As Long, MaxN As Long, C As Long, R As Long, Col As Long
Set Dic = CreateObject("Scripting.Dictionary")
With Sheets("DULIEU")
    sArr = .Range("A1").CurrentRegion.Value
    R = UBound(sArr): C = UBound(sArr, 2)
End With
ReDim dArr(1 To R * C, 1 To C + 2)
ReDim tArr(1 To R, 1 To C + 1)
For I = 2 To R
    K = K + 1
    Col = 0
    Dic.RemoveAll
    For J = 1 To C
        DK = False
        For N = 2 To R
            If sArr(N, J) <> Empty Then
                Tem = sArr(N, J)
                If Not Dic.Exists(Tem) Then
                    Dic.Add Tem, ""
                    Col = Col + 1
                    tArr(K, Col) = Tem
                    sArr(N, J) = Empty              '<----------------Xoa vi tri da lay'
                    DK = True
                    Exit For
                End If
            End If
        Next N
        If DK = False Then Exit For
    Next J
    tArr(K, 101) = Col
Next I
With Sheets("KETQUA")
    .Range("A2").Resize(100, 101).ClearContents
    .Range("A2").Resize(K, 101) = tArr
    .Range("A2").Resize(K, 101).Sort Key1:=.Range("CW2"), Order1:=xlDescending
    .Range("A2").Offset(5).Resize(K, 101).ClearContents '<--------Thay so 5 thanh so 10'
End With
Set Dic = Nothing
End Sub
Mình kiểm tra lại những trường hợp ra kết quả thấy đúng bạn ạ. Nhưng cách này bỏ nhiều trường hợp quá. Nhưng cũng xin cảm ơn bạn rất nhiều!
 
đúng rồi bạn nhập nháy đơn trước dòng 2 dòng lệnh để nó không thực thi
'dem = dem + 1 '2 dong lenh thoat khoi Sub khi khai báo so vong lap dem
'If dem = 30000 Then GoTo thoat ' so vong lap gioi han dem = ?
code chạy rất lâu, khi ra kết quả sẽ chính xác
còn bạn muốn chạy nhanh hơn thì dùng code sau, nhưng không đảm bảo đúng 100%, có thể bỏ sót một số khả năng số cột chọn lớn hơn
Mã:
Sub Loc_Cot()
Dim Dic As Object, Arr(), Darr(), Kq(), i As Integer, S As Integer, j As Integer
Dim C As Integer, k As Integer, dong As Integer, dkq As Integer, jk As Integer
Set Dic = CreateObject("scripting.dictionary")
S = Sheets("DULIEU").UsedRange.Rows.Count - 1
C = 100
dkq = 6 'khai báo so dòng ket qua theo ý
Darr = Sheets("DULIEU").Range("A2", Sheets("DULIEU").Cells(S + 1, C)).Value
ReDim Arr(1 To 2, 1 To C + 1):  ReDim Kq(1 To dkq, 1 To C + 1)
For j = 1 To C
    [COLOR=#ff0000]Arr(2, j) = S[/COLOR]
    For i = 1 To S
        If Darr(i, j) = "" Then
            Arr(2, j) = i - 1:       Exit For
        End If
    Next i
Next j
For k = 1 To 100
    For i = 1 To Arr(2, k)
        Dic.RemoveAll:    Arr(1, C + 1) = 0
        Dic.Add Darr(i, k), ""
        Arr(1, k) = Darr(i, k)
        Arr(1, C + 1) = Arr(1, C + 1) + 1
        For jk = 2 To 100
            j = jk:            If jk = k Then j = 1
            For n = 1 To Arr(2, j)
                If Not Dic.exists(Darr(n, j)) Then
                    Dic.Add Darr(n, j), ""
                    Arr(1, j) = Darr(n, j)
                    Arr(1, C + 1) = Arr(1, C + 1) + 1
                    Exit For
                End If
            Next n
        Next jk
        dong = dong + 1: If dong > dkq + 1 Then dong = dkq + 1
        Kq = ChonDong(Arr, C, Kq, dong, dkq)
    Next i
Next k
Sheets("KETQUA").Range("A2").Resize(dkq, C + 1) = Kq
Set Dic = Nothing
End Sub

Function ChonDong(ST(), C As Integer, Kq(), i As Integer, dkq)
Dim Sarr(), k As Integer
Sarr = Kq
If i <= dkq Then
    For j = 1 To C + 1
        Sarr(i, j) = ST(1, j)
    Next j
Else
    For k = 1 To dkq
        If ST(1, C + 1) > Sarr(k, C + 1) Then
            For j = 1 To C + 1
                Sarr(k, j) = ST(1, j)
            Next j
            Exit For
        End If
    Next k
End If
ChonDong = Sarr
End Function
Với trường hợp nhanh hơn thì đúng là vẫn bỏ sót nhiều trường hợp và có kết quả ở 2 nhóm vẫn giống hệt nhau. Còn code ban đầu thì đúng là mình chạy cả buổi tối mà không xong. Trong khi cấu hình máy cũng khá mạnh (core i7, 2.4Gh). Không biết bạn có biện pháp nào tăng tốc độ nhanh hơn được không ạ. Xin cảm ơn bạn nhiều!
 
bạn chạy code mới, khai báo số nguyên dương vào code để chạy theo ý bạn, chạy càng lâu thì bỏ sót càng ít
code chạy ngẫu nhiên nên mỗi lần chạy có thể kết quả khác nhau
đã loại trừ trùng lập
do ngẫu nhiên nên cũng không biết bỏ sót hay không
Mã:
Sub Loc_Cot()
Dim Dic As Object, DicKQ As Object, tmp As String, Arr(), Darr(), Kq(), i As Integer, j As Integer, n As Integer
Dim C As Integer, k As Integer, dong As Integer, Dkq As Integer, jk As Integer, MinC As Integer, S As Byte, Lap As Byte
Set Dic = CreateObject("scripting.dictionary")
Set DicKQ = CreateObject("scripting.dictionary")
C = 100:     MinC = 150
k = Sheets("DULIEU").UsedRange.Rows.Count - 1
Dkq = 300 'khai báo Dkq, so dòng ket qua theo ý
Lap = 10   'khai báo Lap, càng lon chay càng lau và ít bo sot ket qua
Darr = Sheets("DULIEU").Range("A2", Sheets("DULIEU").Cells(k + 2, C)).Value
ReDim Arr(1 To 2, 1 To C + 1):  ReDim Kq(1 To Dkq, 1 To C + 1)
For j = 1 To C
    For i = 1 To k + 1
        If Darr(i, j) = "" Then
            Arr(2, j) = i - 1:       Exit For
        End If
    Next i
Next j
For S = 1 To Lap
  For k = 1 To 100
    For i = 1 To Arr(2, k)
        Dic.RemoveAll:    Arr(1, C + 1) = 0
        Dic.Add Darr(i, k), ""
        Arr(1, k) = Darr(i, k)
        Arr(1, C + 1) = Arr(1, C + 1) + 1
        For jk = 2 To 100
            j = jk:            If jk = k Then j = 1
            For n = 1 To Arr(2, j)
                If Not Dic.exists(Darr(n, j)) Then
                    Dic.Add Darr(n, j), ""
                    Arr(1, j) = Darr(n, j)
                    Arr(1, C + 1) = Arr(1, C + 1) + 1
                    Exit For
                End If
            Next n
        Next jk
        tmp = ""
        For j = 1 To C
          tmp = tmp & "z" & Arr(1, j)
        Next j
        If Not DicKQ.exists(tmp) Then
          DicKQ.Add tmp, ""
        Else
          GoTo Tiep
        End If
        If dong < Dkq Then
            dong = dong + 1
            For j = 1 To C + 1
                Kq(dong, j) = Arr(1, j)
            Next j
            If MinC > Arr(1, C + 1) Then MinC = Arr(1, C + 1)
        Else
            If Arr(1, C + 1) > MinC Then
              For n = 1 To Dkq
                If Kq(n, C + 1) = MinC Then
                  For j = 1 To C + 1
                    Kq(n, j) = Arr(1, j)
                  Next j
                  Exit For
                End If
              Next n
              MinC = 150
              For n = 1 To Dkq
                If MinC > Kq(n, C + 1) Then MinC = Kq(n, C + 1)
              Next n
            End If
        End If
Tiep:
    Next i
  Next k
  Darr = NgauNhien(Darr, Arr, C)
Next S
Sheets("KETQUA").Range("A2:CW2000").ClearContents
Sheets("KETQUA").Range("A2").Resize(Dkq, C + 1) = Kq
Set Dic = Nothing:    Set DicKQ = Nothing
End Sub


Function NgauNhien(Darr(), Arr(), C)
Dim Dic As Object, tmp As Integer, Sarr(), i As Integer, j As Integer, k As Integer
Set Dic = CreateObject("scripting.dictionary")
ReDim Sarr(1 To UBound(Darr), 1 To UBound(Darr, 2))
For j = 1 To C
    For i = 1 To k + 1
        If Darr(i, j) = "" Then
            Arr(2, j) = i - 1:       Exit For
        End If
    Next i
Next j
For j = 1 To C
  Dic.RemoveAll:  k = 0
  Do
    tmp = Int((Arr(2, j) * Rnd) + 1)
    If Not Dic.exists(tmp) Then
      k = k + 1:  Dic.Add tmp, ""
      Sarr(k, j) = Darr(tmp, j)
    End If
  Loop Until k = Arr(2, j)
Next j
NgauNhien = Sarr
Set Dic = Nothing
End Function
 

File đính kèm

bạn chạy code mới, khai báo số nguyên dương vào code để chạy theo ý bạn, chạy càng lâu thì bỏ sót càng ít
code chạy ngẫu nhiên nên mỗi lần chạy có thể kết quả khác nhau
đã loại trừ trùng lập
do ngẫu nhiên nên cũng không biết bỏ sót hay không
Mã:
Sub Loc_Cot()
Dim Dic As Object, DicKQ As Object, tmp As String, Arr(), Darr(), Kq(), i As Integer, j As Integer, n As Integer
Dim C As Integer, k As Integer, dong As Integer, Dkq As Integer, jk As Integer, MinC As Integer, S As Byte, Lap As Byte
Set Dic = CreateObject("scripting.dictionary")
Set DicKQ = CreateObject("scripting.dictionary")
C = 100:     MinC = 150
k = Sheets("DULIEU").UsedRange.Rows.Count - 1
Dkq = 300 'khai báo Dkq, so dòng ket qua theo ý
Lap = 10   'khai báo Lap, càng lon chay càng lau và ít bo sot ket qua
Darr = Sheets("DULIEU").Range("A2", Sheets("DULIEU").Cells(k + 2, C)).Value
ReDim Arr(1 To 2, 1 To C + 1):  ReDim Kq(1 To Dkq, 1 To C + 1)
For j = 1 To C
    For i = 1 To k + 1
        If Darr(i, j) = "" Then
            Arr(2, j) = i - 1:       Exit For
        End If
    Next i
Next j
For S = 1 To Lap
  For k = 1 To 100
    For i = 1 To Arr(2, k)
        Dic.RemoveAll:    Arr(1, C + 1) = 0
        Dic.Add Darr(i, k), ""
        Arr(1, k) = Darr(i, k)
        Arr(1, C + 1) = Arr(1, C + 1) + 1
        For jk = 2 To 100
            j = jk:            If jk = k Then j = 1
            For n = 1 To Arr(2, j)
                If Not Dic.exists(Darr(n, j)) Then
                    Dic.Add Darr(n, j), ""
                    Arr(1, j) = Darr(n, j)
                    Arr(1, C + 1) = Arr(1, C + 1) + 1
                    Exit For
                End If
            Next n
        Next jk
        tmp = ""
        For j = 1 To C
          tmp = tmp & "z" & Arr(1, j)
        Next j
        If Not DicKQ.exists(tmp) Then
          DicKQ.Add tmp, ""
        Else
          GoTo Tiep
        End If
        If dong < Dkq Then
            dong = dong + 1
            For j = 1 To C + 1
                Kq(dong, j) = Arr(1, j)
            Next j
            If MinC > Arr(1, C + 1) Then MinC = Arr(1, C + 1)
        Else
            If Arr(1, C + 1) > MinC Then
              For n = 1 To Dkq
                If Kq(n, C + 1) = MinC Then
                  For j = 1 To C + 1
                    Kq(n, j) = Arr(1, j)
                  Next j
                  Exit For
                End If
              Next n
              MinC = 150
              For n = 1 To Dkq
                If MinC > Kq(n, C + 1) Then MinC = Kq(n, C + 1)
              Next n
            End If
        End If
Tiep:
    Next i
  Next k
  Darr = NgauNhien(Darr, Arr, C)
Next S
Sheets("KETQUA").Range("A2:CW2000").ClearContents
Sheets("KETQUA").Range("A2").Resize(Dkq, C + 1) = Kq
Set Dic = Nothing:    Set DicKQ = Nothing
End Sub


Function NgauNhien(Darr(), Arr(), C)
Dim Dic As Object, tmp As Integer, Sarr(), i As Integer, j As Integer, k As Integer
Set Dic = CreateObject("scripting.dictionary")
ReDim Sarr(1 To UBound(Darr), 1 To UBound(Darr, 2))
For j = 1 To C
    For i = 1 To k + 1
        If Darr(i, j) = "" Then
            Arr(2, j) = i - 1:       Exit For
        End If
    Next i
Next j
For j = 1 To C
  Dic.RemoveAll:  k = 0
  Do
    tmp = Int((Arr(2, j) * Rnd) + 1)
    If Not Dic.exists(tmp) Then
      k = k + 1:  Dic.Add tmp, ""
      Sarr(k, j) = Darr(tmp, j)
    End If
  Loop Until k = Arr(2, j)
Next j
NgauNhien = Sarr
Set Dic = Nothing
End Function
Cảm ơn bạn nhiều quá. Chuẩn lắm bạn ạ không biết nói gì hơn! Không biết code này của bạn có thể điều chỉnh đi một chút không thì tuyệt vời:
* Có 2 phương án điều chỉnh:
- Phương án ưu tiên số 1: chẳng hạn Sheet(DULIEU) có 400 cột: tìm nhóm số liệu để 80 cột đầu tiên là 80 số bất kì khác nhau không trùng lặp, sau đó tiếp tục xét tiếp đến 80 cột tiếp theo: cũng tìm ra nhóm số không trùng lặp như nhóm đầu nhưng nằm trong phạm vi 80 số đầu tiên đã tìm được (ví dụ 80 cột đầu tiên tìm ra nhóm 80 số từ 01 đến 80 thì nhóm 80 cột tiếp theo này cũng chỉ tìm nhóm số không trùng lặp trong phạm vi từ 01 đến 80). Cứ như vậy xét 80 cột tiếp theo cho đến khi không thoả mãn nữa thì dừng lại. Các kết quả được dán vào sheet(KETQUA).
- Phương án 2: Sheet(DULIEU) có 400 cột: tìm nhóm số liệu 80 số với số cột lớn nhất (mỗi cột chỉ được chọn 1 số - nên mỗi số có thể xuất hiện nhiều lần, cho phép số được chọn ở các cột có thể trùng lặp lại- ví dụ cột 1 chọn số 02 thì cột khác vẫn có thể chọn lại số 02,...). Các kết quả được dán vào sheet(KETQUA).
* Mong bạn xem giúp thì cảm ơn nhiều quá! Một lần nữa xin chân thành cảm ơn bạn!
 
Cảm ơn bạn nhiều quá. Chuẩn lắm bạn ạ không biết nói gì hơn! Không biết code này của bạn có thể điều chỉnh đi một chút không thì tuyệt vời:
* Có 2 phương án điều chỉnh:
- Phương án ưu tiên số 1: chẳng hạn Sheet(DULIEU) có 400 cột: tìm nhóm số liệu để 80 cột đầu tiên là 80 số bất kì khác nhau không trùng lặp, sau đó tiếp tục xét tiếp đến 80 cột tiếp theo: cũng tìm ra nhóm số không trùng lặp như nhóm đầu nhưng nằm trong phạm vi 80 số đầu tiên đã tìm được (ví dụ 80 cột đầu tiên tìm ra nhóm 80 số từ 01 đến 80 thì nhóm 80 cột tiếp theo này cũng chỉ tìm nhóm số không trùng lặp trong phạm vi từ 01 đến 80). Cứ như vậy xét 80 cột tiếp theo cho đến khi không thoả mãn nữa thì dừng lại. Các kết quả được dán vào sheet(KETQUA).
- Phương án 2: Sheet(DULIEU) có 400 cột: tìm nhóm số liệu 80 số với số cột lớn nhất (mỗi cột chỉ được chọn 1 số - nên mỗi số có thể xuất hiện nhiều lần, cho phép số được chọn ở các cột có thể trùng lặp lại- ví dụ cột 1 chọn số 02 thì cột khác vẫn có thể chọn lại số 02,...). Các kết quả được dán vào sheet(KETQUA).
* Mong bạn xem giúp thì cảm ơn nhiều quá! Một lần nữa xin chân thành cảm ơn bạn!
bạn tạo file có dữ liệu gần giống thực tế, để mình dể kiểm tra kết quả và chỉnh code
 
Dạ, cảm ơn bạn nhiều. Đây là file thực tế đây ạ!
bạn xem lại dữ liệu, không tìm được dòng nào thỏa điều kiện, nên sheet ketqua không có gì
sheet1 lưu kết quả lọc không trùng của 5 nhóm
Mã:
Dim Dkq As Integer, Lap As Byte
Sub Main()
Dim Darr(), kq1(), kq2(), kq3(), kq4(), kq5(), Skq(), tmp As String
Dim Dic2 As Object, Dic3 As Object, Dic4 As Object, Dic5 As Object
Dim Sr As Integer, i As Integer, k As Integer, C As Byte, n As Byte, j As Byte
Set Dic = CreateObject("scripting.dictionary")
Set Dic2 = CreateObject("scripting.dictionary")
Set Dic3 = CreateObject("scripting.dictionary")
Set Dic4 = CreateObject("scripting.dictionary")
Set Dic5 = CreateObject("scripting.dictionary")
C = 80
Dkq = 1000 'khai báo Dkq, so dòng ket qua theo ý
Lap = 10   'khai báo Lap, càng lon chay càng lau và ít bo sot ket qua
Sr = Sheets("DULIEU").UsedRange.Rows.Count
ReDim Skq(1 To 1, 1 To C)
For n = 1 To 5
  Darr = Sheets("DULIEU").Cells(2, (n - 1) * C + 1).Resize(Sr, C).Value
  If n = 1 Then
    kq1 = LocCot(Darr(), C)
    Sheets("Sheet1").Cells(2, (n - 1) * C + 1).Resize(Dkq, C) = kq1
  ElseIf n = 2 Then
    kq2 = LocCot(Darr(), C)
    For i = 1 To Dkq
      For j = 1 To C
        Skq(1, j) = Format(kq2(i, j), "00")
      Next j
      tmp = SortArrToStr(Skq, "z")
      Dic2.Add tmp, i
    Next i
    Sheets("Sheet1").Cells(2, (n - 1) * C + 1).Resize(Dkq, C) = kq2
  ElseIf n = 3 Then
    kq3 = LocCot(Darr(), C)
    For i = 1 To Dkq
      For j = 1 To C
        Skq(1, j) = Format(kq3(i, j), "00")
      Next j
      tmp = SortArrToStr(Skq, "z")
      Dic3.Add tmp, i
    Next i
    Sheets("Sheet1").Cells(2, (n - 1) * C + 1).Resize(Dkq, C) = kq3
  ElseIf n = 4 Then
    kq4 = LocCot(Darr(), C)
    For i = 1 To Dkq
      For j = 1 To C
        Skq(1, j) = Format(kq4(i, j), "00")
      Next j
      tmp = SortArrToStr(Skq, "z")
      Dic4.Add tmp, i
    Next i
    Sheets("Sheet1").Cells(2, (n - 1) * C + 1).Resize(Dkq, C) = kq4
  Else
    kq5 = LocCot(Darr(), C)
    For i = 1 To Dkq
      For j = 1 To C
        Skq(1, j) = Format(kq5(i, j), "00")
      Next j
      tmp = SortArrToStr(Skq, "z")
      Dic5.Add tmp, i
    Next i
    Sheets("Sheet1").Cells(2, (n - 1) * C + 1).Resize(Dkq, C) = kq5
  End If
Next n


ReDim Darr(1 To Dkq, 1 To C * 5)
k = 0
For i = 1 To Dkq
  For j = 1 To C
    Skq(1, j) = Format(kq1(i, j), "00")
  Next j
  tmp = SortArrToStr(Skq, "z")
  If Dic2.exists(tmp) Or Dic3.exists(tmp) Or Dic4.exists(tmp) Or Dic5.exists(tmp) Then
    k = k + 1
    For j = 1 To C
      Darr(k, j) = kq1(i, j)
      If Dic2.exists(tmp) Then Darr(k, j + 80 * 1) = kq2(Dic2.Item(tmp), j)
      If Dic3.exists(tmp) Then Darr(k, j + 80 * 2) = kq3(Dic3.Item(tmp), j)
      If Dic4.exists(tmp) Then Darr(k, j + 80 * 3) = kq4(Dic4.Item(tmp), j)
      If Dic5.exists(tmp) Then Darr(k, j + 80 * 4) = kq5(Dic5.Item(tmp), j)
    Next j
  End If
Next i
Set Dic = Nothing:  Set Dic2 = Nothing:  Set Dic3 = Nothing:  Set Dic4 = Nothing: Set Dic5 = Nothing
Sheets("KETQUA").Range("A2").Resize(2000, 400).ClearContents
If k > 0 Then Sheets("KETQUA").Range("A2").Resize(k, 400) = Darr
End Sub


Function LocCot(Darr(), C As Byte)
Dim Dic As Object, DicKQ As Object, tmp As String, Arr(), Kq(), i As Integer, j As Integer, n As Integer
Dim k As Integer, dong As Long, jk As Integer, MinC As Integer, S As Byte
Set Dic = CreateObject("scripting.dictionary")
Set DicKQ = CreateObject("scripting.dictionary")
ReDim Arr(1 To 2, 1 To C + 1):  ReDim Kq(1 To Dkq, 1 To C + 1)
For j = 1 To C
    For i = 1 To UBound(Darr) + 1
        If Darr(i, j) = "" Then
            Arr(2, j) = i - 1:       Exit For
        End If
    Next i
Next j
For S = 1 To Lap
  For k = 1 To C
    For i = 1 To Arr(2, k)
        Dic.RemoveAll:    Arr(1, C + 1) = 0
        Dic.Add Darr(i, k), ""
        Arr(1, k) = Darr(i, k)
        Arr(1, C + 1) = Arr(1, C + 1) + 1
        For jk = 2 To C
            j = jk:            If jk = k Then j = 1
            For n = 1 To Arr(2, j)
                If Not Dic.exists(Darr(n, j)) Then
                    Dic.Add Darr(n, j), ""
                    Arr(1, j) = Darr(n, j)
                    Arr(1, C + 1) = Arr(1, C + 1) + 1
                    Exit For
                End If
            Next n
            If Arr(1, C + 1) < jk Then GoTo Tiep
        Next jk
        tmp = SortArrToStr(Arr, "z")
        If Not DicKQ.exists(tmp) Then
          DicKQ.Add tmp, ""
        Else
          GoTo Tiep
        End If
        If dong < Dkq Then
          dong = dong + 1
          For j = 1 To C + 1
            Kq(dong, j) = Arr(1, j)
          Next j
        Else
          GoTo Thoat
        End If
Tiep:
    Next i
  Next k
  Darr = NgauNhien(Darr, Arr, C)
Next S
Thoat:
LocCot = Kq
Erase Arr:            Erase Kq
Set Dic = Nothing:    Set DicKQ = Nothing
End Function


Public Function SortArrToStr(Arr As Variant, Str As String) As String
  Dim ArrList As Object, Darr As Variant, j As Byte, tmp As String
  Set ArrList = CreateObject("System.Collections.ArrayList")
  For j = LBound(Arr, 2) To UBound(Arr, 2)
    tmp = Arr(1, j):   ArrList.Add tmp
  Next
  ArrList.Sort
  Darr = ArrList.ToArray
  SortArrToStr = Join(Darr, Str)
  Set ArrList = Nothing:    Erase Darr
End Function


Function NgauNhien(Darr(), Arr(), C)
Dim Dic As Object, tmp As Integer, Sarr(), i As Integer, j As Integer, k As Integer
Set Dic = CreateObject("scripting.dictionary")
ReDim Sarr(1 To UBound(Darr), 1 To UBound(Darr, 2))
For j = 1 To C
    For i = 1 To k + 1
        If Darr(i, j) = "" Then
            Arr(2, j) = i - 1:       Exit For
        End If
    Next i
Next j
For j = 1 To C
  Dic.RemoveAll:  k = 0
  Do
    tmp = Int((Arr(2, j) * Rnd) + 1)
    If Not Dic.exists(tmp) Then
      k = k + 1:  Dic.Add tmp, ""
      Sarr(k, j) = Darr(tmp, j)
    End If
  Loop Until k = Arr(2, j)
Next j
NgauNhien = Sarr
Set Dic = Nothing
End Function
 
bạn xem lại dữ liệu, không tìm được dòng nào thỏa điều kiện, nên sheet ketqua không có gì
sheet1 lưu kết quả lọc không trùng của 5 nhóm
Mã:
Dim Dkq As Integer, Lap As Byte
Sub Main()
Dim Darr(), kq1(), kq2(), kq3(), kq4(), kq5(), Skq(), tmp As String
Dim Dic2 As Object, Dic3 As Object, Dic4 As Object, Dic5 As Object
Dim Sr As Integer, i As Integer, k As Integer, C As Byte, n As Byte, j As Byte
Set Dic = CreateObject("scripting.dictionary")
Set Dic2 = CreateObject("scripting.dictionary")
Set Dic3 = CreateObject("scripting.dictionary")
Set Dic4 = CreateObject("scripting.dictionary")
Set Dic5 = CreateObject("scripting.dictionary")
C = 80
Dkq = 1000 'khai báo Dkq, so dòng ket qua theo ý
Lap = 10   'khai báo Lap, càng lon chay càng lau và ít bo sot ket qua
Sr = Sheets("DULIEU").UsedRange.Rows.Count
ReDim Skq(1 To 1, 1 To C)
For n = 1 To 5
  Darr = Sheets("DULIEU").Cells(2, (n - 1) * C + 1).Resize(Sr, C).Value
  If n = 1 Then
    kq1 = LocCot(Darr(), C)
    Sheets("Sheet1").Cells(2, (n - 1) * C + 1).Resize(Dkq, C) = kq1
  ElseIf n = 2 Then
    kq2 = LocCot(Darr(), C)
    For i = 1 To Dkq
      For j = 1 To C
        Skq(1, j) = Format(kq2(i, j), "00")
      Next j
      tmp = SortArrToStr(Skq, "z")
      Dic2.Add tmp, i
    Next i
    Sheets("Sheet1").Cells(2, (n - 1) * C + 1).Resize(Dkq, C) = kq2
  ElseIf n = 3 Then
    kq3 = LocCot(Darr(), C)
    For i = 1 To Dkq
      For j = 1 To C
        Skq(1, j) = Format(kq3(i, j), "00")
      Next j
      tmp = SortArrToStr(Skq, "z")
      Dic3.Add tmp, i
    Next i
    Sheets("Sheet1").Cells(2, (n - 1) * C + 1).Resize(Dkq, C) = kq3
  ElseIf n = 4 Then
    kq4 = LocCot(Darr(), C)
    For i = 1 To Dkq
      For j = 1 To C
        Skq(1, j) = Format(kq4(i, j), "00")
      Next j
      tmp = SortArrToStr(Skq, "z")
      Dic4.Add tmp, i
    Next i
    Sheets("Sheet1").Cells(2, (n - 1) * C + 1).Resize(Dkq, C) = kq4
  Else
    kq5 = LocCot(Darr(), C)
    For i = 1 To Dkq
      For j = 1 To C
        Skq(1, j) = Format(kq5(i, j), "00")
      Next j
      tmp = SortArrToStr(Skq, "z")
      Dic5.Add tmp, i
    Next i
    Sheets("Sheet1").Cells(2, (n - 1) * C + 1).Resize(Dkq, C) = kq5
  End If
Next n


ReDim Darr(1 To Dkq, 1 To C * 5)
k = 0
For i = 1 To Dkq
  For j = 1 To C
    Skq(1, j) = Format(kq1(i, j), "00")
  Next j
  tmp = SortArrToStr(Skq, "z")
  If Dic2.exists(tmp) Or Dic3.exists(tmp) Or Dic4.exists(tmp) Or Dic5.exists(tmp) Then
    k = k + 1
    For j = 1 To C
      Darr(k, j) = kq1(i, j)
      If Dic2.exists(tmp) Then Darr(k, j + 80 * 1) = kq2(Dic2.Item(tmp), j)
      If Dic3.exists(tmp) Then Darr(k, j + 80 * 2) = kq3(Dic3.Item(tmp), j)
      If Dic4.exists(tmp) Then Darr(k, j + 80 * 3) = kq4(Dic4.Item(tmp), j)
      If Dic5.exists(tmp) Then Darr(k, j + 80 * 4) = kq5(Dic5.Item(tmp), j)
    Next j
  End If
Next i
Set Dic = Nothing:  Set Dic2 = Nothing:  Set Dic3 = Nothing:  Set Dic4 = Nothing: Set Dic5 = Nothing
Sheets("KETQUA").Range("A2").Resize(2000, 400).ClearContents
If k > 0 Then Sheets("KETQUA").Range("A2").Resize(k, 400) = Darr
End Sub


Function LocCot(Darr(), C As Byte)
Dim Dic As Object, DicKQ As Object, tmp As String, Arr(), Kq(), i As Integer, j As Integer, n As Integer
Dim k As Integer, dong As Long, jk As Integer, MinC As Integer, S As Byte
Set Dic = CreateObject("scripting.dictionary")
Set DicKQ = CreateObject("scripting.dictionary")
ReDim Arr(1 To 2, 1 To C + 1):  ReDim Kq(1 To Dkq, 1 To C + 1)
For j = 1 To C
    For i = 1 To UBound(Darr) + 1
        If Darr(i, j) = "" Then
            Arr(2, j) = i - 1:       Exit For
        End If
    Next i
Next j
For S = 1 To Lap
  For k = 1 To C
    For i = 1 To Arr(2, k)
        Dic.RemoveAll:    Arr(1, C + 1) = 0
        Dic.Add Darr(i, k), ""
        Arr(1, k) = Darr(i, k)
        Arr(1, C + 1) = Arr(1, C + 1) + 1
        For jk = 2 To C
            j = jk:            If jk = k Then j = 1
            For n = 1 To Arr(2, j)
                If Not Dic.exists(Darr(n, j)) Then
                    Dic.Add Darr(n, j), ""
                    Arr(1, j) = Darr(n, j)
                    Arr(1, C + 1) = Arr(1, C + 1) + 1
                    Exit For
                End If
            Next n
            If Arr(1, C + 1) < jk Then GoTo Tiep
        Next jk
        tmp = SortArrToStr(Arr, "z")
        If Not DicKQ.exists(tmp) Then
          DicKQ.Add tmp, ""
        Else
          GoTo Tiep
        End If
        If dong < Dkq Then
          dong = dong + 1
          For j = 1 To C + 1
            Kq(dong, j) = Arr(1, j)
          Next j
        Else
          GoTo Thoat
        End If
Tiep:
    Next i
  Next k
  Darr = NgauNhien(Darr, Arr, C)
Next S
Thoat:
LocCot = Kq
Erase Arr:            Erase Kq
Set Dic = Nothing:    Set DicKQ = Nothing
End Function


Public Function SortArrToStr(Arr As Variant, Str As String) As String
  Dim ArrList As Object, Darr As Variant, j As Byte, tmp As String
  Set ArrList = CreateObject("System.Collections.ArrayList")
  For j = LBound(Arr, 2) To UBound(Arr, 2)
    tmp = Arr(1, j):   ArrList.Add tmp
  Next
  ArrList.Sort
  Darr = ArrList.ToArray
  SortArrToStr = Join(Darr, Str)
  Set ArrList = Nothing:    Erase Darr
End Function


Function NgauNhien(Darr(), Arr(), C)
Dim Dic As Object, tmp As Integer, Sarr(), i As Integer, j As Integer, k As Integer
Set Dic = CreateObject("scripting.dictionary")
ReDim Sarr(1 To UBound(Darr), 1 To UBound(Darr, 2))
For j = 1 To C
    For i = 1 To k + 1
        If Darr(i, j) = "" Then
            Arr(2, j) = i - 1:       Exit For
        End If
    Next i
Next j
For j = 1 To C
  Dic.RemoveAll:  k = 0
  Do
    tmp = Int((Arr(2, j) * Rnd) + 1)
    If Not Dic.exists(tmp) Then
      k = k + 1:  Dic.Add tmp, ""
      Sarr(k, j) = Darr(tmp, j)
    End If
  Loop Until k = Arr(2, j)
Next j
NgauNhien = Sarr
Set Dic = Nothing
End Function
Cảm ơn bạn nhiều quá! Không biết bạn có xem giúp phương án 2 không ạ? Cảm ơn bạn!
 
giờ bận rồi, tuần sau sẽ viết cho bạn, hy vọng viết được
Vâng. cảm ơn bạn. Trong code trên khi mình thử test lại: ví dụ cho dòng 2 dữ liệu từ cột 1 đến cột 80 lần lượt từ 01 đến 80, đến cột 81 là 01, cột 82 là 02. sau đó cột 83 là 83, cột 84 là 84, ... thì kết quả cũng không có xuất hiện kết quả nhóm này bạn ạ?
 
Mong các bạn GPE xem giúp mình phương án 2 ở bài #29 ạ: Sheet(DULIEU) có 400 cột: tìm nhóm số liệu 80 số với số cột lớn nhất (mỗi cột chỉ được chọn 1 số - nên mỗi số có thể xuất hiện nhiều lần, cho phép số được chọn ở các cột có thể trùng lặp lại- ví dụ cột 1 chọn số 02 thì cột khác vẫn có thể chọn lại số 02,...). Các kết quả được dán vào sheet(KETQUA).
Rất mong các bạn giúp đỡ! Cảm ơn nhiều!
 
Cảm ơn bạn nhiều quá! Không biết bạn có xem giúp phương án 2 không ạ? Cảm ơn bạn!
GPE có thể giải thích giúp mình lỗi này không ạ: khi mình khai báo vòng lặp lên 200 thì thông báo lỗi: this key is already associated with an element of this collection.
và trong code báo vào chỗ : Dic2.Add tmp, i
- Mong các bạn xem giúp.
- P/s: Mong GPE giúp mình trường hợp 2: Dữi liệu ở sheet(DULIEU): tìm nhóm gồm 80 số (hoặc 90 số cũng được) sao cho khi đối chiếu các phần tử của nhóm cần tìm với các dữ liệu của từng cột lần lượt từ cột 1 cho đến cột thứ n trong sheet(DULIEU) thì có ít nhất 1 phần tử cuả nhóm nằm trong dữ liệu của cột. (Nói theo cách khác là: Giao giữa Tập hợp (nhóm 80 số) với Tập hợp (dữ liệu trong từng cột) là khác tập rỗng ). Quy tắc đối chiếu là đối chiếu lần lượt từ cột 1 cho đến cột thứ n, nếu đến cột thứ n + 1 mà phần tử trong nhóm cần tìm không có trong cột dữ liệu thì dừng lại không đối chiếu nữa. Tìm nhóm số và dán kết quả sang sheet(KETQUA) từ dòng 2 trở xuống tương ứng với số cột n lớn nhất đầu tiên, rồi đến các kết quả với số cột giảm dần (có thể lấy đến 1000 dòng kết quả nếu có).
+ Thực sự rất rất cần các bạn và GPE giúp đỡ cho trường hợp này! Xin cảm kích vô cùng!
 

File đính kèm

Vâng. cảm ơn bạn. Trong code trên khi mình thử test lại: ví dụ cho dòng 2 dữ liệu từ cột 1 đến cột 80 lần lượt từ 01 đến 80, đến cột 81 là 01, cột 82 là 02. sau đó cột 83 là 83, cột 84 là 84, ... thì kết quả cũng không có xuất hiện kết quả nhóm này bạn ạ?
yêu cầu là nhóm 2 phải có giá trị giống nhóm 1? ví dụ của bạn đâu có giống
các bộ giá trị bạn xem ở sheet1
 
yêu cầu là nhóm 2 phải có giá trị giống nhóm 1? ví dụ của bạn đâu có giống
các bộ giá trị bạn xem ở sheet1
Dạ, có trường hợp xảy ra với dữ liệu là trong tất cả các nhóm 80 số đó mà nhóm có số cột lớn nhất lớn hơn 80 và nhỏ hơn 160 (ví dụ nhóm 80 số có số cột lớn nhất là 82 cột thì 80 cột đầu tiên chứa 80 số đó rồi, còn lại 2 cột tiếp theo là cột 81, 82 sẽ có chứa dữ liệu ở trong nhóm 80 số đó) khi đó kết quả dán vào sheet(KETQUA).
- Sau nhiều ngày suy nghĩ nếu trường hợp không có nhóm 80 số nào thoả mãn được 80 cột đầu tiên thì kết quả sẽ không tồn tại.
* Vậy mong bạn HieuCD và GPE xem giúp đỡ ở phương án trường hợp 2 ở bài #37. Xin cảm ơn rất nhiều!
 
Dạ, có trường hợp xảy ra với dữ liệu là trong tất cả các nhóm 80 số đó mà nhóm có số cột lớn nhất lớn hơn 80 và nhỏ hơn 160 (ví dụ nhóm 80 số có số cột lớn nhất là 82 cột thì 80 cột đầu tiên chứa 80 số đó rồi, còn lại 2 cột tiếp theo là cột 81, 82 sẽ có chứa dữ liệu ở trong nhóm 80 số đó) khi đó kết quả dán vào sheet(KETQUA).
- Sau nhiều ngày suy nghĩ nếu trường hợp không có nhóm 80 số nào thoả mãn được 80 cột đầu tiên thì kết quả sẽ không tồn tại.
* Vậy mong bạn HieuCD và GPE xem giúp đỡ ở phương án trường hợp 2 ở bài #37. Xin cảm ơn rất nhiều!
để khắc phục lổi dòng lệnh
Dic2.Add tmp, i
bạn thay bằng lệnh
If Not Dic2.exists(tmp) Then Dic2.Add tmp, i

tóm lại chỉ cần tìm 80 số (hoặc nhỏ hơn 80 số được không?) không trùng trong 100 số từ 00 đến 99 ? sao cho tất cả 400 cột đều chứa 1 trong 80 số đó, hoặc ít hơn 400 nhưng lấy số cột lớn nhất
 
để khắc phục lổi dòng lệnh
Dic2.Add tmp, i
bạn thay bằng lệnh
If Not Dic2.exists(tmp) Then Dic2.Add tmp, i

tóm lại chỉ cần tìm 80 số (hoặc nhỏ hơn 80 số được không?) không trùng trong 100 số từ 00 đến 99 ? sao cho tất cả 400 cột đều chứa 1 trong 80 số đó, hoặc ít hơn 400 nhưng lấy số cột lớn nhất
Dạ, vâng đúng như ý hiểu của bạn rồi bạn ạ: Chỉ cần tìm nhóm số không trùng trong 100 số từ 00 đến 99 sao cho tất cả 400 cột đều chứa 1 trong các số đó, hoặc ít hơn 400 nhưng lấy số cột lớn nhất. (nếu tạo được hộp thông báo nhập số liệu cho các trường hợp trước khi chạy code: ví dụ như trường hợp tìm nhóm 80 số mình chỉ việc nhập 80 và chạy code để tìm, hoặc tìm nhóm 70 số chỉ việc nhập 70 và chạy code để tìm,..v.v.v.). Cảm ơn bạn giúp đỡ mình!
 
Dạ, vâng đúng như ý hiểu của bạn rồi bạn ạ: Chỉ cần tìm nhóm số không trùng trong 100 số từ 00 đến 99 sao cho tất cả 400 cột đều chứa 1 trong các số đó, hoặc ít hơn 400 nhưng lấy số cột lớn nhất. (nếu tạo được hộp thông báo nhập số liệu cho các trường hợp trước khi chạy code: ví dụ như trường hợp tìm nhóm 80 số mình chỉ việc nhập 80 và chạy code để tìm, hoặc tìm nhóm 70 số chỉ việc nhập 70 và chạy code để tìm,..v.v.v.). Cảm ơn bạn giúp đỡ mình!

Bạn áp dụng cái file các số nhiều này để làm gì vậy, có thể nói cho tôi và mọi người học hỏi ?
 
Dạ, vâng đúng như ý hiểu của bạn rồi bạn ạ: Chỉ cần tìm nhóm số không trùng trong 100 số từ 00 đến 99 sao cho tất cả 400 cột đều chứa 1 trong các số đó, hoặc ít hơn 400 nhưng lấy số cột lớn nhất. (nếu tạo được hộp thông báo nhập số liệu cho các trường hợp trước khi chạy code: ví dụ như trường hợp tìm nhóm 80 số mình chỉ việc nhập 80 và chạy code để tìm, hoặc tìm nhóm 70 số chỉ việc nhập 70 và chạy code để tìm,..v.v.v.). Cảm ơn bạn giúp đỡ mình!
sheet ketqua là giá trị từng cột, cột cuối là là số giá trị không trùng
sheet1 là các giá trị chọn
Mã:
Dim nn As Byte, C As Integer
Sub TimTrung()
Dim Dic As Object, DicKQ As Object, tmp As String, Arr(), Darr(), Sarr(), Tmparr, Kq(), KqCot()
Dim i As Integer, j As Integer, n As Integer, k As Integer, Dkq As Long, S As Integer, Lap As Integer
Set Dic = CreateObject("scripting.dictionary")
Set DicKQ = CreateObject("scripting.dictionary")
n = Sheets("DULIEU").UsedRange.Rows.Count - 1
C = 80:     nn = 100
Dkq = 1000 'khai báo Dkq, so dòng ket qua theo ý
Lap = 5000   'khai báo Lap > Dkq, càng lon chay càng lau và ít bo sot ket qua
Darr = Sheets("DULIEU").Range("A2:OJ" & n + 1).Value
ReDim Sarr(1 To n + 1, 1 To C * 5)


For j = 1 To C * 5
  For i = 1 To n
    If Darr(i, j) <> "" Then
      tmp = Darr(i, j) & "z" & j
      If Not Dic.exists(tmp) Then Dic.Add tmp, ""
    End If
  Next i
Next j


ReDim Kq(1 To Dkq, 1 To C * 5 + 1)
ReDim KqCot(1 To Dkq, 1 To C + 1)
n = 0
For S = 1 To Lap
  ReDim Sarr(1 To nn)
  Sarr = NN_80
  ReDim Arr(1 To 2, 1 To C * 5 + 1)
  k = 0
  For i = 1 To nn
    For j = 1 To C * 5
      If Arr(2, j) = "" Then
        tmp = Sarr(i) & "z" & j
        If Dic.exists(tmp) Then
          k = k + 1
          Arr(1, j) = Sarr(i)
          Arr(2, j) = j
        End If
      End If
    Next j
    If k = 400 Then
      tmp = SortArrToStr(Arr, "z", C * 5)
      If Not DicKQ.exists(tmp) Then
        DicKQ.Add tmp, ""
        n = n + 1
        Kq(n, C * 5 + 1) = i
        For j = 1 To C * 5
          Kq(n, j) = Arr(1, j)
        Next j
        tmp = SortArrToStr(Sarr, "z", C)
        Tmparr = Split(tmp, "z")
        For j = 1 To i
          KqCot(n, j) = Tmparr(j - 1)
        Next j
        KqCot(n, C + 1) = i
      End If
    End If
  Next i
  If n = Dkq Then Exit For
Next S
Sheets("KETQUA").Range("A2").Resize(10000, 400).ClearContents
Sheets("Sheet1").Range("A2").Resize(10000, 401).ClearContents
If n > 0 Then
  Sheets("KETQUA").Range("A2").Resize(n, C * 5 + 1) = Kq
  Sheets("Sheet1").Range("A2").Resize(n, C + 1) = KqCot
  Sheets("Sheet1").Activate
  Sheets("Sheet1").Range("D2").Resize(n, C + 1).Sort [s2], 1, Header:=xlNo
End If
Set Dic = Nothing:  Set DicKQ = Nothing
Erase Arr:    Erase Darr:   Erase Sarr:    Erase Kq:   Erase Tmparr:    Erase KqCot
End Sub


Function SortArrToStr(Tarr As Variant, Str As String, k As Integer) As String
  Dim ArrList As Object, Tmparr As Variant, j As Integer, tmp As String
  Set ArrList = CreateObject("System.Collections.ArrayList")
  For j = 1 To k
    If k = 400 Then
      tmp = Tarr(1, j)
    Else
      tmp = Tarr(j)
    End If
    ArrList.Add tmp
  Next j
  ArrList.Sort
  Tmparr = ArrList.ToArray
  SortArrToStr = Join(Tmparr, Str)
  Set ArrList = Nothing:    Erase Tmparr
End Function


Function NN_80() As Variant
Dim Dic As Object, Tarr(), tmp As Byte, k As Byte
Set Dic = CreateObject("scripting.dictionary")
ReDim Tarr(1 To nn)
  Do
    tmp = Int(100 * Rnd)
    If Not Dic.exists(tmp) Then
      k = k + 1:  Dic.Add tmp, ""
      Tarr(k) = tmp
    End If
  Loop Until k = nn
NN_80 = Tarr
Set Dic = Nothing:  Erase Tarr
End Function
 
sheet ketqua là giá trị từng cột, cột cuối là là số giá trị không trùng
sheet1 là các giá trị chọn
Mã:
Dim nn As Byte, C As Integer
Sub TimTrung()
Dim Dic As Object, DicKQ As Object, tmp As String, Arr(), Darr(), Sarr(), Tmparr, Kq(), KqCot()
Dim i As Integer, j As Integer, n As Integer, k As Integer, Dkq As Long, S As Integer, Lap As Integer
Set Dic = CreateObject("scripting.dictionary")
Set DicKQ = CreateObject("scripting.dictionary")
n = Sheets("DULIEU").UsedRange.Rows.Count - 1
C = 80:     nn = 100
Dkq = 1000 'khai báo Dkq, so dòng ket qua theo ý
Lap = 5000   'khai báo Lap > Dkq, càng lon chay càng lau và ít bo sot ket qua
Darr = Sheets("DULIEU").Range("A2:OJ" & n + 1).Value
ReDim Sarr(1 To n + 1, 1 To C * 5)


For j = 1 To C * 5
  For i = 1 To n
    If Darr(i, j) <> "" Then
      tmp = Darr(i, j) & "z" & j
      If Not Dic.exists(tmp) Then Dic.Add tmp, ""
    End If
  Next i
Next j


ReDim Kq(1 To Dkq, 1 To C * 5 + 1)
ReDim KqCot(1 To Dkq, 1 To C + 1)
n = 0
For S = 1 To Lap
  ReDim Sarr(1 To nn)
  Sarr = NN_80
  ReDim Arr(1 To 2, 1 To C * 5 + 1)
  k = 0
  For i = 1 To nn
    For j = 1 To C * 5
      If Arr(2, j) = "" Then
        tmp = Sarr(i) & "z" & j
        If Dic.exists(tmp) Then
          k = k + 1
          Arr(1, j) = Sarr(i)
          Arr(2, j) = j
        End If
      End If
    Next j
    If k = 400 Then
      tmp = SortArrToStr(Arr, "z", C * 5)
      If Not DicKQ.exists(tmp) Then
        DicKQ.Add tmp, ""
        n = n + 1
        Kq(n, C * 5 + 1) = i
        For j = 1 To C * 5
          Kq(n, j) = Arr(1, j)
        Next j
        tmp = SortArrToStr(Sarr, "z", C)
        Tmparr = Split(tmp, "z")
        For j = 1 To i
          KqCot(n, j) = Tmparr(j - 1)
        Next j
        KqCot(n, C + 1) = i
      End If
    End If
  Next i
  If n = Dkq Then Exit For
Next S
Sheets("KETQUA").Range("A2").Resize(10000, 400).ClearContents
Sheets("Sheet1").Range("A2").Resize(10000, 401).ClearContents
If n > 0 Then
  Sheets("KETQUA").Range("A2").Resize(n, C * 5 + 1) = Kq
  Sheets("Sheet1").Range("A2").Resize(n, C + 1) = KqCot
  Sheets("Sheet1").Activate
  Sheets("Sheet1").Range("D2").Resize(n, C + 1).Sort [s2], 1, Header:=xlNo
End If
Set Dic = Nothing:  Set DicKQ = Nothing
Erase Arr:    Erase Darr:   Erase Sarr:    Erase Kq:   Erase Tmparr:    Erase KqCot
End Sub


Function SortArrToStr(Tarr As Variant, Str As String, k As Integer) As String
  Dim ArrList As Object, Tmparr As Variant, j As Integer, tmp As String
  Set ArrList = CreateObject("System.Collections.ArrayList")
  For j = 1 To k
    If k = 400 Then
      tmp = Tarr(1, j)
    Else
      tmp = Tarr(j)
    End If
    ArrList.Add tmp
  Next j
  ArrList.Sort
  Tmparr = ArrList.ToArray
  SortArrToStr = Join(Tmparr, Str)
  Set ArrList = Nothing:    Erase Tmparr
End Function


Function NN_80() As Variant
Dim Dic As Object, Tarr(), tmp As Byte, k As Byte
Set Dic = CreateObject("scripting.dictionary")
ReDim Tarr(1 To nn)
  Do
    tmp = Int(100 * Rnd)
    If Not Dic.exists(tmp) Then
      k = k + 1:  Dic.Add tmp, ""
      Tarr(k) = tmp
    End If
  Loop Until k = nn
NN_80 = Tarr
Set Dic = Nothing:  Erase Tarr
End Function
Cảm ơn bạn. Mình kiểm tra code thì thấy cột kết quả cuối của sheet(KETQUA) không đúng với kiểm tra trong thực tế và các số chọn ở sheet1 có những số không có ở sheet(KETQUA). Bạn kiểm tra hộ giúp!
p/s: mình kiểm tra thử lấy 5 kết quả!
 

File đính kèm

Cảm ơn bạn. Mình kiểm tra code thì thấy cột kết quả cuối của sheet(KETQUA) không đúng với kiểm tra trong thực tế và các số chọn ở sheet1 có những số không có ở sheet(KETQUA). Bạn kiểm tra hộ giúp!
p/s: mình kiểm tra thử lấy 5 kết quả!
bạn chỉnh lại 2 đoạn code
Mã:
    If k = 400 Then
      tmp = SortArrToStr(Arr, "z", C * 5)
      If Not DicKQ.exists(tmp) Then
        DicKQ.Add tmp, ""
        n = n + 1
        Kq(n, C * 5 + 1) = i
        For j = 1 To C * 5
          Kq(n, j) = Arr(1, j)
        Next j
        Tmparr = Split(tmp, "z")
        KqCot(n, 1) = Tmparr(0)
        k = 1
        For j = 1 To 399
          If KqCot(n, k) <> Tmparr(j) Then
            k = k + 1
            KqCot(n, k) = Tmparr(j)
          End If
        Next j
        Kq(n, C * 5 + 1) = k
        KqCot(n, C + 1) = k
      End If
    End If
Mã:
Function SortArrToStr(Tarr As Variant, Str As String, k As Integer) As String
  Dim ArrList As Object, Tmparr As Variant, j As Integer, tmp As String
  Set ArrList = CreateObject("System.Collections.ArrayList")
  For j = 1 To k
    tmp = Tarr(1, j)
    ArrList.Add tmp
  Next j
  ArrList.Sort
  Tmparr = ArrList.ToArray
  SortArrToStr = Join(Tmparr, Str)
  Set ArrList = Nothing:    Erase Tmparr
End Function
 
bạn chỉnh lại 2 đoạn code
Mã:
    If k = 400 Then
      tmp = SortArrToStr(Arr, "z", C * 5)
      If Not DicKQ.exists(tmp) Then
        DicKQ.Add tmp, ""
        n = n + 1
        Kq(n, C * 5 + 1) = i
        For j = 1 To C * 5
          Kq(n, j) = Arr(1, j)
        Next j
        Tmparr = Split(tmp, "z")
        KqCot(n, 1) = Tmparr(0)
        k = 1
        For j = 1 To 399
          If KqCot(n, k) <> Tmparr(j) Then
            k = k + 1
            KqCot(n, k) = Tmparr(j)
          End If
        Next j
        Kq(n, C * 5 + 1) = k
        KqCot(n, C + 1) = k
      End If
    End If
Mã:
Function SortArrToStr(Tarr As Variant, Str As String, k As Integer) As String
  Dim ArrList As Object, Tmparr As Variant, j As Integer, tmp As String
  Set ArrList = CreateObject("System.Collections.ArrayList")
  For j = 1 To k
    tmp = Tarr(1, j)
    ArrList.Add tmp
  Next j
  ArrList.Sort
  Tmparr = ArrList.ToArray
  SortArrToStr = Join(Tmparr, Str)
  Set ArrList = Nothing:    Erase Tmparr
End Function
Dạ, vâng, cảm ơn bạn nhiều. Mình sửa lại code như bạn hướng dẫn. Phần sheet(KETQUA) thì chuẩn rồi ạ, nhưng phần sheet1 thì số giá trị chọn lại khác so với phần sheet(KETQUA). Mong Bạn xem giúp!
 

File đính kèm

Dạ, vâng, cảm ơn bạn nhiều. Mình sửa lại code như bạn hướng dẫn. Phần sheet(KETQUA) thì chuẩn rồi ạ, nhưng phần sheet1 thì số giá trị chọn lại khác so với phần sheet(KETQUA). Mong Bạn xem giúp!
sheet1 đã sort theo thứ tự nên thứ tự dòng khác với sheet ketqua, mình tạo thêm cột cuối là thứ tự dòng tương ứng ở sheet ketqua, và đã bỏ lệnh sort, nếu muốn sort thì bỏ dấu nháy ' phía trước
Mã:
Dim nn As Byte, C As Integer
Sub TimTrung()
Dim Dic As Object, DicKQ As Object, tmp As String, Arr(), Darr(), Sarr(), Tmparr, Kq(), KqCot()
Dim i As Integer, j As Integer, n As Integer, k As Integer, Dkq As Long, S As Integer, Lap As Integer
Set Dic = CreateObject("scripting.dictionary")
Set DicKQ = CreateObject("scripting.dictionary")
n = Sheets("DULIEU").UsedRange.Rows.Count - 1
C = 80:     nn = 100
Dkq = 5 '1000 'khai báo Dkq, so dòng ket qua theo ý
Lap = 5000   'khai báo Lap > Dkq, càng lon chay càng lau và ít bo sot ket qua
Darr = Sheets("DULIEU").Range("A2:OJ" & n + 1).Value
ReDim Sarr(1 To n + 1, 1 To C * 5)


For j = 1 To C * 5
  For i = 1 To n
    If Darr(i, j) <> "" Then
      tmp = Darr(i, j) & "z" & j
      If Not Dic.exists(tmp) Then Dic.Add tmp, ""
    End If
  Next i
Next j


ReDim Kq(1 To Dkq, 1 To C * 5 + 1)
[COLOR=#ff0000]ReDim KqCot(1 To Dkq, 1 To C + 2)[/COLOR]
n = 0
For S = 1 To Lap
  ReDim Sarr(1 To nn)
  Sarr = NN_80
  ReDim Arr(1 To 2, 1 To C * 5 + 1)
  k = 0
  For i = 1 To nn
    For j = 1 To C * 5
      If Arr(2, j) = "" Then
        tmp = Sarr(i) & "z" & j
        If Dic.exists(tmp) Then
          k = k + 1
          Arr(1, j) = Sarr(i)
          Arr(2, j) = j
        End If
      End If
    Next j


  If k = 400 Then
      tmp = SortArrToStr(Arr, "z", C * 5)
      If Not DicKQ.exists(tmp) Then
        DicKQ.Add tmp, ""
        n = n + 1
        Kq(n, C * 5 + 1) = i
        For j = 1 To C * 5
          Kq(n, j) = Arr(1, j)
        Next j
        Tmparr = Split(tmp, "z")
        KqCot(n, 1) = Tmparr(0)
        k = 1
        For j = 1 To 399
          If KqCot(n, k) <> Tmparr(j) Then
            k = k + 1
            KqCot(n, k) = Tmparr(j)
          End If
        Next j
        Kq(n, C * 5 + 1) = k
        KqCot(n, C + 1) = k
        [COLOR=#ff0000]KqCot(n, C + 2) = n + 1[/COLOR]
      End If
    End If
  
  Next i
  If n = Dkq Then Exit For
Next S
Sheets("KETQUA").Range("A2").Resize(10000, 400).ClearContents
Sheets("Sheet1").Range("A2").Resize(10000, 82).ClearContents
If n > 0 Then
  Sheets("KETQUA").Range("A2").Resize(n, C * 5 + 1) = Kq
  Sheets("Sheet1").Range("A2").Resize(n, C + 2) = KqCot
  Sheets("Sheet1").Activate
  [COLOR=#ff0000]'Sheets("Sheet1").Range("A2").Resize(n, C + 2).Sort [CC2], 1, Header:=xlNo[/COLOR]   'bo dau nhay dau dong neu muon sort tu thap den cao
End If
Set Dic = Nothing:  Set DicKQ = Nothing
Erase Arr:    Erase Darr:   Erase Sarr:    Erase Kq:   Erase Tmparr:    Erase KqCot
End Sub
 
sheet1 đã sort theo thứ tự nên thứ tự dòng khác với sheet ketqua, mình tạo thêm cột cuối là thứ tự dòng tương ứng ở sheet ketqua, và đã bỏ lệnh sort, nếu muốn sort thì bỏ dấu nháy ' phía trước
Mã:
Dim nn As Byte, C As Integer
Sub TimTrung()
Dim Dic As Object, DicKQ As Object, tmp As String, Arr(), Darr(), Sarr(), Tmparr, Kq(), KqCot()
Dim i As Integer, j As Integer, n As Integer, k As Integer, Dkq As Long, S As Integer, Lap As Integer
Set Dic = CreateObject("scripting.dictionary")
Set DicKQ = CreateObject("scripting.dictionary")
n = Sheets("DULIEU").UsedRange.Rows.Count - 1
C = 80:     nn = 100
Dkq = 5 '1000 'khai báo Dkq, so dòng ket qua theo ý
Lap = 5000   'khai báo Lap > Dkq, càng lon chay càng lau và ít bo sot ket qua
Darr = Sheets("DULIEU").Range("A2:OJ" & n + 1).Value
ReDim Sarr(1 To n + 1, 1 To C * 5)


For j = 1 To C * 5
  For i = 1 To n
    If Darr(i, j) <> "" Then
      tmp = Darr(i, j) & "z" & j
      If Not Dic.exists(tmp) Then Dic.Add tmp, ""
    End If
  Next i
Next j


ReDim Kq(1 To Dkq, 1 To C * 5 + 1)
[COLOR=#ff0000]ReDim KqCot(1 To Dkq, 1 To C + 2)[/COLOR]
n = 0
For S = 1 To Lap
  ReDim Sarr(1 To nn)
  Sarr = NN_80
  ReDim Arr(1 To 2, 1 To C * 5 + 1)
  k = 0
  For i = 1 To nn
    For j = 1 To C * 5
      If Arr(2, j) = "" Then
        tmp = Sarr(i) & "z" & j
        If Dic.exists(tmp) Then
          k = k + 1
          Arr(1, j) = Sarr(i)
          Arr(2, j) = j
        End If
      End If
    Next j


  If k = 400 Then
      tmp = [SIZE=4][B][COLOR=#ff8c00]SortArrToStr[/COLOR][/B][/SIZE](Arr, "z", C * 5)
      If Not DicKQ.exists(tmp) Then
        DicKQ.Add tmp, ""
        n = n + 1
        Kq(n, C * 5 + 1) = i
        For j = 1 To C * 5
          Kq(n, j) = Arr(1, j)
        Next j
        Tmparr = Split(tmp, "z")
        KqCot(n, 1) = Tmparr(0)
        k = 1
        For j = 1 To 399
          If KqCot(n, k) <> Tmparr(j) Then
            k = k + 1
            KqCot(n, k) = Tmparr(j)
          End If
        Next j
        Kq(n, C * 5 + 1) = k
        KqCot(n, C + 1) = k
        [COLOR=#ff0000]KqCot(n, C + 2) = n + 1[/COLOR]
      End If
    End If
  
  Next i
  If n = Dkq Then Exit For
Next S
Sheets("KETQUA").Range("A2").Resize(10000, 400).ClearContents
Sheets("Sheet1").Range("A2").Resize(10000, 82).ClearContents
If n > 0 Then
  Sheets("KETQUA").Range("A2").Resize(n, C * 5 + 1) = Kq
  Sheets("Sheet1").Range("A2").Resize(n, C + 2) = KqCot
  Sheets("Sheet1").Activate
  [COLOR=#ff0000]'Sheets("Sheet1").Range("A2").Resize(n, C + 2).Sort [CC2], 1, Header:=xlNo[/COLOR]   'bo dau nhay dau dong neu muon sort tu thap den cao
End If
Set Dic = Nothing:  Set DicKQ = Nothing
Erase Arr:    Erase Darr:   Erase Sarr:    Erase Kq:   Erase Tmparr:    Erase KqCot
End Sub
Cảm ơn bạn! Khi mình cho chạy code thấy báo lỗi: "Sub or Function not defined" và báo chỗ chữ vàng mình tô đậm. Bạn xem giúp ạ. Cảm ơn sự giúp đỡ của bạn nhiều!
 
Cảm ơn bạn! Khi mình cho chạy code thấy báo lỗi: "Sub or Function not defined" và báo chỗ chữ vàng mình tô đậm. Bạn xem giúp ạ. Cảm ơn sự giúp đỡ của bạn nhiều!
hơi lạ, có 2 Function bạn có cho module không?
bạn nhận file
 

File đính kèm

hơi lạ, có 2 Function bạn có cho module không?
bạn nhận file
Bạn ơi, có một điều lạ là mình chạy thử tất cả các trường hợp của các nhóm mà không có trường hợp nào của nhóm có chứa 1 giá trị nào từ 00 đến 09? Kết quả chỉ có các giá trị từ 10 trở lên? Bạn xem có sai xót ở đâu không ạ? Xin cảm ơn bạn!
 
Bạn ơi, có một điều lạ là mình chạy thử tất cả các trường hợp của các nhóm mà không có trường hợp nào của nhóm có chứa 1 giá trị nào từ 00 đến 09? Kết quả chỉ có các giá trị từ 10 trở lên? Bạn xem có sai xót ở đâu không ạ? Xin cảm ơn bạn!
bạn chỉnh lại toàn bộ code
Mã:
Dim nn As Byte, C As Integer
Sub TimTrung()
Dim Dic As Object, DicKQ As Object, tmp As String, Arr(), Darr(), Sarr(), Tmparr, Kq(), KqCot()
Dim i As Integer, j As Integer, n As Integer, k As Integer, Dkq As Long, S As Integer, Lap As Integer
Set Dic = CreateObject("scripting.dictionary")
Set DicKQ = CreateObject("scripting.dictionary")
n = Sheets("DULIEU").UsedRange.Rows.Count - 1
C = 80:     nn = 100
Dkq = 5 '1000 'khai báo Dkq, so dòng ket qua theo ý
Lap = 5000   'khai báo Lap > Dkq, càng lon chay càng lau và ít bo sot ket qua
Darr = Sheets("DULIEU").Range("A2:OJ" & n + 1).Value
ReDim Sarr(1 To n + 1, 1 To C * 5)


For j = 1 To C * 5
  For i = 1 To n
    If Darr(i, j) <> "" Then
      tmp = Val(Darr(i, j)) & "z" & j
      If Not Dic.exists(tmp) Then Dic.Add tmp, ""
    End If
  Next i
Next j


ReDim Kq(1 To Dkq, 1 To C * 5 + 1)
ReDim KqCot(1 To Dkq, 1 To C + 2)
n = 0
For S = 1 To Lap
  ReDim Sarr(1 To nn)
  Sarr = NN_80
  ReDim Arr(1 To 2, 1 To C * 5 + 1)
  k = 0
  For i = 1 To nn
    For j = 1 To C * 5
      If Arr(2, j) = "" Then
        tmp = Sarr(i) & "z" & j
        If Dic.exists(tmp) Then
          k = k + 1
          Arr(1, j) = Sarr(i)
          Arr(2, j) = j
        End If
      End If
    Next j


  If k = 400 Then
      tmp = SortArrToStr(Arr, "z", C * 5)
      If Not DicKQ.exists(tmp) Then
        DicKQ.Add tmp, ""
        n = n + 1
        Kq(n, C * 5 + 1) = i
        For j = 1 To C * 5
          Kq(n, j) = Arr(1, j)
        Next j
        Tmparr = Split(tmp, "z")
        KqCot(n, 1) = Tmparr(0)
        k = 1
        For j = 1 To 399
          If KqCot(n, k) <> Tmparr(j) Then
            k = k + 1
            KqCot(n, k) = Tmparr(j)
          End If
        Next j
        Kq(n, C * 5 + 1) = k
        KqCot(n, C + 1) = k
        KqCot(n, C + 2) = n + 1
      End If
    End If
  
  Next i
  If n = Dkq Then Exit For
Next S
Sheets("KETQUA").Range("A2").Resize(10000, 400).ClearContents
Sheets("Sheet1").Range("A2").Resize(10000, 82).ClearContents
If n > 0 Then
  Sheets("KETQUA").Range("A2").Resize(n, C * 5 + 1) = Kq
  Sheets("Sheet1").Range("A2").Resize(n, C + 2) = KqCot
  Sheets("Sheet1").Activate
  'Sheets("Sheet1").Range("A2").Resize(n, C + 2).Sort [CC2], 1, Header:=xlNo
End If
Set Dic = Nothing:  Set DicKQ = Nothing
Erase Arr:    Erase Darr:   Erase Sarr:    Erase Kq:   Erase Tmparr:    Erase KqCot
End Sub
  
Function SortArrToStr(Tarr As Variant, Str As String, k As Integer) As String
  Dim ArrList As Object, Tmparr As Variant, j As Integer, tmp As String
  Set ArrList = CreateObject("System.Collections.ArrayList")
  For j = 1 To k
    tmp = Format(Tarr(1, j), "00")
    ArrList.Add tmp
  Next j
  ArrList.Sort
  Tmparr = ArrList.ToArray
  SortArrToStr = Join(Tmparr, Str)
  Set ArrList = Nothing:    Erase Tmparr
End Function
 
Function NN_80() As Variant
Dim Dic As Object, Tarr(), tmp As Byte, k As Byte
Set Dic = CreateObject("scripting.dictionary")
ReDim Tarr(1 To nn)
  Do
    tmp = Int(100 * Rnd)
    If Not Dic.exists(tmp) Then
      k = k + 1:  Dic.Add tmp, ""
      Tarr(k) = tmp
    End If
  Loop Until k = nn
NN_80 = Tarr
Set Dic = Nothing:  Erase Tarr
End Function
 
Bạn ơi khi mình điểu chỉnh dữ liệu ở sheet(DULIEU) lên 1200 cột, thì mình chỉnh lại code như sau:
Dim nn As Byte, C As IntegerSub TimTrung()
Dim Dic As Object, DicKQ As Object, Tmp As String, Arr(), Darr(), Sarr(), Tmparr, Kq(), KqCot()
Dim i As Integer, j As Integer, n As Integer, k As Integer, Dkq As Long, S As Integer, Lap As Integer
Set Dic = CreateObject("scripting.dictionary")
Set DicKQ = CreateObject("scripting.dictionary")
n = Sheets("DULIEU").UsedRange.Rows.Count - 1
C = 80: nn = 100
Dkq = 500 '1000 'khai báo Dkq, so dòng ket qua theo ý
Lap = 20000 'khai báo Lap > Dkq, càng lon chay càng lau và ít bo sot ket qua
Darr = Sheets("DULIEU").Range("A2:ATD" & n + 1).Value 'ATD: la dia chi cot cuoi cung 1200
ReDim Sarr(1 To n + 1, 1 To C * 5)




For j = 1 To C * 5
For i = 1 To n
If Darr(i, j) <> "" Then
Tmp = Val(Darr(i, j)) & "z" & j
If Not Dic.exists(Tmp) Then Dic.Add Tmp, ""
End If
Next i
Next j




ReDim Kq(1 To Dkq, 1 To C * 5 + 1)
ReDim KqCot(1 To Dkq, 1 To C + 2)
n = 0
For S = 1 To Lap
ReDim Sarr(1 To nn)
Sarr = NN_80
ReDim Arr(1 To 2, 1 To C * 5 + 1)
k = 0
For i = 1 To nn
For j = 1 To C * 5
If Arr(2, j) = "" Then
Tmp = Sarr(i) & "z" & j
If Dic.exists(Tmp) Then
k = k + 1
Arr(1, j) = Sarr(i)
Arr(2, j) = j
End If
End If
Next j


If k = 1200 Then '1200 la so cot toan vung du lieu
Tmp = SortArrToStr(Arr, "z", C * 5)
If Not DicKQ.exists(Tmp) Then
DicKQ.Add Tmp, ""
n = n + 1
Kq(n, C * 5 + 1) = i
For j = 1 To C * 5
Kq(n, j) = Arr(1, j)
Next j
Tmparr = Split(Tmp, "z")
KqCot(n, 1) = Tmparr(0)
k = 1
For j = 1 To 1199 '1199 la so cot it hon 1
If KqCot(n, k) <> Tmparr(j) Then
k = k + 1
KqCot(n, k) = Tmparr(j)
End If
Next j
Kq(n, C * 5 + 1) = k
KqCot(n, C + 1) = k
KqCot(n, C + 2) = n + 1
End If
End If

Next i
If n = Dkq Then Exit For
Next S
Sheets("KETQUA").Range("A2").Resize(10000, 1200).ClearContents '1200 la so cot toan vung du lieu
Sheets("Sheet1").Range("A2").Resize(10000, 82).ClearContents
If n > 0 Then
Sheets("KETQUA").Range("A2").Resize(n, C * 5 + 1) = Kq
Sheets("Sheet1").Range("A2").Resize(n, C + 2) = KqCot
Sheets("Sheet1").Activate
'Sheets("Sheet1").Range("A2").Resize(n, C + 2).Sort [CC2], 1, Header:=xlNo
End If
Set Dic = Nothing: Set DicKQ = Nothing
Erase Arr: Erase Darr: Erase Sarr: Erase Kq: Erase Tmparr: Erase KqCot
End Sub

Function SortArrToStr(Tarr As Variant, Str As String, k As Integer) As String
Dim ArrList As Object, Tmparr As Variant, j As Integer, Tmp As String
Set ArrList = CreateObject("System.Collections.ArrayList")
For j = 1 To k
Tmp = Format(Tarr(1, j), "00")
ArrList.Add Tmp
Next j
ArrList.Sort
Tmparr = ArrList.ToArray
SortArrToStr = Join(Tmparr, Str)
Set ArrList = Nothing: Erase Tmparr
End Function

Function NN_80() As Variant
Dim Dic As Object, Tarr(), Tmp As Byte, k As Byte
Set Dic = CreateObject("scripting.dictionary")
ReDim Tarr(1 To nn)
Do
Tmp = Int(100 * Rnd)
If Not Dic.exists(Tmp) Then
k = k + 1: Dic.Add Tmp, ""
Tarr(k) = Tmp
End If
Loop Until k = nn
NN_80 = Tarr
Set Dic = Nothing: Erase Tarr
End Function

Và kết quả sau khi chạy code là báo lỗi "type mismath" và code báo vàng chỗ mình tô đậm. Bạn xem giúp lỗi đó là như thế nào và cách khắc phục ra sao? Xin cảm ơn bạn nhiều!
 
Bạn ơi khi mình điểu chỉnh dữ liệu ở sheet(DULIEU) lên 1200 cột, thì mình chỉnh lại code như sau:


Và kết quả sau khi chạy code là báo lỗi "type mismath" và code báo vàng chỗ mình tô đậm. Bạn xem giúp lỗi đó là như thế nào và cách khắc phục ra sao? Xin cảm ơn bạn nhiều!
Mã:
[COLOR=#000000][I]Set Dic = Nothing: Set DicKQ = Nothing[/I][/COLOR]
[COLOR=#000000][I]Erase Arr: Erase Darr: Erase Sarr: Erase Kq[/I][/COLOR][SIZE=4][COLOR=#000000][I][B][COLOR=#ff8c00]: Erase Tmparr[/COLOR][/B][/I][/COLOR][/SIZE][COLOR=#000000][I]: Erase KqCot
[/I][/COLOR]các lệnh trên dùng để xóa bộ nhớ đã chiếm dụng của code, có thì tốt, không có cũng được. bạn xóa chổ màu vàng đi
quan trọng là bạn phải tính lại tham số C*5, bạn thay bằng 1200 hoặc C*15
dữ liệu quá lớn và dạng chuổi, không biết bộ nhớ có chịu nổi không
 
Mã:
[COLOR=#000000][I]Set Dic = Nothing: Set DicKQ = Nothing[/I][/COLOR]
[COLOR=#000000][I]Erase Arr: Erase Darr: Erase Sarr: Erase Kq[/I][/COLOR][SIZE=4][COLOR=#000000][I][B][COLOR=#ff8c00]: Erase Tmparr[/COLOR][/B][/I][/COLOR][/SIZE][COLOR=#000000][I]: Erase KqCot[/I][/COLOR]
các lệnh trên dùng để xóa bộ nhớ đã chiếm dụng của code, có thì tốt, không có cũng được. bạn xóa chổ màu vàng đi
quan trọng là bạn phải tính lại tham số C*5, bạn thay bằng 1200 hoặc C*15
dữ liệu quá lớn và dạng chuổi, không biết bộ nhớ có chịu nổi không
Cảm ơn bạn rất nhiều. Trong code trên khi mình cho chạy code thì mình tìm ra được những nhóm kết quả có 20-30 giá trị là đã thoả mãn rồi. Nếu mình muốn tìm ra những nhóm mà phải có 80-90 giá trị mới lấy thì mình làm như thế nào? Cảm ơn bạn nhiều!
 
Cảm ơn bạn rất nhiều. Trong code trên khi mình cho chạy code thì mình tìm ra được những nhóm kết quả có 20-30 giá trị là đã thoả mãn rồi. Nếu mình muốn tìm ra những nhóm mà phải có 80-90 giá trị mới lấy thì mình làm như thế nào? Cảm ơn bạn nhiều!
các số còn lại bạn cho số nào cũng được, miễn đừng trùng là được rồi
 
các số còn lại bạn cho số nào cũng được, miễn đừng trùng là được rồi
Mong bạn có thể nói rõ được không ạ? ví dụ ở sheet(KETQUA): trong tất cả những trường hợp thoả mãn với số cột lớn nhất (các giá trị có thể trùng lặp) thì chỉ lấy trường hợp nào mà nhóm có 80 giá trị khác nhau (các giá trị trong nhóm cho phép được trùng lặp giữa các cột khác nhau) dán vào sheet(KETQUA) khi đó mình điều chỉnh code như thế nào ạ? Cảm ơn bạn!
 
giả sử có 20 số từ 0 đến 19 đã thỏa điều kiện, thì bạn chọn thêm 60 số trong dãy từ 20 đến 99 là được rồi, với dư liệu của bạn thì lúc nào cũng đúng
còn viết code để phân phối lại cho từng cột thì tuần sau mới rảnh
 
giả sử có 20 số từ 0 đến 19 đã thỏa điều kiện, thì bạn chọn thêm 60 số trong dãy từ 20 đến 99 là được rồi, với dư liệu của bạn thì lúc nào cũng đúng
còn viết code để phân phối lại cho từng cột thì tuần sau mới rảnh
Vâng cảm ơn bạn. Mình sẽ đợi bạn viết lại code để phân phố lại cho từng cột! Đợi tin của bạn! Cảm ơn nhiều!
 
bạn chạy code mới, khai báo số nguyên dương vào code để chạy theo ý bạn, chạy càng lâu thì bỏ sót càng ít
code chạy ngẫu nhiên nên mỗi lần chạy có thể kết quả khác nhau
đã loại trừ trùng lập
do ngẫu nhiên nên cũng không biết bỏ sót hay không
Mã:
Sub Loc_Cot()
Dim Dic As Object, DicKQ As Object, tmp As String, Arr(), Darr(), Kq(), i As Integer, j As Integer, n As Integer
Dim C As Integer, k As Integer, dong As Integer, Dkq As Integer, jk As Integer, MinC As Integer, S As Byte, Lap As Byte
Set Dic = CreateObject("scripting.dictionary")
Set DicKQ = CreateObject("scripting.dictionary")
C = 100:     MinC = 150
k = Sheets("DULIEU").UsedRange.Rows.Count - 1
Dkq = 300 'khai báo Dkq, so dòng ket qua theo ý
Lap = 10   'khai báo Lap, càng lon chay càng lau và ít bo sot ket qua
Darr = Sheets("DULIEU").Range("A2", Sheets("DULIEU").Cells(k + 2, C)).Value
ReDim Arr(1 To 2, 1 To C + 1):  ReDim Kq(1 To Dkq, 1 To C + 1)
For j = 1 To C
    For i = 1 To k + 1
        If Darr(i, j) = "" Then
            Arr(2, j) = i - 1:       Exit For
        End If
    Next i
Next j
For S = 1 To Lap
  For k = 1 To 100
    For i = 1 To Arr(2, k)
        Dic.RemoveAll:    Arr(1, C + 1) = 0
        Dic.Add Darr(i, k), ""
        Arr(1, k) = Darr(i, k)
        Arr(1, C + 1) = Arr(1, C + 1) + 1
        For jk = 2 To 100
            j = jk:            If jk = k Then j = 1
            For n = 1 To Arr(2, j)
                If Not Dic.exists(Darr(n, j)) Then
                    Dic.Add Darr(n, j), ""
                    Arr(1, j) = Darr(n, j)
                    Arr(1, C + 1) = Arr(1, C + 1) + 1
                    Exit For
                End If
            Next n
        Next jk
        tmp = ""
        For j = 1 To C
          tmp = tmp & "z" & Arr(1, j)
        Next j
        If Not DicKQ.exists(tmp) Then
          DicKQ.Add tmp, ""
        Else
          GoTo Tiep
        End If
        If dong < Dkq Then
            dong = dong + 1
            For j = 1 To C + 1
                Kq(dong, j) = Arr(1, j)
            Next j
            If MinC > Arr(1, C + 1) Then MinC = Arr(1, C + 1)
        Else
            If Arr(1, C + 1) > MinC Then
              For n = 1 To Dkq
                If Kq(n, C + 1) = MinC Then
                  For j = 1 To C + 1
                    Kq(n, j) = Arr(1, j)
                  Next j
                  Exit For
                End If
              Next n
              MinC = 150
              For n = 1 To Dkq
                If MinC > Kq(n, C + 1) Then MinC = Kq(n, C + 1)
              Next n
            End If
        End If
Tiep:
    Next i
  Next k
  Darr = NgauNhien(Darr, Arr, C)
Next S
Sheets("KETQUA").Range("A2:CW2000").ClearContents
Sheets("KETQUA").Range("A2").Resize(Dkq, C + 1) = Kq
Set Dic = Nothing:    Set DicKQ = Nothing
End Sub


Function NgauNhien(Darr(), Arr(), C)
Dim Dic As Object, tmp As Integer, Sarr(), i As Integer, j As Integer, k As Integer
Set Dic = CreateObject("scripting.dictionary")
ReDim Sarr(1 To UBound(Darr), 1 To UBound(Darr, 2))
For j = 1 To C
    For i = 1 To k + 1
        If Darr(i, j) = "" Then
            Arr(2, j) = i - 1:       Exit For
        End If
    Next i
Next j
For j = 1 To C
  Dic.RemoveAll:  k = 0
  Do
    tmp = Int((Arr(2, j) * Rnd) + 1)
    If Not Dic.exists(tmp) Then
      k = k + 1:  Dic.Add tmp, ""
      Sarr(k, j) = Darr(tmp, j)
    End If
  Loop Until k = Arr(2, j)
Next j
NgauNhien = Sarr
Set Dic = Nothing
End Function
Bạn ơi, với code không lấy kết quả trùng ở bài #28, Hôm nay mình kiểm tra lại thêm lần nữa. Khi cho chạy với vòng lặp 250, lấy 30 kết quả đầu tiên thì mình thấy kết quả vẫn có giá trị trùng lặp: ví dụ dòng 2 giá trị 99 bị trùng 2 lần. Mong bạn xem giúp vì sao lại như vậy, mình gửi file minh hoạ cho bạn kiểm tra! Xin cảm ơn!
p/s: Ngoài ra khi mình muốn khai báo với vòng lặp lớn hơn 250 thì báo lỗi tràn ra: overflow!
 

File đính kèm

Lần chỉnh sửa cuối:
Bạn ơi, với code không lấy kết quả trùng ở bài #28, Hôm nay mình kiểm tra lại thêm lần nữa. Khi cho chạy với vòng lặp 250, lấy 30 kết quả đầu tiên thì mình thấy kết quả vẫn có giá trị trùng lặp: ví dụ dòng 2 giá trị 99 bị trùng 2 lần. Mong bạn xem giúp vì sao lại như vậy, mình gửi file minh hoạ cho bạn kiểm tra! Xin cảm ơn!
p/s: Ngoài ra khi mình muốn khai báo với vòng lặp lớn hơn 250 thì báo lỗi tràn ra: overflow!
bạn dùng code mới
Mã:
Sub Loc_Cot()
Dim Dic As Object, DicKQ As Object, tmp As String, Arr(), Sarr(), Darr(), Kq(), i As Integer, j As Integer, n As Integer
Dim C As Integer, k As Integer, dong As Integer, Dkq As Integer, jk As Integer, MinC As Integer, S As Integer, Lap As Integer
Set Dic = CreateObject("scripting.dictionary")
Set DicKQ = CreateObject("scripting.dictionary")
C = 100:     MinC = 150
k = Sheets("DULIEU").UsedRange.Rows.Count - 1
Dkq = 30 'khai báo Dkq, so dòng ket qua theo ý
Lap = 350  'khai báo Lap, càng lon chay càng lau và ít bo sot ket qua
Sarr = Sheets("DULIEU").Range("A2", Sheets("DULIEU").Cells(k + 2, C)).Value
ReDim Darr(1 To UBound(Sarr), 1 To UBound(Sarr, 2))
ReDim Arr(1 To 2, 1 To C + 1):  ReDim Kq(1 To Dkq, 1 To C + 1)
For j = 1 To C
  Dic.RemoveAll:  k = 0
  For i = 1 To UBound(Sarr)
    If Sarr(i, j) <> "" Then
      If Not Dic.exists(Sarr(i, j)) Then
        Dic.Add Sarr(i, j), ""
        k = k + 1
        Darr(k, j) = Sarr(i, j)
      End If
    Else
      Arr(2, j) = k:       Exit For
    End If
  Next i
Next j
For S = 1 To Lap
  For k = 1 To C
    For i = 1 To Arr(2, k)
        Dic.RemoveAll:      Dic.Add Darr(i, k), ""
        Arr(1, C + 1) = 0:  Arr(1, k) = Darr(i, k)
        Arr(1, C + 1) = Arr(1, C + 1) + 1
        For jk = 2 To C
            j = jk:            If jk = k Then j = 1
            Arr(1, j) = ""
            For n = 1 To Arr(2, j)
                If Not Dic.exists(Darr(n, j)) Then
                    Dic.Add Darr(n, j), ""
                    Arr(1, j) = Darr(n, j)
                    Arr(1, C + 1) = Arr(1, C + 1) + 1
                    Exit For
                End If
            Next n
        Next jk
        tmp = ""
        For j = 1 To C
          If Arr(1, j) = "" Then
            tmp = tmp & "z" & "_"
          Else
            tmp = tmp & "z" & Arr(1, j)
          End If
        Next j
        If Not DicKQ.exists(tmp) Then
          DicKQ.Add tmp, ""
        Else
          GoTo Tiep
        End If
        If dong < Dkq Then
            dong = dong + 1
            For j = 1 To C + 1
                Kq(dong, j) = Arr(1, j)
            Next j
            If MinC > Arr(1, C + 1) Then MinC = Arr(1, C + 1)
        Else
            If Arr(1, C + 1) > MinC Then
              For n = 1 To Dkq
                If Kq(n, C + 1) = MinC Then
                  For j = 1 To C + 1
                    Kq(n, j) = Arr(1, j)
                  Next j
                  Exit For
                End If
              Next n
              MinC = 150
              For n = 1 To Dkq
                If MinC > Kq(n, C + 1) Then MinC = Kq(n, C + 1)
              Next n
            End If
        End If
Tiep:
    Next i
  Next k
  Darr = NgauNhien(Darr, Arr, C)
Next S
Sheets("KETQUA").Range("A2:CW2000").ClearContents
Sheets("KETQUA").Range("A2").Resize(Dkq, C + 1) = Kq
Set Dic = Nothing:    Set DicKQ = Nothing
End Sub


Function NgauNhien(Darr(), Arr(), C)
Dim Dic As Object, tmp As Integer, Sarr(), i As Integer, j As Integer, k As Integer
Set Dic = CreateObject("scripting.dictionary")
ReDim Sarr(1 To UBound(Darr), 1 To UBound(Darr, 2))
For j = 1 To C
  Dic.RemoveAll:  k = 0
  Do
    tmp = Int((Arr(2, j) * Rnd) + 1)
    If Not Dic.exists(tmp) Then
      k = k + 1:  Dic.Add tmp, ""
      Sarr(k, j) = Darr(tmp, j)
    End If
  Loop Until k = Arr(2, j)
Next j
NgauNhien = Sarr
Set Dic = Nothing
End Function
 
quote_icon.png
Nguyên văn bởi winvista
Bạn áp dụng cái file các số nhiều này để làm gì vậy, có thể nói cho tôi và mọi người học hỏi ?

Sơn Mã cho câu trả lời?

Bạn áp dụng cái file các số nhiều này để làm gì vậy, có thể nói cho tôi và mọi người học hỏi ?
 
Cảm ơn bạn rất nhiều. Trong code trên khi mình cho chạy code thì mình tìm ra được những nhóm kết quả có 20-30 giá trị là đã thoả mãn rồi. Nếu mình muốn tìm ra những nhóm mà phải có 80-90 giá trị mới lấy thì mình làm như thế nào? Cảm ơn bạn nhiều!
bạn chạy code
Mã:
Dim C As Integer
Sub TimTrung1()
Dim Dic As Object, DicKQ As Object, tmp As String, Arr(), Darr(), Sarr(), Tmparr, Kq(), KqCot()
Dim i As Integer, j As Integer, k As Integer, Cot As Integer, Vong As Integer, S As Long, Dkq As Long, Lap As Long, n As Long
Set Dic = CreateObject("scripting.dictionary")
Set DicKQ = CreateObject("scripting.dictionary")
n = Sheets("DULIEU").UsedRange.Rows.Count - 1
Cot = Sheets("DULIEU").UsedRange.Columns.Count
C = 80      'khai báo so cot ket qua
Dkq = 1000  'khai báo so dòng ket qua
Lap = 5000  'khai báo so dòng Lap > Dkq, càng lon chay càng lau và ít bo sot ket qua
Darr = Sheets("DULIEU").Range("A2").Resize(n + 1, Cot).Value
ReDim Sarr(1 To n + 1, 1 To Cot)


For j = 1 To Cot
  For i = 1 To n
    If Darr(i, j) <> "" Then
      tmp = Val(Darr(i, j)) & "z" & j
      If Not Dic.exists(tmp) Then Dic.Add tmp, ""
    End If
  Next i
Next j


ReDim Kq(1 To Dkq, 1 To Cot + 1)
ReDim KqCot(1 To Dkq, 1 To C + 2)
n = 0
For S = 1 To Lap
  ReDim Sarr(1 To C)
  ReDim Arr(1 To 2, 1 To Cot + 1)
  Sarr = NN_C:   k = 0:    Vong = 0
  Do
    For i = 1 To C
      For j = 1 To Cot
        If Arr(2, j) = "" Then
          If Dic.exists(Sarr(i) & "z" & j) Then
            k = k + 1
            Arr(1, j) = Sarr(i)
            Arr(2, j) = j
            Exit For
          End If
        End If
      Next j
    Next i
    Vong = Vong + 1
    If Vong = Cot Then GoTo tiep
  Loop Until k = Cot
  
  If k = Cot Then
      tmp = SortArrToStr(Arr, "z", Cot)
      If Not DicKQ.exists(tmp) Then
        DicKQ.Add tmp, ""
        n = n + 1
        Kq(n, Cot + 1) = i
        For j = 1 To Cot
          Kq(n, j) = Arr(1, j)
        Next j
        Tmparr = Split(tmp, "z")
        KqCot(n, 1) = Tmparr(0)
        k = 1
        For j = 1 To Cot - 1
          If KqCot(n, k) <> Tmparr(j) Then
            k = k + 1
            KqCot(n, k) = Tmparr(j)
          End If
        Next j
        Kq(n, Cot + 1) = k
        KqCot(n, C + 1) = k
        KqCot(n, C + 2) = n + 1
      End If
    End If
  If n = Dkq Then Exit For
tiep:
Next S


Sheets("KETQUA").Range("A2").Resize(10000, Cot).ClearContents
Sheets("Sheet1").Range("A2").Resize(10000, C + 2).ClearContents
If n > 0 Then
  Sheets("KETQUA").Range("A2").Resize(n, Cot + 1) = Kq
  Sheets("Sheet1").Range("A2").Resize(n, C + 2) = KqCot
  Sheets("Sheet1").Activate
End If
Set Dic = Nothing:  Set DicKQ = Nothing
Erase Arr:    Erase Darr:   Erase Sarr:    Erase Kq:   Erase Tmparr:    Erase KqCot
End Sub


Function SortArrToStr(Tarr As Variant, Str As String, k As Integer) As String
  Dim ArrList As Object, Tmparr As Variant, j As Integer, tmp As String
  Set ArrList = CreateObject("System.Collections.ArrayList")
  For j = 1 To k
    tmp = Format(Tarr(1, j), "00")
    ArrList.Add tmp
  Next j
  ArrList.Sort
  Tmparr = ArrList.ToArray
  SortArrToStr = Join(Tmparr, Str)
  Set ArrList = Nothing:    Erase Tmparr
End Function
 
Function NN_C() As Variant
Dim Dic As Object, Tarr(), tmp As Byte, k As Byte
Set Dic = CreateObject("scripting.dictionary")
ReDim Tarr(1 To C)
  Do
    tmp = Int(100 * Rnd)
    If Not Dic.exists(tmp) Then
      k = k + 1:  Dic.Add tmp, ""
      Tarr(k) = tmp
    End If
  Loop Until k = C
NN_C = Tarr
Set Dic = Nothing:  Erase Tarr
End Function
 
bạn chạy code
Mã:
Dim C As Integer
Sub TimTrung1()
Dim Dic As Object, DicKQ As Object, tmp As String, Arr(), Darr(), Sarr(), Tmparr, Kq(), KqCot()
Dim i As Integer, j As Integer, k As Integer, Cot As Integer, Vong As Integer, S As Long, Dkq As Long, Lap As Long, n As Long
Set Dic = CreateObject("scripting.dictionary")
Set DicKQ = CreateObject("scripting.dictionary")
n = Sheets("DULIEU").UsedRange.Rows.Count - 1
Cot = Sheets("DULIEU").UsedRange.Columns.Count
C = 80      'khai báo so cot ket qua
Dkq = 1000  'khai báo so dòng ket qua
Lap = 5000  'khai báo so dòng Lap > Dkq, càng lon chay càng lau và ít bo sot ket qua
Darr = Sheets("DULIEU").Range("A2").Resize(n + 1, Cot).Value
ReDim Sarr(1 To n + 1, 1 To Cot)


For j = 1 To Cot
  For i = 1 To n
    If Darr(i, j) <> "" Then
      tmp = Val(Darr(i, j)) & "z" & j
      If Not Dic.exists(tmp) Then Dic.Add tmp, ""
    End If
  Next i
Next j


[SIZE=3][COLOR=#ffd700]ReDim Kq(1 To Dkq, 1 To Cot + 1)[/COLOR][/SIZE][COLOR=#ffd700][/COLOR]
ReDim KqCot(1 To Dkq, 1 To C + 2)
n = 0
For S = 1 To Lap
  ReDim Sarr(1 To C)
  ReDim Arr(1 To 2, 1 To Cot + 1)
  Sarr = NN_C:   k = 0:    Vong = 0
  Do
    For i = 1 To C
      For j = 1 To Cot
        If Arr(2, j) = "" Then
          If Dic.exists(Sarr(i) & "z" & j) Then
            k = k + 1
            Arr(1, j) = Sarr(i)
            Arr(2, j) = j
            Exit For
          End If
        End If
      Next j
    Next i
    Vong = Vong + 1
    If Vong = Cot Then GoTo tiep
  Loop Until k = Cot
  
  If k = Cot Then
      tmp = SortArrToStr(Arr, "z", Cot)
      If Not DicKQ.exists(tmp) Then
        DicKQ.Add tmp, ""
        n = n + 1
        Kq(n, Cot + 1) = i
        For j = 1 To Cot
          Kq(n, j) = Arr(1, j)
        Next j
        Tmparr = Split(tmp, "z")
        KqCot(n, 1) = Tmparr(0)
        k = 1
        For j = 1 To Cot - 1
          If KqCot(n, k) <> Tmparr(j) Then
            k = k + 1
            KqCot(n, k) = Tmparr(j)
          End If
        Next j
        Kq(n, Cot + 1) = k
        KqCot(n, C + 1) = k
        KqCot(n, C + 2) = n + 1
      End If
    End If
  If n = Dkq Then Exit For
tiep:
Next S


Sheets("KETQUA").Range("A2").Resize(10000, Cot).ClearContents
Sheets("Sheet1").Range("A2").Resize(10000, C + 2).ClearContents
If n > 0 Then
  Sheets("KETQUA").Range("A2").Resize(n, Cot + 1) = Kq
  Sheets("Sheet1").Range("A2").Resize(n, C + 2) = KqCot
  Sheets("Sheet1").Activate
End If
Set Dic = Nothing:  Set DicKQ = Nothing
Erase Arr:    Erase Darr:   Erase Sarr:    Erase Kq:   Erase Tmparr:    Erase KqCot
End Sub


Function SortArrToStr(Tarr As Variant, Str As String, k As Integer) As String
  Dim ArrList As Object, Tmparr As Variant, j As Integer, tmp As String
  Set ArrList = CreateObject("System.Collections.ArrayList")
  For j = 1 To k
    tmp = Format(Tarr(1, j), "00")
    ArrList.Add tmp
  Next j
  ArrList.Sort
  Tmparr = ArrList.ToArray
  SortArrToStr = Join(Tmparr, Str)
  Set ArrList = Nothing:    Erase Tmparr
End Function
 
Function NN_C() As Variant
Dim Dic As Object, Tarr(), tmp As Byte, k As Byte
Set Dic = CreateObject("scripting.dictionary")
ReDim Tarr(1 To C)
  Do
    tmp = Int(100 * Rnd)
    If Not Dic.exists(tmp) Then
      k = k + 1:  Dic.Add tmp, ""
      Tarr(k) = tmp
    End If
  Loop Until k = C
NN_C = Tarr
Set Dic = Nothing:  Erase Tarr
End Function
Bạn ơi, khi mình cập nhật thêm dữ liệu ở sheet(DULIEU) lên 2500 cột dữ liệu thì mình thấy báo lỗi OUT OFF MEMORY và báo lỗi code chỗ tô vàng! Bạn giúp mình điều chỉnh code chỗ nào để có thể sử dụng số liệu lên 2500 cột được không? Xin chân thành cảm ơn bạn!
 
Bạn ơi, khi mình cập nhật thêm dữ liệu ở sheet(DULIEU) lên 2500 cột dữ liệu thì mình thấy báo lỗi OUT OFF MEMORY và báo lỗi code chỗ tô vàng! Bạn giúp mình điều chỉnh code chỗ nào để có thể sử dụng số liệu lên 2500 cột được không? Xin chân thành cảm ơn bạn!
bạn thử giảm số dòng kết quả lại xem sao
nếu không được thì có nhiều cách:
- chia dữ liệu ra từng phần để xử lý
- dùng công cụ lập trình khác mạnh hơn
- trang bị siêu máy tính
các cách nầy chỉ dành cho dân chuyên nghiệp, không có mình trong đó
 
Mình mới đọc bài đăng của bạn & xin vài í như sau:

Có tăng lên 2500 cột chăng nữa, nhưng ta chỉ chọn lấy 100 cột có nhiều số nhất mà thôi!

Để vậy: Trong từng cột ta cần xử lí xóa các số trùng trong nó trước đi đã.

Sau đó là chọn lấy 100 cột;

Từ 100 cột ta lại áp dụng macro bài trên của chàng HieuXD xem sao(?)

Nếu 100 cột đã chọn chưa thỏa, thì ta lại nâng dần số cột lên, theo chuỗi nào đó, như 110, 120, . . . .

Chúc vui & thành công!

Nếu đem cái này áp dụng chơi sổ số & trúng thì mời bọn này với nha!
 
Chúc vui & thành công!
Nếu đem cái này áp dụng chơi sổ số & trúng thì mời bọn này với nha!
khà khà, chắc hơn 99,999% là không được mời rồi
dùng toán thống kê để thắng bạc chỉ là các truyền thuyết được thổi phồng của giới truyền thông và của các thầy dạy toán xác suất thống kê, nhằm kích thích sự thích thú và đam mê trong việc học và nghiên cứu môn học khó nuốt của những học trò ngây thơ. có những người có trong tay hàng trăm, hàng nghìn nhà toán học và tin học hàng đầu thế giới nhưng không bao giờ nghiên cứu cách đánh thắng bạc thắng sổ số, vì họ biết chắc chắn sẽ thất bại
sổ số là trò chơi may rủi và ngẫu nhiên, phần thắng luôn thuộc về người đề ra luật chơi, người mua vé số biết sẽ thua, nhưng lại được niềm hy vọng với giá không mắc lắm.
dùng toán thống kê để tính số có khả năng trúng, tìm đủ cách nhưng sai cứ kế tiếp sai, đành bám vào hy vọng, có ngày nào đó nằm mơ thấy trúng số
 
Có tăng lên 2500 cột chăng nữa, nhưng ta chỉ chọn lấy 100 cột có nhiều số nhất mà thôi!

Để vậy: Trong từng cột ta cần xử lí xóa các số trùng trong nó trước đi đã.

Sau đó là chọn lấy 100 cột;

Từ 100 cột ta lại áp dụng macro bài trên của chàng HieuXD xem sao(?)

Nếu 100 cột đã chọn chưa thỏa, thì ta lại nâng dần số cột lên, theo chuỗi nào đó, như 110, 120, . . . .

Chúc vui & thành công!

Nếu đem cái này áp dụng chơi sổ số & trúng thì mời bọn này với nha!
Vâng, ý này của bạn hay quá! Mong bạn giúp đỡ. Xin cảm ơn ạ!
 
Dạo này phong trào lotto phát triển vậy, không biết ai nhờ excel, gpe trúng chưa nhỉ?, trúng thì trích 10% thì cả diễn đàn nhậu to
 
Có tăng lên 2500 cột chăng nữa, nhưng ta chỉ chọn lấy 100 cột có nhiều số nhất mà thôi!

Để vậy: Trong từng cột ta cần xử lí xóa các số trùng trong nó trước đi đã.

Sau đó là chọn lấy 100 cột;

Từ 100 cột ta lại áp dụng macro bài trên của chàng HieuXD xem sao(?)

Nếu 100 cột đã chọn chưa thỏa, thì ta lại nâng dần số cột lên, theo chuỗi nào đó, như 110, 120, . . . .

Chúc vui & thành công!

Nếu đem cái này áp dụng chơi sổ số & trúng thì mời bọn này với nha!
Mình tìm trên diễn đàn bài xoá dữ liệu trùng trong từng cột nhưng không có. Bạn và GPE có thể giúp làm thế nào xử lí xoá các số trùng trong từng cột được? Xin cảm ơn!
 
& đây, xin mời:

PHP:
Option Explicit
Sub TaoDanhSachDuyNhatTheoCot()

Dim Dict As Object, Arr() As String, tArr As Variant
Dim iRow As Long, W As Long, Rws As Long, Col As Integer, J As Integer

With Sheets("DuLieu")
  Rws = .[B2].CurrentRegion.Rows.Count
  Col = .[B2].CurrentRegion.Columns.Count
  For J = 1 To Col
    Set Dict = CreateObject("Scripting.Dictionary")
    tArr = .Cells(2, J).Resize(Rws).Value
    ReDim Arr(1 To Rws + 2, 1 To 1)
    W = 2
    For iRow = 1 To UBound(tArr, 1)
        If Not IsEmpty(tArr(iRow, 1)) And Not Dict.exists(tArr(iRow, 1)) Then
            W = W + 1
            Dict.Add tArr(iRow, 1), W
            Arr(W, 1) = Right("0" & CStr(tArr(iRow, 1)), 2)
        Else
        End If
    Next iRow
    If W Then
        Arr(1, 1) = W
'Chép Lên Trang Tính Khác:'
        Sheets("GPE").Cells(1, J).Resize(W + 1, 1).Value = Arr
        Erase Arr()
    End If
 Next J
End With
End Sub
 
PHP:
Option Explicit
Sub TaoDanhSachDuyNhatTheoCot()

Dim Dict As Object, Arr() As String, tArr As Variant
Dim iRow As Long, W As Long, Rws As Long, Col As Integer, J As Integer

With Sheets("DuLieu")
  Rws = .[B2].CurrentRegion.Rows.Count
  Col = .[B2].CurrentRegion.Columns.Count
  For J = 1 To Col
    Set Dict = CreateObject("Scripting.Dictionary")
    tArr = .Cells(2, J).Resize(Rws).Value
    ReDim Arr(1 To Rws + 2, 1 To 1)
    W = 2
    For iRow = 1 To UBound(tArr, 1)
        If Not IsEmpty(tArr(iRow, 1)) And Not Dict.exists(tArr(iRow, 1)) Then
            W = W + 1
            Dict.Add tArr(iRow, 1), W
            Arr(W, 1) = Right("0" & CStr(tArr(iRow, 1)), 2)
        Else
        End If
    Next iRow
    If W Then
        Arr(1, 1) = W
'Chép Lên Trang Tính Khác:'
        Sheets("GPE").Cells(1, J).Resize(W + 1, 1).Value = Arr
        Erase Arr()
    End If
 Next J
End With
End Sub
Thấy Set Dict trong vòng lặp j hình như có gì đó không ổn thì phải.

Chúc năm mới phát tài!
 
Dễ vậy có đáng gì mà gọi là chia sẻ bạn.
Viết hơn 2000 bài như bạn chắc có lẽ cũng đã biết
Anh SA_DQ (>4000 bài viết) mà viết như vậy chắc có lý do.

Mình không biết dễ vậy là như nào. Nếu được, bạn có thể làm cho mọi người tham khảo không?
 
Anh SA_DQ (>4000 bài viết) mà viết như vậy chắc có lý do.
Mình không biết dễ vậy là như nào. Nếu được, bạn có thể làm cho mọi người tham khảo không?
Nếu viết lại thì tôi sẽ viết thế này.
Dict chỉ tạo 1 lần để giảm bộ nhớ, dùng RemoveAll xóa nội dung trong Dict khi sang cột mới.
Mã:
For J = 1 To Col
Set Dict = CreateObject("Scripting.Dictionary")
=>
Mã:
Set Dict = CreateObject("Scripting.Dictionary")
For J = 1 To Col
Dict.RemoveAll
---
Chắc tết nhất Bác SA_DQ mắc chuyện, viết vội nên cũng chỉ dám nói là "hình như".
 
Nếu viết lại thì:
Dict chỉ tạo 1 lần để giảm bộ nhớ, dùng RemoveAll xóa nội dung trong Dict khi sang cột mới.

Chắc tết nhất Bác SA_DQ mắc chuyện, viết vội nên cũng chỉ dám nói là "hình như".

2uả thật là mình chưa biết rằng: xài lệnh Set .. . như vậy nhiều lần trong vòng lặp là tổn hao bộ nhớ.

Nhưng chắc 1 điều là bạn viết như vậy là chuẩn rồi!

Rất mong những ai quan tâm cũng như hiểu biết viết tiếp về vấn đề này, để mọi người cùng nhau trao đổi.

Chúc xuân vui vẻ!
 
Lần chỉnh sửa cuối:
Mình tìm trên diễn đàn bài xoá dữ liệu trùng trong từng cột nhưng không có. Bạn và GPE có thể giúp làm thế nào xử lí xoá các số trùng trong từng cột được? Xin cảm ơn!
vậy là bạn đọc mà không hiểu các đoạn code rồi, các code loại trùng của các bài trước
Mã:
For j = 1 To C
  Dic.RemoveAll:  k = 0
  For i = 1 To UBound(Sarr)
    If Sarr(i, j) <> "" Then
      If Not Dic.exists(Sarr(i, j)) Then
        Dic.Add Sarr(i, j), ""
        k = k + 1
        Darr(k, j) = Sarr(i, j)
      End If
    Else
      Arr(2, j) = k:       Exit For
    End If
  Next i
Next j
Mã:
For j = 1 To Cot
  For i = 1 To n
    If Darr(i, j) <> "" Then
      tmp = Val(Darr(i, j)) & "z" & j
      If Not Dic.exists(tmp) Then Dic.Add tmp, ""
    End If
  Next i
Next j
 
2uả thật là mình chưa biết rằng: xài lệnh Set .. . như vậy nhiều lần trong vòng lặp là tổn hao bộ nhớ.

Nhưng chắc 1 điều là bạn viết như vậy là chuẩn rồi!

Rất mong những ai quan tâm cũng như hiểu biết viết tiếp về vấn đề này, để mọi người cùng nhau trao đổi.

Chúc xuân vui vẻ!

Không hẳn là hao tổn bộ nhớ đâu. Khi code set nó vào cái khác thì cái cũ bị bỏ rơi/mất chủ. Trên nguyên tắc, VBA tự động biết dọn rác, sẽ thâu hồi lại bộ nhớ.
Tuy nhiên, trên thực tế, có thể cơ quan này làm việc chậm trễ 1 chút, gây nên việc kẹt vùng nhớ.
Vấn đề trong code của bạn là cái đối tượng được tạo lại nhiều lần, hơi hao tổn công sức máy.
 
vậy là bạn đọc mà không hiểu các đoạn code rồi, các code loại trùng của các bài trước
Mã:
For j = 1 To C
  Dic.RemoveAll:  k = 0
  For i = 1 To UBound(Sarr)
    If Sarr(i, j) <> "" Then
      If Not Dic.exists(Sarr(i, j)) Then
        Dic.Add Sarr(i, j), ""
        k = k + 1
        Darr(k, j) = Sarr(i, j)
      End If
    Else
      Arr(2, j) = k:       Exit For
    End If
  Next i
Next j
Mã:
For j = 1 To Cot
  For i = 1 To n
    If Darr(i, j) <> "" Then
      tmp = Val(Darr(i, j)) & "z" & j
      If Not Dic.exists(tmp) Then Dic.Add tmp, ""
    End If
  Next i
Next j
Cảm ơn bạn. Mình hiểu rồi ạ!
 

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

Back
Top Bottom