excel

Split a cell into 2 rows in Excel


I want to insert 3 rows in column Level. For cell in Level, I need to create 3 rows, each with values "low", "medium" and "high". Currently I'm using a very manual process by inserting 2 other rows, and merge all columns except for "Level". is there a more efficient way to do it?

Original table:

enter image description here

Expected output:

enter image description here


Solution

  • As @Harun24hr said - you'll need VBA to do this.

    enter image description here

    This code allows you to define where your table is, what column you want to add your headings to and what the headings are.

    'Constants appear at the very top of the module.
    Public Const ERR_COL_NOT_FOUND As Long = vbObjectError + 513
    Public Const ERR_SINGLE_ROW As Long = vbObjectError + 514
    
    Public Sub Test()
    
        'Call the AddLevels procedure and pass it the arguments required to work.
        AddLevels ThisWorkbook.Worksheets("Sheet1").Range("B2:G4"), _
                  "Level", _
                  "Low", "Medium", "High"
    
    End Sub
    
    
    'Arguments the procedure accepts:
    'Target:     The range that the table covers.
    'ColName:    The heading that the "Levels" will be placed under.
    'Headings(): The heading that need adding - this can be as many headings as you want.
    Public Sub AddLevels(Target As Range, ColName As String, ParamArray Headings() As Variant)
    
        On Error GoTo ErrHandler
    
    
        'Number of Headings that are being added.
        'The array starts at 0 so for 3 headings this will return 2.
        'It should be less as the first row already exists.
        Dim RowsToAdd As Long
        RowsToAdd = UBound(Headings)
    
        'The range must include the headings and at least one row of data.
        If Target.Rows.Count >= 2 Then
        
            'Find the heading we're adding "Headings" to.
            With Target.Rows(1)
                Dim SplitCol As Range
                Set SplitCol = .Find(What:=ColName, _
                                     After:=.Cells(.Cells.Count), _
                                     LookIn:=xlValues, _
                                     LookAt:=xlWhole, _
                                     SearchOrder:=xlByColumns, _
                                     SearchDirection:=xlNext, _
                                     MatchCase:=False)
            End With
                
            If Not SplitCol Is Nothing Then
            
                'Calculate the column within Target.
                'So if Target starts in column B and "Level" is in column E this will return 4.
                'Column E is the fourth column in the range B:G.
                Dim ColNum As Long
                ColNum = SplitCol.Column - Target.Column + 1
            
                Dim x As Long, y As Long
                
                'As we're adding rows we need to start from the bottom and work up
                'otherwise the row count will go astray as extra rows are added.
                For x = Target.Rows.Count To 2 Step -1
                    
                    'Add the blank rows.
                    For y = 1 To RowsToAdd
                        Target.Rows(x + 1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
                    Next y
                    
                    'Paste the Level headings into the correct column.
                    Target.Rows(x).Resize(y).Columns(ColNum) = Application.WorksheetFunction.Transpose(Headings)
                    
                    'Merge the cells except for the Level column.
                    Dim Col As Range
                    For Each Col In Target.Columns
                        If Col.Column <> SplitCol.Column Then
                            With Col.Rows(x).Resize(y)
                                .HorizontalAlignment = xlCenter
                                .VerticalAlignment = xlCenter
                                .MergeCells = True
                            End With
                        End If
                    Next Col
                    
                    'Add borders to the new range.
                    Dim z As Long
                    For z = 7 To 12
                        With Target.Rows(x).Resize(y).Borders(z)
                            .LineStyle = xlContinuous
                            .Weight = xlThin
                            .ColorIndex = 0
                        End With
                    Next z
    
                Next x
            
            Else
                'Raise error as the split column wasn't found.
                Err.Raise ERR_COL_NOT_FOUND, , "Column to split not found."
            End If
        Else
            'Raise error as Target only has a single row - which must be the headings.
            Err.Raise ERR_SINGLE_ROW, , "Target must be more than a single row."
        End If
        
    TidyExit:
        
    Exit Sub 'End of the main body of the procedure.
    
    'Error handling.
    ErrHandler:
        MsgBox Err.Number & vbCr & vbCr & Err.Description, vbOKOnly, "Error"
        Resume TidyExit 'Resume execution at this label - giving a single exit point in the procedure.
        
    End Sub