Devido ao grande número de Quads possíveis ao lidar com 22 células por linha, sugiro uma abordagem diferente da que você usou para duplas e trigêmeos.
Eu criaria um objeto definido pelo usuário (classe) para conter informações sobre o conteúdo do quad e uma contagem. (Eu também joguei um método para criar uma matriz dos itens Quad). Então eu coletaria as quadras em um objeto de dicionário - no código abaixo eu usei early-binding (defina uma referência, em Tools --> References
to Microsoft Scripting Runtime
, mas se isso for distribuído, provavelmente você deve mudar para tarde Ligação.
Ao coletar os quadriciclos após a primeira linha, podemos usar o dicionário para testar se o quad já existe; se isso acontecer, adicionamos um à contagem; se isso não acontecer, nós o armazenamos como um novo quad.
O intervalo é dimensionado procurando a última linha na coluna A; e a última coluna na linha 1. Ele pressupõe que seus dados iniciem em A1 (como você mostra na planilha) e que não haja linhas de cabeçalho. Se esse não for o caso, talvez seja necessário fazer alguns ajustes.
Ele também assume que as entradas em cada linha são classificadas. Se esse não for o caso, você precisará adicionar uma rotina de classificação antes de gerar o Quad.
EDIT : Note que a rotina irá falhar (com um erro 1004) se a saída desejada incluir mais de 2 ^ 20 quads, devido ao limite de linhas do Excel. Existem pelo menos duas maneiras de lidar com isso:
-
Aumente o limiar de modo a produzir somente quads que tenham uma contagem de 2, 3 ou o que for necessário para se encaixar em um único conjunto de colunas (provavelmente o método mais simples)
-
altere a rotina de saída para distribuir a saída em vários conjuntos de colunas.
Módulo de turma
Be sure to rename this to cQuad
Option Explicit
'Rename cQuad
Private pQ1 As Long
Private pQ2 As Long
Private pQ3 As Long
Private pQ4 As Long
Private pCnt As Long
Private pArr As Variant
Public Property Get Q1() As Long
Q1 = pQ1
End Property
Public Property Let Q1(Value As Long)
pQ1 = Value
End Property
Public Property Get Q2() As Long
Q2 = pQ2
End Property
Public Property Let Q2(Value As Long)
pQ2 = Value
End Property
Public Property Get Q3() As Long
Q3 = pQ3
End Property
Public Property Let Q3(Value As Long)
pQ3 = Value
End Property
Public Property Get Q4() As Long
Q4 = pQ4
End Property
Public Property Let Q4(Value As Long)
pQ4 = Value
End Property
Public Property Get Arr() As Variant
Dim V(1 To 4)
V(1) = Me.Q1
V(2) = Me.Q2
V(3) = Me.Q3
V(4) = Me.Q4
Arr = V
End Property
Public Property Get Cnt() As Long
Cnt = pCnt
End Property
Public Property Let Cnt(Value As Long)
pCnt = Value
End Property
Módulo regular
Option Explicit
'Set Reference to Microsoft Scripting Runtime
Sub CheckForQuads()
Dim cQ As cQuad, dQ As Dictionary
Dim vSrc As Variant, vRes As Variant
Dim I As Long, J As Long
Dim wsData As Worksheet, wsRes As Worksheet, rRes As Range
Dim V, W
Dim sKey As String
Set wsData = Worksheets("Data")
Set wsRes = Worksheets("Results")
Set rRes = wsRes.Cells(1, 10)
With wsData
I = .Cells(.Rows.Count, 1).End(xlUp).Row 'Last Row
J = .Cells(1, .Columns.Count).End(xlToLeft).Column 'Last Column
vSrc = .Range(.Cells(1, 1), .Cells(I, J))
End With
Set dQ = New Dictionary
For I = 1 To UBound(vSrc, 1)
'Size array for number of combos in each row
V = Combos(Application.WorksheetFunction.Index(vSrc, I, 0))
'create an object for each Quad, including each member, and the count
For J = 1 To UBound(V, 1)
Set cQ = New cQuad
With cQ
.Q1 = V(J, 1)
.Q2 = V(J, 2)
.Q3 = V(J, 3)
.Q4 = V(J, 4)
.Cnt = 1
sKey = Join(.Arr, Chr(1))
'Add one to the count if Quad already exists
If Not dQ.Exists(sKey) Then
dQ.Add sKey, cQ
Else
dQ(sKey).Cnt = dQ(sKey).Cnt + 1
End If
End With
Next J
Next I
'Output the results
'set a threshold
Const TH As Long = 1
'Size the output array
I = 0
For Each V In dQ.Keys
If dQ(V).Cnt >= TH Then I = I + 1
Next V
ReDim vRes(0 To I, 1 To 5)
'Headers
vRes(0, 1) = "Value 1"
vRes(0, 2) = "Value 2"
vRes(0, 3) = "Value 3"
vRes(0, 4) = "Value 4"
vRes(0, 5) = "Count"
'Output the data
I = 0
For Each V In dQ.Keys
Set cQ = dQ(V)
With cQ
If .Cnt >= TH Then
I = I + 1
vRes(I, 1) = .Q1
vRes(I, 2) = .Q2
vRes(I, 3) = .Q3
vRes(I, 4) = .Q4
vRes(I, 5) = .Cnt
End If
End With
Next V
'Output the data
Set rRes = rRes.Resize(UBound(vRes, 1) + 1, UBound(vRes, 2))
With rRes
.EntireColumn.Clear
.Value = vRes
With .Rows(1)
.Font.Bold = True
.HorizontalAlignment = xlCenter
End With
.EntireColumn.AutoFit
.Sort key1:=.Columns(.Columns.Count), _
order1:=xlDescending, Header:=xlYes, MatchCase:=False
End With
End Sub
Function Combos(Vals)
Dim I As Long, J As Long, K As Long, L As Long, M As Long
Dim V
ReDim V(1 To WorksheetFunction.Combin(UBound(Vals), 4), 1 To 4)
M = 0
For I = 1 To UBound(Vals) - 3
For J = I + 1 To UBound(Vals) - 2
For K = J + 1 To UBound(Vals) - 1
For L = K + 1 To UBound(Vals)
M = M + 1
V(M, 1) = Vals(I)
V(M, 2) = Vals(J)
V(M, 3) = Vals(K)
V(M, 4) = Vals(L)
Next L
Next K
Next J
Next I
Combos = V
End Function