1


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

我每次都想在一个单元格中进行每种组合。

我想随时更改范围内的字符串数以及字符串组合的数量(在下面的示例中,范围内有 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
4

1 回答 1

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

将以下代码放入代码模块中。

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被递归调用。这种方法的性能很差(因为它使用字符串数组并进行了大量的重新分配)。如果您考虑更大的数据集,则必须对其进行优化。

于 2013-08-22T12:14:12.417 回答