Limit numbers for X and 2

Kishan

Well-known Member
Joined
Mar 15, 2011
Messages
1,648
Office Version
  1. 2010
Platform
  1. Windows
Using Excel 2000</SPAN></SPAN>
Hi,</SPAN></SPAN>

The code below generate any combinations I use for example Const v& = 4 to 14 where Array is ("1", "X", "2") (3^4=81, and 3^14=4.782.969) so in the given example 3^4= 81 combinations are generated in the column A and column C & D there is a resume how many combinations can be found with example (4-1's=1) with (3-1's & 1-x's =4) </SPAN></SPAN>

My query is it possible to limit the numbers of X's & 2's to get only output for those combinations only, like for example 2-1's, 1-X's, 1-2's =12 combinations showed highlighted in blue that can be generated only. So the output only 12 not all the 81 </SPAN></SPAN>
Code....</SPAN></SPAN>
Code:
Sub GenerateCombi()
Const v& = 4
     
Dim z, y() As String, q(), u&, g&
Dim a&, b&, c&, d&, p&, MaxRow&
MaxRow = Rows.Count
z = Array("1", "X", "2")
u = UBound(z) + 1
ReDim y(1 To u ^ v, 1 To 1)
     
For a = 1 To v
    For b = 1 To u ^ v Step u ^ a
        For c = b To b + u ^ (a - 1) - 1
            For d = 1 To u
                y(c + u ^ (a - 1) * (d - 1), 1) = _
                    z(d - 1) & y(c + u ^ (a - 1) * (d - 1), 1)
            Next d
        Next c
    Next b
Next a

For a = 1 To u ^ v Step MaxRow
ReDim q(1 To MaxRow, 1 To 1)
    g = 0: p = p + 1
    For b = 1 To MaxRow
        If a + b > u ^ v + 1 Then Exit For
        q(b, 1) = y(a + b - 1, 1)
        g = g + 1
    Next b
Cells(p).Resize(g) = q
Next a

End Sub
</SPAN></SPAN>

Example data... </SPAN></SPAN>


Book1
ABCDE
11111
2111X
31112
411X11 | X | 2Total
511XX4 | 0 | 01
611X23 | 1 | 04
711213 | 0 | 14
8112X2 | 2 | 06
911222 | 1 | 112
101X112 | 0 | 26
111X1X1 | 3 | 04
121X121 | 2 | 112
131XX11 | 1 | 212
141XXX1 | 0 | 34
151XX20 | 4 | 01
161X210 | 3 | 14
171X2X0 | 2 | 26
181X220 | 1 | 34
1912110 | 0 | 41
20121X
211212
2212X1
2312XX
2412X2
251221
26122X
271222
28X111
29X11X
30X112
31X1X1
32X1XX
33X1X2
34X121
35X12X
36X122
37XX11
38XX1X
39XX12
40XXX1
41XXXX
42XXX2
43XX21
44XX2X
45XX22
46X211
47X21X
48X212
49X2X1
50X2XX
51X2X2
52X221
53X22X
54X222
552111
56211X
572112
5821X1
5921XX
6021X2
612121
62212X
632122
642X11
652X1X
662X12
672XX1
682XXX
692XX2
702X21
712X2X
722X22
732211
74221X
752212
7622X1
7722XX
7822X2
792221
80222X
812222
82
83
84
85
Sheet1


Thank you in advance</SPAN></SPAN>

Regards,</SPAN></SPAN>
Kishan</SPAN></SPAN>
 
Last edited:

Excel Facts

Will the fill handle fill 1, 2, 3?
Yes! Type 1 in a cell. Hold down Ctrl while you drag the fill handle.
Hi,</SPAN></SPAN>

It may be easier way to build a new code in which with the array of ("1", "X", "2") option of selection outcomes for 4 to 14 matches. And the limit for X and 2
</SPAN></SPAN>
For example: if selection could permit following options
</SPAN></SPAN>
Outcome=4
</SPAN></SPAN>
Limit for X= 1
</SPAN></SPAN>
Limit for 2= 1
</SPAN></SPAN>
Than combinations will be total 12 in each of the 4 outcome only 1 time will be X =1, and 2=1 in any of the 4 outcomes
</SPAN></SPAN>
Example combinations...
</SPAN></SPAN>


Book1
AB
111X2
2112X
31X12
41X21
5121X
612X1
7X112
8X121
9X211
10211X
1121X1
122X11
13
14
Sheet2


Thank you in advance
</SPAN></SPAN>

Regards,
</SPAN></SPAN>
Kishan
</SPAN></SPAN>
 
Last edited:
Upvote 0
Hi,</SPAN></SPAN>

It may be easier way to build a new code in which with the array of ("1", "X", "2") option of selection outcomes for 4 to 14 matches. And the limit for X and 2
</SPAN></SPAN>
For example: if selection could permit following options
</SPAN></SPAN>
Outcome=4
</SPAN></SPAN>
Limit for X= 1
</SPAN></SPAN>
Limit for 2= 1
</SPAN></SPAN>
Than combinations will be total 12 in each of the 4 outcome only 1 time will be X =1, and 2=1 in any of the 4 outcomes
</SPAN></SPAN>
Hi,</SPAN></SPAN>

I am sure there is no macro that can do what I have requested neither in the goggle search nor in the MrExcel site.
</SPAN></SPAN>

Please any one can help to make it or May I did not find give me a link.
</SPAN></SPAN>

Thank you in advance
</SPAN></SPAN>

Regards,
</SPAN></SPAN>
Kishan
</SPAN></SPAN>
 
Upvote 0
Try:

Rich (BB code):
Public MyDict

Sub CallRecur()
Dim MyChars As String, MyMaxes As Variant, MaxLen As Long, MyOutput As Range

    Set MyDict = CreateObject("Scripting.Dictionary")
    
    MyChars = "1X2"
    MyMaxes = Array(2, 1, 1)
    MaxLen = 4
    Set MyOutput = Range("C3")
    
    Call Recur(MyChars, MyMaxes, MaxLen, "", 0)
    
    Range(MyOutput, Cells(Rows.Count, MyOutput.Column)).ClearContents
    MyOutput.Resize(MyDict.Count).Value = WorksheetFunction.Transpose(MyDict.keys)
    
End Sub

Sub Recur(ByRef RChars, ByRef RMaxes, ByRef ML, ByVal RStr, ByVal Depth)
Dim i as long, li as long

    If ML = Depth Then
        MyDict(RStr) = 1
        Exit Sub
    End If
    
    For i = 1 To Len(RChars)
        li = Len(RStr) - Len(Replace(RStr, Mid(RChars, i, 1), ""))
        If li < RMaxes(i - 1) Then Call Recur(RChars, RMaxes, ML, RStr & Mid(RChars, i, 1), Depth + 1)
    Next i
    
End Sub
Set the parameters in red as desired.
 
Last edited:
Upvote 0
Can you make use of a formula solution? If so, put this formula in cell D5 and copy it down to the row for the last data cell in Column C...

=SUMPRODUCT(--(LEN(A1:A81)-LEN(SUBSTITUTE(A1:A81,"1",""))=--LEFT(C5)),--(LEN(A1:A81)-LEN(SUBSTITUTE(A1:A81,"X",""))=--MID(C5,5,1)),--(LEN(A1:A81)-LEN(SUBSTITUTE(A1:A81,"2",""))=--RIGHT(C5)))
 
Upvote 0
Try:

Rich (BB code):
Public MyDict

Sub CallRecur()
Dim MyChars As String, MyMaxes As Variant, MaxLen As Long, MyOutput As Range

    Set MyDict = CreateObject("Scripting.Dictionary")
    
    MyChars = "1X2"
    MyMaxes = Array(2, 1, 1)
    MaxLen = 4
    Set MyOutput = Range("C3")
    
    Call Recur(MyChars, MyMaxes, MaxLen, "", 0)
    
    Range(MyOutput, Cells(Rows.Count, MyOutput.Column)).ClearContents
    MyOutput.Resize(MyDict.Count).Value = WorksheetFunction.Transpose(MyDict.keys)
    
End Sub

Sub Recur(ByRef RChars, ByRef RMaxes, ByRef ML, ByVal RStr, ByVal Depth)
Dim i as long, li as long

    If ML = Depth Then
        MyDict(RStr) = 1
        Exit Sub
    End If
    
    For i = 1 To Len(RChars)
        li = Len(RStr) - Len(Replace(RStr, Mid(RChars, i, 1), ""))
        If li < RMaxes(i - 1) Then Call Recur(RChars, RMaxes, ML, RStr & Mid(RChars, i, 1), Depth + 1)
    Next i
    
End Sub
Set the parameters in red as desired.
Hi Eric, thank you very much for building a new macro I liked the way you build it so I can Set the parameters in red as desired. That is fantastic option. MyMaxes = Array(2, 1, 1) I see also that I did not mentioned 1's only limit for the X's & 2's but you caught the idea. Thank you for your understanding it was bit complicate. </SPAN></SPAN>

I tried the macro, which worked perfectly as per giving example post #1, and might it will work also fine with all the parameters with new versions.</SPAN></SPAN>

After I tried with the version 2000, which I am, running found it stop at the line below </SPAN></SPAN>
Code:
 MyOutput.Resize(MyDict.Count).Value = WorksheetFunction.Transpose(MyDict.keys)
</SPAN></SPAN>

For some example in the case of following parameters...noticed that may be "WorksheetFunction.Transpose" is not compatible with large data in my version and also 2000 has 65536 max row so need that the code continue writing after 65000 in the next column...to complete the target combinations. </SPAN></SPAN>


Book1
DEFGH
51X2CombiStatus
69052.002Work Fne
75902.002Work Fne
893220.020Stop at the line above
983360.060Stop at the line above
10734120.120Stop at the line above
11554252.252Stop at the line above
12563168.168Stop at the line above
1357272.072Stop at the line above
1458118.018Stop at the line above
Sheet10


I do appreciate your kind help</SPAN></SPAN>

Please can you take a look?</SPAN></SPAN>

Kind Regards,</SPAN></SPAN>
Kishan</SPAN></SPAN>
 
Last edited:
Upvote 0
Can you make use of a formula solution? If so, put this formula in cell D5 and copy it down to the row for the last data cell in Column C...

=SUMPRODUCT(--(LEN(A1:A81)-LEN(SUBSTITUTE(A1:A81,"1",""))=--LEFT(C5)),--(LEN(A1:A81)-LEN(SUBSTITUTE(A1:A81,"X",""))=--MID(C5,5,1)),--(LEN(A1:A81)-LEN(SUBSTITUTE(A1:A81,"2",""))=--RIGHT(C5)))
Hi Rick, the formula you gave that count the column A as per column C patterns but I wanted a combinations generator, any way thank you for your help </SPAN></SPAN>

Kind Regards,
</SPAN></SPAN>
Kishan
</SPAN></SPAN>
 
Upvote 0
I really must stress that there is NEVER any real good reason to actually enumerate all of the combinations. If you get up to the tens of thousands, or hundreds of thousands of combinations, there's no way you can possibly find anything. Nevertheless, here's some code to use multiple columns if needed:

Rich (BB code):
Public MyDict


Sub CallRecur()
Dim MyChars As String, MyMaxes As Variant, MaxLen As Long, MyOutput As Range
Dim MaxOutputRows As Long, MyTable As Variant, i As Long, MyKeys As Variant


    Set MyDict = CreateObject("Scripting.Dictionary")
    
    MyChars = "1X2"
    MyMaxes = Array(2, 1, 1)
    MaxLen = 4
    Set MyOutput = Range("C3")
    MaxOutputRows = 10000
    
    Call Recur(MyChars, MyMaxes, MaxLen, "", 0)
    
    MyKeys = MyDict.keys
    ctr = 1
    ReDim MyTable(1 To MaxOutputRows, 1 To 1)
    For i = 0 To MyDict.Count - 1
        MyTable(ctr, 1) = MyKeys(i)
        ctr = ctr + 1
        If ctr > MaxOutputRows Then
            Range(MyOutput, Cells(Rows.Count, MyOutput.Column)).ClearContents
            MyOutput.Resize(MaxOutputRows).Value = MyTable
            ReDim MyTable(1 To MaxOutputRows, 1 To 1)
            Set MyOutput = MyOutput.Offset(, 1)
            ctr = 1
        End If
    Next i
    If ctr > 1 Then
        Range(MyOutput, Cells(Rows.Count, MyOutput.Column)).ClearContents
        MyOutput.Resize(MaxOutputRows).Value = MyTable
    End If
    
End Sub


Sub Recur(ByRef RChars, ByRef RMaxes, ByRef ML, ByVal RStr, ByVal Depth)
Dim i As Long, li As Long


    If ML = Depth Then
        MyDict(RStr) = 1
        Exit Sub
    End If
    
    For i = 1 To Len(RChars)
        li = Len(RStr) - Len(Replace(RStr, Mid(RChars, i, 1), ""))
        If li < RMaxes(i - 1) Then Call Recur(RChars, RMaxes, ML, RStr & Mid(RChars, i, 1), Depth + 1)
    Next i
    
End Sub
 
Upvote 0
I really must stress that there is NEVER any real good reason to actually enumerate all of the combinations. If you get up to the tens of thousands, or hundreds of thousands of combinations, there's no way you can possibly find anything. Nevertheless, here's some code to use multiple columns if needed:
I am totally agreed with you it is worthless but creating all may understand it better. I am very grateful to you. :)

I really must stress that there is NEVER any real good reason to actually enumerate all of the combinations. If you get up to the tens of thousands, or hundreds of thousands of combinations, there's no way you can possibly find anything. Nevertheless, here's some code to use multiple columns if needed:

Rich (BB code):
Public MyDict


Sub CallRecur()
Dim MyChars As String, MyMaxes As Variant, MaxLen As Long, MyOutput As Range
Dim MaxOutputRows As Long, MyTable As Variant, i As Long, MyKeys As Variant


    Set MyDict = CreateObject("Scripting.Dictionary")
    
    MyChars = "1X2"
    MyMaxes = Array(2, 1, 1)
    MaxLen = 4
    Set MyOutput = Range("C3")
    MaxOutputRows = 10000
    
    Call Recur(MyChars, MyMaxes, MaxLen, "", 0)
    
    MyKeys = MyDict.keys
    ctr = 1
    ReDim MyTable(1 To MaxOutputRows, 1 To 1)
    For i = 0 To MyDict.Count - 1
        MyTable(ctr, 1) = MyKeys(i)
        ctr = ctr + 1
        If ctr > MaxOutputRows Then
            Range(MyOutput, Cells(Rows.Count, MyOutput.Column)).ClearContents
            MyOutput.Resize(MaxOutputRows).Value = MyTable
            ReDim MyTable(1 To MaxOutputRows, 1 To 1)
            Set MyOutput = MyOutput.Offset(, 1)
            ctr = 1
        End If
    Next i
    If ctr > 1 Then
        Range(MyOutput, Cells(Rows.Count, MyOutput.Column)).ClearContents
        MyOutput.Resize(MaxOutputRows).Value = MyTable
    End If
    
End Sub


Sub Recur(ByRef RChars, ByRef RMaxes, ByRef ML, ByVal RStr, ByVal Depth)
Dim i As Long, li As Long


    If ML = Depth Then
        MyDict(RStr) = 1
        Exit Sub
    End If
    
    For i = 1 To Len(RChars)
        li = Len(RStr) - Len(Replace(RStr, Mid(RChars, i, 1), ""))
        If li < RMaxes(i - 1) Then Call Recur(RChars, RMaxes, ML, RStr & Mid(RChars, i, 1), Depth + 1)
    Next i
    
End Sub
Wow! Eric, very much kind of you quick alters a macro to work with my version, it is so flexible and easy-to-use. It is absolutely an extraordinary and powerful solution. :pray:</SPAN></SPAN>

Macro worked very flawless with all the parameters without any limits.
</SPAN></SPAN>

I heartily appreciate your time and kind help, Thank you
</SPAN></SPAN>

Kind Regards,
</SPAN></SPAN>
Kishan :-D
</SPAN></SPAN>
 
Upvote 0

Forum statistics

Threads
1,223,162
Messages
6,170,431
Members
452,326
Latest member
johnshaji

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top