I am trying to copy a set of filtered data from one sheet to the bottom of another sheet. And my code works great except for the first time upon opening the file I get a:
Run Time error 1004
If I quit the debugger and re-run the macro it works great.
Here is my code: noted where the problem occurs.
Sub MoveData_Click()
'Select the filtered alarm data and paste on the master spreadsheet
Sheets("DailyGen").Select
ActiveSheet.UsedRange.Offset(5, 0).SpecialCells _
(xlCellTypeVisible).Copy
Sheets("2015 Master").Select
If ActiveWorkbook.ActiveSheet.FilterMode _
Or ActiveWorkbook.ActiveSheet.AutoFilterMode Then
ActiveWorkbook.ActiveSheet.ShowAllData
End If
Range("C4").Select
Selection.End(xlDown).Select
ActiveCell.Offset(1, -2).Range("A1").Select
ActiveSheet.Paste '~~> THIS IS WHERE IT ERRORS
'Sort newest to oldest in the date column
ActiveWorkbook.Worksheets("2015 Master").ListObjects("Table44").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("2015 Master").ListObjects("Table44").Sort.SortFields.Add _
Key:=Range("Table44[[#All],[Active Time]]"), _
SortOn:=xlSortOnValues,
Order:=xlDescending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("2015 Master").ListObjects("Table44").Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
When you ShowAllData (same as Data->Clear in the Filter section) you are emptying the clipboard and telling Excel to forget about the copied Range. Do it outside of VBA to confirm if you want. Excel loves to empty the clipboard when you edit a cell or do much of anything other than selecting.
To fix, do the Copy after the ShowAllData. In your case, you will have to Select the Worksheet back and forth.
You should generally work to avoid using Select and Activate for your VBA. See this post for details.
Here is the final code with the changes made:
Sub MoveData_Click()
'Select the filtered alarm data and paste on the master spreadsheet
Sheets("2015 Master").Select
If ActiveWorkbook.ActiveSheet.FilterMode Or ActiveWorkbook.ActiveSheet.AutoFilterMode Then
ActiveWorkbook.ActiveSheet.ShowAllData
End If
Sheets("DailyGen").Select
ActiveSheet.UsedRange.Offset(5, 0).SpecialCells _
(xlCellTypeVisible).Copy
Sheets("2015 Master").Select
Range("C4").Select
Selection.End(xlDown).Select
ActiveCell.Offset(1, -2).Range("A1").Select
ActiveSheet.Paste
'Sort newest to oldest in the date column
ActiveWorkbook.Worksheets("2015 Master").ListObjects("Table44").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("2015 Master").ListObjects("Table44").Sort.SortFields.Add _
Key:=Range("Table44[[#All],[Active Time]]"), SortOn:=xlSortOnValues, Order _
:=xlDescending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("2015 Master").ListObjects("Table44").Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
Related
I'm trying to autofilter data in a sheet with 7 columns before copying to another workbook. This is to be used on different data that will have a different number of rows each time.
The issue is that when it autofilters the data it records the number of rows which is different each time (see Range("B1:B124")) below, which it will then apply the next time I try to use it
ChDir "F:\Work-Macro"
Workbooks.Open Filename:="F:\Work-Macro\usage.xls"
Cells.Select
With Selection.Font
.Name = "Calibri"
.Size = 10
End With
Range("D:E,I:L").Select
Range("I1").Activate
Selection.Delete Shift:=xlToLeft
Columns("A:F").Select
Range("F1").Activate
Selection.AutoFilter
ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort.SortFields.Add2 Key:= _
Range("B1:B124"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption _
:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
there must be a way to apply the autofilter in a dynamic way without it recording the number of rows filtered
Instead of using a fixed range, you want to know the last cell that is in use:
Range("B2:B" & ActiveWorkbook.sheets("Sheet1").cells(rows.count,2).end(xlup).row)
The ActiveWorkbook.sheets("Sheet1").cells(rows.count,2).end(xlup).row) part will return the last row in use in column 2.
By the way, I suggest that you clean up your code after recording. Using Select and Activate is almost never necessary in a macro. It slows your code down and is very error sensitive.
I have a macro that selects a range of cells, erases the cells, sorts the data by alphabetical order and saves the file.
I need the macro to copy the selected range of cells to another excel sheet but I am not able to create the code.
The code of my macro is:
Sub SAVE1()
'
' SAVE1 Macro
'
'
Range("B8:K8").Select
Selection.ClearContents
ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort.SortFields.Add Key:=Range _
("B7:B85"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Range("B8").Select
ActiveWorkbook.Save
End Sub
Please let me know if you have some ideas.
Many thanks for your help.
Joao
Thanks so much for reading my questions. I tried to search the similar questions in the stackoverflow but failed to get the answer...thanks so much if you can help me.
My purpose here is to copy and paste the data from Sheets("Parts") to Sheets("Summary"), and then sort by A column, ignoring the empty cell.
A1: 2.1
A2:
A3: 1.1
A4: 1.2
After sorting :
A1: 1.1
A2: 1.2
A3: 2.1
A4:
The macro is success in the Macro builder but then failed in the worksheet (First row empty). Indeed I try to not copying the empty cell with "SkipBlanks" but not functional...
Sub IEMacro()
Dim Lastcell As Range
Sheets("Parts").Range("A3:A300").Copy
With Sheets("Summary")
Set Lastcell = .Range("A65536").End(xlUp)
.Range("A2", Lastcell).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=True, Transpose:=False
.Range("A2", Lastcell).Sort Key1:=ActiveCell, Order1:=xlAscending, Header:=xlGuess
End With
This should apply the sorting key properly :
Sub IEMacro()
Dim LastCell As Range
Sheets("Parts").Range("A3:A300").Copy
With Sheets("Summary")
Set LastCell = .Range("A" & .Rows.count).End(xlUp)
.Range("A2").PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, _
SkipBlanks:=True, _
Transpose:=False
With .Sort
.SortFields.Clear
.SortFields.Add Key:=Sheets("Summary").Range(Sheets("Summary").Range("A1"), LastCell), _
SortOn:=xlSortOnValues, _
Order:=xlAscending, _
DataOption:=xlSortNormal
.SetRange Sheets("Summary").Range(Sheets("Summary").Range("A1"), LastCell)
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
End Sub
In that case you need to select complete range till the last column of your data then sort it to ascending order, fianlly go with the auto filter.
Sub sort()
'selecting complete range change it as required
Range("A1:O12").Select
' Replace the sheet name with yours
ActiveWorkbook.Worksheets("Sheet1").sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").sort.SortFields.Add Key:=Range("A1"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet1").sort
'sorting complete range change it as required
.SetRange Range("A1:O11")
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
This is my Workbook:
Sheets layout:
Source: Pivot Table with Analysis Services connection
Distributors: Stuff to be sorted connected with the Pivot
Output: Chart based on sorted data of Distributors + Slicers connected to Pivot
What I need to do is: Launch Sorting Macro after each OLAP Query (= each time I use the slicers).
Sorting Code
Sub Sorting()
'This line finds the last occupied row in column A
'And you can use that LR variable in all the following Range Statements.
LR = Cells(Rows.Count, "C").End(xlUp).Row
ActiveWorkbook.Worksheets("Distributors").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Distributors").Sort.SortFields.Add Key:=Range("C4:C102" & LR) _
, SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Distributors").Sort
.SetRange Range("A3:C102" & LR)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
ActiveWorkbook.Worksheets("Distributors").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Distributors").Sort.SortFields.Add Key:=Range("D4:D102") _
, SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Distributors").Sort
.SetRange Range("D3:F102")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
Solved. Launch Macro after each Pivot Update
Alt+F11, Right click on Source (Sheet with PivotTable)
View Code
Insert the Event trigger
Event Trigger
Private Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)
'your_macro_here
End Sub
Keep in mind that you can't enter reference to a Module. Insert directly your macro.
I am working on a project that will sort all the cells in another worksheet based on criteria. I need to activate a cell in another worksheet to make it work. I tried finding a solution but no luck.
I recorded a macro from my workbook and tweaked it a bit so it would fit my need. When I run the code, Runtime Error 1004 appears.
I need a code to replace
SetRange ActiveCell.Offset(-1, 0).Range("A1:AF30436")
Any suggestion will be appreciated.
Here's the code:
Sheets("Source").Select
ActiveWorkbook.Worksheets("Source").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Source").Sort.SortFields.Add Key:=ActiveCell.Range _
("A1:A30435"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ActiveWorkbook.Worksheets("Source").Sort
.SetRange ActiveCell.Offset(-1, 0).Range("A1:AF30436")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
when you record macro, you click on the cell in the second sheet and start the sort routine. Macro correctly recorded this.
however when you are doing this in VBA, the "active cell" could be anything and in most cases you dont need this as long as you know the datarange that you need to work with
dim ws as WorkSheet
set ws = Sheets("Source")
ws.Sort.SortFields.Clear
ws.Sort.SortFields.Add Key:=ws.Range _
("A1:A30435"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ws.Sort
.SetRange Range("A1:AF30436") ' Change here to itended dataset
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With