Slow running macro - excel

I've created a macro (using lots of online help) to take data from one sheet, create another sheet, format the data and set up the printer.
Everything works as it should but the macro seems to take a long time to run.
Would someone be able to look at my code and see if I've done something that I shouldn't?
Thanks
Sub Preactor_Sort()
Application.ScreenUpdating = False
'**Copy "Full List" Data into New Sheet**
Sheets("FULL LIST").Select
Range("A8:R8").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Sheets.Add(Before:=Sheets("MASTER")).Name = "Sorted Full"
Range("A1").Select
ActiveSheet.Paste
ActiveWindow.Zoom = 60
'**************************************************
'**Formatting and removing previous conditional formatting**
Cells.FormatConditions.Delete
Cells.Select
With Selection.Font
.Name = "Calibri"
.Size = 9
.Bold = False
.Color = vbBlack
End With
With Selection
.VerticalAlignment = xlCenter
.HorizontalAlignment = xlCenter
.WrapText = True
.Interior.ColorIndex = 0
.RowHeight = 23
End With
Cells.EntireColumn.AutoFit
'***************************************************
'**Deleting Unwanted Columns**
Columns("E:E").Select
Selection.Cut
Columns("C:C").Select
Selection.Insert Shift:=xlToRight
Columns("A:C").Select
Range("A1").Activate
Selection.Delete Shift:=xlToLeft
'***************************************************
'**Rearranging Columns**
Columns("G:H").Select
Selection.Cut
Columns("B:B").Select
Selection.Insert Shift:=xlToRight
Columns("K:L").Select
Selection.Cut
Columns("E:E").Select
Selection.Insert Shift:=xlToRight
'****************************************************
'**Sorting Day/Date**
Columns("C:C").Select
Selection.NumberFormat = "dd/mm/yy hh:mm"
Columns("C:C").EntireColumn.AutoFit
Columns("C:C").Select
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Columns("C:C").Select
Selection.NumberFormat = "General"
'**Find Last Row**
LR = Cells.Find("*", Cells(1, 1), xlFormulas, xlPart, xlByRows, xlPrevious, False).Row
'**Insert Formula**
Range("C2").Formula = "=TEXT(D2,""ddd"")"
'**Drag Formula down to last row**
Range("C2").AutoFill Range("C2:C" & LR)
Columns("C:C").EntireColumn.AutoFit
'*****************************************************
'**Sorting**
With ActiveSheet.Sort
.SortFields.Add2 Key:=Range("C1"), Order:=xlAscending, CustomOrder:="Mon,Tue,Wed,Thu,Fri,Sat,Sun", DataOption:=xlSortNormal
.SortFields.Add2 Key:=Range("B1"), SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder:="Make,Discharge,Packing,Wrapping", DataOption:=xlSortNormal
.SetRange Range("A:P")
.Header = xlYes
.Apply
End With
'******************************************************
'**Formatting**
Range("C:C,E:E").Select
With Selection
.Font.Bold = True
End With
Columns("B:B").Select
Selection.ColumnWidth = 10
Columns("F:G").Select
Selection.ColumnWidth = 25
Columns("A:A").Select
Selection.ColumnWidth = 8
Columns("I:J").Select
Selection.ColumnWidth = 5
Columns("L:N").Select
Selection.ColumnWidth = 15
Columns("O:O").Select
Selection.ColumnWidth = 80
Columns("H:H").Select
Selection.ColumnWidth = 40
Columns("K:K").Select
Selection.ColumnWidth = 6
'**Conditional Formatting**
'** Alternating Rows
Dim lastRow As Long
lastRow = Range("A1:P1").End(xlDown).Row
For Each cell In Range("A1:P" & lastRow)
If cell.Row Mod 2 = 1 Then
cell.Interior.ColorIndex = 34 'Light Blue
End If
Next cell
'**Highlighting Operations
Dim cell1 As Range
For Each cell1 In Range("B:B")
If cell1.Value = "Make" Then
cell1.Interior.ColorIndex = 35 'Light Green
ElseIf cell1.Value = "Discharge" Then
cell1.Interior.ColorIndex = 36 'Light Yellow
ElseIf cell1.Value = "Packing" Then
cell1.Interior.ColorIndex = 19 'Light Cream
ElseIf cell1.Value = "Wrapping" Then
cell1.Interior.ColorIndex = 6 'Yellow
ElseIf cell1.Value = "Boxing" Then
cell1.Interior.ColorIndex = 44 'Light Orange
ElseIf cell1.Value = "Oil Phase" Then
cell1.Interior.ColorIndex = 38 'Pink
End If
Next
'**Highlighting Day
Dim cell2 As Range
For Each cell2 In Range("C:C")
If cell2.Value = "Mon" Then
cell2.Interior.ColorIndex = 7 'Pink
ElseIf cell2.Value = "Tue" Then
cell2.Interior.ColorIndex = 4 'Green
ElseIf cell2.Value = "Wed" Then
cell2.Interior.ColorIndex = 6 'Yellow
ElseIf cell2.Value = "Thu" Then
cell2.Interior.ColorIndex = 45 'Orange
ElseIf cell2.Value = "Fri" Then
cell2.Interior.ColorIndex = 33 'Blue
End If
Next
'** Top Bar Colour
Range("A1:P1").Select
With Selection
.Interior.ColorIndex = 15
.Font.Bold = True
End With
'*********************************************************
'** Printer Setup
Application.PrintCommunication = True
With ActiveSheet.PageSetup
.PrintTitleRows = ""
.PrintTitleColumns = ""
End With
ActiveSheet.PageSetup.PrintArea = ""
With ActiveSheet.PageSetup
.LeftMargin = Application.InchesToPoints(0.12)
.RightMargin = Application.InchesToPoints(0.12)
.TopMargin = Application.InchesToPoints(0.16)
.BottomMargin = Application.InchesToPoints(0.16)
.HeaderMargin = Application.InchesToPoints(0.12)
.FooterMargin = Application.InchesToPoints(0.12)
.PrintHeadings = False
.PrintGridlines = False
.PrintComments = xlPrintNoComments
.PrintQuality = 600
.CenterHorizontally = True
.CenterVertically = False
.Orientation = xlLandscape
.Draft = False
.PaperSize = xlPaperA3
.FirstPageNumber = xlAutomatic
.Order = xlDownThenOver
.BlackAndWhite = False
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = False
.PrintErrors = xlPrintErrorsDisplayed
.OddAndEvenPagesHeaderFooter = False
.DifferentFirstPageHeaderFooter = False
.ScaleWithDocHeaderFooter = True
.AlignMarginsHeaderFooter = True
End With
' Application.PrintCommunication = False
End Sub

Trying adding in this, it speeds up by turning off screen updating, events, animations etc, this should speed it up a bit!
At the start of your code add in this sub
Call TurnOffCode
At the end of your code add in this sub
Call TurnOnCode
This is what they should both look like
Sub TurnOffCode() 'Used to turn off settings to make workbook run faster
Application.Calculation = xlCalculationManual 'Set calculations to manual
Application.ScreenUpdating = False 'Turns off screen updating
Application.EnableEvents = False 'Turns off events
Application.EnableAnimations = False 'Turns off animations
Application.DisplayStatusBar = False 'Turns off display status bar
Application.PrintCommunication = False 'Turns off print communications
End Sub
Sub TurnOnCode() 'Used to turn settings back on to normal
Application.Calculation = xlCalculationAutomatic 'Set calculations to automatic
Application.ScreenUpdating = True 'Turns on screen updating
Application.EnableEvents = True 'Turns on events
Application.EnableAnimations = True 'Turns on animations
Application.DisplayStatusBar = True 'Turns on display status bar
Application.PrintCommunication = True 'Turns on print communications
End Sub
However, you should also avoid using selects as well, look at the comment section for a page displaying that information

Thanks for looking at this for me.
I tried the solution that EuanM28 offered and this did marginally increase the speed - from 38sec to around 34sec.
I made a couple of tweaks to my code from
Dim cell1 As Range
For Each cell1 In Range("B:B")
to
Dim cell1 As Range
For Each cell1 In Range("B2:B" & LR) '*LR = last row variable defined earlier in the code
and
Dim cell2 As Range
For Each cell2 In Range("C:C")
to
Dim cell2 As Range
For Each cell2 In Range("C2:C" & LR)
This made a huge difference (34sec to 6sec) I'm guessing because it's no longer cycling through all the rows on the sheet and just the populated ones.
I will have to look into removing .Selects as suggested (didn't realise it causes so many issues!)
Thanks

You have a lot of select statements in your code only to subsequently do something with the selection you can avoid that.
A section like the below
Application.ScreenUpdating = False
'**Copy "Full List" Data into New Sheet**
Sheets("FULL LIST").Select
Range("A8:R8").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Sheets.Add(Before:=Sheets("MASTER")).Name = "Sorted Full"
Range("A1").Select
ActiveSheet.Paste
ActiveWindow.Zoom = 60
'**************************************************
'**Formatting and removing previous conditional formatting**
Cells.FormatConditions.Delete
Cells.Select
With Selection.Font
.Name = "Calibri"
.Size = 9
.Bold = False
.Color = vbBlack
End With
With Selection
.VerticalAlignment = xlCenter
.HorizontalAlignment = xlCenter
.WrapText = True
.Interior.ColorIndex = 0
.RowHeight = 23
End With
Cells.EntireColumn.AutoFit
can be rewritten as:
Dim slc As Range
Dim rng As Range
'Application.ScreenUpdating = False <= be careful with setting update to false as it will not restore if your program encounters an error!
'**Copy "Full List" Data into New Sheet**
Set rng = Sheets(1).Range("A8:R8")
Set slc = Range(rng, rng.End(xlDown))
slc.Copy
Sheets.Add(Before:=Sheets(1)).Name = "Sorted Full"
Sheets("Sorted Full").Paste
ActiveWindow.Zoom = 60
'**************************************************
'**Formatting and removing previous conditional formatting**
Cells.FormatConditions.Delete
With Cells.Font
.Name = "Calibri"
.Size = 9
.Bold = False
.Color = vbBlack
End With
With Cells
.VerticalAlignment = xlCenter
.HorizontalAlignment = xlCenter
.WrapText = True
.Interior.ColorIndex = 0
.RowHeight = 23
End With
Cells.EntireColumn.AutoFit
This will prevent Excel from making the select statement which is causing the slow execution and flickering of the screen.
If you apply that throughout your code you will have a much cleaner execution, without the need to turn off screen updating.
So, if you clean up your code a bit it can look like below:
Mind you, even this has plenty of room for improvement but at least it get's rid of most of the select statements.
This can still be combined with the solution proposed by #EuanM28
However, there are some drawbacks with switching of calculation and screenupdates that may require appropriate ErrorHandling in case your macro encounters an error.
So, combining them would look like the below:
Sub Preactor_Sort()
On Error GoTo ErrorHandler '<= called in case of an Error
Call ToggleCode(False)
Dim slc As Range
Dim rng As Range
'Application.ScreenUpdating = True
'**Copy "Full List" Data into New Sheet**
Set rng = Sheets(1).Range("A8:R8")
Set slc = Range(rng, rng.End(xlDown))
slc.Copy
Sheets.Add(Before:=Sheets(1)).Name = "Sorted Full"
Sheets("Sorted Full").Paste
ActiveWindow.Zoom = 60
'**************************************************
'**Formatting and removing previous conditional formatting**
With Cells
.FormatConditions.Delete
.VerticalAlignment = xlCenter
.HorizontalAlignment = xlCenter
.WrapText = True
.Interior.ColorIndex = 0
.RowHeight = 23
With .Font
.Name = "Calibri"
.Size = 9
.Bold = False
.Color = vbBlack
End With
.EntireColumn.AutoFit
End With
'***************************************************
'**Deleting Unwanted Columns**
columns("E:E").Cut
columns("C:C").Insert Shift:=xlToRight
columns("A:C").Delete Shift:=xlToLeft
'***************************************************
'**Rearranging Columns**
columns("G:H").Cut
columns("B:B").Insert Shift:=xlToRight
columns("K:L").Cut
columns("E:E").Insert Shift:=xlToRight
'****************************************************
'**Sorting Day/Date**
columns("C:C").NumberFormat = "dd/mm/yy hh:mm"
columns("C:C").EntireColumn.AutoFit
columns("C:C").Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
columns("C:C").NumberFormat = "General"
'**Find Last Row**
LR = Cells.Find("*", Cells(1, 1), xlFormulas, xlPart, xlByRows, xlPrevious, False).row
'**Insert Formula**
Range("C2").Formula = "=TEXT(D2,""ddd"")"
'**Drag Formula down to last row**
Range("C2").AutoFill Range("C2:C" & LR)
columns("C:C").EntireColumn.AutoFit
'*****************************************************
'**Sorting**
With ActiveSheet.Sort
.SortFields.Add2 Key:=Range("C1"), Order:=xlAscending, CustomOrder:="Mon,Tue,Wed,Thu,Fri,Sat,Sun", DataOption:=xlSortNormal
.SortFields.Add2 Key:=Range("B1"), SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder:="Make,Discharge,Packing,Wrapping", DataOption:=xlSortNormal
.SetRange Range("A:P")
.Header = xlYes
.Apply
End With
'******************************************************
'**Formatting**
Range("C:C,E:E").Font.Bold = True
columns("B:B").ColumnWidth = 10
columns("F:G").ColumnWidth = 25
columns("A:A").ColumnWidth = 8
columns("I:J").ColumnWidth = 5
columns("L:N").ColumnWidth = 15
columns("O:O").ColumnWidth = 80
columns("H:H").ColumnWidth = 40
columns("K:K").ColumnWidth = 6
'**Conditional Formatting**
'** Alternating Rows
Dim lastRow As Long
lastRow = Range("A1:P1").End(xlDown).row
For Each cell In Range("A1:P" & lastRow)
If cell.row Mod 2 = 1 Then
cell.Interior.ColorIndex = 34 'Light Blue
End If
Next cell
'**Highlighting Operations
Dim cell1 As Range
For Each cell1 In Range("B:B")
If cell1.value = "Make" Then
cell1.Interior.ColorIndex = 35 'Light Green
ElseIf cell1.value = "Discharge" Then
cell1.Interior.ColorIndex = 36 'Light Yellow
ElseIf cell1.value = "Packing" Then
cell1.Interior.ColorIndex = 19 'Light Cream
ElseIf cell1.value = "Wrapping" Then
cell1.Interior.ColorIndex = 6 'Yellow
ElseIf cell1.value = "Boxing" Then
cell1.Interior.ColorIndex = 44 'Light Orange
ElseIf cell1.value = "Oil Phase" Then
cell1.Interior.ColorIndex = 38 'Pink
End If
Next
'**Highlighting Day
Dim cell2 As Range
For Each cell2 In Range("C:C")
If cell2.value = "Mon" Then
cell2.Interior.ColorIndex = 7 'Pink
ElseIf cell2.value = "Tue" Then
cell2.Interior.ColorIndex = 4 'Green
ElseIf cell2.value = "Wed" Then
cell2.Interior.ColorIndex = 6 'Yellow
ElseIf cell2.value = "Thu" Then
cell2.Interior.ColorIndex = 45 'Orange
ElseIf cell2.value = "Fri" Then
cell2.Interior.ColorIndex = 33 'Blue
End If
Next
'** Top Bar Colour
'Range("A1:P1").Select
With Range("A1:P1")
.Interior.ColorIndex = 15
.Font.Bold = True
End With
'*********************************************************
'** Printer Setup
'Application.PrintCommunication = True
With ActiveSheet.PageSetup
.PrintTitleRows = ""
.PrintTitleColumns = ""
End With
ActiveSheet.PageSetup.PrintArea = ""
With ActiveSheet.PageSetup
.LeftMargin = Application.InchesToPoints(0.12)
.RightMargin = Application.InchesToPoints(0.12)
.TopMargin = Application.InchesToPoints(0.16)
.BottomMargin = Application.InchesToPoints(0.16)
.HeaderMargin = Application.InchesToPoints(0.12)
.FooterMargin = Application.InchesToPoints(0.12)
.PrintHeadings = False
.PrintGridlines = False
.PrintComments = xlPrintNoComments
.PrintQuality = 600
.CenterHorizontally = True
.CenterVertically = False
.Orientation = xlLandscape
.Draft = False
.PaperSize = xlPaperA3
.FirstPageNumber = xlAutomatic
.Order = xlDownThenOver
.BlackAndWhite = False
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = False
.PrintErrors = xlPrintErrorsDisplayed
.OddAndEvenPagesHeaderFooter = False
.DifferentFirstPageHeaderFooter = False
.ScaleWithDocHeaderFooter = True
.AlignMarginsHeaderFooter = True
End With
' Application.PrintCommunication = False
Call ToggleCode(True)
Exit Sub
ErrorHandler:
Call ToggleCode(True) '<= this ensures your application get's reset in case of an Error
End Sub
Sub ToggleCode(Optional switch As Boolean = True) 'Used to turn on/off settings to make workbook run faster
If (switch) Then
Application.Calculation = xlCalculationAutomatic 'Set calculations to automatic
Else
Application.Calculation = xlCalculationManual 'Set calculations to manual
End If
Application.ScreenUpdating = switch 'Turns on/off screen updating
Application.EnableEvents = switch 'Turns on/off events
Application.EnableAnimations = switch 'Turns on/off animations
Application.DisplayStatusBar = switch 'Turns on/off display status bar
Application.PrintCommunication = switch 'Turns on/off print communications
End Sub

Related

Intermittent Run-time Error 1004 or 13 in Excel 365

I am at a loss, I have been working to create this macro to help automate an obnoxious process we have at work and the best way to sum up where it is right now is, 60% of the time it works every time!
The macro takes a workbook with the raw data, reorders the columns, filters out data based on certain criteria, creates separate files for each unique value in one of the columns and then attaches that newly created workbook to an email. The email has text and a logo that is placed into the body of the email. Altogether, when the macro finishes running, it will create anywhere from 7 to 11 separate files and emails.
The problem I am having is when I run the macro, 1 of the following 3 things happens:
No issue, it runs perfectly as expected
I get Run-time error '1004':
Method 'SaveAs' of object '_Workbook' failed
This error happens on this line in the code:
ActiveWorkbook.SaveAs FName
I get Run-time error '13':
Type mismatch
This error happens on this line in the code:
OutMailDocument.Range(0, 1).InsertBefore EmailText
I have tried searching several sites and although I can find information about the errors, I can't seem to find anything that has provided any help in fixing the problem.
I do not know where in my macro I went wrong, but I don't understand why sometimes it works just fine and other times I get one of the 2 errors?
Anyway, I am hoping someone may be able to help provide some guidance as to where I am going wrong. I have posted the full code below for reference:
Sub FeeManagement()
Dim CurrentColumn As Integer
Dim Columnheading As String
Dim lastrow As Long
Dim columnorder As Variant, ndx As Integer
Dim found As Range, counter As Integer
Dim wb As Workbook, ws As Worksheet
Dim lr As Long
Dim i As Integer
Dim ar As Variant
Dim j As Long
Dim rng As Range
Dim OutApp As Object
Dim Outmail As Object
Dim OutMailDocumet As Object
Dim OutShape As Excel.Shape
Dim OutWorksheet As Excel.Worksheet
Dim FName As String
Dim FPath As String
Application.ScreenUpdating = False
ActiveSheet.Cells.Interior.Color = xlNone
Range("A1").End(xlDown).Offset(1).Resize(ActiveSheet.UsedRange.Rows.Count).EntireRow.Delete
ActiveSheet.Cells.Font.Name = "Arial"
ActiveSheet.Cells.Font.Size = "10"
Sheets("Sheet1").Copy before:=Sheets(Sheets.Count)
ActiveSheet.Name = "Original"
Worksheets("Sheet1").Activate
'Remove Unwanted Columns
For CurrentColumn = ActiveSheet.UsedRange.Columns.Count To 1 Step -1
Columnheading = ActiveSheet.UsedRange.Cells(1, CurrentColumn).Value
Select Case Columnheading
Case "Auditor", "Auditor ID", "SAI. Nbr", "Pol. Form", "Pol. Nbr", "Aud. Type", "Days todue date", "Pol. Eff Date", "End Date", "Due Date", "Ins. Name", _
"State", "Market Group", "Scheduled Dt.", "Assigned Date", "CI Date", "Aud. System Key"
Case Else
ActiveSheet.Columns(CurrentColumn).Delete
End Select
Next
'Rearrange Columns
columnorder = Array("Auditor", "Assigned Date", "SAI. Nbr", "Ins Name", "State", "Pol. Eff Date", "End Date", "Due Date", "Pol. Form", "Pol. Nbr", "Days to ue date", _
"MarketGroup", "Aud. Type", "Aud. System Key", "Scheduled DT.", "CI Date", "Auditor ID")
counter = 1
For ndx = LBound(columnorder) To UBound(columnorder)
Set found = Rows("1:1").Find(columnorder(ndx), LookIn:=xlValues, Lookat:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False)
If Not found Is Nothing Then
If found.Column <> counter Then
found.EntireColumn.Cut
Columns(counter).Insert Shift:=xlToRight
Application.CutCopyMode = False
End If
counter = counter + 1
End If
Next ndx
'Add Due Date Columns and Amend Auditor Column
Range("K1").Value = "Days To Due Date"
Columns("L:L").Insert Shift:=xlToRight, _
CopyOrigin:=xlFormatFromLeftOrAbove
Range("L1").Value = "Days Assigned"
Range("S1").Value = "Sched DT Helper"
Range("T1").Value = "CI Helper"
With Sheets("Sheet1")
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
With .Range("K2:K" & lastrow)
.NumberFormat = "0"
End With
With .Range("L2:L" & lastrow)
.Formula = "=-(B2-Today())"
.NumberFormat = "0"
End With
With .Range("S2:S" & lastrow)
.Formula = "=(Q2-Today())"
.NumberFormat = "0"
End With
With .Range("T2:T" & lastrow)
.Formula = "=ABS(Q2-Today())"
.NumberFormat = "0"
End With
End With
Columns("A:B").Insert Shift:=xlToRight, _
CopyOrigin:=xlFormatFromLeftOrAbove
Range("B1").Value = "Auditor"
With Sheets("Sheet1")
lastrow = .Cells(.Rows.Count, "C").End(xlUp).Row
With .Range("B2:B" & lastrow)
.Formula = "=left(C,25)"
End With
End With
Sheets("Sheet1").Columns("B").Copy
Sheets("Sheet1").Columns("A").PasteSpecial Paste:=xlPasteValues
Columns("B:C").EntireColumn.Delete
Worksheets("Sheet1").Columns("A:Z").AutoFit
Worksheets("Sheet1").Range("A1").AutoFilter
'Filter and Delete records based on assigned/due dates & scheduled DT/CI Dates
Set ws = ActiveSheet
On Error Resume Next
ws.ShowAllData
On Error GoTo 0
ws.Range("A1:A20000").AutoFilter Field:=12, Criteria:="<=6"
Application.DisplayAlerts = False
ws.Range("A2:Z20000").SpecialCells(xlCellTypeVisible).Delete
Application.DisplayAlerts = True
ws.ShowAllData
ws.Range("A1:A20000").AutoFilter Field:=11, Criteria:=">=30"
Application.DisplayAlerts = False
ws.Range("A2:Z20000").SpecialCells(xlCellTypeVisible).Delete
Application.DisplayAlerts = True
ws.ShowAllData
ws.Range("A1:A20000").AutoFilter Field:=19, Criteria:=">=-3"
Application.DisplayAlerts = False
ws.Range("A2:Z20000").SpecialCells(xlCellTypeVisible).Delete
Application.DisplayAlerts = True
ws.ShowAllData
ws.Range("A1:A20000").AutoFilter Field:=20, Criteria:="<=6"
Application.DisplayAlerts = False
ws.Range("A2:Z20000").SpecialCells(xlCellTypeVisible).Delete
Application.DisplayAlerts = True
ws.ShowAllData
On Error Resume Next
ws.ShowAllData
On Error GoTo 0
Columns("S:T").EntireColumn.Delete
Columns("P:Q").EntireColumn.Delete
ws.AutoFilter.Sort.SortFields.Clear
ws.AutoFilter.Sort.SortFields.Add2 Key:=Range( _
"K1:K10000"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ws.AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Columns("P:T").Insert Shift:=xlToRight, _
CopyOrigin:=xlFormatFromLeftOrAbove
Range("P1").Value = "New Status"
Range("Q1").Value = "New Status Text"
Range("R1").Value = "Date"
Range("S1").Value = "New Status Date"
Range("T1").Value = "Host Status"
'Create separate worksheets
Set wb = ActiveWorkbook
Set ws = ActiveSheet
lr = ws.Range("A" & Rows.Count).End(xlUp).Row
Set rng = ws.Range("A1:A" & lr)
j = ws.[A1].CurrentRegion.Columns.Count + 1
rng.AdvancedFilter 2, , ws.Cells(1, j), True
ar = ws.Range(ws.Cells(2, j), ws.Cells(Rows.Count, j).End(xlUp))
ws.Columns(j).Clear
For i = 1 To unbound(ar)
rng.AutoFilter 1, ar(i, 1)
If Not Evaluate("=ISREF('" & ar(i, 1) & "'!A10") Then
Sheets.Add(after:=Sheets(Sheets.Count)).Name = ar(i, 1)
Else
Sheets(ar(i, 1)).Move after:=Sheets(Sheets.Count)
End If
ws.Range("A1:A" & lr).Resize(, j - 1).Copy [A1]
Next
ws.AutoFilterMode = False
Sheet("Sheet1").Name = "Modified"
'Create separate files and email
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> "original" And ws.Name <> "Modified" Then
ws.Copy
Workbooks("Fee Management Macro.xlsm").Sheets("List").Copy before:=Sheets(Sheets.Count)
Range("A2:A13").Select
ActiveWorkbook.Names.Add Name:="StatusList", RefersToR1C1:="=List!R2C1:R12C1"
ActiveWorkbook.Names("StatusList").Comment = ""
Worksheets("Lis").Visible = False
Rows("2:2").Select
ActiveWindow.FreezePanes = True
With ActiveSheet
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
With .Range("S2:S" & lastrow)
.Formula = "=Now()"
End With
With .Range("T2:T") & lastrow
.Formula = "=IFERROR(VLOOKUP(RC[-4],List!C[-19]:[C-18],2,FALSE,"""")"
End With
With .Range("P2:P" & lastrow).Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:="=Statuslist"
.IgnoreBlank = False
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = "Select Status"
.ErrorMessage = "Please select status from the list"
.ShowInput = True
.ShowError = True
End With
With .Range("Q2:Q" & lastrow).Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:="=0", Formula2:="460"
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = "Max 460 Characters"
.InputMessage = "If black, do not complete"
.ErrorMessage = "Max 460 Characters"
.ShowInput = True
.ShowError = True
End With
With .Range("R2:R" & lastrow).Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlGreater, Formula1:="11/1/2012"
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = "Invalid Date"
.InputMessage = "If black, do not complete"
.ErrorMessage = "Please enter a valid date."
.ShowInput = True
.ShowError = True
End With
With .Range("P2:P" & lastrow).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent4
.TintAndShade = 0.599993896298105
.Patterntintshade = 0
End With
With .Range("Q2:Q" & lastrow).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorLight1
.TintAndShade = 0
.Patterntintshade = 0
End With
With .Range("R2:R" & lastrow).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorLight1
.TintAndShade = 0
.Patterntintshade = 0
End With
With .Range("R2:R" & lastrow).FormatConditions
.Add Type:=xlExpression, Formula1:= _
"=$P2=""Contacted Insured"""
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent4
.TinAndShade = 0.599963377788629
End With
Selection.FormatConditions(1).StopIfTrue = False
End With
With .Range("R2:R" & lastrow).FormatConditions
.Add Type:=xlExpression, Formula1:= _
"=$P2=""Appointment Date Set"""
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent4
.TinAndShade = 0.599963377788629
End With
Selection.FormatConditions(1).StopIfTrue = False
End With
With .Range("R2:R" & lastrow).FormatConditions
.Add Type:=xlExpression, Formula1:= _
"=$P2=""Close Out Submitted"""
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent4
.TinAndShade = 0.599963377788629
End With
Selection.FormatConditions(1).StopIfTrue = False
End With
With .Range("R2:R" & lastrow).FormatConditions
.Add Type:=xlExpression, Formula1:= _
"=$P2=""Contacted Agent"""
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent4
.TinAndShade = 0.599963377788629
End With
Selection.FormatConditions(1).StopIfTrue = False
End With
With .Range("R2:R" & lastrow).FormatConditions
.Add Type:=xlExpression, Formula1:= _
"=$P2=""Other"""
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent4
.TinAndShade = 0.599963377788629
End With
Selection.FormatConditions(1).StopIfTrue = False
End With
End With
Rows("1:1").Select
With Selection
.Font.Bold = True
.Font.Underline = xlUnderlineStyleSingle
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
ActiveSheet.Columns("A:Z").AutoFit
ActiveSheet.Columns("A:Z").HorizontalAlignment = xlCenter
ActiveSheet.Columns("A:Z").VerticalAlignment = xlCenter
ActiveSheet.Range("A1").AutoFilter
With ActiveSheet.Sort
.SortFields.Add Key:=Range("K1"), Order:=xlAscending
.Header = xlYes
.Apply
End With
lcol = Cells(1, Columns.Count).End(xlToLeft).Column
lrow = Cells(Rows.Count, "A").End(xlUp).Row
Range(Cells(1, lcol + 1), Cells(Rows.Count, Columns.Count)).EntireColumn.Hidden = True
Range(Cells(lrow + 1, 1), Cells(Rows.Count, Columns.Count)).EntireRow.Hidden = True
Columns("C").Hidden = True
Columns("O").Hidden = True
Columns("S").Hidden = True
Columns("T").Hidden = True
Columns("U").Hidden = True
Range("A1").Select
Selection.AutoFilter
Range("R:R").Select
Selection.NumberFormat = "yyy-mm-dd;#"
Range("H;H,G:G,F;F,B:B").Select
Selection.NumberFormat = "m/d/yyy"
Range("D:D,A:A").Select
Range("A1").Activate
With Selection
.HorizontalAlignment = xlLeft
.VerticalAlignment = xlCenter
.WrapText = False
.Orientation = 0
.AddIndent = False
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
Rows("1:1").Select
With Selection
.HorizontalAlignment = xlCenter
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
Columns("A:A").ColumnWidth = 25
Columns("D:D").ColumnWidth = 30
Columns("P:P").ColumnWidth = 30
Columns("Q:Q").ColumnWidth = 35
Columns("R:R").ColumnWidth = 10
Range("P:P,Q:Q,R:R").Locked = False
ActiveSheet.Protect Password:="ChrisBrianGreg2020", Userinterfaceonly:=True
FName = ws.Name & ".xlsx"
ActiveWorkbook.SaveAs FName
Set EmailText = Workbooks("Fee Management Macro.xlsm").Sheets("List").Range("M14")
Set OutWorksheet = Workbooks("Fee Management Macro.xlsm").Sheets("List")
Set OutApp = CreateObject("Outlook.Application")
Set Outmail = OutApp.CreateItem(OutAppOutMailItem)
Set OutMailDocument = Outmail.GetInspector.WordEditor
On Error Resume Next
With Outmail
.To = ""
.CC = ""
.BCC = ""
.Subject = "Weekly Inventory Status Update -" & " " & Date & " " & "-" & " " & ws.Name
.Body = ""
.Attachments.Add ActiveWorkbook.FullName
.Display
End With
On Error GoTo 0
'Copy Images to the email
For Each OutShape In OutWorksheet.Shapes
OutShape.Copy
OutMailDocument.Range(0, 1).Paste
Next
OutMailDocument.Range(0, 1).InsertBefore EmailText
Application.CutCopyMode = False
FName = Application.ActiveWorkbook.FullName
ActiveWorkbook.Saved = True
Application.ActiveWorkbook.ChangeFileAccess xlReadOnly
Kill FName
Application.ActiveWorkbook.Close False
End If
Next ws
Set Outmail = Nothing
Set OutApp = Nothing
Application.ScreenUpdating = True
End Subenter code here

vba macro with 3 command buttons linked with each other

How to apply a macro function with three command buttons ? I tried with below code.. but returns the macro applied on different sheet.
cmd button1: browses the main raw data file.
cmd button2: vlookup data file for the main raw data file.
cmd button3: Run the macro below function on the main raw data file.
your ideas will be much helpful.. thanks in advance.
Option Explicit
Sub currentZOE3()
'declare variable to store path
Dim Get_Path As String
Dim fileExplorer As FileDialog
Set fileExplorer = Application.FileDialog(msoFileDialogFilePicker)
'To allow or disable to multi select
fileExplorer.AllowMultiSelect = False
With fileExplorer
If .Show <> 0 Then
Get_Path = .SelectedItems(1)
End If
Worksheets("sheet1").Cells(3, 4).Value = Get_Path
End With
End Sub
Sub lastweekZOE3()
'declare variable to store path
Dim Get_Path As String
Dim fileExplorer As FileDialog
Set fileExplorer = Application.FileDialog(msoFileDialogFilePicker)
'To allow or disable to multi select
fileExplorer.AllowMultiSelect = False
With fileExplorer
If .Show <> 0 Then
Get_Path = .SelectedItems(1)
End If
Worksheets("sheet1").Cells(5, 4).Value = Get_Path
End With
End Sub
Sub Macro4()
'
' Macro4 Macro
'
'
Dim updWb As Workbook
Dim DSheet As Worksheet
Set updWb = Workbooks.Open(Worksheets("sheet1").Cells(3, 4).Value)
Set DSheet = updWb.Sheets("Sheet1")
Cells.Select
Selection.Borders(xlDiagonalDown).LineStyle = xlNone
Selection.Borders(xlDiagonalUp).LineStyle = xlNone
With Selection.Borders(xlEdgeLeft)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeTop)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeRight)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlInsideVertical)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlInsideHorizontal)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Font
.Name = "Calibri"
.Size = 10
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.ColorIndex = xlAutomatic
.TintAndShade = 0
.ThemeFont = xlThemeFontMinor
End With
Rows("1:1").Select
Selection.Font.Bold = True
With Selection.Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent4
.TintAndShade = 0.399975585192419
.PatternTintAndShade = 0
End With
ActiveWindow.ScrollColumn = 2
ActiveWindow.ScrollColumn = 3
ActiveWindow.ScrollColumn = 4
ActiveWindow.ScrollColumn = 5
ActiveWindow.ScrollColumn = 6
ActiveWindow.ScrollColumn = 7
ActiveWindow.ScrollColumn = 8
ActiveWindow.ScrollColumn = 9
ActiveWindow.ScrollColumn = 10
ActiveWindow.ScrollColumn = 11
ActiveWindow.ScrollColumn = 12
ActiveWindow.ScrollColumn = 13
Columns("N:N").Select
Selection.TextToColumns Destination:=Range("N1"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _
:=Array(1, 1), TrailingMinusNumbers:=True
'
ActiveWindow.ScrollColumn = 2
ActiveWindow.ScrollColumn = 3
ActiveWindow.ScrollColumn = 4
ActiveWindow.ScrollColumn = 5
ActiveWindow.ScrollColumn = 6
ActiveWindow.ScrollColumn = 7
ActiveWindow.ScrollColumn = 8
ActiveWindow.ScrollColumn = 9
ActiveWindow.ScrollColumn = 10
ActiveWindow.ScrollColumn = 11
ActiveWindow.ScrollColumn = 12
Columns("Q:S").Select
Selection.Insert Shift:=xlToRight
Range("Q1") = "Concantenate"
Range("R1") = "Delivery Plan"
Range("S1") = "Last Week Comments"
Range("Q2").Select
ActiveCell.FormulaR1C1 = "=RC[-16]&RC[-9]&RC[-7]"
Range("S2").Select
ActiveCell.FormulaR1C1 = "=VLOOKUP(RC[-2],'[Last Week.xlsx]Sheet1'!C1:C2,2,0)"
Range("R2").Select
ActiveCell.FormulaR1C1 = _
"=IFS(RC22=""YBWR"",""What"",ISNUMBER(RC25),""Fully Delivered"",RC19=""Billable Only"",""BILLABLE ONLY"",AND(ISBLANK(RC25),NOT(ISBLANK(RC27))),""Under shipment"",AND(ISBLANK(RC25),ISBLANK(RC27),ISNUMBER(RC14)),""Under packing"",AND(ISBLANK(RC25),ISBLANK(RC27),ISBLANK(RC14)),TEXT(WEEKNUM(RC23),""W00""))"
Range("P3").Select
Selection.End(xlDown).Select
Range("Q8833:S8833").Select
Range(Selection, Selection.End(xlUp)).Select
Selection.FillDown
Cells.Select
Range("Q8833").Activate
Selection.Columns.AutoFit
With Cells
.FormatConditions.Add Type:=xlExpression, Formula1:= _
"=($R1=""What"")"
With .FormatConditions(.FormatConditions.Count)
.SetFirstPriority
With .Interior
.PatternColorIndex = xlAutomatic
.Color = 12173758
.TintAndShade = 0
End With
StopIfTrue = False
End With
End With
With Cells
.FormatConditions.Add Type:=xlExpression, Formula1:= _
"=($R1=""Fully Delivered"")"
With .FormatConditions(.FormatConditions.Count)
.SetFirstPriority
With .Interior
.PatternColorIndex = xlAutomatic
.Color = 5691552
.TintAndShade = 0
End With
StopIfTrue = False
End With
End With
With Cells
.FormatConditions.Add Type:=xlExpression, Formula1:= _
"=($R1=""under shipment"")"
With .FormatConditions(.FormatConditions.Count)
.SetFirstPriority
With .Interior
.PatternColorIndex = xlAutomatic
.Color = 3774674
.TintAndShade = 0
End With
StopIfTrue = False
End With
End With
With Cells
.FormatConditions.Add Type:=xlExpression, Formula1:= _
"=($R1=""under packing"")"
With .FormatConditions(.FormatConditions.Count)
.SetFirstPriority
With .Interior
.PatternColorIndex = xlAutomatic
.Color = 15793920
.TintAndShade = 0
End With
StopIfTrue = False
End With
End With
Sheets(Array("Sheet2", "Sheet3")).Select
Sheets("Sheet3").Activate
Application.DisplayAlerts = False
ActiveWindow.SelectedSheets.Delete
Range("A1").Select
Selection.AutoFilter
ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort.SortFields.Add2 Key:= _
Range("A1:A8837"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption _
:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
ActiveSheet.Range("$A$1:$BE$8837").AutoFilter Field:=1
'Declare Variables
Dim PSheet As Worksheet
Dim DSheet As Worksheet
Dim PCache As PivotCache
Dim PTable As PivotTable
Dim PRange As Range
Dim LastRow As Long
Dim LastCol As Long
Dim pvtfield As PivotField
On Error Resume Next
Application.DisplayAlerts = False
Worksheets("PivotTable").Delete
Sheets.Add Before:=ActiveSheet
ActiveSheet.Name = "PivotTable"
Application.DisplayAlerts = True
Set PSheet = Worksheets("PivotTable")
Set DSheet = Worksheets("Sheet1")
'Define Data Range
LastRow = DSheet.Cells(Rows.Count, 1).End(xlUp).Row
LastCol = DSheet.Cells(1, Columns.Count).End(xlToLeft).Column
Set PRange = DSheet.Cells(1, 1).Resize(LastRow, LastCol)
'Define Pivot Cache
Set PCache = ActiveWorkbook.PivotCaches.Create _
(SourceType:=xlDatabase, SourceData:=PRange). _
CreatePivotTable(TableDestination:=PSheet.Cells(2, 2), _
TableName:="PivotTable")
'Insert Blank Pivot Table
Set PTable = PCache.CreatePivotTable _
(TableDestination:=PSheet.Cells(1, 1), TableName:="PivotTable")
'Insert Row Fields
With ActiveSheet.PivotTables("PivotTable").PivotFields("Sold to name")
.Orientation = xlRowField
.Position = 1
End With
With ActiveSheet.PivotTables("PivotTable").PivotFields("Sales Document")
.Orientation = xlRowField
.Position = 2
End With
With ActiveSheet.PivotTables("PivotTable").PivotFields("Customer purchase order number")
.Orientation = xlRowField
.Position = 3
End With
'Insert Column Fields
With ActiveSheet.PivotTables("PivotTable").PivotFields("Delivery Plan")
.Orientation = xlColumnField
.Position = 1
End With
'Insert Data Field
With ActiveSheet.PivotTables("PivotTable").PivotFields("SO Net value")
.Orientation = xlDataField
.Position = 1
.Function = xlSum
.NumberFormat = "#,##0"
.Name = " Sum SO Net value "
End With
'classic and expand/collapse button removal
Range("C7").Select
With ActiveSheet.PivotTables("PivotTable")
.InGridDropZones = True
.RowAxisLayout xlTabularRow
End With
Range("B4").Select
ActiveSheet.PivotTables("PivotTable").ShowDrillIndicators = False
'Format Pivot
TableActiveSheet.PivotTables("PivotTable").ShowTableStyleRowStripes = TrueActiveSheet.PivotTables("PivotTable").TableStyle2 = "PivotStyleMedium9"
End Sub
Once you have the path of the file using the FileDialog method.
You can use the below function to open that excel and update the contents of it's worksheets.
Dim updWb As Workbook, wSheet As Worksheet
Set updWb = Workbooks.Open("<path of the workbook to be updated>")
Set wSheet = updWb.Sheets("<sheet-name> or <sheet-index>")

Select next unique value

I am looking to copy data from a column to a column on another sheet.
Sheet one has a list of ID numbers (starting at F3) next to clock in and out times. There will be anything from 5 - 31 entries of the ID number, before moving to the next employee.
On sheet two is a time sheet with one row per day. The first row of each employee is blank (starting at C8) with the balance of data on that row (name, trade, site etc.) being a reference to this blank cell. There will be anywhere from 29 - 31 rows per employee on sheet two, to allow for all calendar days of the month.
I am trying to search sheet one for the next unique ID, then copy that value to the next available blank cell on sheet two.
The code I have works (sort of) when referencing between sheets and filling in the first value. Selecting the next unique value and then looping till the end of the list is eluding me.
Image of spreadsheets: https://www.dropbox.com/s/vg08uxb9kma2tza/VBA%20Help.jpg?dl=0
Sub TimesheetID()
ThisVal = ActiveCell.Value
ThisRow = ActiveCell.Row
ThisCol = ActiveCell.Column
FinalRow = Cells(Rows.Count, 2).End(xlUp).Row
Worksheets("All Go").Activate
Range("E3").Select
Selection.Copy
Worksheets("Timesheet").Activate
Range("C7").Select
ActiveCell.Offset(1, 0).Select
ActiveSheet.Paste
Application.CutCopyMode = False
With Selection.Font
.Name = "Arial"
.Size = 8
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.ColorIndex = 1
.TintAndShade = 0
.ThemeFont = xlThemeFontNone
End With
With Selection.Font
.Name = "Arial"
.Size = 11
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.ColorIndex = 1
.TintAndShade = 0
.ThemeFont = xlThemeFontNone
End With
With Selection
.HorizontalAlignment = xlLeft
.VerticalAlignment = xlBottom
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
Selection.End(xlDown).Select
ActiveCell.Offset(1, 0).Select
Worksheets("All GO").Activate
GoAgain:
ThisRow = ThisRow + 1
If ThisRow > Application.Rows.Count Then
Cells(ThisRow - 1, ThisCol).Select
Beep
Exit Sub
End If
If Cells(ThisRow, ThisCol).Value = ThisVal Then
GoTo GoAgain
Else
Cells(ThisRow, ThisCol).Select
End If
ActiveCell.Select
Selection.Copy
Worksheets("Timesheet").Activate
ActiveSheet.Paste
Application.CutCopyMode = False
With Selection.Font
.Name = "Arial"
.Size = 8
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.ColorIndex = 1
.TintAndShade = 0
.ThemeFont = xlThemeFontNone
End With
With Selection.Font
.Name = "Arial"
.Size = 11
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.ColorIndex = 1
.TintAndShade = 0
.ThemeFont = xlThemeFontNone
End With
With Selection
.HorizontalAlignment = xlLeft
.VerticalAlignment = xlBottom
.WrapText = True
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
End Sub
This example uses two dictionaries and the Dictionary.Exists method to create an array of unique values from the range A1:A50.
Option Explicit
Sub UniqueList()
Dim UniqueDic As Object
Dim AllDic As Object
Dim rng As Range
Dim c As Range
Dim UniqueArray() As Variant
Set UniqueDic = CreateObject("Scripting.Dictionary")
Set AllDic = CreateObject("Scripting.Dictionary")
Set rng = ActiveSheet.Range("$A$1:$A50")
For Each c In rng.Cells
If Not AllDic.Exists(c.Value2)
UniqueDic.Add c.Value2, c.Row
AllDic.Add c.Value2, c.Row
Else
If Not UniqueDic.Exists(c.Value2) Then
UniqueDic.Remove c.Value2
End If
End If
Next
UniqueArray() = Array(UniqueDic.Keys)
End Sub
If a range is traversed and a dictionary, "AllDic", gains a key equal to the cell value when Not AllDic.Exists Cell.Value evaluates to true; then AllDic.Keys will return an array of values unique to "AllDic" but not necessarily unique to the range.
Using two dictionaries, "AllDic" and "UniqueDic", if they both get the same key when Not AllDic.Exists Cell.Value evaluates to true, but when it is false "UniqueDic" will lose a key if Not UniqueDic.Exists Cell.Value is true; then keys from both dictionaries will return arrays with unique values, however, "UniqueDic" will not have any values that repeat in the range.
I managed to work around using this:
Sub TDSFillTest()
Dim BadgeNo As Integer
Dim BlankCount As Integer
Dim LoopCount As Integer
LoopCount = 1
ThisVal = ActiveCell.Value
ThisRow = ActiveCell.Row
ThisCol = ActiveCell.Column
Worksheets("Timesheet").Activate 'Go to Timesheet and count blank cells
BlankCount = Range(("C8"), Cells(Rows.Count, 2).End(xlUp)).Cells.SpecialCells(xlCellTypeBlanks).Count
Worksheets("All Go").Activate 'Starting Point
Range("F3").Copy Worksheets("Timesheet").Range("C8") 'First Value to Timesheet
Worksheets("All Go").Activate ' Return to TDS
Range("F3").Select
Do Until LoopCount > BlankCount
Worksheets("All Go").Activate
Do
ActiveCell.Offset(1, 0).Select
If ActiveCell.Value <> ActiveCell.Offset(-1, 0).Value Then Exit Do
Loop
ActiveCell.Copy
Worksheets("Timesheet").Activate
ActiveCell.Offset(1, 0).Select
Selection.End(xlDown).Select
ActiveCell.Offset(1, 0).Select
ActiveSheet.Paste
LoopCount = LoopCount + 1
Loop
End Sub
I'm going to take yours and run through it in detail so I can learn the more efficient methods. Thanks!

Copy & paste is stalling my macro

I have a macro which takes data from one workbook, filters the fairly large page down to the data i require only, then copies values to a dummy sheet in my main workbook where non required rows are removed and columns are sorted into an order more suitable for my application.
my problem is it takes an age to complete and quite often crashes.
I am still new to VBA and have tried my best to slicken the code but am not getting anywhere. I have used F8 to define the areas which slow it up and they are the filtering, copy/paste and cut/insert. If anyone can help it would be greatly appreciated.
Thanks in advance
M
`Sub NEW_OPS_AWAY_REPORT()
MsgBox ("BOTTLENECKS AND OPS AWAY SPREADSHEET & GEARSHOP WORK TO LIST FROM REPORT CENTRE MUST BE OPEN FOR THIS REPORT TO FUNCTION CORRECTLY")
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
Windows("DAILY BOTTLENECKS ANALYSIS & OPS AWAY.xlsm").Activate
Sheets("WIP by Op").Visible = True
Sheets("WIP by Op").Range("$A$1:$Q$47290").AutoFilter Field:=1, Criteria1:="TS1H124*", Operator:=xlFilterValues
Windows("PRESS QUENCH FIRST OFF DATABASE.xlsm").Activate
Sheets("REPORT DATA TRANSFER").Visible = True
Sheets("REPORT DATA TRANSFER").Select
Cells.Select
Selection.ClearContents
Windows("DAILY BOTTLENECKS ANALYSIS & OPS AWAY.xlsm").Activate
Sheets("WIP by Op").Select
Cells.Select
Selection.Copy
Windows("PRESS QUENCH FIRST OFF DATABASE.xlsm").Activate
ActiveSheet.Paste
Range("F:F,G:G,H:H,M:M,P:P,Q:Q").Select
Range("Q1").Activate
Application.CutCopyMode = False
Selection.Delete Shift:=xlToLeft
Columns("A:K").Select
Columns("A:K").EntireColumn.AutoFit
Columns("J:J").Select
Selection.Cut
Columns("A:A").Select
Selection.Insert Shift:=xlToRight
Columns("I:I").Select
Selection.Cut
Columns("B:B").Select
Selection.Insert Shift:=xlToRight
Columns("J:J").Select
Selection.Cut
Columns("C:C").Select
Selection.Insert Shift:=xlToRight
Columns("G:G").Select
Selection.Cut
Columns("D:D").Select
Selection.Insert Shift:=xlToRight
Columns("H:H").Select
Selection.Cut
Columns("E:E").Select
Selection.Insert Shift:=xlToRight
Columns("H:H").Select
Selection.Cut
Columns("F:F").Select
Selection.Insert Shift:=xlToRight
Columns("J:J").Select
Selection.Cut
Columns("I:I").Select
Selection.Insert Shift:=xlToRight
Application.Calculation = xlCalculationAutomatic
Range("A1:K1").Select
Selection.AutoFilter
ActiveWorkbook.Worksheets("REPORT DATA TRANSFER").AutoFilter.Sort.SortFields. _
Clear
ActiveWorkbook.Worksheets("REPORT DATA TRANSFER").AutoFilter.Sort.SortFields. _
Add Key:=Range("A1"), SortOn:=xlSortOnValues, Order:=xlAscending, _
DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("REPORT DATA TRANSFER").AutoFilter.Sort
.header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Sheets("Ops Away Report").Select
Columns("A:K").Select
Selection.ClearContents
Sheets("REPORT DATA TRANSFER").Select
Columns("A:K").Select
Selection.Copy
Sheets("Ops Away Report").Select
Range("A1").Select
ActiveSheet.Paste
Range("A:A,E:E,F:F,I:I,J:J").Select
Range("J1").Activate
Application.CutCopyMode = False
With Selection
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlBottom
.WrapText = False
.Orientation = 0
.AddIndent = False
.IndentLevel = 0
.ShrinkToFit = False
.ReadingOrder = xlContext
.MergeCells = False
End With
Range("A1").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Borders(xlDiagonalDown).LineStyle = xlNone
Selection.Borders(xlDiagonalUp).LineStyle = xlNone
With Selection.Borders(xlEdgeLeft)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeTop)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlEdgeRight)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlInsideVertical)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Selection.Borders(xlInsideHorizontal)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
Range("A1:L1").Select
Selection.AutoFilter
Columns("B:B").Select
Sheets("REPORT DATA TRANSFER").Visible = False
Dim lastRow As Long
lastRow = Range("A2").End(xlDown).Row
For Each Cell In Range("A2:Q" & lastRow) ''change range accordingly
If Cell.Row Mod 2 = 1 Then ''highlights row 2,4,6 etc|= 0 highlights 1,3,5
Cell.Interior.ColorIndex = 34 ''color to preference
Else
Cell.Interior.ColorIndex = xlNone ''color to preference or remove
End If
Next Cell
Columns("D:D").EntireColumn.AutoFit
Columns("H:H").ColumnWidth = 7.43
Range("A1:O1").AutoFilter
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.EnableEvents = True
ActiveSheet.DisplayPageBreaks = True
End Sub`
Looking through your code there's a lot of extra code in there.
For instance, adding a border around each cell can be done with Selection.Borders.LineStyle = xlContinuous
This code starts with the two workbooks closed. Update the Const variables with the correct file paths.
You'll probably need to disable events still, depending on what code's in the other workbooks.
Public Sub New_Ops_Away_Report()
Const BottleNecks_Path As String = "C:\Somefolder\DAILY BOTTLENECKS ANALYSIS & OPS AWAY.xlsm"
Const OpsAway_Path As String = "C:\Somefolder\PRESS QUENCH FIRST OFF DATABASE.xlsm"
Dim wrkBk_BottleNeck As Workbook
Dim wrkbk_OpsAway As Workbook
Dim rWIP_LastCell As Range
Dim rReport_LastCell As Range
Set wrkBk_BottleNeck = Workbooks.Open(Filename:=BottleNecks_Path)
Set wrkbk_OpsAway = Workbooks.Open(Filename:=OpsAway_Path)
'Clear the contents of the named sheet.
wrkbk_OpsAway.Worksheets("REPORT DATA TRANSFER").Cells.ClearContents
With wrkBk_BottleNeck
'Find the last populated cell on the worksheet.
Set rWIP_LastCell = LastCell(.Worksheets("WIP by OP"))
With .Worksheets("WIP by OP")
With .Range(.Cells(1, 1), rWIP_LastCell)
'Add a filter from A1 to the last populated cell.
.AutoFilter Field:=1, Criteria1:="TS1H124*", Operator:=xlFilterValues
.Copy Destination:=wrkbk_OpsAway.Worksheets("REPORT DATA TRANSFER").Range("A1")
End With
End With
End With
With wrkbk_OpsAway.Worksheets("REPORT DATA TRANSFER")
''''''''''''''''''''''''
'This bit is confusing in your code.
'I think it's trying to do as below, but I've commented out the last line
'as it appears to clear the data you just copied over.
.Range("F:F,G:G,H:H,M:M,P:P,Q:Q").Delete Shift:=xlToLeft
.Columns("A:K").EntireColumn.AutoFit
'.Columns("A:J").EntireColumn.ClearContents
''''''''''''''''''''''''
'Find last populated cell on the worksheet.
Set rReport_LastCell = LastCell(wrkbk_OpsAway.Worksheets("REPORT DATA TRANSFER"))
With .Sort
.SortFields.Clear
.SortFields.Add Key:=Range("A1").Resize(rReport_LastCell.Row), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SetRange wrkbk_OpsAway.Worksheets("REPORT DATA TRANSFER").Range("A1").Resize(rReport_LastCell.Row, rReport_LastCell.Column)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
.Range("A1").Resize(rReport_LastCell.Row, rReport_LastCell.Column).Borders.LineStyle = xlContinuous
End With
End Sub
Public Function LastCell(wrkSht As Worksheet, Optional Col As Long = 0) As Range
Dim lLastCol As Long, lLastRow As Long
On Error Resume Next
With wrkSht
lLastCol = .Cells.Find("*", , , , xlByColumns, xlPrevious).Column
lLastRow = .Cells.Find("*", , , , xlByRows, xlPrevious).Row
If lLastCol = 0 Then lLastCol = 1
If lLastRow = 0 Then lLastRow = 1
Set LastCell = wrkSht.Cells(lLastRow, lLastCol)
End With
On Error GoTo 0
End Function

Insert New Row using `With` instead of `.Select`

I'm having trouble trying to use with instead of .select when writing code to insert a new row. I have been told multiple times that .select is not to be used as it is much slower.
My macro creates a new row but deletes the contents in the row below and copies the formatting of the row above which never happened when I was using .select. This also means that the increasing number in cell B11 is not correct as it starts again from 1 due to the cleared contents below.
Sub New_Entry()
Application.ScreenUpdating = False
Application.EnableEvents = False
Dim rng As Range
Set rng = Range("B11:AB11")
With rng
.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
End With
Application.CutCopyMode = False
With rng
.ClearContents
.Interior.ColorIndex = xlNone
.Borders.LineStyle = xlContinuous
End With
With Range("B11")
.Value = Range("B12") + 1
End With
With rng
.Font.Bold = False
.Font.ColorIndex = xlAutomatic
.Font.TintAndShade = 0
End With
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Any help would be appreciated, thanks!
As far as I can see you have two questions:
1. Why does this delete the content?
That is because your With rng takes Set rng = Range("B11:AB11") and does .ClearContents to it at the same time as it inserts a row.
You can check this by switching around the order of your code.
All With statements with the same condition always run at the same time.
2. Why is the formatting copied?
The format isn't actually copied, you are formatting every line you create with .Borders.LineStyle = xlContinuous.
This should work:
Sub New_Entry()
Application.ScreenUpdating = False
Application.EnableEvents = False
Dim rng As Range
Set rng = Range("B11:AB11")
With rng
'.ClearContents
.Interior.ColorIndex = xlNone
'.Borders.LineStyle = xlContinuous
'End With
'With rng
.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
End With
Application.CutCopyMode = False
With Range("B11")
.Value = Range("B12") + 1
End With
With rng
.Font.Bold = False
.Font.ColorIndex = xlAutomatic
.Font.TintAndShade = 0
End With
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
.Select is slower because it runs code line by line.
The range "rng" seems to shift down after the insert. Here is the route I would take:
Sub New_Entry()
Application.ScreenUpdating = False
Application.EnableEvents = False
Range("B11:AB11").Insert Shift:=xlDown
Range("B11").Value = Range("B12") + 1
With Range("B11:AB11")
.Interior.ColorIndex = xlNone
.Borders.LineStyle = xlContinuous
.Font.Bold = False
.Font.ColorIndex = xlAutomatic
.Font.TintAndShade = 0
End With
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub

Resources