У меня было подобное требование несколько лет назад. Я не помню, почему, и у меня больше нет кода, но я помню алгоритм. Для меня это было одноразовое упражнение, поэтому я хотел простой код. Я не заботился об эффективности.
Я буду использовать одноосновные массивы, потому что это упрощает объяснение. Поскольку VBA поддерживает одноосновные массивы, все должно быть в порядке, хотя это простая настройка для массивов, начинающихся с нуля, если вы этого хотите.
AllFields (от 1 до NumFields) содержит имена.
Есть цикл: для Inx = 1 до 2 ^ NumFields - 1
В цикле рассматривайте Inx как двоичное число с битами, пронумерованными от 1 до NumFields. Для каждого N от 1 до NumFields, если бит N равен единице, включите AllFields (N) в эту комбинацию.
Этот цикл генерирует 2 ^ NumFields - 1 комбинации:
Names: A B C
Inx: 001 010 011 100 101 110 111
CombinationS: C B BC A A C AB ABC
Единственная сложность с VBA - получить значение Бита N.
Дополнительная секция
Поскольку каждый имел возможность реализовать биты моего алгоритма, я подумал, что лучше показать, как я это сделал.
Я заполнил массив тестовых данных неприятным набором имен полей, поскольку нам не сказали, какие символы могут быть в имени.
Подпрограмма GenerateCombination делает бизнес. Я фанат рекурсии, но я не думаю, что мой алгоритм достаточно сложен, чтобы оправдать его использование в этом случае. Я возвращаю результат в неровном массиве, который я предпочитаю конкатенации. Вывод GenerateCombination выводится в непосредственное окно, чтобы продемонстрировать его вывод.
Option Explicit
Эта процедура демонстрирует комбинации Generate
Sub Test()
Dim InxComb As Integer
Dim InxResult As Integer
Dim TestData() As Variant
Dim Result() As Variant
TestData = Array("A A", "B,B", "C|C", "D;D", "E:E", "F.F", "G/G")
Call GenerateCombinations(TestData, Result)
For InxResult = 0 To UBound(Result)
Debug.Print Right(" " & InxResult + 1, 3) & " ";
For InxComb = 0 To UBound(Result(InxResult))
Debug.Print "[" & Result(InxResult)(InxComb) & "] ";
Next
Debug.Print
Next
End Sub
GenerateCombination делает бизнес.
Sub GenerateCombinations(ByRef AllFields() As Variant, _
ByRef Result() As Variant)
Dim InxResultCrnt As Integer
Dim InxField As Integer
Dim InxResult As Integer
Dim I As Integer
Dim NumFields As Integer
Dim Powers() As Integer
Dim ResultCrnt() As String
NumFields = UBound(AllFields) - LBound(AllFields) + 1
ReDim Result(0 To 2 ^ NumFields - 2) ' one entry per combination
ReDim Powers(0 To NumFields - 1) ' one entry per field name
' Generate powers used for extracting bits from InxResult
For InxField = 0 To NumFields - 1
Powers(InxField) = 2 ^ InxField
Next
For InxResult = 0 To 2 ^ NumFields - 2
' Size ResultCrnt to the max number of fields per combination
' Build this loop's combination in ResultCrnt
ReDim ResultCrnt(0 To NumFields - 1)
InxResultCrnt = -1
For InxField = 0 To NumFields - 1
If ((InxResult + 1) And Powers(InxField)) <> 0 Then
' This field required in this combination
InxResultCrnt = InxResultCrnt + 1
ResultCrnt(InxResultCrnt) = AllFields(InxField)
End If
Next
' Discard unused trailing entries
ReDim Preserve ResultCrnt(0 To InxResultCrnt)
' Store this loop's combination in return array
Result(InxResult) = ResultCrnt
Next
End Sub