Reputation: 3474
I'm trying to run my first macro against a dataset with almost 11k rows. However when I run it, it freezes Excel making me have to force quit it.
What I expect to happen is in cell 11 for each row, that contains 1-5 elements "blue|red|gray|round". I want to copy that entire row to a new sheet for each element, updating cell 11 in that row to the element.
So in this example, with the 4 elements above, 4 rows (one for each element) would be written to the new sheet.
Option Explicit
Sub ReorgData2()
Dim i As Long
Dim WrdArray() As String
Dim element As Variant
Application.ScreenUpdating = False
With Sheets("Sheet5")
For i = 1 To Rows.Count
WrdArray() = Split(.Cells(i, 11), "|")
For Each element In WrdArray()
ActiveCell.EntireRow.Copy
Sheets("Sheet6").Paste
Sheets("Sheet6").Cells(i, 11) = element
Next element
Next i
End With
Application.ScreenUpdating = True
End Sub
Upvotes: 0
Views: 3037
Reputation: 29421
you should run considerably faster if you:
limit ranges to be copied from each row to the actually "filled" cells, instead of the whole row
copy values only between ranges
don't loop through WrdArray
and simply paste its values in one shot
like follows
Sub ReorgData2()
Dim WrdArray As Variant
Dim cell As Range
Dim lastRow As Long
Set sht6 = Worksheets("Sheet6")
Application.ScreenUpdating = False
With Worksheets("Sheet5")
For Each cell In .Range("K1", .Cells(.Rows.count, "K").End(xlUp)).SpecialCells(xlCellTypeConstants, xlTextValues) '<--| loop through column K cells with text values only
WrdArray = Split(cell, "|")
With .Range(.Cells(cell.row, 1), .Cells(cell.row, .Columns.count).End(xlToLeft)) '<--| reference current row range from column 1 to last not empty one
lastRow = sht6.Cells(Rows.count, 1).End(xlUp).Offset(1).row '<--| find sheet 6 column A first empty row index after last not empty cell
sht6.Cells(lastRow, 1).Resize(UBound(WrdArray) + 1, .Columns.count).Value = .Value '<--| copy referenced range to as many sheet6 rows as 'WrdArray' elements
sht6.Cells(lastRow, 11).Resize(UBound(WrdArray) + 1).Value = Application.Transpose(WrdArray) '<--| update sheet 6 column K only with 'WrdArray' elements
End With
Next
End With
Application.ScreenUpdating = True
End Sub
Upvotes: 0
Reputation: 23974
You need to keep track of where you are writing on Sheet6, so that you aren't constantly writing over the top of a single row. (The code following uses a variable i6
to do that.)
You should also only run your loop down until you reach the last non-empty cell. (I have assumed in the following code that column K always contains a value in every row that is to be copied.) Otherwise you will be processing 1,048,576 rows, but you only have meaningful information in about 1% of those rows.
Option Explicit
Sub ReorgData2()
Dim i5 As Long
Dim i6 As Long
Dim WrdArray() As String
Dim element As Variant
Application.ScreenUpdating = False
With Worksheets("Sheet5")
For i5 = 1 To .Cells(.Rows.Count, "K").End(xlUp).Row
WrdArray() = Split(.Cells(i5, 11), "|")
For Each element In WrdArray()
i6 = i6 + 1 ' increment a counter each time we write a new row
.Rows(i5).Copy Worksheets("Sheet6").Rows(i6)
Worksheets("Sheet6").Cells(i6, 11).Value = element
Next element
Next i5
End With
Application.ScreenUpdating = True
End Sub
Upvotes: 1