vba if cells do not equal values then delete - vba

I'm fairly new to VBA and I can't seem to figure this one out through google.
I'm trying to run through a worksheet and use an If statement to delete unnecessary columns, based on their row 1 values. I'm trying to do it like this:
Sub Macro1
Dim cell As Range
For Each cell In Rows("1")
If cell.Value <> "order_number", "tax_details", "etc"
Then .EntireColumn.delete
End Sub
But I can't seem to figure out how to use the "If cell.Value" statement with multiple values, nor how to delete the columns that I don't want. Any help is much appreciated.
Cheers,
Justin
Edit: Thanks for all the responses guys, everything was super helpful. Fixed the problem and I learned a lot.

You are close.
Your For loop must be ended with a Next statement
your Then must occur on the same line as your If to be valid and should be closed with an End If (unless you do a one-liner)
You must test your conditions separately with an AND separating them
Cell is already a keyword here (subclass of a Range) so change that variable to rngCell or something different.
Rows("1") would be better as an explicit range otherwise it will literally loop through every column in that row. That's a lot of columns.
Sub Macro1
Dim rngCell As Range
For Each rngCell In Range("A1:GZ1").Cells
If rngCell.Value <> "order_number" And rngCell.Value <> "tax_details" AND rngCell.Value <> "etc" Then
rngCell.EntireColumn.delete
End If
Next cell
End Sub

No other response seems to be addressing the fact that you looping left-to-right while deleting columns. Delete rows from bottom to top and delete columns from right to left or you risk skipping over cells/columns.
Sub Macro1
Dim i as long
with worksheets("sheet1")
For i=.cells(1, .columns.count).end(xltoleft).column to 1 step-1
select case lcase(.cells(1, i).value)
case "order_number", "tax_details", "etc"
'do nothing
case else
.columns(i).entirecolumn.delete
end select
next i
end with
End Sub

In order to test multiple conditions, you use logical operators(AND, OR, NOT, etc) to create a single logical statement(i.e. a single value for all 3). If you want any of the conditions to work, use "or" and if you need all 3 conditions to be met, use AND.
If cell.Value <> "order_number", "tax_details", "etc"
should be
If cell.Value <> "order_number" OR cell.value <> "tax_details" OR cell.value <> "etc" then
To delete the entire column that way, you'd need to reference which column you're trying to delete. If you're iterating over the rows, you'd access it by
Cell.EntireColumn.delete

You must compare/evaluate each time.
If cell.Value <> "order_number" And cell.Value <> "tax_details" And cell.Value <> "etc"

Related

VBA checking no results after filtering a table

I have the following table:
And the following code (that filters this table):
Sub testFilter()
Dim tbl As ListObject
Dim filteredRange As Range
Set tbl = Sheet1.ListObjects("testTbl")
tbl.Range.AutoFilter Field:=2, Criteria1:=Array("a", "b")
On Error Resume Next
Set filteredRange = tbl.ListColumns("status").DataBodyRange.SpecialCells(xlVisible)
On Error GoTo 0
If filteredRange Is Nothing Then
'do something
Else
Debug.Print filteredRange.Address
End If
End Sub
I expect filteredRange to be nothing.
But it's not nothing, and the address it prints is:
$1:$1,$3:$1048576
which is basically the entire sheet beside the one row I have in the table.
What am I doing wrong?
I need the ability to detect that the filter gave no results.
I can reproduce this behavior, but only if the table has only one row of data. As soon as a second row is added, it behaves as expected. I cannot find an explanation for that, could be one of the quirks of Excel.
If it can really happen with your data that the table has only one row, you could maybe use the workaround
If filteredRange Is Nothing Or (tbl.Range.Rows.Count = 2 And tbl.Range.Rows(2).Hidden) Then
One remark: I think your filter-statement needs a parameter Operator:=xlFilterValues if you pass an array of values:
tbl.Range.AutoFilter Field:=2, Criteria1:=Array("a", "b"), Operator:=xlFilterValues

VBA go to next row and pull formula from above after data has been entered

I have the excel formula below to pull data from another sheet.
=IF(ISNUMBER(SEARCH("Yes",Sheet7!C4)),Sheet7!A4,"")
These cells used, C4 and A4, will always remain the same. Different item numbers are being scanned in one after another so the values in the cells will change.
When the word Yes is shown in C4 i would like it to record the item # in A4 into the new sheet. This formula works great for that.
However, after the item # is recorded in the new sheet, i would like it to go down to the next row and copy the formula so it can record the next item # scanned.
Is this VBA possible? thank you!
I think you are trying to get something like
If Worksheets("Sheet7").Range("C4").Value Like "*Yes*" Then
ActiveCell.Value = Worksheets("Sheet7").Range("A4").Value
Else
ActiveCell.Value = ""
End If
but don't use ActiveCell - use a proper reference to the cell in which you want to put the value. (Your question doesn't contain enough information to determine what the location is, which is why I was forced to just refer to it as ActiveCell.)
Based on comments, it sounds like you want the following Worksheet_Change event in Worksheets("Sheet7"):
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count <> 1 Then
Exit Sub
End If
If Intersect(Range("A4"), Target) Is Nothing Then
Exit Sub
End If
If Range("C4").Value Like "*Yes*" Then
With Worksheets("Sheet1")
.Cells(.Rows.Count, "A").End(xlUp).Offset(1, 0).Value = Target.Value
End With
End If
End Sub

IF & Statement from excel to VBA

I am a bit new to using VBA. I have a data table, that pulls data in from one of the programs I use, and is filtered through Microsoft Query. There is one column I can't sort, so I need to use an if and statement to remove unwanted data. I came up with this if statement, which highlights the rows I want to delete, but I don't know how to put it into VBA.
=IF(L5="Program",L6<>"lathe"),"2","")
Basically I want the VBA to look at Column L:L. If the cell=program, and the cell below does not equal lathe I want the row above to be deleted. If the cell doesn't equal program continue looking until the end of the data.
In VBA, you'd use the IF ... And ... Then structure, thus:
If Range("L5")="Program" And Range("L6") <> "lathe" Then
'Do something
End If
You'll probably want to replace the Range(...) statements with a range variable of some sort to store the cells you're really interested in, but that should give you an idea of the structure you're looking for.
EDITED TO ADD:
Loop through all of column L like this:
Dim rngCheck as Range
Dim rngCell as Range
Set rngCheck = Range("L1", "L" & Rows.Count - 1)
For each rngCell in rngCheck
If rngCell.value = "Program" And rngCell.offset(1,0).value <> "lathe" then
rngCell.offset(-1,0).EntireRow.Delete
End if
Next rngCell
This:
Creates a range to look at (column L)
Loops through all cells in that column (the For each loop)
Runs our IF logic and
...deletes the entire row if the logic is met.
Here is your idea behind it. you will just need to fix the format as you'd like.
If cells(5, "L") = "Program" AND cells(6, "L") <> "Lathe" Then
cells (6, "M") = 2
Else
cells (6, "M") = ""
EndIf
The best is to loop on column L. Imagine your data is from row 3 to 150
for i = 3 to 150
if lcase(range("L"&i).value) = "program" and lcase(range("L"&i+1).value) <> "lathe" then
rows(i).entirerow.delete
end if
next i

If statement that contains <> to condition not working

I am having issues with this code whereby the columns still display despite not meeting the IF condition:
If CBool(Application.WorksheetFunction.CountIf(.Columns(j), "<>0"))
The code loops through columns and only displays columns that have values > 0. I do not know if the issue is with j or with the CBool condition itself. I would like some help as I really need this code for my excel as it would be then much easier and useful to analyze! Thank you.
Sub TestPasteColumnData3()
Dim lastcol As Long
Dim j As Long
With Worksheets("WF - L12 (3)")
lastcol = .Cells(5, Columns.Count).End(xlToLeft).Column
For j = 3 To lastcol
'change >0 to <>0 and 3 to j
If CBool(Application.WorksheetFunction.CountIf(.Columns(j), "<>0")) Then
.Columns(j).Copy Destination:=Worksheets("Sheet 1").Columns(j) 'Dont delete, this code works
Else
MsgBox ("No Value")
Exit Sub
End If
Next
End With
MsgBox ("Done")
End Sub
The CountIf function will count ANYTHING, including blank cells, in the range if it is not equal to 0, which will cause your
CBool(Application.WorksheetFunction.CountIf(.Columns(j), "<>0"))
to be TRUE if you have anything other than a column full of 0's (with no blanks)
You might try
If Application.WorksheetFunction.Sum(.Columns(j)) > 0 Then
.Columns(j).Copy Destination:=Worksheets("Sheet 1").Columns(j) 'Dont delete, this code works
Else
MsgBox ("No Value")
Exit Sub
End If
which will give you any column that has anything that is greater than 0, but still account for any blanks (or otherwise) you may have in the column.
WorksheetFunction.CountIf will return a count of cells that satisfy a given condition. You're converting that count to a Boolean - that will evaluate to True for any non-zero result.
You need to compare that count to something e.g. > 0 to result in a Boolean expression (then you can remove the CBool) to achieve the expected result.
If Application.WorksheetFunction.CountIf(.Columns(j), "<>0") > 0 Then
But then, if any non-zero integer converts to True, this code is equivalent (albeit less explicit about what it's doing):
If CBool(Application.WorksheetFunction.CountIf(.Columns(j), "<>0")) Then
Therefore, that condition cannot be the problem.
You need to place a break point (F9) before the loop, run the code, and step through (F8) to see what's going on. The problem might be with the usage of WorksheetFunction.CountIf against your specific worksheet data.

How to delete row based on cell value

I have a worksheet, I need to delete rows based on cell value ..
Cells to check are in Column A ..
If cell contains "-" .. Delete Row
I can't find a way to do this .. I open a workbook, copy all contents to another workbook, then delete entire rows and columns, but there are specific rows that has to be removed based on cell value.
Need Help Here.
UPDATE
Sample of Data I have
The easiest way to do this would be to use a filter.
You can either filter for any cells in column A that don't have a "-" and copy / paste, or (my more preferred method) filter for all cells that do have a "-" and then select all and delete - Once you remove the filter, you're left with what you need.
Hope this helps.
The screenshot was very helpful - the following code will do the job (assuming data is located in column A starting A1):
Sub RemoveRows()
Dim i As Long
i = 1
Do While i <= ThisWorkbook.ActiveSheet.Range("A1").CurrentRegion.Rows.Count
If InStr(1, ThisWorkbook.ActiveSheet.Cells(i, 1).Text, "-", vbTextCompare) > 0 Then
ThisWorkbook.ActiveSheet.Cells(i, 1).EntireRow.Delete
Else
i = i + 1
End If
Loop
End Sub
Sample file is shared: https://www.dropbox.com/s/2vhq6vw7ov7ssya/RemoweDashRows.xlsm
You could copy down a formula like the following in a new column...
=IF(ISNUMBER(FIND("-",A1)),1,0)
... then sort on that column, highlight all the rows where the value is 1 and delete them.
if you want to delete rows based on some specific cell value.
let suppose we have a file containing 10000 rows, and a fields having value of NULL.
and based on that null value want to delete all those rows and records.
here are some simple tip.
First open up Find Replace dialog, and on Replace tab, make all those cell containing NULL values with Blank.
then press F5 and select the Blank option, now right click on the active sheet, and select delete, then option for Entire row.
it will delete all those rows based on cell value of containing word NULL.
If you're file isn't too big you can always sort by the column that has the - and once they're all together just highlight and delete. Then re-sort back to what you want.
You can loop through each the cells in your range and use the InStr function to check if a cell contains a string, in your case; a hyphen.
Sub DeleteRowsWithHyphen()
Dim rng As Range
For Each rng In Range("A2:A10") 'Range of values to loop through
If InStr(1, rng.Value, "-") > 0 Then 'InStr returns an integer of the position, if above 0 - It contains the string
rng.Delete
End If
Next rng
End Sub
This is the autofilter macro you could base a function off of:
Selection.AutoFilter
ActiveSheet.Range("$A$1:$A$10").AutoFilter Field:=1, Criteria1:="=*-*", Operator:=xlAnd
Selection.AutoFilter
I use this autofilter function to delete matching rows:
Public Sub FindDelete(sCol As String, vSearch As Variant)
'Simple find and Delete
Dim lLastRow As Integer
Dim rng As Range
Dim rngDelete As Range
Range(sCol & 1).Select
[2:2].Insert
Range(sCol & 2) = "temp"
With ActiveSheet
.usedrange
lLastRow = .Cells.SpecialCells(xlCellTypeLastCell).Row
Set rng = Range(sCol & 2, Cells(lLastRow, sCol))
rng.AutoFilter Field:=1, Criteria1:=vSearch, Operator:=xlAnd
Set rngDelete = rng.SpecialCells(xlCellTypeVisible)
rng.AutoFilter
rngDelete.EntireRow.Delete
.usedrange
End With
End Sub
call it like:
call FindDelete "A", "=*-*"
It's saved me a lot of work. Good luck!