Function CmbRnk(ByVal a&, ByVal b&, ByVal Rng As Range) As Variant
Dim i&, j&, Tb&()
Tb = RngToTab(Rng)
If UBound(Tb) = 0 Then CmbRnk = CVErr(xlErrNum): Exit Function
If Not IsCmb(a, b, Tb) Then CmbRnk = CVErr(xlErrNum): Exit Function
CmbRnk = 1
For i = 2 To Tb(1): CmbRnk = CmbRnk + CmbNb(a + 1 - i, b - 1): Next i
For j = 2 To b: For i = Tb(j - 1) + 2 To Tb(j): CmbRnk = CmbRnk + CmbNb(a + 1 - i, b - j): Next i, j
End Function
Private Function RngToTab(ByVal Rng As Range) As Long()
Dim ai&, am&, bi&, bm&, i&, j&, Tb&(), ws As Worksheet
Set ws = Rng.Worksheet
ai = Rng.Row: am = Rng.Rows.Count: bi = Rng.Column: bm = Rng.Columns.Count
ReDim Tb(am * bm)
On Error GoTo Line1
For i = ai To ai + am - 1: For j = bi To bi + bm - 1
Tb((i - ai) * bm + j - bi + 1) = ws.Cells(i, j)
Next j, i
Line2:
RngToTab = Tb: Exit Function
Line1:
ReDim Tb(0): GoTo Line2
End Function
Private Function IsCmb(ByVal a&, ByVal b&, Tb&()) As Boolean
Dim i&
If UBound(Tb) <> b Then Exit Function
If a < 1 Or b < 1 Or b > a Then Exit Function
For i = 1 To UBound(Tb)
If Not (Tb(i) > Tb(i - 1)) Or Tb(i) > a Or Tb(i) < 1 Then Exit Function
Next i
IsCmb = True
End Function
Private Function CmbNb(ByVal a&, ByVal b&) As Double
Dim c&
c = a - b
If b < c Then c = b
If c = 0 Then CmbNb = 1 Else CmbNb = MthFac(a, c) / MthFac(c)
End Function
Private Function MthFac(ByVal a&, Optional Nb& = 0) As Double
Dim i&, n&
If Nb = 0 Then Nb = a
MthFac = 1
For i = 0 To Nb - 1: MthFac = MthFac * (a - i): Next i
End Function