【问题标题】:Excel vba Create combinations in same row each oneExcel vba 在同一行中创建每个组合
【发布时间】:2015-01-30 22:55:36
【问题描述】:


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

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

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

【问题讨论】:

  • 欢迎来到 SO。你尝试了什么?
  • 感谢 Arno,我尝试了在 web 中找到的模块。作为 Vba 中的新模块,我无法自己进行更改。
  • 您能否对示例数据进行格式化以更易于理解? ABCD 都在一个单元格中吗?它们是用空格分隔的吗?
  • 感谢我的回复。在我的初始范围内,每个字符串都在一个单元格中。不是 ABCD 都在一个单元格中。所以,它们没有用空格分隔。
  • 但是每个组合 id 都喜欢在一个单元格中。例如 ABC 所有这些都在一个单元格中,ABD 所有这些都在该行的下一个单元格中。

标签: vba excel


【解决方案1】:

这是一种方法:

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

【讨论】:

  • 嗨 d-stroyer。非常感谢您的回答。我只是试试这个,但有一个问题。在此函数的导出中没有字母队列。示例:对于 4 组字母 ABCD,3 的组合是 ACD。你的功能给了我 CDA,我不想要它。有没有办法可以修复它?
  • 另外,当我选择时,对于 4 组字母 ABCD,2 个字母的组合(我更改为 {=k_combinations(CONCATENATE(A2;B2;C2;D2);2)})给出我只有四个梳子并重复相同。它应该返回六种不同的组合。再次感谢您的友好回答。
  • 这不是代码的问题。您在 E2 中输入了一个公式,然后将其扩展至 F2,... 这意味着您在 F2 中的公式与 E2 中的公式不同。正如我的帖子中所说,您必须将其写为 数组公式
  • 当然这不是代码问题。问题是我的问题,因为我没有看到你的 3 个帮助步骤。现在真的有效。非常感谢。
  • 很高兴它可以工作。实际上,我在您上次发表评论后添加了 3 个帮助。这个excel功能不是最人性化的。顺便说一句,如果你喜欢我的回答,请accept它。
猜你喜欢
  • 1970-01-01
  • 2013-05-25
  • 2015-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-29
  • 1970-01-01
相关资源
最近更新 更多