託尼Dallimore的修改後的一些代碼Creating a list of all possible unique combinations from an array (using VBA)
用法:
- 在微距 「stackBox」
---變 「工作表Sheet1」 工作表的名稱,你想
輸入的框的單元格A1數
輸入B1的名稱,C1,...等上..
呼叫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
讓我回到你今晚。我剛剛意識到,如果我要超過16種不同類型的框,excel沒有足夠的行。所以我認爲在填滿時我必須嘗試將它向右移動。只是爲了增加這個問題。宏是否可以在粘貼之前檢查盒子組合。就像讀取盒子的高度和重量一樣,以便它在堆疊時粘貼這個呢?當它超過一定的高度和重量時,它不會打擾它。 Thx已經爲你輸入了。 – dave123
如果您使用的是Excel 2003或更低版本,那麼您將沒有足夠的行來輸出所有組合。我們或許可以它輸出到第二,第三,...列起 只要結果不是更大然後65,536行,256列= 2^24 ..它應該是確定 對於第二和第三個問題,當然這是可能。你可以在之後處理它。 – Larry
完美,讓我們繼續。 A,B,C,d,E,F,G,H,I,J。如果你能提供幫助,我會問另一個關於檢查身高和體重的問題。再次感謝 – dave123