Reputation: 57
I'm looking for exactly this operation: How do I duplicate rows based on cell contents (cell contains semi-colon seperated data)
But with an added column: Starting table vs End result
What I have:
| Name | Size | Photo |
|--------|------------|---------|
| Tshirt | 10, 12, 14 | 144.jpg |
| Jeans | 30, 40, 42 | 209.jpg |
| Dress | 8 | 584.jpg |
| Shoe | 6 | 178.jpg |
What I would like:
| Name | Size | Photo | Primary |
|--------|------|---------|---------|
| Tshirt | 10 | 144.jpg | 1 |
| Tshirt | 12 | 144.jpg | 0 |
| Tshirt | 14 | 144.jpg | 0 |
| Jeans | 30 | 209.jpg | 1 |
| Jeans | 40 | 209.jpg | 0 |
| Jeans | 42 | 209.jpg | 0 |
| Dress | 8 | 584.jpg | 1 |
| Shoe | 6 | 178.jpg | 1 |
Right now the code I found works perfectly but I don't know how to add the "Primary" column.
Sub SplitCell()
Dim cArray As Variant
Dim cValue As String
Dim rowIndex As Integer, strIndex As Integer, destRow As Integer
Dim targetColumn As Integer
Dim lastRow As Long, lastCol As Long
Dim srcSheet As Worksheet, destSheet As Worksheet
targetColumn = 2 'column with semi-colon separated data
Set srcSheet = ThisWorkbook.Worksheets("Sheet1") 'sheet with data
Set destSheet = ThisWorkbook.Worksheets("Sheet2") 'sheet where result will be displayed
destRow = 0
With srcSheet
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
lastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
For rowIndex = 1 To lastRow
cValue = .Cells(rowIndex, targetColumn).Value 'getting the cell with semi-colon separated data
cArray = Split(cValue, ";") 'splitting semi-colon separated data in an array
For strIndex = 0 To UBound(cArray)
destRow = destRow + 1
destSheet.Cells(destRow, 1) = .Cells(rowIndex, 1)
destSheet.Cells(destRow, 2) = Trim(cArray(strIndex))
destSheet.Cells(destRow, 3) = .Cells(rowIndex, 3)
Next strIndex
Next rowIndex
End With
End Sub
Thanks for your help!
Upvotes: 2
Views: 125
Reputation: 37347
Try this slight modification of your code, you'll have to declare additional variable Dim priority As Boolean
:
For rowIndex = 1 To lastRow
cValue = .Cells(rowIndex, targetColumn).Value 'getting the cell with semi-colon separated data
cArray = Split(cValue, ";") 'splitting semi-colon separated data in an array
priority = True
For strIndex = 0 To UBound(cArray)
destRow = destRow + 1
destSheet.Cells(destRow, 1) = .Cells(rowIndex, 1)
destSheet.Cells(destRow, 2) = Trim(cArray(strIndex))
destSheet.Cells(destRow, 3) = .Cells(rowIndex, 3)
destSheet.Cells(destRow, 4) = IIf(priority, 1, 0)
priority = False
Next strIndex
Next rowIndex
Upvotes: 2
Reputation: 13386
your whole sub can boil down to:
Sub SplitCell()
Dim vals As Variant
vals = ThisWorkbook.Worksheets("Sheet001").Range("A1").CurrentRegion.value
Dim iVal As Long
With ThisWorkbook.Worksheets("Sheet002")
.Range("A1:C1").value = Application.index(vals, 1, 0)
.Range("D1").value = "Primary"
For iVal = 2 To UBound(vals)
With .Cells(.Rows.Count, 1).End(xlUp).Offset(1).Resize(UBound(Split(vals(iVal, 2) & ",", ",")))
.Offset(, 0).value = vals(iVal, 1)
.Offset(, 1).value = Application.Transpose(Split(vals(iVal, 2) & ",", ","))
.Offset(, 2).value = vals(iVal, 3)
.Offset(, 3).value = Application.Transpose(Split("1," & String(.Rows.Count - 1, ","), ","))
End With
Next
.Range("D1", .Cells(.Rows.Count, 1).End(xlUp)).SpecialCells(xlCellTypeBlanks).value = 0
End With
End Sub
Upvotes: 0
Reputation: 23081
Here is a slightly different approach, which avoids the second loop.
Sub SplitCell()
Dim cArray As Variant
Dim rowIndex As Long, destRow As Long
Dim targetColumn As Long
Dim lastRow As Long, lastCol As Long
Dim srcSheet As Worksheet, destSheet As Worksheet
targetColumn = 2 'column with semi-colon separated data
Set srcSheet = ThisWorkbook.Worksheets("Sheet1") 'sheet with data
Set destSheet = ThisWorkbook.Worksheets("Sheet2") 'sheet where result will be displayed
destRow = 1
With srcSheet
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
lastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
destSheet.Cells(1, 4).Value = "Primary"
For rowIndex = 1 To lastRow
cArray = Split(srcSheet.Cells(rowIndex, targetColumn), ";") 'splitting semi-colon separated data in an array
destSheet.Cells(destRow, 1).Resize(UBound(cArray) + 1).Value = srcSheet.Cells(rowIndex, targetColumn - 1).Value
destSheet.Cells(destRow, 2).Resize(UBound(cArray) + 1).Value = Application.Transpose(cArray)
destSheet.Cells(destRow, 3).Resize(UBound(cArray) + 1).Value = srcSheet.Cells(rowIndex, targetColumn + 1).Value
If rowIndex > 1 Then destSheet.Cells(destRow, 4).Value = 1
If UBound(cArray) > 0 Then
destSheet.Cells(destRow + 1, 4).Resize(UBound(cArray)).Value = 0
End If
destRow = destSheet.Cells(Rows.Count, 1).End(xlUp).Row + 1
Next rowIndex
End With
End Sub
Upvotes: 0
Reputation: 84465
Note: I am using this "," delimiter as your data shows that rather than your code which is using ";". Simply swop if necessary.
Option Explicit
Sub SplitCell()
Dim cArray As Variant
Dim cValue As String
Dim rowIndex As Long, strIndex As Long, destRow As Long
Dim targetColumn As Long
Dim lastRow As Long, lastCol As Long
Dim srcSheet As Worksheet, destSheet As Worksheet
targetColumn = 2 'column with semi-colon separated data
Set srcSheet = ThisWorkbook.Worksheets("Sheet1") 'sheet with data
Set destSheet = ThisWorkbook.Worksheets("Sheet2") 'sheet where result will be displayed
destRow = 0
With srcSheet
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
lastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
For rowIndex = 1 To lastRow
cValue = .Cells(rowIndex, targetColumn).Value 'getting the cell with semi-colon separated data
cArray = Split(cValue, ",") 'splitting semi-colon separated data in an array
For strIndex = 0 To UBound(cArray)
destRow = destRow + 1
destSheet.Cells(destRow, 1) = .Cells(rowIndex, 1)
destSheet.Cells(destRow, 2) = Trim(cArray(strIndex))
destSheet.Cells(destRow, 3) = .Cells(rowIndex, 3)
If rowIndex = 1 Then
destSheet.Cells(destRow, 4) = "Primary"
Else
If strIndex = 0 Then
destSheet.Cells(destRow, 4) = 1
Else
destSheet.Cells(destRow, 4) = 0
End If
End If
Next strIndex
Next rowIndex
End With
End Sub
Upvotes: 0