VBA rows for reconciliations - excel
I am new VBA user trying to assemble a very basic trade reconciliation template. I seem to have the majority done, but I cant seem to work out the sorting behavior "such that" all stocks that are unmatched shown on separate row lines. As you can see I was able to get the sorting to work for the main portion of items that matched, but all the unmatched items just get pushed to the bottom. That is fine, but really they should be on separate rows to show visually that each line item is separately unmatched.
This is as far as I could get with my code. Separating out the rows with all unmatched items where say the stock name (A4 vs. H4) and also the quantity (E4 vs L4) are not matching all should be getting moved to their own line item - to visually confirm for the end reader there is a unmatch.
Sub Sample_Trade_Recon()
Application.ScreenUpdating = False
' Tab 1 & Tab 2 Raw data pasted in. Do a prelim sort of the actual columns
you want compare on the summary sheet'
Sheets("QT").Select Range("A3:G300").Select
ActiveWorkbook.Worksheets("QT").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("QT").Sort.SortFields.Add Key:=Range("A3:A300"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("QT").Sort.SortFields.Add Key:=Range("B3:B300"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("QT").Sort.SortFields.Add Key:=Range("C3:C300"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("QT").Sort.SortFields.Add Key:=Range("D3:D300"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("QT").Sort.SortFields.Add Key:=Range("E3:E300"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("QT").Sort.SortFields.Add Key:=Range("F3:F300"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("QT").Sort.SortFields.Add Key:=Range("G3:G300"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal With
ActiveWorkbook.Worksheets("QT").Sort .SetRange Range("A3:G300") .Header =
xlGuess .MatchCase = False .Orientation = xlTopToBottom .SortMethod =
xlPinYin .Apply End With
Sheets("SSC").Select
Range("A3:G300").Select
ActiveWorkbook.Worksheets("SSC").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("SSC").Sort.SortFields.Add Key:=Range("A3:A300"),
_
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("SSC").Sort.SortFields.Add Key:=Range("B3:B300"),
_
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("SSC").Sort.SortFields.Add Key:=Range("C3:C300"),
_
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("SSC").Sort.SortFields.Add Key:=Range("D3:D300"),
_
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("SSC").Sort.SortFields.Add Key:=Range("E3:E300"),
_
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("SSC").Sort.SortFields.Add Key:=Range("F3:F300"),
_
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("SSC").Sort.SortFields.Add Key:=Range("G3:G300"),
_
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("SSC").Sort
.SetRange Range("A3:G300")
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
' Tab 1 Raw data columns you want compared '
Sheets("QT").Select
Range("A3:A40").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Recon").Select
Range("A4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Sheets("QT").Select
Range("B3:B40").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Recon").Select
Range("B4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Sheets("QT").Select
Range("C3:C40").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Recon").Select
Range("C4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Selection.NumberFormat = "m/d/yyyy"
Sheets("QT").Select
Range("D3:D40").Select
Selection.Copy
Sheets("Recon").Select
Range("D4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Selection.NumberFormat = "m/d/yyyy"
Sheets("QT").Select
Range("E3:E40").Select
Selection.Copy
Sheets("Recon").Select
Range("E4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Sheets("QT").Select
Range("F3:F40").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Recon").Select
Range("F4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Sheets("QT").Select
Range("G3:G40").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Recon").Select
Range("G4").Select
Selection.PasteSpecial Paste:=xlPasteValues
' Tab 2 Raw data columns you want compared '
Sheets("SSC").Select
Range("A3:A45").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Recon").Select
Range("H4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Sheets("SSC").Select
Range("B3:B45").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Recon").Select
Range("I4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Sheets("SSC").Select
Range("C3:C45").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Recon").Select
Range("J4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Selection.NumberFormat = "m/d/yyyy"
Sheets("SSC").Select
Range("D3:D45").Select
Selection.Copy
Sheets("Recon").Select
Range("K4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Selection.NumberFormat = "m/d/yyyy"
Sheets("SSC").Select
Range("E3:E45").Select
Selection.Copy
Sheets("Recon").Select
Range("L4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Sheets("SSC").Select
Range("F3:F45").Select
Selection.Copy
Sheets("Recon").Select
Range("M4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Sheets("SSC").Select
Range("G3:G45").Select
Selection.Copy
Sheets("Recon").Select
Range("N4").Select
Selection.PasteSpecial Paste:=xlPasteValues
MsgBox ("Recon is assembled; please comment on all differences !")
End Sub
So looks like im getting very close to the desired behavior. Only issue is its happening only once ?
Please see the updated code and let me know if anyone can assist with why its not repeating when the skip row is showing.
enter image description here
Sub Sample_Trade_Recon()
Application.ScreenUpdating = False
' Tab 1 & Tab 2 Raw data pasted in. Do a prelim sort of the actual columns
you want compare on the summary sheet'
Sheets("QT").Select
Range("A3:G300").Select
ActiveWorkbook.Worksheets("QT").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("QT").Sort.SortFields.Add Key:=Range("A3:A300"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("QT").Sort.SortFields.Add Key:=Range("B3:B300"), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("QT").Sort.SortFields.Add Key:=Range("C3:C300"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("QT").Sort.SortFields.Add Key:=Range("D3:D300"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("QT").Sort.SortFields.Add Key:=Range("E3:E300"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("QT").Sort.SortFields.Add Key:=Range("F3:F300"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("QT").Sort.SortFields.Add Key:=Range("G3:G300"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("QT").Sort
.SetRange Range("A3:G300")
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Sheets("SSC").Select
Range("A3:G300").Select
ActiveWorkbook.Worksheets("SSC").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("SSC").Sort.SortFields.Add Key:=Range("A3:A300"),
_
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("SSC").Sort.SortFields.Add Key:=Range("B3:B300"),
_
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("SSC").Sort.SortFields.Add Key:=Range("C3:C300"),
_
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("SSC").Sort.SortFields.Add Key:=Range("D3:D300"),
_
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("SSC").Sort.SortFields.Add Key:=Range("E3:E300"),
_
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("SSC").Sort.SortFields.Add Key:=Range("F3:F300"),
_
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("SSC").Sort.SortFields.Add Key:=Range("G3:G300"),
_
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("SSC").Sort
.SetRange Range("A3:G300")
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
' Tab 1 Raw data columns you want compared '
Sheets("QT").Select
Range("A3:A300").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Recon").Select
Range("A4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Sheets("QT").Select
Range("B3:B300").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Recon").Select
Range("B4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Sheets("QT").Select
Range("C3:C300").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Recon").Select
Range("C4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Selection.NumberFormat = "m/d/yyyy"
Sheets("QT").Select
Range("D3:D300").Select
Selection.Copy
Sheets("Recon").Select
Range("D4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Selection.NumberFormat = "m/d/yyyy"
Sheets("QT").Select
Range("E3:E300").Select
Selection.Copy
Sheets("Recon").Select
Range("E4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Sheets("QT").Select
Range("F3:F300").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Recon").Select
Range("F4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Sheets("QT").Select
Range("G3:G300").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Recon").Select
Range("G4").Select
Selection.PasteSpecial Paste:=xlPasteValues
' Tab 2 Raw data columns you want compared '
Sheets("SSC").Select
Range("A3:A300").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Recon").Select
Range("H4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Sheets("SSC").Select
Range("B3:B300").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Recon").Select
Range("I4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Sheets("SSC").Select
Range("C3:C300").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Recon").Select
Range("J4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Selection.NumberFormat = "m/d/yyyy"
Sheets("SSC").Select
Range("D3:D300").Select
Selection.Copy
Sheets("Recon").Select
Range("K4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Selection.NumberFormat = "m/d/yyyy"
Sheets("SSC").Select
Range("E3:E300").Select
Selection.Copy
Sheets("Recon").Select
Range("L4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Sheets("SSC").Select
Range("F3:F300").Select
Selection.Copy
Sheets("Recon").Select
Range("M4").Select
Selection.PasteSpecial Paste:=xlPasteValues
Sheets("SSC").Select
Range("G3:G300").Select
Selection.Copy
Sheets("Recon").Select
Range("N4").Select
Selection.PasteSpecial Paste:=xlPasteValues
'Dynamic Sorting based on column total lengths'
Dim lastA, lastB, shortCol, rw As Integer
'Determine short column so we know when to stop
lastA = WorksheetFunction.CountA(Range("A:A"))
lastB = WorksheetFunction.CountA(Range("H:H"))
If lastA > lastB Then _
shortCol = 2 Else shortCol = 1
'Set First Check Row
rw = 4
nxtChk:
'Check Column A against Column H, Row by Row
'Insert cell at non-matching data
If Cells(rw, 26) <> "Keep" And shortCol = 2 Then
Cells(rw, 8).Insert shift:=xlDown
Cells(rw, 9).Insert shift:=xlDown
Cells(rw, 10).Insert shift:=xlDown
Cells(rw, 11).Insert shift:=xlDown
Cells(rw, 12).Insert shift:=xlDown
Cells(rw, 13).Insert shift:=xlDown
Cells(rw, 14).Insert shift:=xlDown
Refresh all formulas in difference column so excel knows where to insert
the skip row (based on formulas)'
Range("O4:Z4").Select
Selection.AutoFill Destination:=Range("O4:Z300")
Else
If Cells(rw, 26) <> "Keep" And shortCol = 1 Then
Cells(rw, 1).Insert shift:=xlDown
Cells(rw, 2).Insert shift:=xlDown
Cells(rw, 3).Insert shift:=xlDown
Cells(rw, 4).Insert shift:=xlDown
Cells(rw, 5).Insert shift:=xlDown
Cells(rw, 6).Insert shift:=xlDown
Cells(rw, 7).Insert shift:=xlDown
'Refresh all formulas in difference column so excel knows where to insert
the skip row (based on formulas)'
Range("O4:Z4").Select
Selection.AutoFill Destination:=Range("O4:Z300")
End If
'If there is nothing left to check in the skiprow column , we're done
If Cells(rw, 26) = " " Then Exit Sub
'If not, increment Row counter and loop
rw = rw + 1
GoTo nxtChk
End If
Range("O4:Z4").Select
Selection.AutoFill Destination:=Range("O4:Z300")
Application.ScreenUpdating = True
'Operations Team notices to review data presentation'
MsgBox ("Please insert comments into Column AA for all differences !")
MsgBox ("NOTE: If identifer data sorting is off slightly; then please fix by
repasting the data grids on either side up/down a row as needed to realign
properly. This often happens when Identifiers Repeat ")
End Sub
Related
Copying Excel Data to another worksheet - VBA Error
I have the following VBA code that copys specific values from the open workbook and then pastes them to another and then saves it. Recently this macro stopped working and throws an error message. I would appreciate some help fixing this. Error Message Run-time error: 1004: To copy all cells from another worksheet to this worksheet, make sure you paste them into the first cell (A1 or R1C1) VBA CODE Sub ExportImportFile() Worksheets("Estimate Import Calc").Activate ActiveWorkbook.Worksheets("Estimate Import Calc").Sort.SortFields.Clear ActiveWorkbook.Worksheets("Estimate Import Calc").Sort.SortFields.Add2 Key:= _ Range("n2:n19"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:= _ xlSortNormal With ActiveWorkbook.Worksheets("Estimate Import Calc").Sort .SetRange Range("A1:o19") .Header = xlYes .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With 'Reset LastRow LastRow = Range("n" & Rows.Count).End(xlUp).Row 'Remove Zeros ActiveSheet.Range("$A$1:$n$" & LastRow).AutoFilter Field:=14, Criteria1:="0", Operator:=xlOr FirstRow = Worksheets("Estimate Import Calc").AutoFilter.Range.Offset(1).SpecialCells(xlCellTypeVisible).Cells().Row Rows(FirstRow).Select Range(Selection, Selection.End(xlDown)).Select Selection.SpecialCells(xlCellTypeVisible).Select Selection.Delete ActiveSheet.ShowAllData Range("A2:o19").Select Cells.Select Selection.Copy Sheets("Estimate Import").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False Sheets("Estimate Import").Copy Worksheets("Estimate Import").Rows(1).Delete ActiveWorkbook.SaveAs Filename:=ThisWorkbook.Path & "\" & Range("A1").Value & "_" & "ProjectBudget_EstimateImport.CSV", FileFormat:=xlCSV, CreateBackup:=False ActiveWorkbook.ActiveSheet.Columns("A").Delete ActiveWorkbook.Save ActiveWorkbook.Close End Sub
Pivot table is not populating data and stops at a certain month
I have a pivot table that pulls the month and storage location but when I add April data and run the macro it does not populate in the pivot table. It's pulling data in the columns ($A:$AA) but it's not picking up that certain month which is weird. I went into the pivot table filter and april is selected but it's just not pulling the data from the template tab. I attached the VBA below and also a pic of the pivot ' RunData Macro ' ' Columns("A:L").Select Application.CutCopyMode = False ActiveWorkbook.Worksheets("Template").Sort.SortFields.Clear ActiveWorkbook.Worksheets("Template").Sort.SortFields.Add Key:=Range( _ "B2:B9435"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _ xlSortNormal ActiveWorkbook.Worksheets("Template").Sort.SortFields.Add Key:=Range( _ "K2:K9435"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _ xlSortNormal ActiveWorkbook.Worksheets("Template").Sort.SortFields.Add Key:=Range( _ "E2:E9435"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _ xlSortNormal ActiveWorkbook.Worksheets("Template").Sort.SortFields.Add Key:=Range( _ "F2:F9435"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _ xlSortNormal ActiveWorkbook.Worksheets("Template").Sort.SortFields.Add Key:=Range( _ "D2:D9435"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:= _ xlSortNormal With ActiveWorkbook.Worksheets("Template").Sort .SetRange Range("A1:L9435") .Header = xlYes .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With Sheets("Formulas").Select Range("M2:Z2").Select Selection.Copy Sheets("Template").Select Range("M2").Select ActiveSheet.Paste Range("M2:Z2").Select Selection.AutoFill Destination:=Range("M2:Z100000") Range("M2:Z100000").Select Columns("M:Z").Select Selection.Copy Columns("M:M").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False ActiveWindow.ScrollColumn = 7 ActiveWindow.ScrollColumn = 6 ActiveWindow.ScrollColumn = 5 ActiveWindow.ScrollColumn = 4 ActiveWindow.ScrollColumn = 3 ActiveWindow.ScrollColumn = 2 ActiveWindow.ScrollColumn = 1 Range("A1").Select Application.CutCopyMode = False ActiveWorkbook.RefreshAll ActiveWorkbook.Save End Sub
sorting excel Macro get stuck in excel
I have a VBA which works fine (Takes time to execute) in my excel 365 but does not work in excel 2016 I am importing excel as SHEET (2) and sorting first and second sheet respective columns and copying second sheet to first after last used column. ActiveWorkbook.Sheets("SHEET").Select Range("C1").Select Application.CutCopyMode = False Selection.AutoFilter ActiveWorkbook.Worksheets("SHEET").AutoFilter.Sort.SortFields.Clear ActiveWorkbook.Worksheets("SHEET").AutoFilter.Sort.SortFields.Add2 Key:=Range _ ("C1:C50000"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _ xlSortNormal With ActiveWorkbook.Worksheets("SHEET").AutoFilter.Sort .Header = xlYes .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With Sheets("SHEET (2)").Select Range("A1").Select Selection.AutoFilter ActiveWorkbook.Worksheets("SHEET (2)").AutoFilter.Sort.SortFields.Clear ActiveWorkbook.Worksheets("SHEET (2)").AutoFilter.Sort.SortFields.Add2 Key:= _ Range("A1:A50000"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption _ :=xlSortNormal With ActiveWorkbook.Worksheets("SHEET (2)").AutoFilter.Sort .Header = xlYes .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With ActiveWorkbook.Sheets("SHEET").Select Sheets("SHEET (2)").Select ' origin sheet Range("A1").Select Range(Selection, Selection.End(xlToRight)).Select X = Selection.Columns.count ' get number of columns Range(Selection, Selection.End(xlDown)).Select Selection.Copy Sheets("SHEET").Select ' destination sheet Range("AH1").Select ActiveSheet.Paste I have two problems code get stuck with runtime error 438 at line of in excel 2016 ActiveWorkbook.Worksheets("SHEET").AutoFilter.Sort.SortFields.Add2 Key:=Range _ ("C1:C50000"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _ xlSortNormal If I have more than 10000 rows its runs very slowly. can any one guide me with this please?
Adjust all worksheets with the same layout
I'm trying to remove unwanted lines off all the worksheets. For example: I have multiples worksheets that I need to make a treatment that consist on finding a special character like "-" and remove everything that is above that line, and I mean exclude all lines. I'm stuck now.. I can't do it properly to apply to all my worksheets and the cell range is different each day. So far I could do.. Sub Clean() ' ' Clean Macro ' ' Cells.Select Selection.AutoFilter ActiveWorkbook.Worksheets("Sheet1.txt").AutoFilter.Sort.SortFields.Clear ActiveWorkbook.Worksheets("Sheet1.txt").AutoFilter.Sort.SortFields.Add Key _ :=Range("A1:A66723"), SortOn:=xlSortOnValues, Order:=xlAscending, _ DataOption:=xlSortNormal With ActiveWorkbook.Worksheets("Sheet1.txt").AutoFilter.Sort .Header = xlYes .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With Columns("A:A").Select Selection.Find(What:="-", After:=ActiveCell, LookIn:=xlFormulas, LookAt _ :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _ False, SearchFormat:=False).Activate Range("A59044").Select Range(Selection, Selection.End(xlDown)).Select Range(Selection, Selection.End(xlDown)).Select Range(Selection, Selection.End(xlDown)).Select Range(Selection, Selection.End(xlDown)).Select Range(Selection, Selection.End(xlDown)).Select Range(Selection, Selection.End(xlDown)).Select Range(Selection, Selection.End(xlDown)).Select Range(Selection, Selection.End(xlDown)).Select Range(Selection, Selection.End(xlDown)).Select Selection.EntireRow.Delete Selection.End(xlUp).Select Selection.End(xlUp).Select End Sub
This works for me: Sub Clean() Dim ws As Worksheet Dim Search As Range Dim addr As String For Each ws In Worksheets ws.Activate With ws.Sort .SortFields.Clear .SortFields.Add Key:=Range("A1"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal .SetRange Cells .Header = xlNo .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With With ws.Range("A:A") Set Search = .Find(What:="-", LookIn:=xlValues, SearchOrder:=xlByRows, SearchDirection:=xlNext) If Not Search Is Nothing Then addr = Search.Address Else Exit Sub End If End With Range(addr).Select ActiveCell.Offset(1, 0).Select Range(ActiveCell, ActiveCell.End(xlDown)).Select Selection.EntireRow.Delete Next End Sub
Combining repeating columns
I am trying to write an excel macro to combine columns in a spreadsheet. Specifically, there are seven columns, each with unique headers, that repeat indefinitely. I want to combine all of the columns with the same headers into one, leaving only seven columns with all of the data. I do not want to concatenate the columns, but rather have each new column's data added to the previous one at the bottom. As you can see in the code below, I have frankensteined it with macros I recorded and macros I have found online, as well as some of my own code here and there. It's very ineloquent and lengthy, and I'm sure there's an easier solution. Sub Pop() ' ' Pop Macro ' Dim i As Integer Dim ws As Worksheet Dim from_lastcol As Long Dim from_lastrow As Long Dim to_lastrow As Long Dim from_colndx As Long Dim ws_from As Worksheet, ws_to As Worksheet Dim iSheetCount Application.ScreenUpdating = False 'Format Application.ScreenUpdating = False Rows("1:1").Select Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove Range("A1").Select ActiveCell.FormulaR1C1 = "=R[1]C" Range("B1").Select ActiveCell.FormulaR1C1 = "=IF(OR(R[1]C=R[1]C[-1]),"""",R[1]C)" Range("B1").Select Selection.Copy Range("C1").Select ActiveSheet.Paste Application.CutCopyMode = False ActiveCell.FormulaR1C1 = "=IF(OR(R[1]C=R[1]C[-1],R[1]C=R[1]C[-2]),"""",R[1]C)" Range("C1").Select Selection.Copy Range("D1").Select ActiveSheet.Paste Application.CutCopyMode = False ActiveCell.FormulaR1C1 = _ "=IF(OR(R[1]C=R[1]C[-1],R[1]C=R[1]C[-2],R[1]C=R[1]C[-3]),"""",R[1]C)" Range("D1").Select Selection.Copy Range("E1").Select ActiveSheet.Paste Application.CutCopyMode = False ActiveCell.FormulaR1C1 = _ "=IF(OR(R[1]C=R[1]C[-1],R[1]C=R[1]C[-2],R[1]C=R[1]C[-3],R[1]C=R[1]C[-4]),"""",R[1]C)" Range("E1").Select Selection.Copy Range("F1").Select ActiveSheet.Paste Application.CutCopyMode = False ActiveCell.FormulaR1C1 = _ "=IF(OR(R[1]C=R[1]C[-1],R[1]C=R[1]C[-2],R[1]C=R[1]C[-3],R[1]C=B2F2=R[1]C[-5]),"""",R[1]C)" Range("F1").Select ActiveCell.FormulaR1C1 = _ "=IF(OR(R[1]C=R[1]C[-1],R[1]C=R[1]C[-2],R[1]C=R[1]C[-3],R[1]C=R[1]C[-4],R[1]C=R[1]C[-5]),"""",R[1]C)" Range("F1").Select Selection.Copy Range("G1").Select ActiveSheet.Paste Application.CutCopyMode = False ActiveCell.FormulaR1C1 = _ "=IF(OR(R[1]C=R[1]C[-1],R[1]C=R[1]C[-2],R[1]C=R[1]C[-3],R[1]C=R[1]C[-4],R[1]C=B2G2=R[1]C[-6]),"""",R[1]C)" Range("G1").Select ActiveCell.FormulaR1C1 = _ "=IF(OR(R[1]C=R[1]C[-1],R[1]C=R[1]C[-2],R[1]C=R[1]C[-3],R[1]C=R[1]C[-4],R[1]C=R[1]C[-5],R[1]C=R[1]C[-6]),"""",R[1]C)" Range("G1").Select Selection.Copy Range("H1").Select ActiveSheet.Paste Application.CutCopyMode = False ActiveCell.FormulaR1C1 = _ "=IF(OR(R[1]C=R[1]C[-1],R[1]C=R[1]C[-2],R[1]C=R[1]C[-3],R[1]C=R[1]C[-4],R[1]C=R[1]C[-5],R[1]C=R[1]C[-6],R[1]C=R[1]C[-7]),"""",R[1]C)" Range("H1").Select Selection.Copy Range("I1").Select ActiveSheet.Paste Application.CutCopyMode = False ActiveCell.FormulaR1C1 = _ "=IF(OR(R[1]C=R[1]C[-1],R[1]C=R[1]C[-2],R[1]C=R[1]C[-3],R[1]C=R[1]C[-4],R[1]C=R[1]C[-5],R[1]C=R[1]C[-6],R[1]C=R[1]C[-7],R[1]C=R[1]C[-8]),"""",R[1]C)" Range("I1").Select Selection.Copy Range("J1").Select ActiveSheet.Paste Application.CutCopyMode = False ActiveCell.FormulaR1C1 = _ "=IF(OR(R[1]C=R[1]C[-1],R[1]C=R[1]C[-2],R[1]C=R[1]C[-3],R[1]C=R[1]C[-4],R[1]C=R[1]C[-5],R[1]C=R[1]C[-6],R[1]C=R[1]C[-7],R[1]C=R[1]C[-8],R[1]C=R[1]C[-9]),"""",R[1]C)" Rows("1:1").Select Selection.Copy Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _ False, Transpose:=False Rows("1:1").Select Application.CutCopyMode = False Selection.Copy Sheets.Add Sheets("Sheet2").Select Sheets.Add Sheets("Sheet3").Select Sheets.Add Sheets("Sheet4").Select Sheets.Add Sheets("Sheet5").Select Sheets.Add Sheets("Sheet6").Select Sheets.Add Sheets("Sheet7").Select Sheets.Add Sheets("Sheet8").Select Sheets.Add Sheets("Sheet9").Select Sheets.Add Sheets("Sheet10").Select Sheets.Add Sheets("Sheet11").Select Sheets("Sheet11").Name = "Legend" ActiveSheet.Paste ActiveWindow.SmallScroll ToRight:=-4 ActiveWindow.ScrollWorkbookTabs Sheets:=-1 ActiveWindow.ScrollWorkbookTabs Sheets:=-1 Sheets("Sheet1").Select Rows("1:1").Select Application.CutCopyMode = False Selection.Delete Shift:=xlUp Sheets("Sheet2").Select 'Format Sheet 2 Sheets("Sheet2").Select Range("A1").Select ActiveCell.FormulaR1C1 = "=IF(Sheet1!R1C=Legend!R1C1,Sheet1!RC,""P"")" Range("A1").Select Selection.AutoFill Destination:=Range("A1:A500"), Type:=xlFillDefault Range("A1:A500").Select Selection.AutoFill Destination:=Range("A1:ZZ500"), Type:=xlFillDefault Range("A1:ZZ500").Select Selection.Copy Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _ False, Transpose:=False Application.CutCopyMode = False Selection.Replace what:="P", Replacement:="", lookat:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False ActiveWorkbook.ActiveSheet.Sort.SortFields.Clear ActiveWorkbook.ActiveSheet.Sort.SortFields.Add Key:=Range("A1:ZZ1") _ , SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal With ActiveWorkbook.ActiveSheet.Sort .SetRange Range("A1:ZZ500") .header = xlNo .MatchCase = False .Orientation = xlLeftToRight .SortMethod = xlPinYin .Apply End With 'Format Sheet 3 Sheets("Sheet3").Select Range("A1").Select ActiveCell.FormulaR1C1 = "=IF(Sheet1!R1C=Legend!R1C2,Sheet1!RC,""P"")" Range("A1").Select Selection.AutoFill Destination:=Range("A1:A500"), Type:=xlFillDefault Range("A1:A500").Select Selection.AutoFill Destination:=Range("A1:ZZ500"), Type:=xlFillDefault Range("A1:ZZ500").Select Selection.Copy Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _ False, Transpose:=False Application.CutCopyMode = False Selection.Replace what:="P", Replacement:="", lookat:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False ActiveWorkbook.ActiveSheet.Sort.SortFields.Clear ActiveWorkbook.ActiveSheet.Sort.SortFields.Add Key:=Range("A1:ZZ1") _ , SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal With ActiveWorkbook.ActiveSheet.Sort .SetRange Range("A1:ZZ500") .header = xlNo .MatchCase = False .Orientation = xlLeftToRight .SortMethod = xlPinYin .Apply End With 'Format Sheet 4 Sheets("Sheet4").Select Range("A1").Select ActiveCell.FormulaR1C1 = "=IF(Sheet1!R1C=Legend!R1C3,Sheet1!RC,""P"")" Range("A1").Select Selection.AutoFill Destination:=Range("A1:A500"), Type:=xlFillDefault Range("A1:A500").Select Selection.AutoFill Destination:=Range("A1:ZZ500"), Type:=xlFillDefault Range("A1:ZZ500").Select Selection.Copy Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _ False, Transpose:=False Application.CutCopyMode = False Selection.Replace what:="P", Replacement:="", lookat:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False ActiveWorkbook.ActiveSheet.Sort.SortFields.Clear ActiveWorkbook.ActiveSheet.Sort.SortFields.Add Key:=Range("A1:ZZ1") _ , SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal With ActiveWorkbook.ActiveSheet.Sort .SetRange Range("A1:ZZ500") .header = xlNo .MatchCase = False .Orientation = xlLeftToRight .SortMethod = xlPinYin .Apply End With 'Format Sheet 5 Sheets("Sheet5").Select Range("A1").Select ActiveCell.FormulaR1C1 = "=IF(Sheet1!R1C=Legend!R1C4,Sheet1!RC,""P"")" Range("A1").Select Selection.AutoFill Destination:=Range("A1:A500"), Type:=xlFillDefault Range("A1:A500").Select Selection.AutoFill Destination:=Range("A1:ZZ500"), Type:=xlFillDefault Range("A1:ZZ500").Select Selection.Copy Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _ False, Transpose:=False Application.CutCopyMode = False Selection.Replace what:="P", Replacement:="", lookat:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False ActiveWorkbook.ActiveSheet.Sort.SortFields.Clear ActiveWorkbook.ActiveSheet.Sort.SortFields.Add Key:=Range("A1:ZZ1") _ , SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal With ActiveWorkbook.ActiveSheet.Sort .SetRange Range("A1:ZZ500") .header = xlNo .MatchCase = False .Orientation = xlLeftToRight .SortMethod = xlPinYin .Apply End With 'Format Sheet 6 Sheets("Sheet6").Select Range("A1").Select ActiveCell.FormulaR1C1 = "=IF(Sheet1!R1C=Legend!R1C5,Sheet1!RC,""P"")" Range("A1").Select Selection.AutoFill Destination:=Range("A1:A500"), Type:=xlFillDefault Range("A1:A500").Select Selection.AutoFill Destination:=Range("A1:ZZ500"), Type:=xlFillDefault Range("A1:ZZ500").Select Selection.Copy Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _ False, Transpose:=False Application.CutCopyMode = False Selection.Replace what:="P", Replacement:="", lookat:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False ActiveWorkbook.ActiveSheet.Sort.SortFields.Clear ActiveWorkbook.ActiveSheet.Sort.SortFields.Add Key:=Range("A1:ZZ1") _ , SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal With ActiveWorkbook.ActiveSheet.Sort .SetRange Range("A1:ZZ500") .header = xlNo .MatchCase = False .Orientation = xlLeftToRight .SortMethod = xlPinYin .Apply End With 'Format Sheet 7 Sheets("Sheet7").Select Range("A1").Select ActiveCell.FormulaR1C1 = "=IF(Sheet1!R1C=Legend!R1C6,Sheet1!RC,""P"")" Range("A1").Select Selection.AutoFill Destination:=Range("A1:A500"), Type:=xlFillDefault Range("A1:A500").Select Selection.AutoFill Destination:=Range("A1:ZZ500"), Type:=xlFillDefault Range("A1:ZZ500").Select Selection.Copy Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _ False, Transpose:=False Application.CutCopyMode = False Selection.Replace what:="P", Replacement:="", lookat:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False ActiveWorkbook.ActiveSheet.Sort.SortFields.Clear ActiveWorkbook.ActiveSheet.Sort.SortFields.Add Key:=Range("A1:ZZ1") _ , SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal With ActiveWorkbook.ActiveSheet.Sort .SetRange Range("A1:ZZ500") .header = xlNo .MatchCase = False .Orientation = xlLeftToRight .SortMethod = xlPinYin .Apply End With 'Format Sheet 8 Sheets("Sheet8").Select Range("A1").Select ActiveCell.FormulaR1C1 = "=IF(Sheet1!R1C=Legend!R1C7,Sheet1!RC,""P"")" Range("A1").Select Selection.AutoFill Destination:=Range("A1:A500"), Type:=xlFillDefault Range("A1:A500").Select Selection.AutoFill Destination:=Range("A1:ZZ500"), Type:=xlFillDefault Range("A1:ZZ500").Select Selection.Copy Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _ False, Transpose:=False Application.CutCopyMode = False Selection.Replace what:="P", Replacement:="", lookat:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False ActiveWorkbook.ActiveSheet.Sort.SortFields.Clear ActiveWorkbook.ActiveSheet.Sort.SortFields.Add Key:=Range("A1:ZZ1") _ , SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal With ActiveWorkbook.ActiveSheet.Sort .SetRange Range("A1:ZZ500") .header = xlNo .MatchCase = False .Orientation = xlLeftToRight .SortMethod = xlPinYin .Apply End With 'Format Sheet 9 Sheets("Sheet9").Select Range("A1").Select ActiveCell.FormulaR1C1 = "=IF(Sheet1!R1C=Legend!R1C8,Sheet1!RC,""P"")" Range("A1").Select Selection.AutoFill Destination:=Range("A1:A500"), Type:=xlFillDefault Range("A1:A500").Select Selection.AutoFill Destination:=Range("A1:ZZ500"), Type:=xlFillDefault Range("A1:ZZ500").Select Selection.Copy Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _ False, Transpose:=False Application.CutCopyMode = False Selection.Replace what:="P", Replacement:="", lookat:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False ActiveWorkbook.ActiveSheet.Sort.SortFields.Clear ActiveWorkbook.ActiveSheet.Sort.SortFields.Add Key:=Range("A1:ZZ1") _ , SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal With ActiveWorkbook.ActiveSheet.Sort .SetRange Range("A1:ZZ500") .header = xlNo .MatchCase = False .Orientation = xlLeftToRight .SortMethod = xlPinYin .Apply End With 'Format Sheet 10 Sheets("Sheet10").Select Range("A1").Select ActiveCell.FormulaR1C1 = "=IF(Sheet1!R1C=Legend!R1C9,Sheet1!RC,""P"")" Range("A1").Select Selection.AutoFill Destination:=Range("A1:A500"), Type:=xlFillDefault Range("A1:A500").Select Selection.AutoFill Destination:=Range("A1:ZZ500"), Type:=xlFillDefault Range("A1:ZZ500").Select Selection.Copy Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _ False, Transpose:=False Application.CutCopyMode = False Selection.Replace what:="P", Replacement:="", lookat:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False ActiveWorkbook.ActiveSheet.Sort.SortFields.Clear ActiveWorkbook.ActiveSheet.Sort.SortFields.Add Key:=Range("A1:ZZ1") _ , SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal With ActiveWorkbook.ActiveSheet.Sort .SetRange Range("A1:ZZ500") .header = xlNo .MatchCase = False .Orientation = xlLeftToRight .SortMethod = xlPinYin .Apply End With 'Cycle For i = 2 To 10 mysheet = "Sheet" & i Sheets(mysheet).Select On Error GoTo Error_Handler 'CollapseColumns Set ws_from = ActiveWorkbook.ActiveSheet Rows("1:1").Select Selection.Delete Shift:=xlUp from_lastcol = ws_from.Cells(1, Columns.Count).End(xlToLeft).Column 'Turn error checking off so if no "AllData" trying to delete doesn't generate Error On Error Resume Next 'so not prompted to confirm delete Application.DisplayAlerts = False 'Delete if already exists so don't get error ActiveWorkbook.Worksheets("AllData").Delete Application.DisplayAlerts = True 'turn error checking back on On Error GoTo 0 'since you refer to "AllData" throughout Set ws_to = Worksheets.Add ws_to.Name = "AllData" For from_colndx = 1 To from_lastcol from_lastrow = ws_from.Cells(Rows.Count, from_colndx).End(xlUp).Row 'If you're going to exceed 65536 rows If from_lastrow + ws_to.Cells(Rows.Count, 1).End(xlUp).Row <= 65536 Then to_lastrow = ws_to.Cells(Rows.Count, 1).End(xlUp).Row Else GoTo Error_Handler End If ws_from.Range(ws_from.Cells(1, from_colndx), ws_from.Cells(from_lastrow, _ from_colndx)).Copy ws_to.Cells(to_lastrow + 1, 1) Next For iSheetCount = 1 To Sheets.Count Sheets(iSheetCount).Name = iSheetCount Next iSheetCount ' this deletes any blank rows ws_to.Columns(1).SpecialCells(xlCellTypeBlanks).EntireRow.Delete Next i Error_Handler: Sheets("Sheet2").Delete Sheets("Sheet3").Delete Sheets("Sheet4").Delete Sheets("Sheet5").Delete Sheets("Sheet6").Delete Sheets("Sheet7").Delete Sheets("Sheet8").Delete Sheets("Sheet9").Delete Sheets("Sheet10").Delete Sheets("AllData").Delete Application.ScreenUpdating = True End Sub
First off, you should always avoid using Select, Selection, & ActiveCell as explained here. The macro recorder is a good place to start, so good job getting the macro to work! I believe the following code will accomplish what you want to happen without having to add and delete sheets: Option Explicit Sub Test() Dim ws As Worksheet Dim FirstLastRow As Long Dim curLastRow As Long Dim LastColumn As Long Dim i As Long, j As Long Application.ScreenUpdating = False Set ws = ThisWorkbook.Worksheets("Sheet1") LastColumn = ws.Cells(1, Columns.Count).End(xlToLeft).Column For i = 1 To LastColumn FirstLastRow = ws.Cells(Rows.Count, i).End(xlUp).Row For j = LastColumn To i + 1 Step -1 If ws.Cells(1, j).Value = ws.Cells(1, i).Value And i <> j Then curLastRow = ws.Cells(Rows.Count, j).End(xlUp).Row ws.Range(ws.Cells(2, j), ws.Cells(curLastRow, j)).Copy ws.Cells(FirstLastRow + 1, i) ws.Columns(j).Delete Shift:=xlToLeft FirstLastRow = ws.Cells(Rows.Count, i).End(xlUp).Row End If Next j LastColumn = ws.Cells(1, Columns.Count).End(xlToLeft).Column Next i For i = 1 To LastColumn curLastRow = ws.Cells(Rows.Count, i).End(xlUp).Row With ws.Sort .SortFields.Clear .SortFields.Add Key:=ws.Range(ws.Cells(2, i), ws.Cells(curLastRow, i)), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal .SetRange ws.Range(ws.Cells(2, i), ws.Cells(curLastRow, i)) .Header = xlNo .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With Next i Application.ScreenUpdating = True End Sub Notes: You'll need to replace "Sheet1" with the correct sheet reference if it changes. Option Explicit at the top forces you to dimension each variable before it is used. This helps eliminate issues in the future because all variables that you do not dimension are automatically dimensioned as Variant by Excel. EDIT Here's a different variation tailored specifically to your workbook (http://imgur.com/hGCoWHt) that does not rely on finding LastColumn: Option Explicit Sub Test2() Dim ws As Worksheet Dim FirstLastRow As Long Dim curLastRow As Long Dim i As Long Application.ScreenUpdating = False Set ws = ThisWorkbook.Worksheets("Sheet1") Do Until ws.Cells(1, 8).Value = "" For i = 7 To 1 Step -1 FirstLastRow = ws.Cells(Rows.Count, i).End(xlUp).Row curLastRow = ws.Cells(Rows.Count, i + 7).End(xlUp).Row ws.Range(ws.Cells(2, i + 7), ws.Cells(curLastRow, i + 7)).Copy ws.Cells(FirstLastRow + 1, i) ws.Columns(i + 7).Delete Next i Loop For i = 1 To 7 curLastRow = ws.Cells(Rows.Count, i).End(xlUp).Row With ws.Sort .SortFields.Clear .SortFields.Add Key:=ws.Range(ws.Cells(2, i), ws.Cells(curLastRow, i)), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal .SetRange ws.Range(ws.Cells(2, i), ws.Cells(curLastRow, i)) .Header = xlNo .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With Next i Application.ScreenUpdating = True End Sub