VBA macro delete cells containing #N/A and shift up the cells (not the rows) - excel

I'm creating a ranking and I need to delete all the cells with #N/A (pasted as text, not formula) and to delete those cells and shhift them up.
The worksheet contains 503 raws and I need it from column A to T.
Thanks in advance, I have tried so many VBA codes of this web and I'm not able to find something that works.

Try,
dim rng as range
with worksheets("sheet1")
on error resume next
set rng = .range("A:T").specialcells(xlcelltypeformulas, xlerrors)
if not rng is nothing then
rng.delete shift:=xlup
end if
set rng = .range("A:T").specialcells(xlcelltypeconstants, xlerrors)
if not rng is nothing then
rng.delete shift:=xlup
end if
on error goto 0
end with

This should work. There are faster ways of doing what you ask, but since you don't have that big of a data set, I just modified some code I had available.
Sub KillPoundNa()
Dim rCell As Range, WS As Worksheet, KillRng As Range, UndesireableText As String
UndesireableText = "#N/A"
Set WS = ActiveSheet
Set KillRng = WS.Cells(Rows.Count, 1)
For Each rCell In WS.UsedRange.Cells
If InStr(1, rCell.Text, UndesireableText, vbTextCompare) > 0 Then
Set KillRng = Union(KillRng, rCell)
End If
Next rCell
KillRng.Delete (xlUp)
End Sub

Related

How to delete a row if there is no value in a column?

I'm trying to delete rows in table if there is no value in a certain column.
I've used a code that deletes rows if there is one cell value missing, but I would like to delete rows if a cell does not contain a value in a certain column.
For example, if there is no value in Column G Row 5 then I want to delete the entire row.
Sub Test2()
Dim rng As Range
On Error Resume Next
Set rng = Range("Table3").SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If Not rng Is Nothing Then
rng.Delete Shift:=xlUp
End If
End Sub
This deletes all rows with any type of missing cell value.
Two small changes:
Sub Test2()
Dim rng As Range
On Error Resume Next
Set rng = Range("G:G").SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If Not rng Is Nothing Then
rng.EntireRow.Delete Shift:=xlShiftUp
End If
End Sub
EDIT:
If you want to work directly with the table, then consider iterating over the ListRows of the table in question, something like this:
Sub Test2()
Dim myTbl As ListObject
Set myTbl = Sheet1.ListObjects("table3") ' change sheet as necessary
Dim indx As Long
indx = myTbl.ListColumns("ColumnName").Index
Dim rngToDelete As Range
Dim myRw As ListRow
For Each myRw In myTbl.ListRows
If IsEmpty(myRw.Range(1, indx).Value) Then
If rngToDelete Is Nothing Then
Set rngToDelete = myRw.Range
Else
Set rngToDelete = Union(rngToDelete, myRw.Range)
End If
End If
Next myRw
If Not rngToDelete Is Nothing Then
rngToDelete.Delete Shift:=xlShiftUp
End If
End Sub
Note: Technically, it's xlShiftUp, not xlUp.

How To Find A Specific Cell With The Relevent Data?

I'm trying to find some macro that will run all over the worksheet and select all the relevant cells.
I have written some macro that find the cell but only one cell-its not selecting all the cells.
Dim myRange As Range
Dim myCell As Range
Set myRange = Range("A1:GG1000")
Dim mynumer As Integer
mynumber = 7
For Each myCell In myRange
If myCell = mynumber Then
myCell.Select
End If
Next myCell
how i can run the macro and see all the relevant cells?
thanks!
Maybe try some .FindNext iteration.
Just adapted from the above link:
Sub Test()
Dim cl As Range, rng As Range
With ThisWorkbook.Sheets("Sheet1").Range("A1:GG1000")
Set cl = .Find(7, LookIn:=xlValues, lookat:=xlWhole)
If Not cl Is Nothing Then
firstAddress = cl.Address
Do
If Not rng Is Nothing Then
Set rng = Union(rng, cl)
Else
Set rng = cl
End If
Debug.Print rng.Address
Set cl = .FindNext(cl)
If cl Is Nothing Then
GoTo DF
End If
Loop While cl.Address <> firstAddress
End If
DF:
rng.Select
End With
End Sub
The question really is, why do you .Select a range? Most of the time that can be avoided, and most likely the code above can be amended to something much cleaner!
Please take a look at this answer:
How to find a value in an excel column by vba code Cells.Find
The answer beneath the top voted, shows you how to search in the whole spreadsheet.
Best regards,
Timo

Applying Same Excel-VBA Code in All Active Sheets

In need of help in applying the following code below for all sheets. I have tried the code I found online which is ApplyToAllSheets() but I am still new and I don't know how I can make it work. Please help.
Sub ApplyToAllSheets()
Dim wks As Worksheet
For Each wks In ThisWorkbook.Worksheets
Third wks
Next
End Sub
Sub Third(wks As Worksheet)
Dim Rng As Range
Dim cell As Range
Dim ContainWord As String
With wks
Set Rng = .Range(.Range("B1"), .Range("B" & .Rows.Count).End(xlUp))
End With
'For deleting the remaining informations not necessary
Set Rng = Range("B1:B1000")
ContainWord = "-"
For Each cell In Rng.Cells
If cell.Find(ContainWord) Is Nothing Then cell.Clear
Next cell
Set Rng = Range("C1:C1000")
ContainWord = "2019" 'change to current year
For Each cell In Rng.Cells
If cell.Find(ContainWord) Is Nothing Then cell.Clear
Next cell
Set Rng = Range("A1:A1000")
ContainWord = "-"
For Each cell In Rng.Cells
If cell.Find(ContainWord) Is Nothing Then cell.Clear
Next cell
'For deleting the blanks
On Error Resume Next
ActiveSheet.Range("B:B").SpecialCells(xlBlanks).EntireRow.Delete
On Error GoTo 0
'For shifting the date to the left
Columns("C").Cut
Columns("A").Insert Shift:=xlToLeft
Columns("C").Cut
Columns("B").Insert
'For deleting the negative sign "-"
With Columns("B:B")
.Replace What:="-", Replacement:=""
End With
End Sub
It should successfully apply the code to all the sheets
My result is that the first sheet was always cleared and the other sheets are untouched. please help
You've got unqualified - meaning the Worksheet isn't qualified - Range and Columns calls.
This is good - note the period in front of each instance of Range, as well as before Rows.
With wks
Set Rng = .Range(.Range("B1"), .Range("B" & .Rows.Count).End(xlUp))
End With
This, not so much:
Set Rng = Range("B1:B1000") ' no worksheet specified, so it's the ActiveSheet, not wks.
Or again:
Columns("C").Cut
Move that first End With all the way to the end of the Sub, and add a period in front of each instance of Range and Columns. By doing so, they will reference wks and not imply the ActiveSheet.
While you're at it, change that instance of ActiveSheet to wks. You want to work with wks, not the ActiveSheet.

How can I have my loop search for a value rather than a string of words?

I have some data that has both words and values in cells and I am trying to delete the rows that don’t have values in the cells. My code works now if all of the numbers are negative but if there are positive numbers then my code won’t work. How do I fix this?
Sub tval
Dim s As Long
Dim LastRow As Long
S=2
LastRow= cells.find(“*”,[A1],,, xlByRows,xlPreviousRow).row
Do until s>LastRow
DoEvents
If InStr(1,Cells(s,4), “-“) > 0 Then
S=s+1
Else
Cells(s,4).EntireRow.Delete
LastRow=LastRow -1
End if
Loop
End sub
When deleting rows, you should always start from the end.
Sub tval
Dim s As Long
Dim LastRow As Long
LastRow= Cells(Rows.Count, 1).End(xlUp).Row
For s= LastRow to 2 Step -1
If Not IsNumeric(Cells(s,4)) then
Cells(s,4).EntireRow.Delete
End if
Next s
End sub
This should work for you:
Sub tgr()
Dim ws As Worksheet
Dim rTextConstants As Range
Dim rTextFormulas As Range
Dim rCombined As Range
Set ws = ActiveWorkbook.ActiveSheet
'Exclude row 1 so that only text values found in rows 2+ are found
With ws.Range("A2", ws.Cells(ws.Rows.Count, ws.Columns.Count))
On Error Resume Next 'prevent error if no cells found
Set rTextConstants = .SpecialCells(xlCellTypeConstants, xlTextValues)
Set rTextFormulas = .SpecialCells(xlCellTypeFormulas, xlTextValues)
On Error GoTo 0 'remove on error resume next condition
End With
If Not rTextConstants Is Nothing Then Set rCombined = rTextConstants
If Not rTextFormulas Is Nothing Then
If rCombined Is Nothing Then Set rCombined = rTextFormulas Else Set rCombined = Union(rCombined, rTextFormulas)
End If
If Not rCombined Is Nothing Then
rCombined.EntireRow.Delete
Else
MsgBox "No cells containing text found in sheet '" & ws.Name & "'", , "Error"
End If
End Sub
May I suggest a bit of a different approach:
Before:
Code:
Dim RNG1 As Range, RNG2 As Range
Option Explicit
Sub TestCase()
With ActiveWorkbook.Sheets(1)
Set RNG1 = .Range("A1:A" & .Cells(Rows.Count, 1).End(xlUp).Row)
If RNG1.SpecialCells(xlCellTypeConstants, 1).Count <> RNG1.Cells.Count Then
Set RNG2 = Application.Intersect(RNG1, RNG1.SpecialCells(xlCellTypeConstants, 2))
RNG2.EntireRow.Delete
End If
End With
End Sub
After:
You'll need to change this around to suit your range obviously. It should be a good starting point nonetheless.
You can also use AutoFilter to filter the numbers, and delete the visible cells to accomplish this task. The code accounts for a header row.
With ThisWorkbook.Sheets("Sheet1")
With .Range("A1").CurrentRegion
.AutoFilter
.AutoFilter Field:=4, Criteria1:="<>*"
.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
.AutoFilter
End With
End With

Delete rows with merged cells

I found a procedure to highlight merged cells in an active sheet:
I tried a ActiveCell.EntireRow.Delete statement to delete the row that is currently iterated over.
Sub DeleteRows()
Dim x As Range
For Each x In ActiveSheet.UsedRange
If x.MergeCells Then
x.Interior.ColorIndex = 8
ActiveCell.EntireRow.Delete
End If
Next
End Sub
I don't care about highlighting the merged cells. The goal is to delete any row that has a merged cell.
Find out all merged cell ranges, club them and delete in one go.
Sub DeleteRows()
Dim x As Range
Dim rngDelete As Range
For Each x In ActiveSheet.UsedRange
If x.MergeCells Then
If rngDelete Is Nothing Then
Set rngDelete = x
Else
Set rngDelete = Union(rngDelete, x)
End If
End If
Next
If Not rngDelete Is Nothing Then
rngDelete.EntireRow.Delete
End If
End Sub
When deleting rows, always delete from the bottom up or a) you risk deleting the next cell you want to examine and b) you risk skipping over a row that comes up to take the place of a deleted row.
Sub DeleteRows()
Dim r as long, c as long
with ActiveSheet.UsedRange
'work backwards through the rows
For r = .rows.count to 1 step -1
'work forwards through the columns
For c = 1 to .columns.count
If .cells(r, c).MergeCells Then
'once a merged cell is found, delete then go immediately to the next row
.cells(r, c).EntireRow.Delete
exit for
End If
next c
Next r
end with
End Sub
A quick way to do this is to find all the merged cells then delete them in one go: a good way to do this is to use a range.find using a cells 'format' as merged then combine the found ranges
The following code loops through merged ranges and creates a union then selects the entire rows
Sub SelectMerge()
Dim rng As Range, rngUnion As Range, Test As Range
Dim ws As Worksheet: Set ws = ActiveSheet
With Application.FindFormat
.Clear
.MergeCells = True
End With
With ws.UsedRange
Set rng = .Find("", SearchFormat:=True)
Do
If Not rngUnion Is Nothing Then Set rngUnion = Application.Union(rng, rngUnion)
If rngUnion Is Nothing Then Set rngUnion = rng
If rng Is Nothing Then Exit Do
Set rng = .Find("", After:=rng, SearchFormat:=True)
Loop While Application.Intersect(rng, rngUnion) Is Nothing
End With
If Not rngUnion Is Nothing Then rngUnion.EntireRow.Select 'rngUnion.EntireRow.Delete
End Sub

Resources