【问题标题】:stacking and layering boxes in excel [closed]在excel中堆叠和分层框[关闭]
【发布时间】:2012-10-08 16:13:50
【问题描述】:

我正在分层,在 Excel 中堆叠我的选项。我以类似的方式提出了这个问题,但是我现在想在其中添加更多细节。如果我有 n 个要堆叠的盒子,堆叠它们的可能选项是 2^n-1。让我举一个 3 个盒子的例子,我们给它们命名为 A、B、C 和 D。它们的堆叠方式无关紧要,即 AB=BA 和 ABC=CAB,它们算作 1 个堆叠选项。结果是:

A、B、C、AB、BC、AC、ABC

现在我想创建一个 excel 文件,我将在其中输入方框字母,它为我提供了所有堆叠可能性的列表。所以我会提供盒子的数量和字母。 (3 个框,A、B、C)Excel 会读入并在单元格中为我提供选项。

是否可以将选项排成一行?对于 n 个盒子?

这可能吗?谁能帮我解决这个问题?

谢谢你!

【问题讨论】:

  • 今晚让我回复你。我刚刚意识到,如果我要检查 16 种不同类型的框,excel 没有足够的行。所以我想当它被填满时,我必须试着把它移到右边。只是为了补充这个问题。宏是否可以在粘贴之前检查框组合。就像读取盒子的高度和重量一样,所以当它堆叠时它也会粘贴这个?当它超过一定的高度和重量时,它不会打扰它。谢谢你已经输入了。
  • 如果您使用 Excel 2003 或更低版本,那么您将没有足够的行来输出所有组合。我们可能可以将其输出到第 2、3、.. 列,只要结果不大于 65,536 行 x 256 列 = 2^ 24 .. 它应该没问题 对于第 2 和第 3 个问题,肯定是可能的。您可以稍后处理它。
  • 完美,让我们继续几个。 A,B,C,D,E,F,G,H,I,J。如果你能帮忙,我会问另一个关于检查身高和体重的问题。再次感谢
  • 明天我可以帮忙

标签: excel vba combinatorics


【解决方案1】:

根据 Tony Dallimore 在Creating a list of all possible unique combinations from an array (using VBA) 上的帖子修改了一些代码

用法:

  1. 在宏“stackBox”中——将“Sheet1”更改为您的工作表名称 想要

  2. 输入单元格A1中的框数

  3. 在B1、C1、...等中输入名称..

  4. 调用stackBox

“Sheet1”中的输入格式和输出结果:

3   A   B   C   D   E
A                   
B                   
AB                  
C                   
AC                  
BC                  
ABC                 
D                   
AD                  
BD                  
ABD                 
CD                  
ACD                 
BCD                 
E                   
AE                  
BE                  
ABE                 
CE                  
ACE                 
BCE                 
DE                  
ADE                 
BDE                 
CDE 

代码:

 Function stackBox()
    Dim ws As Worksheet
    Dim width As Long
    Dim height As Long
    Dim numOfBox As Long
    Dim optionsA() As Variant
    Dim results() As Variant
    Dim str As String
    Dim outputArray As Variant
    Dim i As Long, j As Long
    Set ws = Worksheets("Sheet1")
    With ws
        'clear last time's output
        height = .Cells(.Rows.Count, 1).End(xlUp).row
        If height > 1 Then
            .Range(.Cells(2, 1), .Cells(height, 1)).ClearContents
        End If

        numOfBox = .Cells(1, 1).Value
        width = .Cells(1, .Columns.Count).End(xlToLeft).Column
        If width < 2 Then
            MsgBox "Error: There's no item, please fill your item in Cell B1,C1,..."
            Exit Function
        End If
        ReDim optionsA(0 To width - 2)
        For i = 0 To width - 2
            optionsA(i) = .Cells(1, i + 2).Value
        Next i

        GenerateCombinations optionsA, results, numOfBox


        ' copy the result to sheet only once
        ReDim outputArray(1 To UBound(results, 1) - LBound(results, 1) + 1, 1 To 1)
        Count = 0
        For i = LBound(results, 1) To UBound(results, 1)
            If Not IsEmpty(results(i)) Then
                'rowNum = rowNum + 1
                str = ""

                For j = LBound(results(i), 1) To UBound(results(i), 1)
                    str = str & results(i)(j)
                Next j
                Count = Count + 1
                outputArray(Count, 1) = str
            '.Cells(rowNum, 1).Value = str
            End If
        Next i
        .Range(.Cells(2, 1), .Cells(UBound(outputArray, 1) + 1, 1)).Value = outputArray
    End With

End Function

Sub GenerateCombinations(ByRef AllFields() As Variant, _
                                             ByRef Result() As Variant, ByVal numOfBox As Long)

  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

    If InxResultCrnt = 0 Then
        Debug.Print "testing"
    End If
    'additional logic here
    If InxResultCrnt >= numOfBox Then
        Result(InxResult) = Empty

    Else
         ' Discard unused trailing entries
        ReDim Preserve ResultCrnt(0 To InxResultCrnt)
        ' Store this loop's combination in return array
        Result(InxResult) = ResultCrnt
    End If

  Next

End Sub

【讨论】:

  • 如果我把盒子的数量设置为 3,我也会得到 ABCDE 的盒子组合......无论如何我不需要这个变量。我只需要知道所有可能的组合。
  • 请确保您使用的是最新版本的代码:P
猜你喜欢
  • 2018-12-03
  • 1970-01-01
  • 2018-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-15
  • 1970-01-01
相关资源
最近更新 更多