The following is an implementation of the Johnson-Trotter algorithm for listing permutations. This is a small modification of the one I wrote once when you play with rude decisions for the Traveler. Note that it returns a 2-dimensional array that can consume a lot of memory. It can be reorganized so that it is a subuser, where the permutations were consumed, not saved. Just replace the piece of code at the bottom (where the current permutation, perm , is stored in the perms array) with code that uses the permutation.
Function Permutations(n As Long) As Variant 'implements Johnson-Trotter algorithm for 'listing permutations. Returns results as a variant array 'Thus not feasible for n > 10 or so Dim perm As Variant, perms As Variant Dim i As Long, j As Long, k As Long, r As Long, D As Long, m As Long Dim p_i As Long, p_j As Long Dim state As Variant m = Application.WorksheetFunction.Fact(n) ReDim perm(1 To n) ReDim perms(1 To m, 1 To n) As Integer ReDim state(1 To n, 1 To 2) 'state(i,1) = where item i is currently in perm 'state(i,2) = direction of i k = 1 'will point to current permutation For i = 1 To n perm(i) = i perms(k, i) = i state(i, 1) = i state(i, 2) = -1 Next i state(1, 2) = 0 i = n 'from here on out, i will denote the largest moving 'will be 0 at the end Do While i > 0 D = state(i, 2) 'swap p_i = state(i, 1) p_j = p_i + D j = perm(p_j) perm(p_i) = j state(i, 1) = p_j perm(p_j) = i state(j, 1) = p_i p_i = p_j If p_i = 1 Or p_i = n Then state(i, 2) = 0 Else p_j = p_i + D If perm(p_j) > i Then state(i, 2) = 0 End If For j = i + 1 To n If state(j, 1) < p_i Then state(j, 2) = 1 Else state(j, 2) = -1 End If Next j 'now find i for next pass through loop If i < n Then i = n Else i = 0 For j = 1 To n If state(j, 2) <> 0 And j > i Then i = j Next j End If 'record perm in perms: k = k + 1 For r = 1 To n perms(k, r) = perm(r) Next r Loop Permutations = perms End Function
Tested as follows:
Sub test() Range("A1:G5040").Value = Permutations(7) Dim A As Variant, i As Long, s As String A = Permutations(10) For i = 1 To 10 s = s & " " & A(3628800, i) Next i Debug.Print s End Sub
The first 20 lines of output are as follows:

In addition, 2 1 3 4 5 6 7 8 9 10 is printed in the direct window. My first version used the vanilla version and caused a memory error with n = 10 . I changed it so that perms redistributed to contain integers (which consume less memory than options) and can now handle 10 . It takes about 10 seconds to run the test code.