Please help - I've been searching for hours and am having no luck!
I'm using Power Query to bring in results from a SQL script. This information updates everytime I open the spreadsheet. Once the information has updated, I would like to delete Rows which have a date in Column C that is greater than today, so they don't get calculated in my VLOOKUP on another sheet.
I've tried the following:
Private Sub Workbook_Open()
Dim LR As Long, I As Long
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
LR = Range("C" & Rows.Count).End(xlUp).Row
For I = LR To 1 Step -1
If Range("C" & I).Value > Date Then Rows(I).Delete
Next I
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
This however doesn't run automatically, and when running it manually it gives "Run-time error '1004': Application-defined or object-defined error" and then proceeds to delete incorrect dates.
I also tried this, but it also deletes the incorrect dates and gives me Run-time error.
Sub DeleteCells()
Dim LR As Long, I As Long
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
LR = Range("C" & Rows.Count).End(xlUp).Row
For I = LR To 1 Step -1
If Range("C" & I).Value > Date Then Rows(I).Delete
Next I
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
EDIT 4/11: I am guessing that the 1004 error occurred because all of the "Branch Not Open" rows had been previously removed. The updated code below wraps an if statement around the autofilter step, which should now only be applied if at least one match for "Branch Not Open" is found in the filter range. Hopefully this version works!
#SickDimension is off to a great start -- but since you know that a number of rows are going to have "Branch Not Open" listed in the "Live Date" column you can remove them quickly using the autofilter. Try this code out (with an update for the LR code too):
Private Sub Workbook_Open()
Dim LR As Long, LC As Long, I As Long
Dim FilterRng As Range
Dim DataSheet As Worksheet
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
'assign worksheet to save time in references
Set DataSheet = ThisWorkbook.Worksheets("Clocking Exceptions")
'Define your filter range as the block of data
LC = DataSheet.Range("A3").End(xlToRight).Column
With DataSheet
LR = .Range("C" & .Rows.Count).End(xlUp).Row
End With
Set FilterRng = Range(DataSheet.Cells(3, 1), DataSheet.Cells(LR, LC))
'autofilter the sheet to remove "Branch Not Open" rows
If Not FilterRng.Find(What:="Branch Not Open", LookIn:=xlValues, LookAt:=xlWhole) Is Nothing Then
With FilterRng
.AutoFilter Field:=3, Criteria1:="Branch Not Open", Operator:=xlAnd
.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With
DataSheet.AutoFilterMode = False
End If
For I = LR To 1 Step -1
If IsDate(DataSheet.Range("C" & I).Value) Then
If DateValue(DataSheet.Range("C" & I).Value) > DateValue(Date) Then Rows(I).Delete
End If
Next I
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
If you need to use it upon opening file, you should specify the sheet you want it to run as upon opening file there is no range/sheet selected there for error '1004' ;) for ex.
'Following line needs to be defined more accurately
Range("C" & I).Value
'Redefine
Sheets("Sheet1").Range("C" & I).Value
Other wise the following will work, add the DateValue() to make the comparioson with the date values -
If DateValue(Range("C" & I).Value) > DateValue(Date) Then Rows(I).Delete
The solution
Private Sub Workbook_Open()
Dim LR As Long, I As Long
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
LR = Sheets("Sheet1").Range("C" & Rows.Count).End(xlUp).Row
For I = LR To 1 Step -1
If IsDate(Sheets("Sheet1").Range("C" & I).Value) Then
If DateValue(Sheets("Sheet1").Range("C" & I).Value) > DateValue(Date) Then Rows(I).Delete
End If
Next I
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
Related
I have the following VBA script, which was simply built to delete the entire row, if a value in Col T is 2. The problem is my dataset is usually large (200k lines +). Is there any way I can speed up this process, or write the script better? The Sheet name is "NonSerial".
Sub DeleteRows()
Dim lr As Long, lr2 As Long
Application.ScreenUpdating = False
lr = Cells(Rows.Count, "T").End(xlUp).Row
Columns("T:T").AutoFilter
ActiveSheet.Range("$T$1:$T$" & lr).AutoFilter Field:=1, Criteria1:="2"
lr2 = Cells(Rows.Count, "T").End(xlUp).Row
If lr2 = 2 Then Exit Sub
Application.DisplayAlerts = False
ActiveSheet.UsedRange.Offset(1, 0).Resize(ActiveSheet.UsedRange.Rows.Count - 1).Rows.Delete
Application.DisplayAlerts = True
Range("T1").AutoFilter
Application.ScreenUpdating = True
End Sub
I'm creating a tool that needs to delete rows that in the column "E" have dates older than 01-01-2019.
Sub OlderDateDelete()
Dim i As Variant
Application.DisplayAlerts = False
For i = Sheets("Iberica Not Sent").Count To 2 Step -1
If Sheets(i).Range("E2").Value < DateValue("01/01/2019") Then
Sheets(i).Delete
End If
Next i
Application.DisplayAlerts = True
End Sub
Watch this lines:
If Sheets(i).Range("E2").Value < DateValue("01/01/2019") Then
Sheets(i).Delete
End If
Those lines will delete your sheet.
I think you should edit it instead as:
If Rows(i).Range("E2").Value < DateValue("01/01/2019") Then
Rows(i).Delete
End If
The easiest I come up with is to put the date "01/01/2019" in a cell, in my example in "G1"
Then convert each range to this cell and delete them:
Sub DeletePreviousYears()
Dim i As Long
Dim LastRow As Long
LastRow = Sheets("Iberica Not Sent").Range("E" & Rows.Count).End(xlUp).Row
Application.DisplayAlerts = False
For i = LastRow To 2 Step -1
If Range("E" & i) <> "" And Range("E" & i).Value < Range("G1").Value Then
Rows(i).Delete
End If
Next i
Application.DisplayAlerts = True
End Sub
The best would also be to use a Function to find the Last Row and come back up with your loop.
Also with your first code using Sheets, you were looping through sheets and not row.
This is to answer your written question. You can use an Autofilter then delete all the visible data except the header row.
With Sheets("Iberica Not Sent")
.AutoFilterMode = False
With Range("A1").CurrentRegion
.AutoFilter Field:=5, Criteria1:="<01/01/2019"
On Error Resume Next
.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With
.AutoFilterMode = False
End With
Or, you can loop like this
Dim lr As Long
Dim i As Long
lr = Cells(Rows.Count, 1).End(xlUp).Row
For i = lr To 2 Step -1
If Cells(i, "E") < DateValue("01/15/2019") Then
Cells(i, "E").EntireRow.Delete
End If
Next i
I prefer to use a filter.
I am using the below code for copying the value of corresponding cell depending on value of another cell but i am getting the error 91. can you please see what i am doing wrong. getting error on
Dim ws As Worksheet, Snags As Worksheet
Dim lr As Long, lrSnags As Long, i As Long
Application.ScreenUpdating = False
For Each ws In Worksheets
If ws.Name <> "Snags" Then
lr = ws.Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To lr
lrSnags = Snags.Range("A" & Rows.Count).End(xlUp).Row + 1
If ws.Range("B") = "Fail" Then
ws.Range("A" & i).Copy
Snags.Range("A" & lrSnags).PasteSpecial xlPasteValues
End If
Next i
End If
Next ws
Application.CutCopyMode = False
Application.ScreenUpdating = True
MsgBox "Complete"
End Sub
getting error at below line
lrSnags = Snags.Range("A" & Rows.Count).End(xlUp).Row + 1
I would guess you did not define your worksheet named "Snags"
You need to set Snags after defining it:
For ex with:
Set Snags = Worksheets("Snags")
Alternatively you can just change your line without defining it to:
lrSnags = Sheets("Snags").Range("A" & Rows.Count).End(xlUp).Row + 1
I have a Spreadsheet "upload" I run a macro to compile the data on the sheet. I have a column "D" which attributes the data to client. I want to look for a specific client and automatically move those rows to another worksheet. I have tried this code, but I am making an error "Upload.Range("D1", Upload.Range("D" & Upload.Rows.Count)"
I anticipate future clients information to need be separated from the initial spreadsheet as well.
Any Help would be much appreciated
Sub TransferData()
Dim ar As Variant
Dim i As Integer
Dim lr As Long
ar = Array("3032")
Application.ScreenUpdating = False
Application.DisplayAlerts = False
For i = 0 To UBound(ar)
Upload.Range("D1", Upload.Range("D" & Upload.Rows.Count).End(xlUp)).AutoFilter 1, ar(i), 4, , 0
lr = Upload.Range("D" & Rows.Count).End(xlUp).Row
If lr > 1 Then
Upload.Range("A2", Upload.Range("G" & Upload.Rows.Count).End(xlUp)).Copy Sheets(ar(i)).Range("A" & Rows.Count).End(3)(2)
Upload.Range("A2", Upload.Range("G" & Upload.Rows.Count).End(xlUp)).Delete
Sheets(ar(i)).Columns.AutoFit
End If
Next i
[G1].AutoFilter
Application.DisplayAlerts = True
Application.CutCopyMode = False
Application.ScreenUpdating = True
MsgBox "Data transfer completed!", vbExclamation, "Status"
End Sub
There is a substantial difference between the worksheet Name property and the worksheet Codename property.
While it is possible to change the worksheet's Codename, it isn't a common practice and if you are unsure then it is most likely that you are referring to the worksheet Name property.
Your narrative says nothing about wanting the 'bottom 10 results' but your code uses 4 for the xlBottom10Items operator (see xlAutoFilterOperator enumeration ).
I have no idea what the 3 in Sheets(ar(i)).Range("A" & Rows.Count).End(3)(2) is intended to represent. I would suppose that you meant xlUp which has a numerical value of -4162. (see xlDirection enumeration).
Sub TransferData()
Dim ar As Variant
Dim i As Long, lr As Long
ar = Array("3032")
' ... app environment settings removed for brevity
'reference the filter worksheet properly
With Worksheets("Upload")
lr = .Range("D" & Rows.Count).End(xlUp).Row
If .AutoFilterMode Then .AutoFilterMode = False
For i = LBound(ar) To UBound(ar)
'there was no mention of 'bottom 10 items in your narrative but your code shows that option
With .Range("D1:D" & lr)
'.AutoFilter field:=1, Criteria1:=ar(i), _
Operator:=xlBottom10Items, VisibleDropDown:=False
.AutoFilter field:=1, Criteria1:=(ar(i)), VisibleDropDown:=False
With .Resize(.Rows.Count - 1, .Columns.Count).Offset(1, 0)
If CBool(Application.Subtotal(103, .Cells)) Then
.Offset(0, -3).Resize(, 7).Copy _
Destination:=Worksheets(ar(i)).Range("A" & Rows.Count).End(xlUp)(2)
Worksheets(ar(i)).Columns.AutoFit
.Delete shift:=xlUp
End If
End With
End With
Next i
If .AutoFilterMode Then .AutoFilterMode = False
End With
' ... app environment settings removed for brevity
MsgBox "Data transfer completed!", vbExclamation, "Status"
End Sub
That should get you started. It seems you still have a few decisions o make based on my notes.
Application.CutCopyMode = False
See Should I turn .CutCopyMode back on before exiting my sub procedure?.
I have below vba code to put a formula in cell AE3 then copy down to last row, i have 5000+ rows but wonder why it take so long to process (about 5 min. and still running), is there a better way to do this? i want copy down to last row as the list is dynamic data with different ranges every day. Thanks.
Sub FillRows()
Dim col_AE As String
Sheet1.Select
col_AE = "=IFERROR(INDEX(setting!C[-17],MATCH(smart!RC[-9],setting!C[-18],0)),"""")"
If col_AE <> vbNullString Then
For j = 3 To Range("A" & Rows.Count).End(xlUp).Row - 1
If Range("ae" & j).Value = vbNullString Then
Range("ae" & j).Value = col_AE
End If
Next j
End If
End Sub
You should turn off both ScreenUpdating and Calculations when working with large numbers of formulas.
This line If col_AE <> vbNullString Then isn't doing anything.
Option Explicit
Sub FillRows()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim col_AE As String
With Sheet1
For j = 3 To .Range("A" & .Rows.Count).End(xlUp).Row - 1
If .Range("ae" & j).Value = vbNullString Then
.Range("ae" & j).FormulaR1C1 = "=IFERROR(INDEX(setting!C[-17],MATCH(smart!RC[-9],setting!C[-18],0)),"""")"
End If
Next j
End With
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
The majority of the processing time is being used because the sheet is recalculating every time a formula is added. I would just turn off ScreenUpdating and Calculations and replace all the formulas. In this way I know that the formulas are consistent and that any errors introduced by users would be corrected.
Sub FillRows2()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim col_AE As String
With Sheet1
.Range("A3", "A" & .Rows.Count).End(xlUp).FormulaR1C1 = "=IFERROR(INDEX(setting!C[-17],MATCH(smart!RC[-9],setting!C[-18],0)),"""")"
End With
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
This might speed it up - turn off the screen updating while it is running.
Application.ScreenUpdating = False
Application.ScreenUpdating = True
Please try this:
Option Explicit
Sub fillFormula()
Dim wbk1 As Workbook
Dim lastRow As Long
Set wbk1 = ActiveWorkbook
With wbk1.Sheets("sheet1")
lastRow = .Range("A" & .Rows.Count).End(xlUp).Row
lastRow = lastRow - 1
.Range("AE3:AE" & lastRow).Formula = _
"=IFERROR(INDEX(setting!C[-17],MATCH(smart!RC[-9]," _
& "setting!C[-18],0)),"""")"
End With
End Sub