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:
You're welcome. :cool:
Hi Eric, thank you so much </SPAN></SPAN>

The code is working swift and flawless the I have the max 252.252 combinations which generates by using MyMaxes = Array(5, 4, 5) & MaxLen = 14
</SPAN></SPAN>
setting MaxOutputRows = 65000. This gives result in 4 columns 65.000+65.000+65.000+54.252 =252.252 total output...
</SPAN></SPAN>

I am finding one difficulty for farther analysis needs to put each column combinations separate (11111XXXX22222) using Text-to-Columns in 14 columns and next column living 3 empty next 14 columns this way I split them in 14+3, 14+3, 14+3, 14+3 so far total columns used 68. As my version has 258 columns it is perfect.
</SPAN></SPAN>

But if this would have only the set I want to output no problem but all the time I need to combine with different set so I get different out put in 1 to max 4 columns depending on total combinations setting MaxOutputRows = 65000.
</SPAN></SPAN>

At this point I require you help once again does it is viable to ask can I get output instead of in the one column in the separate columns. This will avoid for me to use Text-to-Columns and also will be the time saver solution which I did not realize initially.
</SPAN></SPAN>

Please would you consider my request and if possible to make it for me.
</SPAN></SPAN>

Sorry for the inconvenience :oops:
</SPAN></SPAN>

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

Kind Regards,
</SPAN></SPAN>
Kishan
</SPAN></SPAN>
 
Upvote 0

Excel Facts

Waterfall charts in Excel?
Office 365 customers have access to Waterfall charts since late 2016. They were added to Excel 2019.
I can include the Text-to-columns as part of the macro. It increases the time the macro takes to run significantly though. I have an old copy of Excel 2000. On my computer, the original macro ran in 68 seconds, the updated version took 160 seconds.

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, Gap As Long

    Set MyDict = CreateObject("Scripting.Dictionary")
    
    MyChars = "1X2"
    MyMaxes = Array(5, 4, 5)
    MaxLen = 14
    Set MyOutput = Range("C1")
    MaxOutputRows = 65000
    Gap = 3
    
    Range(MyOutput, Cells(Rows.Count, Columns.Count)).ClearContents
    
    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
            MyOutput.Resize(MaxOutputRows).Value = MyTable
            Columns(MyOutput.Column).TextToColumns Destination:=Columns(MyOutput.Column), _
                                                      DataType:=xlDelimited, Comma:=True
            ReDim MyTable(1 To MaxOutputRows, 1 To 1)
            Set MyOutput = MyOutput.Offset(, MaxLen + Gap)
            ctr = 1
        End If
    Next i
    If ctr > 1 Then
        MyOutput.Resize(MaxOutputRows).Value = MyTable
        Columns(MyOutput.Column).TextToColumns Destination:=Columns(MyOutput.Column), _
                                               DataType:=xlDelimited, Comma:=True
    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 can include the Text-to-columns as part of the macro. It increases the time the macro takes to run significantly though. I have an old copy of Excel 2000. On my computer, the original macro ran in 68 seconds, the updated version took 160 seconds.

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, Gap As Long

    Set MyDict = CreateObject("Scripting.Dictionary")
    
    MyChars = "1X2"
    MyMaxes = Array(5, 4, 5)
    MaxLen = 14
    Set MyOutput = Range("C1")
    MaxOutputRows = 65000
    Gap = 3
    
    Range(MyOutput, Cells(Rows.Count, Columns.Count)).ClearContents
    
    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
            MyOutput.Resize(MaxOutputRows).Value = MyTable
            Columns(MyOutput.Column).TextToColumns Destination:=Columns(MyOutput.Column), _
                                                      DataType:=xlDelimited, Comma:=True
            ReDim MyTable(1 To MaxOutputRows, 1 To 1)
            Set MyOutput = MyOutput.Offset(, MaxLen + Gap)
            ctr = 1
        End If
    Next i
    If ctr > 1 Then
        MyOutput.Resize(MaxOutputRows).Value = MyTable
        Columns(MyOutput.Column).TextToColumns Destination:=Columns(MyOutput.Column), _
                                               DataType:=xlDelimited, Comma:=True
    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
Hi Eric, thank you so much for adding macro Text-to-Columns it is time saving solution </SPAN></SPAN>
I appreciate a lot your time and help you spent to solve my query as I wanted. My other macro works very slowly but this update version macro took only 10 seconds and the previous finished only in 7 second that is really amazing. </SPAN></SPAN>

I change the parameter " MyMaxes = Array(13, 0, 1)" & "Set MyOutput = Range("J6")" </SPAN></SPAN>I have filled header in the first 5 rows as shown below </SPAN></SPAN>


Book1
IJKLMNOPQRSTUVWX
1C1C2C3C4C5C6C7C8C9C10C11C12C13C14
2C1C2C3C4C5C6C7C8C9C10C11C12C13C14
3C1C2C3C4C5C6C7C8C9C10C11C12C13C14
4C1C2C3C4C5C6C7C8C9C10C11C12C13C14
5C1C2C3C4C5C6C7C8C9C10C11C12C13C14
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Sheet4


After I run the macro I am getting result as shown below the range is fixed "J6" it wipe out the headers. Please can you check it is doing with me only? </SPAN></SPAN>


Book1
IJKLMNOPQRSTUVWX
1C1
2C1
3C1
4C1
5C1
611111111111112
711111111111121
811111111111211
911111111112111
1011111111121111
1111111111211111
1211111112111111
1311111121111111
1411111211111111
1511112111111111
1611121111111111
1711211111111111
1812111111111111
1921111111111111
20
21
22
23
Sheet5


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

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

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, Gap As Long

    Set MyDict = CreateObject("Scripting.Dictionary")
    
    MyChars = "1X2"
    MyMaxes = Array(5, 4, 5)
    MaxLen = 14
    Set MyOutput = Range("C6")
    MaxOutputRows = 65000
    Gap = 3
    
    Range(MyOutput, Cells(Rows.Count, Columns.Count)).ClearContents
    Set MyOutput = MyOutput.Resize(MaxOutputRows)
    
    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
            MyOutput.Value = MyTable
            MyOutput.TextToColumns Destination:=MyOutput, DataType:=xlDelimited, Comma:=True
            ReDim MyTable(1 To MaxOutputRows, 1 To 1)
            Set MyOutput = MyOutput.Offset(, MaxLen + Gap)
            ctr = 1
        End If
    Next i
    If ctr > 1 Then
        MyOutput.Value = MyTable
        MyOutput.TextToColumns Destination:=MyOutput, DataType:=xlDelimited, Comma:=True
    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 have an old copy of Excel 2000. On my computer
</SPAN></SPAN>
Hi Eric, I am wondering still you got installed a copy of so old version in your computer; that is great, I am running windows 7 professional and this version works fine. BTW I want to update windows 10. Please can you tell me does this version will work in the windows 10?</SPAN></SPAN>

Kind Regards,
</SPAN></SPAN>
Kishan
</SPAN></SPAN>

Try:

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, Gap As Long

    Set MyDict = CreateObject("Scripting.Dictionary")
    
    MyChars = "1X2"
    MyMaxes = Array(5, 4, 5)
    MaxLen = 14
    Set MyOutput = Range("C6")
    MaxOutputRows = 65000
    Gap = 3
    
    Range(MyOutput, Cells(Rows.Count, Columns.Count)).ClearContents
    Set MyOutput = MyOutput.Resize(MaxOutputRows)
    
    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
            MyOutput.Value = MyTable
            MyOutput.TextToColumns Destination:=MyOutput, DataType:=xlDelimited, Comma:=True
            ReDim MyTable(1 To MaxOutputRows, 1 To 1)
            Set MyOutput = MyOutput.Offset(, MaxLen + Gap)
            ctr = 1
        End If
    Next i
    If ctr > 1 Then
        MyOutput.Value = MyTable
        MyOutput.TextToColumns Destination:=MyOutput, DataType:=xlDelimited, Comma:=True
    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
You're a great Eric, I am felling lucky to get an appropriate solution. Thank you for helping me out; I really appreciate your kindness and support.
You have designed a macro so nicely I can say it is a wonderful, better than my request and over my expectations. Macro took just 00:00:09 second to end up.
</SPAN></SPAN>

Good luck and have a great weekend.
</SPAN></SPAN>

Thank you :pray: Eric


Kind Regards,
</SPAN></SPAN>
Kishan
:)</SPAN></SPAN>
 
Upvote 0
My home PC runs Windows 7. It's 10 years old now, but when I bought it, it was high-end. So it surprises me some that the macro takes 3 minutes on my PC, and only 9 seconds on yours. I wouldn't have expected that there would such a big difference, even after 10 years.

As far as running Excel 2000 on Windows 10, I'd expect that it would work, but don't know for sure. It's interesting, I have both Excel 2000 and Excel 2013 installed on the same PC. When installing newer versions of Excel, they typically uninstall the older versions, but they leave Excel 2000 alone.

Anyway, I'm glad I could help, although I'm still skeptical about whether you'll get anything useful from all that data. :eek:
 
Upvote 0
It's 10 years old now, but when I bought it, it was high-end. So it surprises me some that the macro takes 3 minutes on my PC, and only 9 seconds on yours. I wouldn't have expected that there would such a big difference, even after 10 years.
Moore Law certainly predicts that, but it surprises me. CPU clock rates have increased, but I think most performance gains have come through having more cores, which VBA can't avail itself of.
 
Upvote 0
My home PC runs Windows 7. It's 10 years old now, but when I bought it, it was high-end. So it surprises me some that the macro takes 3 minutes on my PC, and only 9 seconds on yours. I wouldn't have expected that there would such a big difference, even after 10 years.
Hi Eric, I apologies as I change the MyMaxes = Array(7, 3, 4) which makes 120.120 combinations Macro took just 00:00:09 second, but with set-up MyMaxes = Array(5, 4, 5) which makes 252.252 combinations Macro took 00:00:33 second to end up. So sorry for the miss information.

As far as running Excel 2000 on Windows 10, I'd expect that it would work, but don't know for sure. It's interesting, I have both Excel 2000 and Excel 2013 installed on the same PC. When installing newer versions of Excel, they typically uninstall the older versions, but they leave Excel 2000 alone.
With windows 7 professional I as I have installed excel 2000 I tried to install excel 2007 and it detect immediately version 2000 and ask to remove it. May be the 2013 is has this option to keep both. Thank you for the information.


Anyway, I'm glad I could help, although I'm still skeptical about whether you'll get anything useful from all that data. :eek:
I am very happy with the macro it is very useful for me. </SPAN></SPAN>:biggrin:

Have a great day
</SPAN></SPAN>

Kind Regards,
</SPAN></SPAN>
Kishan
</SPAN></SPAN>
 
Upvote 0
Moore Law certainly predicts that, but it surprises me. CPU clock rates have increased, but I think most performance gains have come through having more cores, which VBA can't avail itself of.
Hi shg, I have a question Eric macro generate the combinations as per limiting 1, X and 2,

For example setting MyMaxes = Array(10, 0, 4), mean "1's"=10, "X's"=0 and "2's"=4 this gives total 1001 combinations,

If setting MyMaxes = Array(9, 2, 3), mean "1's"=9, "X's"=2 and "2's"=3 this gives total 20020 combinations.
</SPAN></SPAN>

Is there could be any way to calculate different array combinations without using the VBA just with the formula?
</SPAN></SPAN>

Here are some more examples...
</SPAN></SPAN>

1
X
2
TT:Combi
13
0
1
14
12
1
1
182
10
1
3
4.004
10
2
2
6.006
9
3
2
20.020
8
2
4
45.045
8
5
1
18.018
7
0
7
3.432
7
3
4
120.120
6
1
7
24.024

<TBODY>
</TBODY>


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

Kind Regards,
</SPAN></SPAN>
Kishan
</SPAN></SPAN>
 
Last edited:
Upvote 0
A​
B​
C​
D​
E​
1​
1
x
2
2​
13​
0​
1​
14​
D2: {=FACT(SUM(A2:C2)) / PRODUCT(FACT(A2:C2))}
3​
12​
1​
1​
182​
4​
10​
1​
2​
858​
5​
10​
2​
2​
6,006​
6​
9​
3​
2​
20,020​
 
Upvote 0

Forum statistics

Threads
1,217,364
Messages
6,136,117
Members
449,993
Latest member
Sphere2215

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