I have written a short macro to delete all rows that have a value of "Not Applicable" in column I, for the "Budget" tab of my workbook.
The macro does not seem to be doing anything when I run it through my testing:
Sub Remove_NA_Macro_Round_2()
With Sheets("Budget") 'Applying this macro to the "Budget" sheet/tab.
'Establishing our macro range parameters
Dim LastRow As Long
Dim i As Long
'Setting the last row as the ending range for this macro
LastRow = .Range("I50").End(xlUp).Row
'Looping throughout all rows until the "LastRow" ending range set above
For i = LastRow To 1 Step -1
If .Range("I" & i).Value = "Not Applicable" Then
.Range("I" & i).EntireRow.Delete
End If
Next
End With
End Sub
I appreciate any help!
Alternatively, when deleting rows based on a condition, it is faster to use a filter then looping.
Dim rng As Range
Set rng = ThisWorkbook.Sheets("Sheet1").Range("A1:I" & Cells(Rows.Count, "I").End(xlUp).Row)
Application.DisplayAlerts = False
With rng
.AutoFilter
.AutoFilter field:=9, Criteria1:="Not Applicable"
rng.Resize(rng.Rows.Count - 1).Offset(1).SpecialCells(xlCellTypeVisible).Delete 'deletes the visible rows below the first row
.AutoFilter
End With
Application.DisplayAlerts = True
You are not actually referencing the With Sheets("Budget"). Add a period . before each instance of Range, otherwise there's an implicit ActiveSheet, which is not necessarily the Budget tab.
With Sheets("Budget")
...
LastRow = .Range("I50").End(xlUp).Row
...
If .Range("I" & i).Value = "Not Applicable" Then
.Range("I" & i).EntireRow.Delete
End If
...
End With
EDIT:
Based on commentary and your provided screenshot, change how LastRow is determined (get rid of the hard-coded I50):
LastRow = .Cells(.Rows.Count, "I").End(xlUp).Row
Related
I am struggling with the following situation.
I have a set of bulk data in column U, from which I must filter the "missing pole" value.
Next, I must copy this "missing pole" value to column BN, exactly to the same row, where it occurs in column U, as you can see below.
I tried:
Sub Flag()
Dim lRow As Long
If Range("U2:U" & lRow).Value = "Missing pole" Then
Range("U2:U" & lRow).Copy
Range("BN2:BN" & lRow).PasteSpecial xlPasteValues
End If
End Sub
but I am getting error:
Method 'Range' of object'_Global' failed.
Debugger shows:
If Range("U2:U" & lRow).Value = "Missing pole" Then
Other threads are here:
Copy Cells in One Column, Based on Criteria in Another Column, to Another Sheet
VBA - IF a cell in column A = Value, then copy column B, C, D of same row to new worksheet
but without a reasonable solution for me.
How can I copy the certain value occurring in the column (throughout a whole range) to another column placing it exactly in the same row?
Here is the VBA code that would work fine.
The Error is because you are trying to value of Range object you just need a For loop to traverse all the rows and then check if there is any value with "Missing Pole"
Here is the code:
Sub Flag()
Dim LastRow As Long
With ActiveSheet
LastRow = .Cells(.Rows.Count, "U").End(xlUp).Row
End With
For i = 2 To LastRow
If ActiveSheet.Range("U" & i) = "Missing pole" Then
ActiveSheet.Range("BN" & i).Value2 = ActiveSheet.Range("U" & i).Value2
End If
Next i
End Sub
You can make the If statement case insensitive this way:
Sub Flag()
Dim lRow As Long
Dim lLastRow As Long
lLastRow = Range("U" & Rows.Count).End(xlUp).Row
For lRow = 2 To lLastRow
If UCase$(Range("U" & lRow).Value) = "MISSING POLE" Then
' do what you want here
End If
Next
End Sub
I created a macro to in order to generate a daily report. The portion of the macro that finds a value in column AN and deletes the entire row (code edited to delete rows starting from the last used row), works well.
The following example deletes all the rows that do not contain the value "CAT","BAT", or "DOG in column AN.
'False screen updating
Application.ScreenUpdating = False
'deleting all other types other than CAT from "samples" tab (excluding the header row, row 1)
Sheets("sample").Select
Lastrow = Cells(Rows.Count, "AN").End(xlUp).Row
'Deleting rows from bottom up
For i = Lastrow To 2 Step -1
If Range("AN" & i).Value <> "CAT" And _
Range("AN" & i).Value <> "BAT" And _
Range("AN" & i).Value <> "DOG" Then
Rows(i).EntireRow.Delete
End If
Next i
However, would like to create another Sub that deletes all the rows that do contain a specific set of values.
I tried replacing <> with = and ==, however neither worked and no rows were deleted
Below is a sample how to delete rows based on a criteria in column A. Keep in mind that if we delete rows we go backwards to avoid index errors.
Try:
Option Explicit
Sub test()
Dim Lastrow As Long, i As Long
With ThisWorkbook.Worksheets("Sheet1")
Lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
'Where you delete you go backwards
For i = Lastrow To 2 Step -1
If .Range("A" & i).Value = "CAT" Then
.Rows(i).EntireRow.Delete
End If
Next i
End With
End Sub
Thank you everyone for help resolving this issue. I have found that the root cause of my problem was simply the condition statement at the end of my If/Then line. The "And_" statement was saying "If cell equals CAT and BAT and DOG, then delete row" NOT "If cell equals CAT or BAT or DOG, then delete row". Replacing "And_" with "Or_" has fixed this issue.
'False screen updating
Application.ScreenUpdating = False
'deleting all other types other than CAT from "samples" tab (excluding the header row, row 1)
Sheets("sample").Select
Lastrow = Cells(Rows.Count, "AN").End(xlUp).Row
'Deleting rows from bottom up
For i = Lastrow To 2 Step -1
If Range("AN" & i).Value = "CAT" Or _
Range("AN" & i).Value = "BAT" Or _
Range("AN" & i).Value = "DOG" Or _
Range("AN" & i).Value = "" Then
Rows(i).EntireRow.Delete
End If
Next i
However, I would also like to delete rows if the cells is Blank "". Why would the Sub ignore this line?
Range("AN" & i).Value = "" Then
Thanks!
A site that might be able to help you be the following.
https://www.excelcampus.com/vba/delete-rows-cell-values/
I adjusted the code a little.
Sub Delete_Rows_Based_On_Value()
'Apply a filter to a Range and delete visible rows
'Source: https://www.excelcampus.com/vba/delete-rows-cell-values
Dim ws As Worksheet
'Set reference to the sheet in the workbook.
Set ws = ThisWorkbook.Worksheets("sampel")
ws.Activate 'not required but allows user to view sheet if warning message appears
'Clear any existing filters
On Error Resume Next
ws.ShowAllData
On Error GoTo 0
'1. Apply Filter
ws.Range("AN3:BG1000").AutoFilter Field:=1, Criteria1:="<>CAT"
'2. Delete Rows
Application.DisplayAlerts = False
ws.Range("B1:G1000").SpecialCells(xlCellTypeVisible).Delete
Application.DisplayAlerts = True
'3. Clear Filter
On Error Resume Next
ws.ShowAllData
On Error GoTo 0
End Sub
I would tend to do it this way:
Sub DeleteRows()
Dim i As Integer
Dim sht As Worksheet
Set sht = ThisWorkbook.Sheets("sample")
i=1
While sht.(i,1) <> "" 'Assuming first column is full of data to the bottom
If sht.Range("AN" & i) = "CAT" Then
sht.Rows(i).EntireRow.Delete
Else
i=i+1
End If
Wend
End Sub
Having issues in VBA
Trying to delete all rows until value in row 1 = "**GRAD*"
I get Runtime Error 438
Code Below
Public Sub Delete()
Dim i As Long
i = 1 'Start from row 1
Application.ScreenUpdating = False
With ThisWorkbook.Worksheets("Sheet1")
Do Until .Range("A" & i).Value = "**GRAD"
If .Rage("A" & i).Value <> "**GRAD" Then
.Rows(i).EntireRow.Delete
Else: i = i + 1 'Only increment if the row hasn't been deleted to prevent skipping rows
End If
Loop
End With
Application.ScreenUpdating = True
End Sub
Some help would be appreciated, new to VBA.
L.Dutch already gave you the answer to your question
here's an alternative and faster approach
to delete all rows until value in column 1 = "**GRAD*"
Option Explicit
Public Sub Delete()
Dim lastRowToDelete As Long
Dim f As Range
With ThisWorkbook.Worksheets("Sheet0001") '<-- reference your worksheet
With Range("A1", .Cells(.Rows.Count, 1).End(xlUp)) '<-- reference its columns "A" cells from row 1 sown to last not empty one
Set f = .Find(what:="**GRAD", LookIn:=xlValues, lookat:=xlWhole, after:=.Range("A" & .Rows.Count)) '<-- look for the first cell whose value is "**GRAD"
If f Is Nothing Then '<-- if not found then...
lastRowToDelete = .Rows(.Rows.Count).Row '<-- the last row to delete is the last row of the range
Else '<-- otherwise...
lastRowToDelete = f.Row - 1 '<-- the last row to delete is the one preceeding the one with the found cell
End If
End With
If lastRowToDelete > 0 Then .Range("A1:A" & lastRowToDelete).EntireRow.Delete 'delete all rows in a single shot
End With
End Sub
Typo? I read If .Rage("A" & i).Value <> "**GRAD" Then while it should be If .Range("A" & i).Value <> "**GRAD" Then
I am trying to copy the values from one Excel sheet into another using Filter option. For example I have used only ten records, but in real time I am not sure the data that will be present. Also, I need to know the first cell value after a filter. For example, if I use filter the first value is reflecting as B4 and next time it is showing B6. I need to select that also dynamically using macro.
ActiveSheet.Range("$A$1:$BG$10").AutoFilter Field:=2, Criteria1:="2"
Range("B5:BG5").Select
The above code should be modified. Instead of $BG$10 it should be the number of rows, then Instead of B5:BG5 it must be the first cell after filter.
Try this:
Dim rngToFilter As Range
With ActiveSheet
.AutoFilterMode = False 'to make sure no filter is applied yet
Set rngToFilter = .Range("A1", .Range("BG" & Rows.Count).End(xlUp)) 'set the dynamic range
rngToFilter.AutoFilter Field:=2, Criteria1:="2" 'apply the filter
rngToFilter.Resize(.Range("BG" & Rows.Count).End(xlUp).Row - 1).Offset(1, 0).SpecialCells(xlCellTypeVisible).Select 'Offset 1 row to exclude the header, resize to select the first row only.
End With
Above code selects all the items that are filtered.
I you want so select only the 1st item filtered, then use below.
Sub Sample()
Dim rngToFilter As Range, rngFilter As Range
Dim i As Integer
With ActiveSheet
.AutoFilterMode = False 'to make sure no filter is applied yet
Set rngToFilter = .Range("A1", .Range("BG" & Rows.Count).End(xlUp)) 'set the dynamic range
rngToFilter.AutoFilter Field:=2, Criteria1:="2" 'apply the filter
Set rngFilter = rngToFilter.Resize(.Range("BG" & Rows.Count).End(xlUp).Row - 1).Offset(1, _
0).SpecialCells(xlCellTypeVisible)
rngToFilter.Resize(.Range("BG" & Rows.Count).End(xlUp).Row - _
(rngFilter.Cells.Count / rngFilter.Columns.Count)).Offset(1, _
0).SpecialCells(xlCellTypeVisible).Select
End With
End Sub
No error handler yet.
I leave it to you. :D
Try following code:
Sub test()
Dim lastRow As Long, firstVisibleRow As Long
ActiveSheet.AutoFilterMode = False
'find last non empty row number in column A'
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
'apply filter'
Range("$A$1:$BG$" & lastRow).AutoFilter Field:=2, Criteria1:="2"
On Error GoTo errHandler
'find first visible row number in the filtered range, if there is no rows matching the filter criteria, we'll get message from the MsgBox'
firstVisibleRow = Range("$A$2:$BG$" & lastRow).SpecialCells(xlCellTypeVisible).Row
On Error GoTo 0
'select range'
Range("B" & firstVisibleRow & ":BG" & firstVisibleRow).Select
Exit Sub
errHandler:
MsgBox "There is no rows matching the filter criteria"
End Sub
I am using VBA to run a set of data against five "rule" columns stored in another sheet in the workbook. Put simply, I seem to have code which works, but the VBA use of Selection.Formula = returns "False" when an cell formula would return #N/A or #VALUE. It's critical that I get the error values because it tells the user something different than "False". False should mean that column C (see picture of calculation tab below) doesn't pass the rule. The error values mean that either column B is not found with VLookup in the Rules column or the rule was written incorrectly.
Here's what I have so far:
Sub Build_Formulas_v2()
Application.Calculation = xlManual
Range("a2", Range("a65536").End(xlUp)).Offset(0, 6).Select
Selection.Value = _
Evaluate("(""=""&SUBSTITUTE(VLOOKUP(B2,'Logic Statements'!A:E,4,FALSE),""ZZZ"",""c""&ROW()))")
End Sub
Any help would be tremendously appreciated - my VBA knowledge is still growing and is too basic to understand what I'm up against.
I believe you are using Excel 2003. You should never hard code values like A65536. You can get undesirable results in xl2007+ as they have 1048576 rows.
Is this what you are trying?
Sub Build_Formulas_v2()
Dim lRow As Long
Dim ws As Worksheet
Application.Calculation = xlManual
'~~> Change this to the relevant sheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A2:A" & lRow).Offset(0, 6).Formula = _
"=SUBSTITUTE(VLOOKUP(B2,'Logic Statements'!A:E,4,FALSE),""ZZZ"",""c""&ROW())"
'~~> Uncomment the below in case you want to replace formulas with values
'.Range("A2:A" & lRow).Offset(0, 6).Value = .Range("A2:A" & lRow).Offset(0, 6).Value
End With
End Sub
Or if you do not want to use .Offset, then you can directly address Column G
Sub Build_Formulas_v2()
Dim lRow As Long
Dim ws As Worksheet
Application.Calculation = xlManual
'~~> Change this to the relevant sheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("G2:G" & lRow).Formula = _
"=SUBSTITUTE(VLOOKUP(B2,'Logic Statements'!A:E,4,FALSE),""ZZZ"",""C""&ROW())"
'~~> Uncomment the below in case you want to replace formulas with values
'.Range("A2:A" & lRow).Offset(0, 6).Value = _
.Range("A2:A" & lRow).Offset(0, 6).Value
End With
End Sub