Need to transpose multiple comma separated values

SRd240sx

New Member
Joined
Dec 19, 2008
Messages
11
Hey guys, I have a list of comma separated values. I would like to change these to tab separated values, and then transpose them so that they are all displayed in one column. Does anyone know if it's possible to do this in Excel 2007?

Example:

Date | Keywords
1/01/01 | shoe, shoes, clothes, clothing
1/02/01 | shirt, shirts, jacket, jackets

I need the Keywords column to display each value separately, and in one column. I also need each row to have the original date information. So I need it to look like this:

Date | Keywords
1/01/01 | shoe
1/01/01 | shoes
1/01/01 | clothes
1/01/01 | clothing
1/02/01 | shirt
1/02/01 | shirts
1/02/01 | jacket
1/02/01 | jackets

Can anyone help out?
 
Here's a link to a sample if you would like to try it out:

http://spreadsheets.google.com/ccc?key=0AkfHEiWmvbXrdEZxa010T3ZQUVlESFpHVVU0cmFmbWc&hl=en

The code I used:

Code:
Option Explicit

Sub SplitKeywords()
'JBeaucaire  (12/8/2009)
Dim MyArr, v As Long, i As Long, LR As Long
Application.ScreenUpdating = False
LR = Range("A" & Rows.Count).End(xlUp).Row

    For i = LR To 2 Step -1
        MyArr = Split(Range("G" & i), ", ")
        Range("G" & i) = MyArr(0)
        For v = 1 To UBound(MyArr)
            Rows(i + v).Insert xlShiftDown
            Range("A" & i + v, "F" & i + v).Value = Range("A" & i, "F" & i).Value
            Range("G" & i + v) = MyArr(v)
        Next v
    Next i

Application.ScreenUpdating = True
End Sub
 
Upvote 0

Excel Facts

How to fill five years of quarters?
Type 1Q-2023 in a cell. Grab the fill handle and drag down or right. After 4Q-2023, Excel will jump to 1Q-2024. Dash can be any character.
Your amended code ran perfectly on the sheet above when I downloaded it as Excel and tried it. Took a while, but no errors for me.


When you get the error, choose debug. What line of the code is active and highlighted? What are the current values for variables "i" and "v"? Hold your cursor over them to see the answer.
 
Upvote 0
Hello,

You can load an array from a range directly or vice versa. If I understand correctly what you are trying to do based on the sample you posted on Google, the following code will transpose the comma delimited list in Column G into a series of individual rows and will then copy the corresponding static data from columns A - F accordingly (eg if Column G ends up with 4 new rows, then A - F are copied into the new rows as well).

See the GetSplitValues function to see how to setup an array to be copied directly to a range.

The code creates a new sheet and then copies the data to it as it works its way down the orignal souce sheet. It also checks for errors to handle your example error in row 7.

Enjoy...

Code:
Option Explicit

Private Const m_SPLIT_COLUMN As String = "G"

Sub SplitData()
    Dim values As Variant
    Dim newSheet As Worksheet, sheet As Worksheet
    Dim currentRow As Long, lastRow As Long, newRow As Long
    Dim lastStaticColumn As String
    
    Set sheet = ActiveWorkbook.ActiveSheet
    
    ' Create new sheet.
    With ActiveWorkbook.Sheets
        Set newSheet = .Add(after:=.Item(.Count))
    End With
    
    ' Copy headers.
    newRow = 1
    Call CopyEntireRow(1, sheet, newSheet, newRow)
    
    ' Defined to be 1 column to the left of the split data.
    lastStaticColumn = Chr$(Asc(m_SPLIT_COLUMN) - 1)
    
    With sheet
        .Activate
        lastRow = .Cells.SpecialCells(xlCellTypeLastCell).Row
        For currentRow = 2 To lastRow
            .Activate
            If Application.WorksheetFunction.IsErr(.Cells(currentRow, m_SPLIT_COLUMN).Value) Then
                Call CopyEntireRow(currentRow, sheet, newSheet, newRow)
                
            Else
                If Len(Trim$(.Cells(currentRow, m_SPLIT_COLUMN).Value)) > 0 Then
                    ' Create 1s based array based upon comma delimited list.
                    values = GetSplitValues(currentRow, m_SPLIT_COLUMN, sheet)
                    
                    ' Copy array directly to corresponding range on new sheet.
                    With newSheet
                        .Select
                        .Range(.Cells(newRow, m_SPLIT_COLUMN), .Cells(newRow + UBound(values) - 1, m_SPLIT_COLUMN)).Value = values
                    End With
                    
                    ' Copy static data to corresponding new rows created by copying the array above.
                    Call CopyRemainingRowData(currentRow, "A", lastStaticColumn, values, sheet, newSheet, newRow)
                End If
            End If
                    
            ' Added a blank line to make verification easier.
            newRow = newRow + 1
        Next
    End With
    
    newSheet.Cells.EntireColumn.AutoFit
    MsgBox "Completed"
End Sub 'SplitData

Private Sub CopyEntireRow(ByVal currentRow As Long, ByVal currentSheet As Worksheet, ByVal targetSheet As Worksheet, ByRef newRow As Long)
    Dim active As Worksheet
    Set active = ActiveWorkbook.ActiveSheet
    With currentSheet
        .Activate
        .Cells(currentRow, "A").Select
        .Range(Selection, Selection.End(xlToRight)).Copy
    End With
    With targetSheet
        .Select
        .Cells(newRow, "A").Select
        .Paste
    End With
    newRow = newRow + 1
    active.Activate
    Set active = Nothing
End Sub 'CopyEntireRow

Private Function GetSplitValues(ByVal currentRow, ByVal splitColumn As String, ByVal currentSheet As Worksheet) As Variant
    Dim index As Long
    Dim values As Variant
    Dim active As Worksheet
    Set active = ActiveWorkbook.ActiveSheet
    
    ' Create array by splitting comma delimited list.
    ' Alternatively, you could use a Regular Expression split which would handle whitespace and make the trim loop unneeded.
    With currentSheet
        .Select
        values = Split(.Cells(currentRow, m_SPLIT_COLUMN).Value, ",")
    End With
    
    ' Trim them all.
    For index = LBound(values) To UBound(values)
        values(index) = Trim$(values(index))
    Next
    
    ' Convert to 1s based array.
    values = Application.WorksheetFunction.Transpose(values)
    active.Activate
    Set active = Nothing
    GetSplitValues = values
End Function 'GetSplitValues

Private Sub CopyRemainingRowData(ByVal currentRow As Long, ByVal firstColumn As String, ByVal lastColumn As String, ByVal values As Variant, ByVal currentSheet As Worksheet, ByVal targetSheet As Worksheet, ByRef newRow As Long)
    Dim active As Worksheet
    Set active = ActiveWorkbook.ActiveSheet
    With currentSheet
        .Select
        .Range(.Cells(currentRow, firstColumn), .Cells(currentRow, lastColumn)).Copy
    End With
    With targetSheet
        .Select
        .Paste Destination:=.Range(.Cells(newRow, firstColumn), .Cells(newRow + UBound(values) - 1, lastColumn))
    End With
    newRow = newRow + UBound(values)
    active.Activate
    Set active = Nothing
End Sub 'CopyRemainingRowData
 
Upvote 0
...and "i" equals what at that moment?

Hmmm I'm not really sure, how do I find this? This is the code in DEBUG:

Option Explicit

Sub SplitKeywords()
'JBeaucaire (12/8/2009)
Dim MyArr, v As Long, i As Long, LR As Long
Application.ScreenUpdating = False
LR = Range("A" & Rows.Count).End(xlUp).Row

For i = LR To 2 Step -1
MyArr = Split(Range("G" & i), ", ")
Range("G" & i) = MyArr(0)
For v = 1 To UBound(MyArr)
Rows(i + v).Insert xlShiftDown
Range("A" & i + v, "F" & i + v).Value = Range("A" & i, "F" & i).Value
Range("G" & i + v) = MyArr(v)
Next v
Next i

Application.ScreenUpdating = True
End Sub
 
Upvote 0
Hello,

You can load an array from a range directly or vice versa. If I understand correctly what you are trying to do based on the sample you posted on Google, the following code will transpose the comma delimited list in Column G into a series of individual rows and will then copy the corresponding static data from columns A - F accordingly (eg if Column G ends up with 4 new rows, then A - F are copied into the new rows as well).

See the GetSplitValues function to see how to setup an array to be copied directly to a range.

The code creates a new sheet and then copies the data to it as it works its way down the orignal souce sheet. It also checks for errors to handle your example error in row 7.

Enjoy...

Hey I tried this and it works great in the sample! I'll try it with my master document, hopefully there will be no errors, it's a rather large file.

Thanks jbeau and sbendbuckeye, you guys have been very very helpful
 
Upvote 0
You are more than welcome. I have been the beneficiary on this board many more times than I have been the answerer. I haven't read all of the discussion in this thread that closely, but it occurred to me that if your split column is in the middle of all of the other columns, you could simplify your code by moving it to either the beginning or end of your columns while you process it and then move it back when you are finished. That way you are only dealing with 2 blocks of data, your split column and everything else which would presumably be static data and just copied down as you go. An interesting challenge in any event. Good Luck!
 
Upvote 0
SBendBuckeye,

I know this is an old thread, but I have a quick question for you. How would that code look? If you were to move column "G" to say "A" while you are working on it, how would the code look to specify the remaining columns?
 
Upvote 0

Forum statistics

Threads
1,223,247
Messages
6,171,007
Members
452,374
Latest member
keccles

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top