繁体   English   中英

Excel vba如何将数字输出组合成excel行?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM