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

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

Related

VBA code: "select rows to delete except headers" (not working)

I have the following code which should simply select a range of rows and delete them. Unfortunately it deletes the headers as well, no matter how I change the range.
I tried to change the "rng" parameter without success.
Thank you for the feedback you can provide.
Sub delete_rows_range()
'Application.ScreenUpdating = False
Dim rng, Rng_del As Range
Dim leg As Range
Set leg = Worksheets("Sheet1").Range("aB1")
Set rng = Worksheets("Sheet1").Range("b1")
If Worksheets("Sheet1").AutoFilterMode = True Then
Worksheets("Sheet1").AutoFilter.ShowAllData
End If
rng.Select
rng.AutoFilter Field:=2, Criteria1:=leg
'rng.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.delete
rng.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Select
Worksheets("Sheet1").AutoFilterMode = False
End Sub
Your problem is that you are using a single cell as the range.
When you .Offset a single cell range, then use `xlCelTypeVisible.EntireRow.Delete
Excel selects every cell on the sheet and deletes them.
You really should clarify your range with a properly defined range object. e.g.
Dim ws As Worksheet, lRow As Long, rng As Range
Set ws = Worksheets("Sheet1")
lRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
Set rng = ws.Range("A1:AB" & lRow)
But if you want to use B1 as your rng you can replace your line, rng.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Select with this line...
rng.Range(Cells(2, 2), Cells(rng.Rows.Count, 2)).SpecialCells(xlCellTypeVisible).EntireRow.Delete
You are trying to select from a single cell range.
You should do instead:
Sub delete_rows_range()
'Application.ScreenUpdating = False
Dim rng, Rng_del As Range
Dim leg As Range
Set leg = Worksheets("Sheet1").Range("AB1")
Set rng = Worksheets("Sheet1").Range("B1")
If Worksheets("Sheet1").AutoFilterMode = True Then
Worksheets("Sheet1").AutoFilter.ShowAllData
End If
rng.Select
rng.AutoFilter Field:=2, Criteria1:=leg
'rng.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.delete
Worksheets("Sheet1").UsedRange.SpecialCells(xlCellTypeVisible).Rows(2).Select
Worksheets("Sheet1").AutoFilterMode = False
End Sub

Conditional Loop in VBA

Looking for a conditional looping, perhaps Do Until or some similar that will run through the range of cells (say A3:A13) and if there’s a blank cell within that range there would be a command that will automatically hide entire row where the blank cell sits.(if the blank cell is A5 this mean entire row 5 would be hidden) The command will run through until all the the blank cells are detected and automatically all the rows associated with blank cells are hidden until it reach the end of the range A13. Any suggestions kindly welcome.
You can try something like this. First we loop through the range("A" & LRow) it will map all the blank cells and hide all in one go.
Option Explicit
Sub HideRows()
Dim ws As Worksheet
Dim LRow As Long
Dim HideRng As Range
Dim i As Long
Set ws = ActiveSheet
With ws
LRow = .Range("A" & .Rows.Count).End(xlUp).Row
For i = 2 To LRow
If Len(Trim(.Range("A" & i).value)) = 0 Then
If HideRng Is Nothing Then
Set HideRng = .Rows(i)
Else
Set HideRng = Union(HideRng, .Rows(i))
End If
End If
Next i
If Not HideRng Is Nothing Then HideRng.EntireRow.Hidden = True
Set HideRng = Nothing
End With
End Sub

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

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

Deleting rows in a foreach

I'm trying to update a sheet with an import of a .CSV file..
I can read and update all the information. After the update I want to remove some data. All the rows with D empty must be deleted (whole row).
For that, I have a foreach that checks D3:D486 (is last row).
After running the macro, there are some rows deleted, but not all the rows.
Dim rCell As Range
Dim rRng As Range
Debug.Print CStr(LastRow)
Set rRng = Worksheets("sheet1").Range("D3:D" + CStr(LastRow))
For Each rCell In rRng.Cells
If Not IsEmpty(rCell) Then
Debug.Print rCell.Row
Else
Debug.Print "Empty"
Worksheets("sheet1").Rows(rCell.Row).Delete
End If
Next rCell
I guess there is a problem with the for-each.. By example, If he delete row 100, the next time he goes to row 101.. But thats previous row 102..
I can save the cells maybe in an array, but then it would be the same.
Except if I go the other way (from bottom to top). How can I solve this?
i think you've answered your own question: from bottom to top...
and you can try range.EntireRow.Delete method too, something like below
Dim rCell As Range
Dim lastRow, i
lastRow = 1000
For i = lastRow To 1 Step -1
' if condition met
Worksheets("Sheet1").Range("D:" + i).EntireRow.Delete
Next
I would do it like this:
Dim i As Integer
Dim rRng As Range
Debug.Print CStr(LastRow)
Set rRng = Worksheets("sheet1").Range("D3:D" + CStr(LastRow))
For i = 1 To rRng.Cells.Count
If Not IsEmpty(Worksheets("Sheet1").Range("D:" + i).Value) Then
Debug.Print rCell.Row
Else
Debug.Print "Empty"
Worksheets("Sheet1").Range("D:" + i).EntireRow.Delete
i = i - 1
End If
Next
Rex answer is correct, if you want to get cute you can also do it this way:
Sub DeleteRowsWithCriteria()
Dim rng As Range, rngCell As Range, rngDelete As Range
Set rng = Worksheets("sheet1").UsedRange.Columns("D:D").Cells 'Watch out here, if columns A-C are not all used, this doesn't work
For Each rngCell In rng
If rngCell.Value = "" Then
If rngDelete Is Nothing Then
Set rngDelete = rngCell
Else
Set rngDelete = Union(rngDelete, rngCell)
End If
End If
Next rngCell
rngDelete.EntireRow.Delete xlShiftUp
End Sub

In range find this and do that

Have a range of cell with column headings as weeks In the range of cells I want to look for a number, say
1 if it finds a 1 then look at a column in said row for a variable, 2 or 4 whatever Now I want to put a triangle (can be copy and paste a cell) in the cell that has the "1" in it then skip over the number of week variable and add another triangle and keep doing this until the end of the range. Then skip down to the next row and do the same, until the end of the range.
Then change to the next page and do the same thing... through the whole workbook.
I think I have it done, don't know if it's the best way.
I get a error 91 at the end of the second loop, the first time the second loop ends it goes through the error code.
The second time the second loop ends it errors.
I don't understand it runs through once, but not twice.
Sub Add_Triangles2()
Dim Rng As Range
Dim OffNumber As Integer
Dim SetRange As Range
Dim OffsetRange As Range
Dim ws As Worksheet
Set SetRange = Sheets("Sheet1").Range("G25") ' Used to stop the second loop in range
Worksheets(1).Activate
Worksheets(1).Range("A1").Select ' Has item to be pasted (a triangle)
Selection.Copy
For Each ws In Worksheets
Worksheets(ws.Name).Activate
With Range("C4:G25")
Set Rng = .Find(1, LookIn:=xlValues)
If Not Rng Is Nothing Then
FirstAddress = Rng.Address
Do
Rng.Activate
ActiveSheet.Paste
Do
OffNumber = Range("A" & ActiveCell.Row)
Set OffsetRange = SetRange.Offset(0, -OffNumber)
If Not ActiveCell.Address < OffsetRange.Address Then
Exit Do
Else
End If
ActiveCell.Offset(, OffNumber).Select
ActiveSheet.Paste
Loop While (ActiveCell.Address <= OffsetRange.Address)
On Error GoTo ErrorLine
Set Rng = .FindNext(Rng)
Loop While Not Rng Is Nothing And Rng.Address <> FirstAddress
End If
End With
ErrorLine:
On Error GoTo 0
Application.EnableEvents = True
Next ws
Application.CutCopyMode = False
End Sub
I was not able to get an Error 91 using the data set I built from your explanation, maybe a screenshot of the layout could help recreate the issue.
However, I would do something like this, it will look at the value of each cell in the range C4:G25, and if it equals 1, it will paste the symbol stored in Cell A1.
Sub Add_Triangles2()
Dim Rng As Range
Dim rngSymbol As Range
Dim intFindNum As Integer
Dim ws As Worksheet
Set rngSymbol = Range("A1") 'Set range variable to hold address of symbol to be pasted
intFindNum = 1 'Used to hold number to find
Worksheets(1).Activate
For Each ws In Worksheets
Worksheets(ws.Name).Activate
For Each Rng In Range("C4:G25")
If Rng.Value = intFindNum Then
rngSymbol.Copy Rng
End If
Next Rng
Next ws
End Sub
I got it....
Sub Add_TriWorking()
Dim Rng As Range
Dim rngSymbol As Range
Dim intFindNum As Integer
Dim ws As Worksheet
Dim OffNumber As Integer
Dim SetRange As Range
Dim OffsetRange As Range
Set SetRange = Sheets("Sheet1").Range("G25") ' Used to stop the second loop in range
Set rngSymbol = Range("A1") 'Set range variable to hold address of symbol to be pasted
intFindNum = 1 'Used to hold number to find
Worksheets(1).Activate
For Each ws In Worksheets
Worksheets(ws.Name).Activate
For Each Rng In Range("C4:G25")
If Rng.Value = intFindNum Then
rngSymbol.Copy Rng
Rng.Activate
ActiveCell.Copy
Do
OffNumber = Range("A" & ActiveCell.Row)
Set OffsetRange = SetRange.Offset(0, -OffNumber)
If Not ActiveCell.Address < OffsetRange.Address Then
Exit Do
Else
End If
ActiveCell.Offset(, OffNumber).Select
ActiveSheet.Paste
Loop While (ActiveCell.Address <= OffsetRange.Address)
On Error GoTo ErrorLine
End If
Next Rng
ErrorLine:
On Error GoTo 0
Application.EnableEvents = True
Next ws
Application.CutCopyMode = False
End Sub

Resources