![](/img/trans.png)
[英]Excel VBA: How to convert ranges to numbers and get output in a column as list
[英]Excel vba How to get combination of the numbers output into excel rows?
我需要找到一种方法将所有数字组合的结果输出到行中(最好如果可以在一行中)
我有8位数字{1,2,3,4,5,6,7,8}组合的典型输出是i; j(i,j是来自集合的数字,i <j)如果拿起两个。 要生成结果很简单:
Dim Myarray_2 As String
Dim sht as Worksheet
set sht = Sheet1
Myarray_2 = "" ' pick up 2 out of 8
For j = 2 To 8
For i = 1 To j - 1
sht.Cells(i + 1, j + 1) = Str(MyArray(i)) + ";" + Str(MyArray(j))
Myarray_2 = Myarray_2 + Str(MyArray(i)) + ";" + Str(MyArray(j)) + "|"
Next i
Next j
这是拾取2的示例,我已将其输出到工作表的行。
我也有解决方案拿起3,现在我的问题是其余的情况,如何获得输出?
这是拾取3的解决方案:
Dim Myarray_3 As String
Myarray_3 = "" ' 3 out of 8
k = 3
Do While k >= 3 And k <= 8
'inner loop through i j
For j = 2 To k - 1
For i = 1 To j - 1
sht.Cells(i + 11, j - 1 + m) = Str(MyArray(i)) + ";" + Str(MyArray(j)) + ";" + Str(MyArray(k))
Myarray_3 = Myarray_3 + Str(MyArray(i)) + ";" + Str(MyArray(j)) + ";" + Str(MyArray(k)) + "|"
Next i
Next j
k = k + 1
m = m + 7
Loop
顺便说一句,MyArray(i)被初始化为Myarray(i)= i
我找到了一些来自另一位优秀程序员的代码,我更改了代码以适应您的问题。 如果你有N作为你的集/数组的成员数,那么你将有(2 ^ N)-1个组合,但是你可以使用自己的条件过滤它们。 请注意,在您的问题中,使用您的条件进行过滤时,成员的顺序非常重要。
代码将首先生成所有组合,然后应用条件。 数组结果将是主输出,因此其大小始终为(2 ^ N)-1。 数组结果过滤将是您想要的。
请注意,如果您从左到右排序数字,则数组Result和Result_filtered将相同。
您可以将任何您喜欢的格式的输出打印到任何工作表中。
此方法使用按位计算来获取组合:
如果N = 2,那么合并的数量将是(2 ^ 2)-1 = 3我们总是在二进制中排除0'当然{A,B} - > {[00],[01],[10],[ 11]} - > {ignore,[B],[A],[AB]}
我希望这有帮助! 如果确实如此,请点击此复选标记
运行子测试:
Sub Test()
Dim bCondSatisfied As Boolean
Dim InxComb As Integer
Dim InxResult As Integer
Dim count As Integer
Dim i As Integer
Dim j As Integer
Dim arr() As String
Dim TestData() As Variant
Dim Result() As Variant
Dim Result_filtered() As Variant
TestData = Array(1, 3, 2, 4)
Call GenerateCombinations(TestData, Result)
'Now you have all the possible combinations, you can apply custom conditions
'(e.g. any number on the left side of another number should be smaller, practically this is satisfied with the
' given test array, but if the numbers are scrambled it will fix the problem)
ReDim Result_filtered(0 To 0)
Result_filtered(0) = "No Combination Matched the Condition" 'default for the case there is no result matched
count = 0
For i = 0 To UBound(Result)
arr() = Result(i)
bCondSatisfied = True
If UBound(arr) > 0 Then 'if there is more than one number in the array, compare the adjacent numbers
For j = 0 To UBound(arr) - 1
If arr(j) > arr(j + 1) Then
bCondSatisfied = False
Exit For
End If
Next j
End If
'Store the array in the filtered array if it passed the test
If bCondSatisfied = True Then
ReDim Preserve Result_filtered(count)
Result_filtered(count) = arr
count = count + 1
End If
Next i
'Print 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
Debug.Print "-----------------" 'separate two results
'Print Result_filtered
For InxResult = 0 To UBound(Result_filtered)
Debug.Print Right(" " & InxResult + 1, 3) & " ";
For InxComb = 0 To UBound(Result_filtered(InxResult))
Debug.Print "[" & Result_filtered(InxResult)(InxComb) & "] ";
Next
Debug.Print
Next
End Sub
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.