VBA removing rows from a spreadsheet if cells contain a certain string - vba

I am very new to VBA. I am trying to isolate a particular customers transactions on a spread sheet.
Column "A" contains the Customer payment method (prepaid or various other methods). Column "D" contains the customer we are shipping too, Column "L" contains the customer we are shipping from.
If the cell in column "A" has 'prepaid' I want to search column "D" for the customer name (jaba). I will then delete all rows which do not contain this customer. IF the cell in column "A" is not 'prepaid' I want it to search column "L" for the customer name, and delete all rows which do not contain this string. When I run the code provided below I get an 1004 error on the following script 'If cell3.Find(ContainWord) Is Nothing Then'. Any help would be much appreciated.
Sub DoNotContainClearCells()
Dim rng As Range
Dim rng2 As Range
Dim rng3 As Range
Dim cell As Range
Dim cell2 As Range
Dim cell3 As Range
Dim ContainWord As String
'What range do you want to search?
Set rng = Range("A:A")
Set rng2 = Range("D:D")
Set rng3 = Range("L:L")
'What phrase do you want to test for?
ContainWord = "jaba"
For Each cell In rng
If cell.Value = "prepaid" Then
'Loop through each cell in range and test cell contents
For Each cell2 In rng2.Cells
If cell2.Find(ContainWord) Is Nothing Then EntireRow.Delete
Next cell2
Else
'Loop through each cell in range and test cell contents
For Each cell3 In rng3.Cells
If cell3.Find(ContainWord) Is Nothing Then EntireRow.Delete
Next cell3
End If
Next
End Sub

Without discussing the logic of your code, which is not part of the question, I can tell you that the
Run-time error '1004': Object required
in this line:
If cell3.Find(ContainWord) Is Nothing Then EntireRow.Delete
is because the EntireRow.Delete is missing a range (see Range.EntireRow Property (Excel))
Solution: Replace these lines:
If cell2.Find(ContainWord) Is Nothing Then EntireRow.Delete
If cell3.Find(ContainWord) Is Nothing Then EntireRow.Delete
with these:
If cell2.Find(ContainWord) Is Nothing Then cell2.EntireRow.Delete
If cell3.Find(ContainWord) Is Nothing Then cell3.EntireRow.Delete
Suggest to always have at the top of the modules\classes\userforms:
Option Explicit
This would have given a Compile error: Variable not defined highlighting the error earlier at compiling time (see Option Explicit Statement)

Related

How to loop through only the non-empty cell in a column in an excel sheet via VBA?

According to this website.
I think this should work:
Dim cell As Range
For Each cell In xxxSheet.Range("B:B").SpecialCells(xlCellTypeFormulas, xlNumbers)
'Do sth.
Next
which does not work. Is there something missing?
This should be working solution:
For Each cell In xxxSheet.Range("B:B")
If Not IsEmpty(cell) Then
'do sth
End If
Next
Also, if you want to loop until last filled cell, you could use following:
xxxSheet.Range("B1:B" & Cells(Rows.Count, 2).End(xlUp).Row)
instead of
xxxSheet.Range("B:B")
It does not work, because you do not have formulas on column B. Put some formulas and some constants and try this:
Option Explicit
Public Sub TestMe()
Dim myCell As Range
Dim myRange As Range
Set myRange = Worksheets(1).Columns("B:B").SpecialCells(xlCellTypeFormulas, xlNumbers)
For Each myCell In myRange
Debug.Print myCell.Address
Next
Set myRange = Worksheets(1).Columns("B:B").SpecialCells(xlCellTypeConstants, xlNumbers)
For Each myCell In myRange
Debug.Print myCell.Address
Next
End Sub
The first loop would print the addresses of the formula cells, the second the addresses of the constants.
This is the ozgrid explanation about SpecialCells:
http://www.ozgrid.com/VBA/special-cells.htm
The problem is SpecialCells(xlCellTypeFormulas, xlNumbers) is returning only cells with formulas that make numbers (ie. =1+2).
To keep things efficient, you only need to check up to the last filled row
For Each cell In xxxSheet.Range("B1", Cells(Rows.Count, 2).End(xlUp))
If Not IsEmpty(cell) Then
'Do sth.
End If
Next
If you really want you can use SpecialCells() to have a range containing no blanks to loop through. If you only have formulas or only constants, you could use SpecialCells(xlFormulas) or SpecialCells(xlConstants) respectively, but for a more general use case you will have to do do a combination of the two.
Dim cell As Range
Dim searchRange As Range
' SpecialCells errors when there aren't cells instead of giving a useful value
On Error Resume Next
Set searchRange = xxxSheet.Range("B:B").SpecialCells(xlFormulas)
Set searchRange = xxxSheet.Range("B:B").SpecialCells(xlConstants)
Set searchRange = Union(xxxSheet.Range("B:B").SpecialCells(xlConstants), _
xxxSheet.Range("B:B").SpecialCells(xlFormulas))
On Error GoTo 0
If searchRange Is Not Nothing Then ' Only continue if no blanks
For Each cell In searchRange
'Do sth.
Next
End If

Macro to select first non-empty cell in entire sheet

Suppose there is only one non-empty cell in a sheet and you want a macro to find it. So far I have the following code but am struggling to adjust it so it searches all columns, not only one:
Sub FirstNonEmpty()
Dim ws As Worksheet
Set ws = ActiveSheet
For Each cell In ws.Columns(1).Cells
If Not IsEmpty(cell) = True Then cell.Select: Exit For
Next cell
End Sub
Perhaps there is a way to use a variable equal to all columns instead of "1" in "ws.Columns(1).Cells"?
You could use the top formulation if the non-blank cell does not contain a formula, or use xlcelltypeformulas if it's a formula. If you know there is a non-blank, you don't need the On Error. In fact if there is definitely only one you don't need the (1) either.
On Error Resume Next
ActiveSheet.Cells.SpecialCells(xlCellTypeconstants)(1).Select
'or
'ActiveSheet.Cells.SpecialCells(xlCellTypeformulas)(1).Select
Or you may give this a try...
Dim Rng As Range
Set Rng = Cells.Find(what:="*", LookIn:=xlValues)
If Not Rng Is Nothing Then
Rng.Select
End If
You can change the For statement to:
For Each cell In ws.UsedRange.Cells
which has the benefit of not scanning the rows/columns at the end of the worksheet as well.

VBA clear cell range based on a certain condition

This problem may seems pretty simple but I have been dealing with it for 2 days now and cant get it done. I searched other forums to see if they have this same problem but didnt find close to tyhis one.
So I have range K:T starting from row 2 and need to clear the cells that contains #N/A. I wrote the code below but cant seem to make it work.
Sub Clear_cells()
Dim rng As Range, i As Integer
'Set the range to evaluate to rng.
Set rng = Range("K:T")
'Loop backwards through the rows
'in the range that you want to evaluate.
For i = rng.Rows.count To 1 Step -1
'If cell i in the range contains an "N/A", delete cell content
If rng.Cells(i).Value = "#N/A" Then rng.Cells(i).CellRange.ClearContents (1)
Next
End Sub
If your cells contain an error value (i.e. #N/A) rather than the string "#N/A" then you need to check for an error value instead of checking for a string.
Replace
For i = rng.Rows.count To 1 Step -1
'If cell i in the range contains an "N/A", delete cell content
If rng.Cells(i).Value = "#N/A" Then rng.Cells(i).CellRange.ClearContents (1)
Next
with
Dim cel As Range
For Each cel in rng
If IsError(cel.Value) Then
If cel.Value = CVErr(xlErrNA) Then cel.ClearContents
End If
Next
or, if you want to check for all error conditions (such as #DIV/0!), just use
Dim cel As Range
For Each cel in rng
If IsError(cel.Value) Then cel.ClearContents
Next
use the function isna to check for #N/A
If Application.WorksheetFunction.IsNa(rng.Cells(i)) Then rng.Cells(i).CellRange.ClearContents (1)

Static date in the last column

I am looking to do an IF THEN statement that will help me put a date into the U Column. However, I am not sure how to go about it.
Sub()
Dim rng1 As Range
Set rng1 = Selection.SpecialCells("U").xlBlanks
If Not rng1 Is Nothing Then rng1.Value = Format(Now(), "mm-dd-yyyy")
End Sub
When I run this code I receive a run-time error '1004'. Can someone help me with this?
First you want to find the range of cells that actually has data, because you don't want to check rows of column U where the entire row itself is empty. So assuming the last possible row of data can be found in column A, you can use this to set the search range.
With Worksheets("Sheet1") 'qualify sheet, change name as needed
Dim lRow as Long
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
Then, you can set the search range to be from Row 1 to lRow, assuming the data is in a contiguous range left-to-right, top-to-bottom starting in A1. (The On Error statements are necessary, since Excel will throw an error if blank cells do not exist in the range).
Dim rngSearch as Range
On Error Resume Next
Set rngSearch = .Range("U1:U" & lRow).SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If the range is set then you can enter values into the entire range at once (which you had in your code above).
If Not rngSearch is Nothing Then rngSearch.Value = Format(Now(), "mm-dd-yyyy")
End With

search for multiple values - loop

I think this can only be done in VBA. I tried VLOOKUP, but no luck.
I want to search a whole sheet for certain values. These values come from a row in another sheet. Once each value is found, it looks to the top most row and pulls that value.
I might need to loop through each value in the row and search the sheet from there?
my thought/example:
Sheet1!A:A
1234
5325
6346
6342
look in sheet 2 for 1234. lets say its found in cell G5, it will then look at the value in G1 and input that into cell A1 on sheet 2. I'm sorry for making this really confusing.
Here's what I have starting out:
Sub FindValues()
Dim SearchRow As String
Dim SearchRange As Range, cl As Range
Dim FirstFound As String
Dim sh As Worksheet
' Set Search value
SearchRow = Sheets("sheet2").Range("B:B")
getting error on the last line. run-time error '13': type mismatch
You need to Set a Range object. You cannot assign it to a string unless you are looking for a property that is a string like the Address property.
Dim SearchRow As String
Dim SearchRange As Range
SearchRow = Sheets("sheet2").Range("B:B").address
Set SearchRange = Sheets("sheet2").Range("B:B")
Please consider the following code for your requirements:
Sub FindValues()
Dim SearchRow As Range
Dim SearchRange As Range
Dim Cell As Range
Dim FirstFound As Range
' Set Search value
Set SearchRow = Sheets("Sheet1").Range("B:B")
Set SearchRange = Sheets("Sheet2").Range("A:K")
For Each Cell In SearchRow
Set FirstFound = SearchRange.Find(Cell.Value2)
If Not FirstFound Is Nothing Then
Cell.Offset(0, 1).Value2 = SearchRange.Cells(1, FirstFound.Column).Value2
Else
Cell.Offset(0, 1).Value2 = "No Value Found"
End If
Next
End Sub
Note that as per your description I assumed that the SearchRange was more than just 1 column.
Basically the script loops through each Cell in the SearchRow and looks for the value in the SearchRange. If it finds the value and returns a subrange representing cells with the search value and sets the value to the right of each Cell to the value of the top cell of the column where the value was found. Hope this serves your needs. Cheers.