Sub XYZ()
Dim sArr(), a(), uni, S, Res(), tmp$
Dim i&, iR&, r&, j&, c&, k&, q&, sRow&, sCol&, sR&, sC&, Nhom$, strNhom$, Nhom2$
sArr = Range("A3:P26").Value
sR = Application.Count(Range("B3:B26"))
sRow = UBound(sArr): sCol = UBound(sArr, 2)
TroLai:
ReDim Res(1 To sRow, 1 To sCol)
ReDim a(1 To sR, 1 To 4) 'Mang thu tu dong co du lieu va thu tu cot ket qua
k = 0
For i = 1 To UBound(sArr)
Res(i, 1) = sArr(i, 1)
If sArr(i, 2) > 0 Then
If sArr(i, 2) >= sR Then MsgBox ("Vo nghiem"): Exit Sub
k = k + 1
a(k, 1) = i 'Thu tu dong sArr
a(k, 2) = sArr(i, 2) 'So cot ket qua
a(k, 4) = "|"
Res(i, 2) = sArr(i, 2)
End If
Next i
For i = 1 To sR 'thu tu DongNguon mang "a"
c = 0
sC = a(i, 2) 'So cot Nguon
r = a(i, 1) 'thu tu DongNguon sArr
Nhom = sArr(r, 1) & "|"
uni = UniqueRand(sR) 'Mang thu tu ngau nhien khong trung
For j = 1 To sR
iR = uni(j, 1) 'thu tu DongKetQua mang "a"
If iR > 0 And iR <> i Then
If a(iR, 2) > a(iR, 3) Then
uni(j, 1) = Empty 'Loai bo dong uni(j, 1)
c = c + 1 'thu tu cot nguon
a(iR, 3) = a(iR, 3) + 1 'Thu tu Cot ket qua dong iR
tmp = sArr(r, c + 2) 'Ket qua
Res(a(iR, 1), a(iR, 3) + 2) = tmp
a(iR, 4) = a(iR, 4) & Nhom
If c = sC Then Exit For
End If
End If
Next j
Do While c < sC 'Dieu chinh ket qua cac dong
For j = 1 To sR
If a(j, 2) > a(j, 3) Then 'dong ket qua con thieu
strNhom = a(j, 4)
Nhom2 = sArr(a(j, 1), 1)
For j2 = 1 To sR ' dong thay the
If InStr(1, a(j2, 4), "|" & Nhom) = 0 Then
S = Split(a(j2, 4), "|")
For q = 1 To UBound(S) - 1 ' thu tu cot cua dong thay the
If InStr(1, strNhom, "|" & S(q) & "|") = 0 And Nhom2 <> S(q) Then
c = c + 1
tmp = sArr(r, c + 2) 'Ket qua moi
a(j, 3) = a(j, 3) + 1 'Thu tu Cot ket qua dong j
Res(a(j, 1), a(j, 3) + 2) = Res(a(j2, 1), q + 2) 'chinh ket qua theo dong moi
Res(a(j2, 1), q + 2) = tmp 'Thay ket qua moi
a(j2, 4) = Replace(a(j2, 4), "|" & S(q) & "|", "|" & Nhom) 'Chinh strNhom thay the
a(j, 4) = a(j, 4) & S(q) & "|" ' strNhom moi
Exit For
End If
Next q
If q < UBound(S) Then Exit For
End If
Next j2
If j2 < sR + 1 Then Exit For Else GoTo TroLai 'Botay.com, chay lai tu dau
End If
Next j
Loop
Next i
Range("R3").Resize(sRow, sCol) = Res
End Sub
Function UniqueRand(ByVal N As Long) As Variant
Dim Arr() As Long, i&, RndNum&, tmp&
ReDim Arr(1 To N, 1 To 1)
Randomize
For i = 1 To N
RndNum = Int(N * Rnd() + 1)
If Arr(RndNum, 1) = 0 Then tmp = RndNum Else tmp = Arr(RndNum, 1)
If Arr(N, 1) = 0 Then Arr(RndNum, 1) = N Else Arr(RndNum, 1) = Arr(N, 1)
Arr(N, 1) = tmp
N = N - 1
Next i
UniqueRand = Arr
End Function