Optimize slow VBA code - excel

I have the following code - most of which was recorded with the macro recorder. It is slow and seems to be kind of unreliable (sometimes it takes about 1 minute and other times it takes much longer).
I am wondering if anyone here can help me clean this up and get it to run more efficiently.
Thanks!
Sub RemainingMIUL()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Sheets("Sheet2").Select
Columns("A:A").Select
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Sheets("Sheet1").Select
ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort.SortFields.Add Key:=Range _
("L1"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortTextAsNumbers
With ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Columns("L:L").Select
Selection.Copy
Sheets("Sheet2").Select
Range("A1").Select
ActiveSheet.Paste
Sheets("Sheet1").Select
Application.CutCopyMode = False
ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort.SortFields.Add Key:=Range _
("A1"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortTextAsNumbers
With ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Sheets("Sheet2").Select
Range("B2").Select
Dim cell As Range
For Each cell In Range("B2", Cells(Rows.Count, "B").End(xlUp))
If Range("A:A").Find(What:=cell.Value2, LookAt:=xlWhole) Is Nothing Then cell.Interior.Color = vbYellow
Next cell
With Sheets("Sheet2")
For Each cell In .Range("B2", Cells(Rows.Count, "B").End(xlUp))
If .Range("A:A").Find(What:=cell.Value2, LookAt:=xlWhole) Is Nothing Then _
Intersect(.UsedRange, cell.EntireRow).Offset(, 1).Copy _
Sheets("Sheet1").Cells(Rows.Count, "L").End(xlUp).Offset(1)
Next cell
End With
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
End Sub

Try combining the 2 for loops that you have at the bottom of the code. They both loop through the column B and run code when the same criteria is met.
With Sheets("Sheet2")
For Each cell In .Range("B2", Cells(Rows.Count, "B").End(xlUp))
If .Range("A:A").Find(What:=cell.Value2, LookAt:=xlWhole) Is Nothing Then
Intersect(.UsedRange, cell.EntireRow).Offset(, 1).Copy Sheets("Sheet1").Cells(Rows.Count, "L").End(xlUp).Offset(1)
cell.Interior.Color = vbYellow
End if
Next cell
End With
You can then delete the first loop
For Each cell In Range("B2", Cells(Rows.Count, "B").End(xlUp))
If Range("A:A").Find(What:=cell.Value2, LookAt:=xlWhole) Is Nothing Then cell.Interior.Color = vbYellow
Next cell

Related

How to refer to dynamic sheet in Excel VBA instead of Sheet Name - Instead of "Sheet16", i want to refer to the ActiveSheet

How to refer to dynamic sheet in Excel VBA instead of Sheet Name - Instead of "Sheet16", i want to refer to the ActiveSheet, please see below
Sub Macro1()
Cells.Select
Selection.Copy
Sheets.Add After:=ActiveSheet
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.AutoFilter
ActiveWorkbook.Worksheets("Sheet16").AutoFilter.Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet16").AutoFilter.Sort.SortFields.Add2 Key:= _
Range("M1:M12"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption _
:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet16").AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
Just need to change it to (ActiveSheet.Name)
The usage of ActiveSheet (as well of that of ActiveCell, Selection and the like of) should be avoided in favor of that of variables of proper class (e.g.: Worksheet, Range) as follows:
Sub Macro1()
ActiveSheet.UsedRange.Copy ' handle only relevant cells
Sheets.Add After:=ActiveSheet
Dim newSh As Worksheet
Set newSh = ActiveSheet ' set the currently active sheet to the 'newSh' variable of 'Worksheet' class
With newSh ' reference 'newSh' variable
.Paste
Application.CutCopyMode = False
.UsedRange.AutoFilter
Dim keyRng As Range
Set keyRng = .Range("M1:M12") ' set M1:M12 cells range of the referenced sheet as the one for sort keys
With .AutoFilter.Sort ' reference 'Sort' property of 'Autofilter' object of referenced sheet
With .SortFields ' reference 'SortFields' object of referenced 'Sort' property
.Clear
.Add2 Key:=keyRng, _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
End With
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
End Sub
This worked perfectly fine for me :)
Sub Sortieren()
lr = Cells.Find("*", Cells(1, 1), xlFormulas, xlPart, xlByRows, xlPrevious, False).Row
Cells.Select
Selection.AutoFilter
Worksheets(ActiveSheet.Name).Sort.SortFields.Clear
Worksheets(ActiveSheet.Name).AutoFilter.Sort.SortFields.Add2 Key:= _
Range("N1:N" & lr), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption _
:=xlSortNormal
With ActiveWorkbook.Worksheets(ActiveSheet.Name).AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub

Run-time error only after successful runs - Excel VBA

I have an Excel VBA macro that works successfully the first two times I run it, but the third time it gives this error:
Run-Time Error '1004'
The sort reference is not valid. Make sure that it's within the data you want to sort, and the first Sort By box isn't the same or blank.
If I restart Excel it works the first two times, then gives the error again. Why would this happen? Here's my code:
Dim rawData As Object
Dim report As Object
Dim areaCodes As Object
Set rawData = Sheets("RawData")
Set report = Sheets("Report")
Set areaCodes = Sheets("AreaCodes")
report.Cells.Clear
report.Cells.ClearFormats
stateCol = rawData.Cells(1, 1).EntireRow.Find(What:="state", LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False).Column
Dim MyRange As Range
Set MyRange = rawData.Cells(1, stateCol)
With rawData
lastRow = .Cells(Rows.Count, MyRange.Column).End(xlUp).Row
.Range(.Cells(2, stateCol), .Cells(lastRow, stateCol)).Copy
End With
With report
.Range("A3").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
.Range(.Cells(3, 1), .Cells(lastRow + 1, 1)).RemoveDuplicates Columns:=1, Header:=xlNo
End With
lastRow = report.Cells(Rows.Count, Range("A1").Column).End(xlUp).Row
report.Range("B3").Select
ActiveCell.FormulaR1C1 = "=COUNTIF(rawData!C[" & stateCol - 2 & "],report!RC[-1])"
Range("B3").AutoFill Destination:=Range("B3:B" & lastRow)
Range("B" & lastRow + 1).Select
ActiveCell.FormulaR1C1 = "=SUM(R[-" & lastRow - 2 & "]C:R[-1]C)"
Range("C3").Select
ActiveCell.FormulaR1C1 = "=RC[-1]/R" & lastRow + 1 & "C[-1]"
Range("C3").AutoFill Destination:=Range("C3:C" & lastRow)
Range("C" & lastRow + 1).Select
ActiveCell.FormulaR1C1 = "=SUM(R[-" & lastRow - 2 & "]C:R[-1]C)"
Range("C:C").NumberFormat = "0.0%"
Range("A2:A" & lastRow + 1).Select
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
report.Range("A2").Value = "State"
report.Range("A2").Font.Bold = True
report.Range("A:A").HorizontalAlignment = xlCenter
report.Range("A3").FormulaR1C1 = "=INDEX(areaCodes!R2C5:R52C5,MATCH(report!RC[1],AreaCodes!R2C6:R52C6,0))"
Range("A3").Select
ActiveCell.AutoFill Destination:=Range("A3:A" & lastRow)
With report
newLastRow = .Cells(Rows.Count, Range("C1").Column).End(xlUp).Row - 1
.Range(.Cells(3, 3), .Cells(newLastRow, 3)).Copy
.Range("C3").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End With
With report
.Sort.SortFields.Add Key:=Range("C2"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
newLastRow = .Cells(Rows.Count, Range("C1").Column).End(xlUp).Row - 1
With .Sort
.SetRange Range("A2:D" & newLastRow)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
you should qualify the range in your sort instruction, this will produce an error if the sheet report is not activated
With report
.Sort.SortFields.Add Key:=.Range("C2"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
newLastRow = .Cells(Rows.Count, .Range("C1").Column).End(xlUp).Row - 1
With .Sort
.SetRange report.Range("A2:D" & newLastRow)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With

Cleaning up code in recorded Excel Macro

I used the Record Macro function to create this, but it runs real slow and I want to see if anyone had any ideas on how to clean it up. It looks as if I have two sorts here doing the same thing? Thanks in advance.
Sub Activations()
'
' Master_Button2_2_Click Macro
'
'
Application.ScreenUpdating = False
Sheets("Index").Select
Columns("A:C").Select
ActiveWorkbook.Worksheets("Index").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Index").Sort.SortFields.Add Key:=Range("B2:B12000" _
), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Index").Sort
.SetRange Range("A1:C12000")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Sheets("Duplicates").Select
ActiveSheet.Range("$L$4:$N$3476").AutoFilter Field:=1, Criteria1:= _
"Activate"
Sheets("Master").Select
ActiveSheet.Range("$A$2:$BU$11965").AutoFilter Field:=73, Criteria1:= _
"A"
Application.ScreenUpdating = True
End Sub
Your code is fairly straightforward although it isn't entirely clear what it is trying to accomplish. Here is a quick rewrite putting several With ... End With statement to use to narrow down the affected work areas.
Sub Activations()
' Master_Button2_2_Click Macro
Dim lr As Long
appTGGL bTGGL:=False
With Worksheets("Index")
lr = .Cells.SpecialCells(xlCellTypeLastCell).Row
With .Range("A1:C" & lr)
.Cells.Sort Key1:=.Columns(2), Order1:=xlAscending, _
Orientation:=xlTopToBottom, Header:=xlYes
End With
End With
With Worksheets("Duplicates")
If .AutoFilterMode Then .AutoFilterMode = False
lr = .Cells.SpecialCells(xlCellTypeLastCell).Row
With .Range("L4:N" & lr)
.AutoFilter Field:=1, Criteria1:="activate"
End With
End With
With Worksheets("Master")
If .AutoFilterMode Then .AutoFilterMode = False
lr = .Cells.SpecialCells(xlCellTypeLastCell).Row
With .Range("A2:BU" & lr)
.AutoFilter Field:=73, Criteria1:="A"
End With
.Select
End With
appTGGL
End Sub
Sub appTGGL(Optional bTGGL As Boolean = True)
With Application
.EnableEvents = bTGGL
.ScreenUpdating = bTGGL
.DisplayAlerts = bTGGL
.Calculation = IIf(bTGGL, xlCalculationAutomatic, xlCalculationManual)
End With
End Sub
Sample data and a short narrative of explanation would have helped this question. We don't all speak english but we all speak code and data.

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

How to run a macro with a dynamic list

Right now I have multiple macros set up and I would like to cut it down to one. First the user inputs the desired part number they are looking for and the macro will return the all the different versions associated with that part number in a dropdown. Next the user will go and select the version from the dropdown that they want to look at and the next macro will find the name associated with it.
Is there a way for the macro to wait until user has entered a value then continue to execute code again?
THIS IS THE FIRST MACRO
Dim part As String
Application.ScreenUpdating = False
'Filter based on user entry
Sheets("New Revision ").Select
part = Range("B4").Value
Sheets("PN_List").Select
Columns("D:E").Select
Selection.EntireColumn.Hidden = False
ActiveSheet.Range("$A$1:$K$3000").AutoFilter Field:=1, Criteria1:=part
'Take current version and filter it to bottom of the list
ActiveWorkbook.Worksheets("PN_List").AutoFilter.Sort.SortFields.Clear
ActiveWorkbook.Worksheets("PN_List").AutoFilter.Sort.SortFields.Add Key:= _
Range("E1:E3000"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption _
:=xlSortNormal
With ActiveWorkbook.Worksheets("PN_List").AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
'Version Number
Worksheets("PN_List").Activate
Range("B1").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Sheets("table_converter").Visible = True
Sheets("table_converter").Select
Range("A1").Select
ActiveSheet.Paste
Range("A1").Select
Range(Selection, Selection.End(xlDown)).Select
ActiveSheet.ListObjects.Add(xlSrcRange, Range("A1", Selection.End(xlDown)), xlNo).Name = _
"master"
ActiveSheet.ListObjects("master").ShowHeaders = False
Range("master[#All]").Select
ActiveWorkbook.Names.Add Name:="converter", RefersToR1C1:= _
"=master[#All]"
ActiveWorkbook.Names("converter").Comment = ""
'ActiveSheet.ListObjects("master").ShowHeaders = False
'Range(Selection, Selection.End(xlDown)).Select
'Range(Selection, Selection.End(xlDown)).Select
'val = Range(Selection, Selection.End(xlDown)).Value
Worksheets("New Revision ").Activate
'Range("B7").Select
' With Selection.Validation
' .Delete
' .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
' xlBetween, Formula1:=r
' .IgnoreBlank = True
' .InCellDropdown = True
'.InputTitle = ""
'.ErrorTitle = ""
'.InputMessage = ""
'.ErrorMessage = ""
'.ShowInput = True
'.ShowError = True
'End With
'Return PN_List to normal form
Worksheets("PN_List").Activate
ActiveSheet.Range("$A$1:$K$3000").AutoFilter Field:=1
Columns("A:K").Select
ActiveWorkbook.Worksheets("PN_List").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("PN_List").Sort.SortFields.Add Key:=Range( _
"A2:A3000"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
ActiveWorkbook.Worksheets("PN_List").Sort.SortFields.Add Key:=Range( _
"E2:E3000"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ActiveWorkbook.Worksheets("PN_List").Sort
.SetRange Range("A1:K3000")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Selection.AutoFilter
'hide key colunm
Worksheets("PN_List").Activate
Columns("D:E").Select
Selection.EntireColumn.Hidden = True
Range("A1").Select
Worksheets("New Revision ").Activate
Sheets("table_converter").Visible = False
'Entry does not exsit
' If Worksheets("New Revision ").Range("B4") = "" Then
'MsgBox "Part Number Not found. Please refer to the PN List.", vbOKOnly + vbExclamation, "Entry Error"
'End If
' If Worksheets("New Revision ").Range("B6") = "" Then
'Worksheets("New Revision ").Range("B4").ClearContents
'End If
End Sub
HERE IS THE SECOND MACRO
Dim ver_num As String
Dim prt_num As String
Application.ScreenUpdating = False
'Clear Previous Data in Search Version Number
Sheets("table_converter").Visible = True
Sheets("table_converter").Select
Columns("A:A").Select
Selection.Delete Shift:=xlToLeft
On Error Resume Next
ActiveWorkbook.Names("converter").Delete
'Retrun Part Name
Sheets("New Revision ").Select
Range("B4").Select
ver_num = Selection.Value
Range("B6").Select
prt_num = Selection.Value
Sheets("PN_List").Select
'Find part name
ActiveSheet.Range("$A$1:$K$3000").AutoFilter Field:=1
ActiveSheet.Range("$A$1:$K$3000").AutoFilter Field:=1, Criteria1:=ver_num
ActiveSheet.Range("$A$1:$K$3000").AutoFilter Field:=2, Criteria1:=prt_num
Range("F1").End(xlDown).Offset(0, 0).Select
Selection.Copy
Sheets("New Revision ").Select
Range("B8").Select
ActiveCell.PasteSpecial
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlBottom
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
Selection.Font.Bold = True
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 15773696
.TintAndShade = 0
.PatternTintAndShade = 0
End With
'Filter List back to normal
Sheets("PN_List").Select
Columns("D:E").Select
Selection.EntireColumn.Hidden = False
Selection.AutoFilter
Columns("A:A").Select
ActiveWorkbook.Worksheets("PN_List").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("PN_List").Sort.SortFields.Add Key:=Range( _
"A2:A3000"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
ActiveWorkbook.Worksheets("PN_List").Sort.SortFields.Add Key:=Range( _
"E2:E3000"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ActiveWorkbook.Worksheets("PN_List").Sort
.SetRange Range("A1:L3000")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Columns("D:E").Select
Selection.EntireColumn.Hidden = True
Range("A1").Select
Sheets("New Revision ").Select
With Selection.Borders(xlEdgeRight)
.LineStyle = xlDouble
.ColorIndex = xlAutomatic
.TintAndShade = 0
.Weight = xlThick
End With
Selection.Borders(xlInsideVertical).LineStyle = xlNone
Selection.Borders(xlInsideHorizontal).LineStyle = xlNone
Sheets("table_converter").Visible = False
End Sub
Something like value = Inputbox("Input a value : ") ?
Edit: To detail on that, you could do something like
Sub valueMenu()
myValue = InputBox("Input a value : ")
If myValue = 1 Then
'Call Macro1
Macro1
ElseIf myValue = 2 Then
'Call Macro2
Macro2
End If
End Sub
Sub Macro1()
'Do something
End Sub
Sub Macro2()
'Do something else
End Sub

Resources