У меня есть сводная таблица истинности. Эта таблица истинности используется для определения того, какая сборка используется на основе номенклатуры модели. Каждая строка представляет цифру номера модели.
Я хочу отменить консолидацию, чтобы иметь строку для каждой уникальной конфигурации. Это показано ниже.
Вот пример первого неконсолидированного номера сборки.
Я безуспешно попробовал сценарий VBA, приведенный ниже, но открыт для всех вариантов, включая формулу на основе ячеек, чтобы попытаться решить:
Sub UnconsolidateList()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(4) 'Change to your sheet number
Dim lastRow As Integer
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim i As Integer
For i = lastRow To 4 Step -1
Dim configs() As String
configs = Split(ws.Cells(i, 3).Value, ",")
Dim capacities() As String
capacities = Split(ws.Cells(i, 4).Value, ",")
Dim vents() As String
generation = Split(ws.Cells(i, 5).Value, ",")
Dim cases() As String
factoryops = Split(ws.Cells(i, 6).Value, ",")
Dim j As Integer, k As Integer, l As Integer, m As Integer
For j = LBound(configs) To UBound(configs)
For k = LBound(capacities) To UBound(capacities)
For l = LBound(generation) To UBound(generation)
For m = LBound(factoryops) To UBound(factoryops)
If j + k + l + m > 0 Then 'Avoid duplicating the original row
lastRow = lastRow + 1 'Increment the row number where data will be inserted
ws.Rows(lastRow & ":" & lastRow).Insert Shift:=xlDown 'Insert a new row at the end of the list
ws.Cells(lastRow - 1, "A").Copy Destination:=ws.Cells(lastRow, "A") 'Copy part no.
ws.Cells(lastRow - 1, "B").Copy Destination:=ws.Cells(lastRow, "B") 'Copy type
ws.Cells(lastRow, "C").Value2 = Trim(configs(j))
ws.Cells(lastRow, "D").Value2 = Trim(capacities(k))
ws.Cells(lastRow, "E").Value2 = Trim(generation(l))
ws.Cells(lastRow, "F").Value2 = Trim(factoryops(m))
End If
Next m
Next l
Next k
Next j
Next i
End Sub


Option Explicit
Sub Demo()
Dim i As Long, j As Long, c As Variant
Dim arrData, arrRes, iR As Long, aRow() As Variant
Dim LastRow As Long, ColCnt As Long
Dim oSht1 As Worksheet, aTxt
Dim oColl As New Collection
Set oSht1 = Sheets("Sheet1") ' modify as needed
' load source table
arrData = oSht1.Range("A1").CurrentRegion.Value
ColCnt = UBound(arrData, 2)
ReDim aRow(ColCnt - 1)
' loop through each row
For i = LBound(arrData) + 1 To UBound(arrData)
' split all items
For j = LBound(arrData, 2) To UBound(arrData, 2)
aRow(j - 1) = Split(arrData(i, j), ",")
Next j
GenerateCombinations oColl, aRow
Next i
' populate output
ReDim arrRes(1 To oColl.Count, ColCnt - 1)
iR = 0
For Each c In oColl
aTxt = Split(c, "|")
iR = iR + 1
For j = 0 To UBound(aTxt)
arrRes(iR, j) = aTxt(j)
Next
Next
' write output to new sheet
Sheets.Add
Range("A1").Resize(, ColCnt).Value = oSht1.Range("A1").Resize(, ColCnt).Value
Range("A2").Resize(iR, ColCnt).Value = arrRes
End Sub
Sub GenerateCombinations(ByRef oColl As Object, aVals() As Variant, Optional curStr As String = "", Optional colIdx As Long = 0)
Dim i As Long
' If the current index equals the length of the array
If colIdx = UBound(aVals) + 1 Then
' Debug.Print curStr
oColl.Add Mid(curStr, 2)
Exit Sub
End If
' Loop through each element in the current array and recursively call GenerateCombinations
For i = LBound(aVals(colIdx)) To UBound(aVals(colIdx))
GenerateCombinations oColl, aVals, curStr & "|" & aVals(colIdx)(i), colIdx + 1
Next i
End Sub
Нерекурсивный подход:
Sub ExpandListing2()
Dim rw As Range, arr, i As Long, col As Collection, res
Dim cStart As Range, ws As Worksheet, lr As Long
Set ws = ActiveSheet
lr = ws.Cells(Rows.Count, 1).End(xlUp).Row
Set cStart = ws.Range("I2") 'output starts here
'process each row in input table
For Each rw In ActiveSheet.Range("A2:G" & lr).Rows
arr = rw.Value
Set col = New Collection
For i = 1 To UBound(arr, 2)
col.Add Split(arr(1, i), ",") 'split each cell value to an array (1+ elements)
Next i
res = Combine(col)
'write the result to the sheet
With cStart.Resize(UBound(res, 1), UBound(res, 2))
.Value = res
.Font.Color = IIf(rw.Row Mod 2 = 0, vbBlue, vbRed) 'color this block
End With
Set cStart = cStart.Offset(UBound(res, 1)) 'next output start position
Next rw
End Sub
'Create combinations from a collection of arrays
'return as a 2D array
Function Combine(col As Collection)
Dim rv() As String
Dim pos() As Long, lengths() As Long, lbs() As Long, ubs() As Long
Dim t As Long, i As Long, n As Long, ub As Long
Dim numIn As Long, s As String, r As Long, v, tmp()
numIn = col.Count
ReDim pos(1 To numIn)
ReDim lbs(1 To numIn)
ReDim ubs(1 To numIn)
ReDim lengths(1 To numIn)
t = 0
For i = 1 To numIn 'calculate # of combinations, and cache bounds/lengths
'handle cases where only one value in a column (not passed in as array)
If Not TypeName(col(i)) Like "*()" Then
ReDim tmp(1 To 1)
tmp(1) = col(i)
col.Remove i
If i > col.Count Then
col.Add tmp
Else
col.Add tmp, before:=i
End If
End If
lbs(i) = LBound(col(i))
ubs(i) = UBound(col(i))
lengths(i) = (ubs(i) - lbs(i)) + 1
pos(i) = lbs(i)
t = IIf(t = 0, lengths(i), t * lengths(i))
Next i
ReDim rv(1 To t, 1 To numIn) 'resize destination array
For n = 1 To t
For i = 1 To numIn
rv(n, i) = col(i)(pos(i))
Next i
For i = numIn To 1 Step -1
If pos(i) <> ubs(i) Then 'Not done all of this array yet...
pos(i) = pos(i) + 1 'Increment array index
For r = i + 1 To numIn 'Reset all the indexes
pos(r) = lbs(r) ' of the later arrays
Next r
Exit For
End If
Next i
Next n
Combine = rv
End Function
Пример:
Это также можно сделать с помощью Power Query, доступного в Windows Excel 2010+ и Microsoft 365 (Windows или Mac).
Использование Power Query
Data => Get&Transform => from Table/RangeHome => Advanced EditorApplied Steps, чтобы понять алгоритм.let
//Change next line to reflect actual data source
Source = Excel.CurrentWorkbook(){[Name = "Table3"]}[Content],
colNames = Table.ColumnNames(Source),
//type all columns as text
#"Changed Type" = Table.TransformColumnTypes(Source,List.Transform(colNames, each {_, type text})),
//transform all columns to Lists except for the first column (Assembly #)
#"Transform to List" = Table.TransformColumns(#"Changed Type",
List.Transform(List.RemoveFirstN(colNames,1), (cn)=> {cn, each Text.Split(_,","), type {text}})),
//Expand the lists
#"Expand Lists" = List.Accumulate(
Table.ColumnsOfType(#"Transform to List",{type list}),
#"Transform to List",
(s,c)=> Table.ExpandListColumn(s,c))
in
#"Expand Lists"
Здесь есть несколько решений по формулам stackoverflow.com/questions/77917473/… (включая мое, которое, к сожалению, не привлекло особого внимания!)