Excel vba在每个行的同一行中创建组合

时间:2013-08-22 10:17:38

标签: vba excel-vba excel


我需要一个宏的帮助,每个宏都会在同一行中导出一个范围的所有组合(我的意思是水平输出)。

每次我希望每个组合都在一个单元格中。

我想随时更改范围内的字符串数量以及字符串组合的数量(在下面的示例中,范围内有4个字符串,组合中有3个字符串)

1. A B  C  D     -------------ABC --ABD--ACD--BCD
 2. E F  G  H--------------EFG---EFH--EGH--FGH
 3. I G  K  L----------------IGK----IGL---IKL---GKL

在我的网络中找到的模块非常接近我需要的模块。

我是Vba宏的新手,我无法用以下代码实现我想要的东西

Private NextRow As Long

Sub Test()
Dim V() As Variant, SetSize As Integer, i As Integer

    SetSize = Cells(2, Columns.count).End(xlToLeft).Column
    ReDim V(1 To SetSize)

    For i = 1 To SetSize
        V(i) = Cells(2, i).Value
    Next i

    NextRow = 4
    CreateCombinations V, 3, 3

End Sub


Sub CreateCombinations( _
                   OriginalSet() As Variant, _
                  MinSubset As Integer, MaxSubset As Integer)

Dim SubSet() As Variant, SubSetIndex As Long
Dim SubSetCount As Integer, Bit As Integer
Dim k As Integer, hBit As Integer
Dim MaxIndex As Long

hBit = UBound(OriginalSet) - 1
ReDim SubSet(1 To UBound(OriginalSet))

    MaxIndex = 2 ^ UBound(OriginalSet) - 1
    For SubSetIndex = 1 To MaxIndex
        SubSetCount = BitCount(SubSetIndex)
        If SubSetCount >= MinSubset And SubSetCount <= MaxSubset Then
            k = 1
            For Bit = 0 To hBit
                If 2 ^ Bit And SubSetIndex Then
                    SubSet(k) = OriginalSet(Bit + 1)
                    k = k + 1
                End If
            Next Bit
            DoSomethingWith SubSet, SubSetCount
        End If
    Next SubSetIndex
End Sub


Sub DoSomethingWith(SubSet() As Variant, ItemCount As Integer)
Dim i As Integer


    For i = 1 To ItemCount
        Cells(NextRow, i) = SubSet(i)
    Next i
    NextRow = NextRow + 1
End Sub





Function BitCount(ByVal Pattern As Long) As Integer
    BitCount = 0
    While Pattern
        If Pattern And 1 Then BitCount = BitCount + 1
        Pattern = Int(Pattern / 2)
    Wend
End Function

1 个答案:

答案 0 :(得分:0)

这是一种方法:

在excel表格中,添加如下数组公式:

     A     B     C     D    E
 1   
 2   A     B     C     D    {=k_combinations(CONCATENATE(A2;B2;C2;D2);3)}
 3   E     F     G     H    {=k_combinations(CONCATENATE(A3;B3;C3;D3);3)}

请注意,您应该将数组公式扩展到F,G,H等列,以便获得所有结果。 ({}不能手动插入,它们是数组公式的标记):

  1. 选择单元格E2,F2,G2,H2,依此类推至Z2
  2. 键入公式
  3. 要验证输入,请按Ctrl + Shift + Enter
  4. 将以下代码放入代码模块中。

    Public Function k_combinations(ByVal chLetters As String, ByVal k As Long) As Variant
     Dim chCombinations() As String
     Dim uCount As Long
     Dim vReturn() As Variant
     Dim i As Long
    
     uCount = Get_k_combinations(chLetters, chCombinations, k)
    
     ReDim vReturn(0 To uCount - 1) As Variant
    
     For i = 0 To uCount - 1
      vReturn(i) = chCombinations(i)
     Next i
    
     k_combinations = vReturn
    
    End Function
    
    Private Function Get_k_combinations(chLetters As String, chCombinations() As String, ByVal k As Long) As Long
    
     Dim i As Long
     Dim M As Long
     M = Len(chLetters)
    
     If k > 1 Then
    
      Get_k_combinations = 0
      For i = 1 To M - (k - 1)
       Dim chLetter As String
       Dim uNewCombinations As Long
       Dim chSubCombinations() As String
       Dim j As Long
       chLetter = Mid$(chLetters, i, 1)
       uNewCombinations = Get_k_combinations(Right$(chLetters, M - i), chSubCombinations, k - 1)
       ReDim Preserve chCombinations(0 To Get_k_combinations + uNewCombinations) As String
       For j = 0 To uNewCombinations - 1
        chCombinations(Get_k_combinations + j) = chLetter & chSubCombinations(j)
       Next j
       Get_k_combinations = Get_k_combinations + uNewCombinations
      Next i
    
     Else
    
      ReDim chCombinations(0 To M - 1) As String
      For i = 1 To M
       chCombinations(i - 1) = Mid$(chLetters, i, 1)
      Next i
      Get_k_combinations = M
    
     End If
    
    End Function
    
    递归调用

    Get_k_combinations。此方法的性能非常差(因为它使用字符串数组并进行大量重新分配)。如果考虑更大的数据集,则必须对其进行优化。