Option Explicit
Option Base 0
Private Sub PermuteColumns(sourceColumns As Range, targetColumn As Range, separator As String)
Dim r As Long
Dim c As Long
ReDim counters(sourceColumns.Columns.Count - 1) As Long
ReDim lastRows(sourceColumns.Columns.Count - 1) As Long
Dim targetString As String
' Source data must be a single row
If sourceColumns.Rows.Count <> 1 Then Exit Sub
' Columns must be contiguous
If sourceColumns.Count > 1 Then
r = 0
For c = 2 To sourceColumns.Count
If sourceColumns(c).Column - sourceColumns(c - 1).Column <> 1 Then
r = 1
Exit For
End If
Next c
If r = 1 Then Exit Sub
End If
' Target must be a single cell
If targetColumn.Count <> 1 Then Exit Sub
' Set up counters and find the last row for each column
For c = 0 To sourceColumns.Columns.Count - 1
With Sheets(sourceColumns.Parent.Name)
counters(c) = 0
lastRows(c) = .Cells(.Rows.Count, sourceColumns.Column + c).End(xlUp).Row - sourceColumns.Row
End With
Next c
' Now fill in the permutations
r = 0
Do
' The permutation string
targetString = ""
' Look through each column
For c = 0 To sourceColumns.Columns.Count - 1
If separator = vbTab Then
targetColumn.Offset(r, c).Value = sourceColumns(c + 1).Offset(counters(c), 0).Value
Else
targetString = targetString & IIf(targetString = "", "", separator) & sourceColumns(c + 1).Offset(counters(c), 0).Value
End If
Next c
' Transfer the target string if necessary
If separator <> vbTab Then targetColumn.Offset(r, 0).Value = targetString
' Move to the next row
r = r + 1
' Now increment the counters
c = sourceColumns.Columns.Count - 1
Do
counters(c) = counters(c) + 1
If counters(c) > lastRows(c) Then
counters(c) = 0
c = c - 1
Else
Exit Do
End If
Loop Until c < 0
Loop Until c < 0
End Sub
Public Sub Perm_ABCD_I()
PermuteColumns [a1:d1], [I2], " "
End Sub