Delete blank rows using Macro, after Row x - excel

I've found this Macro on another post:
Sub DelBlankRows()
Columns("A:A").Select
Selection.SpecialCells(xlCellTypeBlanks).Select
Selection.EntireRow.Delete
End Sub
Can this be modified so that it only deletes rows after row x (row 14 on the spreadsheet that I'm currently working on)?
Thanks!

this is fairly straightforward.
Rows(x & ":" & y).EntireRow.Delete
Just swap x and y for the rows you want.
As an aside, it is best to avoid selecting ranges unnecessarily as it only slows things down. Any time you select a range then do something with the selection, you can just perform that action directly on the range instead.
EDIT: Just re-read the question - so try this one:
Range("A14:A" & Cells.SpecialCells(xlCellTypeLastCell).Row).SpecialCells(xlCellTypeBlanks).EntireRow.Delete

Related

Ignore Blank Cells in VBA [duplicate]

This question already has answers here:
Copy Non Blank Cells From Range to Range
(2 answers)
Closed 2 years ago.
I am having difficulty having this macro copy and paste only the cells that have data in them. I would like the macro to only select and copy the cells in the columns that have data, ignore the empty cells. what I currently have is this
Sub testest()
Sheet4.Activate
'Dim lrow As Long
'lrow = Sheet4.Range("A", Rows.Count).End(xlUp).Row
Sheet4.Range("A2:A40").Select
Selection.Copy
Sheet5.Activate
Sheet5.Range("A2").PasteSpecial
Sheet4.Activate
Sheet4.Range("B2:B40").Select
Selection.Copy
Sheet5.Activate
Sheet5.Range("B2").PasteSpecial
End Sub
If you want them to paste only the cells with data by shifting the other cells up to fill in the blank ones, you should try the following commands after you select your desired copy range:
Selection.SpecialCells(xlCellTypeBlanks).Select
Selection.Delete Shift:=xlUp
This logic mirrors going to "Find and Select" > "Blanks" > "Delete"
This is not an answer to your question, merely a way to show you how to reduce your code, by eliminating the obsolete activation and selection actions:
Sub testest()
Sheet4.Range("A2:A40").Copy
Sheet5.Range("A2").PasteSpecial
Sheet4.Range("B2:B40").Copy
Sheet5.Range("B2").PasteSpecial
End Sub
In fact, why don't you simply do this:
Sheet4.Range("A2:B40").Copy
Sheet5.Range("A2").PasteSpecial
(Ranges can go over different columns)
There are ways to avoid the usage of the clipboard, but then the complexity of the macro increases, which, I believe, is not what you're looking for.
Similar to the answer by #Dominique, but addressing the empty cells and assuming you gave up on the last row method:
Sub testest()
Dim lrow As Long
lrow = Sheet4.Range("A", Rows.Count).End(xlUp).Row
Sheet4.Range("A2:A" & lrow).SpecialCells(xlCellTypeVisible).Copy
Sheet5.Range("A2").PasteSpecial
Sheet4.Range("B2:B" & lrow).SpecialCells(xlCellTypeVisible).Copy
Sheet5.Range("B2").PasteSpecial
End Sub

Trying to Remove Duplicates based on first column

I am currently trying to remove rows from column A to column V based on duplicates found in column A.
my current formula is:
Workbooks(TgtWB).ActiveSheet.Range("A15:V500").RemoveDuplicates _
Columns:=Array(1), Header:=xlYes
My header is located on row 15.
the error i am getting is
Application-defined or object-defined error
I have tried switching ActiveSheet with worksheet("xxx") but still doesn't seem to work either. i'm not sure what i'm doing wrong here.
Try (note worksheetS, not worksheet),
Workbooks(TgtWB).worksheetS("xxx").Range("A15:V500").RemoveDuplicates Columns:=1, Header:=xlYes
'or,
ActiveSheet.Range("A15:V500").RemoveDuplicates Columns:=1, Header:=xlYes
If TgtWB is open, it may or may not contain the ActiveSheet. Each open workbook does not have an ActiveSheet. There is only one ActiveSheet for the application instance. ActiveSheet is not a property of the Workbooks collection.
Using built in functionality is great, unless you're a beginner like myself and the .Applications and .Worksheets get overwhelming and confusing. For a small data set, such as columns A through V (depending obviously on how many rows you have), a loop and if-statement not only can work well, but can be good practice as well! Something like this may work well:
Dim CurrentValue, LastValue As Variant
LastValue = ""
For I = 1 To 500
CurrentValue = Sheets("Sheet 1").Range("A" & i).Value
If CurrentValue = LastValue Then
Sheets("Sheet 1").Range("A" & i & ":V" & i).Clear Contents
Else
LastValue = CurrentValue
End If
Next i
This will loop through every row, ask if the current value in the cell is the same as the one previously observed (except the first one, the first one will automatically be saved by nature), and if it has been, it will clear the contents of the row. If it's not the same, it will assign it to the new variable and begin looking for new ones.
There are two drawbacks with this method that can be solved by simply adapting the code to your needs:
Non-Sequential Items: If the values that are duplicates are not sequential, the code won't kick them out. At that point I recommend using an application code or a dictionary. Dictionaries are infinitely useful for storing unique data entries and skipping duplicates.
Deleting Rows: When you delete rows in a loop it messes up your loop, throwing off the order of your incrementer. The best way to combat this is by first clearing the columns then having your code loop for empty rows and delete them outside of your loop.
This is very basic but something I've found greatly helpful as a beginner and hopefully other beginners and yourself can learn something from it.
Happy Coding!

Performance of deleting many rows from an autofilter in VBA

I would like to know if there is a faster way do this than the code I am using. I got the code using xlUp from the recorder.
rCnt = Cells(Rows.Count, "B").End(xlUp).Row
ActiveSheet.Range("$B$1:$J" & rCnt).AutoFilter Field:=5, _
Criteria1:=Application.Transpose(arrCodes), Operator:=xlFilterValues
Rows("2:" & rCnt).Delete Shift:=xlUp
And actually, if there was some way to flip the filter, I wouldn't need to delete at all as this is a temporary table that I copy from. However, all my research has failed to find a way to do
Criteria1:=Application.Transpose(<>arrCodes)
and arrCodes has too many elements to list in the filter. And the stuff that is not in arrCodes is way too numerous to make an array from. Thanks.
If you want to just use Excel UI and not formulas or VBA, you can do the following simple steps to get an "inverse" filter. This could then be ported to VBA if needed:
Apply the filter with the opposite conditions
Color those cells in one column (either font or background)
Clear the filter
Filter again but this time by cells in that column without color
Copy those results where you want them
This will not work well if the column already has some background colors. If that is the case, you can add a new column and color it. If this is in VBA, you could automate those steps. There are limits, but this is quick and simple if it applies.
I've had success in the past with building then deleting a range. You can combine ranges with Union(). I've attached a bit of example code, it's not wonderful but it shows the basic concept. This example deletes rows with odd numbers in column A in rows 2 through 11.
Public Sub DeleteRows()
Dim deleteThis As Range
For i = 2 To 11
If Sheet1.Cells(i, 1).Value Mod 2 = 1 Then
If deleteThis Is Nothing Then
Set deleteThis = Sheet1.Rows(i)
Else
Set deleteThis = Union(deleteThis, Sheet1.Rows(i))
End If
End If
Next i
deleteThis.Delete xlShiftUp
End Sub

Excel Macro cut and paste cells with loop

I'm working with lots of data from a clinical study at the moment. For an analysis in SAS I have to change the the arrangement of the data that is stored in an excel table. This means hours of copy and paste if I'd do it manually, so I tried to write a macro. I spent hours on trying to figure out the code, I came up with a draft, of course it doesn't work since I don't have any backgrounds in VBA, so NO deeper understanding of the syntax. Although the problem is REALLY simple. Here's what I want to do (sry, just a link...since I can't post pictures yet)
http://s7.directupload.net/images/140611/b96dhime.png
First the red arrow: cut the value from the top cell in column mmp1_v1 and paste it to the first cell of column mmp1.
Then the blue one: cut the value from the top cell in column mmp1_v2 and paste it to the second cell from the top in column mmp1.
Same thing with the next red and blue arrow. I have 194 rows in every column, 97 with values, 97 empty ones, so the process should be done within a loop, 97 times. All this for a total of 29 columns.
The code I came up with - which obviously doesn't work - looks like this:
Sub cut_paste()
Dim nr As Integer
For nr = 1 to 195
Range("J&nr&").Select
Selection.Cut
Range("I&nr&").Select
ActiveSheet.Paste
Range("K&nr&").Select
Selection.Cut
nr = nr + 1
Range("I&nr&").Select
ActiveSheet.Paste
Next nr
End Sub
I wanted it to do like in Java kind of. I know...not the same language, but I just thought about defining a count variable called 'nr' and insert it into the string that stands for the range. But I don't understand the error messages, and this is definitely not the only problem. Sry for the missing proper terms...English isn't my mother tongue. I'd be SO glad if someone could try to write an example that kind of works the way I imagined. If you could even follow what I wanted to have.
What I still had to do then would be altering the names of the ranges. Since there are another 29 columns that have to be processed in the same way. But still better than just copy and paste all of this manually I think...
Thanks a lot in advance!
You have to handle strings differently in vba. You also need to lose the nr = nr + 1, as the next will increment it. See code below:
Sub cut_paste()
Dim nr As Integer
For nr = 1 to 195
Range("J" & nr).Select
Selection.Cut
Range("I" & nr).Select
ActiveSheet.Paste
Range("K" & nr).Select
Selection.Cut
Range("I" & nr).Select
ActiveSheet.Paste
Next nr
End Sub

Delete entire row if cell contains the string X

I am trying to come up with a way to delete all rows (and shift cells up, if possible) where the website column cell contains the word none. The table contains 5000+ records and this would save me a great amount of time.
I appreciate any suggestions.
This is not necessarily a VBA task - This specific task is easiest sollowed with Auto filter.
1.Insert Auto filter (In Excel 2010 click on home-> (Editing) Sort & Filter -> Filter)
2. Filter on the 'Websites' column
3. Mark the 'none' and delete them
4. Clear filter
Ok I know this for VBA but if you need to do this for a once off bulk delete you can use the following Excel functionality: http://blog.contextures.com/archives/2010/06/21/fast-way-to-find-and-delete-excel-rows/ Hope this helps anyone
Example looking for the string "paper":
In the Find and Replace dialog box, type "paper" in the Find What box.
Click Find All, to see a list of cells with "paper"
Select an item in the list, and press Ctrl+A, to select the entire list, and to select all the "paper" cells on the worksheet.
On the Ribbon's Home tab, click Delete, and then click Delete Sheet Rows.
In the "Developer Tab" go to "Visual Basic" and create a Module. Copy paste the following. Remember changing the code, depending on what you want. Then run the module.
Sub sbDelete_Rows_IF_Cell_Contains_String_Text_Value()
Dim lRow As Long
Dim iCntr As Long
lRow = 390
For iCntr = lRow To 1 Step -1
If Cells(iCntr, 5).Value = "none" Then
Rows(iCntr).Delete
End If
Next
End Sub
lRow : Put the number of the rows that the current file has.
The number "5" in the "If" is for the fifth (E) column
I'd like to add to #MBK's answer. Although I found #MBK's answer to be very helpful in solving a similar problem, it'd be better if #MBK included a screenshot of how to filter a particular column.
This was alluded to in another comment, but you could try something like this.
Sub FilterAndDelete()
Application.DisplayAlerts = False
With Sheet1 'Change this to your sheet name
.AutoFilterMode = False
.Range("A3:K3").AutoFilter
.Range("A3:K3").AutoFilter Field:=5, Criteria1:="none"
.UsedRange.Offset(1, 0).Resize(ActiveSheet.UsedRange.Rows.Count - 1).Rows.Delete
End With
Application.DisplayAlerts = True
End Sub
I haven't tested this and it is from memory, so it may require some tweaking but it should get the job done without looping through thousands of rows. You'll need to remove the 11-Jul so that UsedRange is correct or change the offset to 2 rows instead of 1 in the .Offset(1,0).
Generally, before I do .Delete I will run the macro with .Select instead of the Delete that way I can be sure the correct range will be deleted, that may be worth doing to check to ensure the appropriate range is being deleted.
Try this ...
Dim r as Range
Dim x as Integer
For x = 5000 to 4 step -1 '---> or change as you want //Thanx 4 KazJaw
set r = range("E" & format(x))
if ucase(r.Value) = "NONE" then
Rows(x).EntireRow.Delete
end if
Next
Delete rows 1 and 2 so that your headings are on row 1
Put this in a macro (IT WILL CHECK THROUGH ROW 75000, YOU CAN LOWER THE NUMBER IF YOU WOULD LIKE
Columns("E:E").Select
Selection.AutoFilter
ActiveSheet.Range("$E$1:$E$75000").AutoFilter Field:=1, Criteria1:="none"
Range("E2:E75000").SpecialCells(xlCellTypeVisible).Select
Selection.EntireRow.Delete
ActiveSheet.Cells.EntireRow.Hidden = False
ActiveSheet.Range("$E$1:$E$75000").AutoFilter Field:=1
Columns("E:E").Select
Selection.AutoFilter
Range("E2").Select
Range("A1").Select

Resources