Permutation VBA correction

vergab

New Member
Joined
Jun 21, 2016
Messages
22
Hi,
Could someone help me to convert this code as follows?
Write the permutation of the items listed in column 'A' to separate columns.
I would like to use it as shown in the example.

Sample:

ItemsResult
1123A
212A3
3132A
A13A2
1A23
1A32
213A
21A3
231A
23A1
2A13
2A31
312A
31A2
321A
32A1
3A12
3A21
A123
A132
A213
A231
A312
A321

<tbody>
</tbody>

Code:

Option Explicit
Option Compare Text
Dim CurrentRow
Sub DoString()
On Error Resume Next
Dim Instring As String
Dim i As Integer, j As Integer
Instring = Range("A1").Value
Range("A1").Select
CurrentRow = 1
Call GetPermutation("", Instring)
TxToCoL
End Sub

Sub GetPermutation(X As String, y As String)
On Error Resume Next
Dim j, i
j = Len(y)
If j < 2 Then
Cells(CurrentRow, 1) = X & y
CurrentRow = CurrentRow + 1
Else
For i = 1 To j
Call GetPermutation(X + Mid(y, i, 1), _
Left(y, i - 1) + Right(y, j - i))
Next
End If
End Sub
Sub TxToCoL()
'Range("A1:A" & Range("A" & Rows.Count).End(xlUp).Row).Select
Range("A1:A40320").Select
Selection.TextToColumns Destination:=Range("D1"), DataType:=xlFixedWidth, _
FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1), Array _
(5, 1), Array(6, 1), Array(7, 1), Array(8, 1), Array(9, 1)), _
TrailingMinusNumbers:=True
End Sub
 

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.
I've never done this before. Challenge accepted!
Code:
Sub myPermutation ()
     itemsColumn = 1
     resultColumn = 2
     firstRow = 2
     lastRow = Cells(Rows.Count, itemsColumn).End(xlUp).Row
     
     Dim itemsArray() As String
     a = 0
     ReDim Preserve itemsArray(a)
     r = firstRow
     Do Until r > lastRow
          itemValue = Cells(r, itemsColumn).Value
          ReDim Preserve itemsArray(a)
          itemsArray(a) = itemValue
          a = a + 1
          r = r + 1
     Loop
     If itemsArray(0) = "" _
     And UBound(itemsArray) = 1 Then
          End
     End If
     r = firstRow
     Call generatePermuatations(a, itemsArray, resultColumn, r)
End Sub
Sub generatePermutations(n, A, resultColumn, r)
     printRow = Cells(Rows.Count, resultColumn).End(xlUp).Row + 1
     If printRow < r Then 
          PrintRow = r
     End If
     If n = 1 Then
          For Each element In A
               Cells(printRow, resultColumn).Value = element
               resultColumn = resultColumn + 1
          Next element
          End
     End If
     i = 0
     Do Until i < n - 1
          Call generatePermutations(n - 1, A, resultColumn, r)
          If IsEven(n) Then
               myMove = A(i)
               A(i) = A(n - 1)
               A(n - 1) = myMove
          Else
               myMove = A(0)
               A(0) = A(n - 1)
               A(n - 1) = myMove
          End If
          printRow = Cells(Rows.Count, resultColumn).End(xlUp).Row + 1
          resultC = resultColumn
          For Each element In A
               Cells(printRow, resultColumn).Value = element
               resultC = resultC + 1
          Next element
          i = i + 1
     Loop
     generatePermutations(n - 1, A, resultColumn, r)
End Function

I'm 99% sure this won't work. This is my attempt to translate Heap's algorithm from pseudocode to VBA.
 
Last edited:
Upvote 0
Nice effort WarPig....!!! Good work.

Vergab, you can NOT go wrong with PGC01's code....

Follow this link from within this forum;
http://www.mrexcel.com/forum/excel-...c-applications-combinations-permutations.html

I have used it over the years with great success thanks to PGC01 and have munched it, altered it, loved it, and on occasion hated It! Good luck with it.... Be sure to restrict your output to less than 7 items chosen (or 8) elements with a subset less than 20.....otherwise you'll crash VBA (Excel) unless you own and operate a supercomputer!

Regards,

P.U.
 
Upvote 0
It stopped in the row "Call generatePermutations" with error message:

"Compile error: Sub or Function not defined"
 
Upvote 0
PGC01's code isn't permutation. Permutation result must be "n!" if there are "n" different items.
 
Upvote 0
I've been looking at this. Here's the sheet I have:


Book1
ABCDEFGHIJK
1ItemsResultsResults
2aabcdabcd
3bbacdabdc
4ccabdacbd
5dacbdacdb
6bcadadbc
7cbadadcb
8dbacbacd
9bdacbadc
10adbcbcad
11dabcbcda
12badcbdac
13abdcbdca
14acdbcabd
15cadbcadb
16dacbcbad
17adcbcbda
18cdabcdab
19dcabcdba
20dcbadabc
21cdbadacb
22bdcadbac
23dbcadbca
24cbdadcab
25bcdadcba
Sheet1
Cell Formulas
RangeFormula
H2=GetPermutation($A$2:$A$5, ROW() - 1, COLUMN() - 7)


And here's the code I was using:

Code:
Private savedCount As Long
Private savedOutput() As String
Private Sub GetPermutations(permString As String, currentSelection As String, ByRef currentResult As String)

Dim i As Long

If permString = "" Then
    currentResult = currentResult & IIf(currentResult = "", "", ",") & currentSelection
    Exit Sub
End If

For i = 1 To Len(permString)
    GetPermutations Left$(permString, i - 1) & Mid$(permString, i + 1), currentSelection & Mid$(permString, i, 1), currentResult
Next i

End Sub
Public Function GetPermutation(sourceRange As Range, permNumber As Long, indexNumber As Long) As String

Dim rangeCount As Long
Dim permOutput As String

rangeCount = sourceRange.Count

If permNumber < 1 Or permNumber > WorksheetFunction.Permut(rangeCount, rangeCount) _
Or indexNumber < 1 Or indexNumber > rangeCount Then
    GetPermutation = ""
    Exit Function
End If

If rangeCount <> savedCount Then
    savedCount = rangeCount
    permOutput = ""
    GetPermutations Left$("123456789", savedCount), "", permOutput
    savedOutput = Split(permOutput, ",")
End If

GetPermutation = sourceRange(CLng(Mid$(savedOutput(permNumber - 1), indexNumber, 1))).Value

End Function
Public Sub GeneratePermutations(n As Long, a() As String, r As Long, c As Long)

Dim i As Long
Dim t As String

If n = 1 Then
    For i = 0 To UBound(a)
        Cells(r, c + i).Value = a(i)
    Next i
    r = r + 1
Else
    For i = 0 To n - 2
        GeneratePermutations n - 1, a, r, c
        If n Mod 2 = 0 Then
            t = a(i)
            a(i) = a(n - 1)
            a(n - 1) = t
        Else
            t = a(0)
            a(0) = a(n - 1)
            a(n - 1) = t
        End If
    Next i
    GeneratePermutations n - 1, a, r, c
End If

End Sub
Sub GenerateAllPermutations()

Dim i As Long
Dim s As Range
Dim t As Range
Dim c As Long
Dim r As Long

Set s = Range("$A$2:$A$5")
Set t = Range("$C$2")

ReDim a(s.Count - 1) As String

For i = 1 To s.Count
    a(i - 1) = s(i).Value
Next i

r = t.Row
c = t.Column

GeneratePermutations s.Count, a, r, c

End Sub

Cells C2:F25 were populated by calling GenerateAllPermutations() in which you can see I've defined the source and target ranges.
Cells H2:K25 are populated using a formula (in H2) which you can copy across and down. Note that the formula has a correction factor on the ROW() and COLUMN() which you may need to change if you move it elsewhere. You could change it to:

=GetPermutation($A$2:$A$5, ROW() - ROW($H$2) + 1, COLUMN() - COLUMN($H$2) + 1)

Which might help if you cut and paste it somewhere else.

The GenerateAllPermutations() macro uses a VBA implementation of Heap's algorithm. The UDF is something I knocked together myself that uses caching so it doesn't generate all permutations each time.

These may be useful to you but in the main I just took this on as an interesting exercise :)

WBD
 
Last edited:
Upvote 0
It works! :) How will change the code if I want to write not only 5 but any quantity of items in column A?
 
Upvote 0

Forum statistics

Threads
1,215,684
Messages
6,126,199
Members
449,298
Latest member
Jest

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