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
Related
Looking for a solution to probably a very simple problem but somehow I can not seem to find an answer.
I am looking for a way to copy the first cell of each column. I want to use the copied value to filter it in another workbook. I want to paste the filtered cells below and then repeat the process until all columns have been gone through.
Thus what kind of loop would I use to copy every first cell at a time, store it, then do something with it and then copy the next first cell of a column for all columns?
Could someone please me with this? Your help is much appreciated.
For i = 1 To 207
Columns(i).Select
ActiveCell.Offset(0, 0).Range("A1").Select
Selection.Copy
'How do I store the copied value to use it in an autofilter?
Next i
End Sub
Instead of selecting – and you should avoid using select –
You can set the value to a variable varname = Cells(1,i) for later use,
or better yet, apply directly to your filter.
Dim i As Long
Dim wb2 As Workbook
Set wb2 = Workbooks("Book2") 'the "Other" workbook name here
For i = 1 To wb2.Worksheets.Count 'looping each sheet
wb2.Worksheets(i).Range("A1").AutoFilter Field:=1, Criteria1:= _
ThisWorkbook.Sheets(1).Cells(1, i)
Next i
This is just an example which makes a lot of assumptions that more than likely does not fit with your reality, these has to be changed to fit your scenario, ofc.
But it would go through the specified amount of worksheets in the specified workbook, and filter the first column with the value obtained from the first workbook.
Then, there are quite a few questions on how to copy a filtered range that might give a hint.
I'll start by saying I have no idea if I'm even asking this question correctly...encouraging, huh?
I have an Excel spreadsheet, the first row of which are column headers with the autofilters activated. What I am trying to do is create a loop in VBA where the first individual criterion from the autofilter field:=2 is "checked" and the filtered data gets displayed; then "unchecked" and is undisplayed; and then the next below criterion in the filter box is "checked" and the filtered data gets displayed; then "unchecked" and undisplayed, and so on.
I do have other intentions on what to do with the data when it is displayed after the criteria is "checked" in the filter box, but I'm confident I can figure out the coding for those actions separately.
What I'm trying, or rather hoping, to avoid is creating a separate comma separated value range for what would be a massive array, since there are a lot of criterion in autofilter field:=2, and the those criteria in the autofilter field:=2 will occasionally change. Maybe that's possible, maybe it isn't.
Any help or guidance is greatly appreciated!
UPDATE - I figured that it may be simpler to filter the unique values in column B and then paste those values in a distant spot, column S, on the worksheet. Then I recorded a basic filter macro and changed criteria1:= to cells(uic,19), the values in column S and created a do while loop to run the filter on the criteria in column S adding +1 before each loop.
The code is below -
Sub filter_example()
Dim lastrowuic, lastrowarray As Long
lastrowuic = Cells(Rows.Count, "B").End(xlUp).Row
lastrowarray = Cells(Rows.Count, "S").End(xlUp).Row
Dim uniquesArray As Variant
uniquesArray = Range("B2:B" & lastrowuic)
Dim uic As Integer
uic = 2
With Sheet1
Sheets("Sheet1").Columns("B:B").AdvancedFilter Action:=xlFilterCopy, _
CopyToRange:=.Range("S1"), Unique:=True
End With
Do While lastrowarray
ActiveSheet.Range("$A$1:$S$21").AutoFilter=2,Criteria1:=Cells(uic, 19)
ClearAllFilters = True
uic = uic + 1
Loop
End Sub
The two areas that could afford cleaning up are the activesheet.range and really the end. This loop does do what I want, but I would like it to exit the loop once it gets to the first blank row, following the last row of data, in column "S" (aka 19) and then clear the filter in autofilter=2. That's really it. Otherwise this is doing what I want it to do.
Any additional assistance is appreciated!
Hoping you can help an basic excel user please!
I have a file of around 2000 rows and I need to add a line/break after every third one. Is there a simple way of doing this please?
Your help and advice would be much appreciated.
Thanks
Quick way without VBA
In a empty column add this formula, =IF(MOD(ROW(),3)=0,NA(),"") and copy down
Press F5, Goto .... Special, Formulas Errors (selects every third row)
Insert Rows
step 2 shown below
If you want to try some VBA here is a button click event that will do the insert on every third row. Let me know if you have any questions.
Private Sub CommandButton1_Click()
Dim ws As Excel.Worksheet
Dim lRow As Long
Dim lastRow As Long
'Set the worksheet object to the sheet by name
Set ws = Application.Sheets("Sheet1")
'Set the row to start looping(inserting) rows at
lRow = 4
'Find the last row with a value in column A
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
'Account for the amount of rows that will be inserted.
lastRow = lastRow + (lastRow * 0.33)
'Loop through the worksheet from the start row to the last row
Do While lRow <= lastRow
'Insert a row
ws.Rows(lRow).EntireRow.Insert
'Increment the row to insert at on the next pass of the loop
lRow = lRow + 4
Loop
End Sub
a non vba way is create a new column and insert numbering
1
2
3
4
5
6
......
then for empty row, number as 3,6,9,.... (let say u have 2k records, duplicate it 2k)
then sort by the number column, then remove the column
If your content is the same, or repeating, for each row, you could open the file in any basic text editor and do the following:
Highlight and copy the first three rows (including the third line break).
Using find-and-replace (Opt-Cmd-F in TextEdit on Macs), copy that content into the 'find' field as well as the 'replace' field.
Add a line break at the end of the content you pasted in the 'replace' field.
Execute the find-and-replace action.
This should turn something like this:
item
item
item
item
item
item
item
...into this:
item
item
item
item
item
item
item
...and so on.
This definitely isn't the most elegant solution, but is one of the quickest/simplest I've seen without resorting to a text parsing script in bash, etc.
Assuming data starts in A1, in B1 and copied down to suit (i.e. past the end of the cells populated in ColumnA):
=IF(MOD(ROW(),4)=0,"",OFFSET(A$1,3*INT((ROW()-1)/4)+MOD(ROW(),4)-1,))
Here is a VBA equivalent to the solution proposed by Eric K. above. The orientation assumes column header labels in row 1 that should be left alone.
Sub insBlankFourthRow()
Debug.Print Timer
With Worksheets("Sheet3")
.Columns(1).Insert
With .Cells(1, 1).CurrentRegion '<~~ original CurrentRegion
With .Resize(.Rows.Count - 1, 1).Offset(1, 0)
.Cells(1, 1) = 1
.Cells.DataSeries Rowcol:=xlColumns, Type:=xlLinear, Step:=1
End With
With .Resize(Int(.Rows.Count / 3) + 1, 1).Offset(.Rows.Count, 0)
.Cells(1, 1) = 3.5
.Cells.DataSeries Rowcol:=xlColumns, Type:=xlLinear, Step:=3
End With
End With
'
With .Cells(1, 1).CurrentRegion '<~~ new expanded CurrentRegion
.Cells.Sort Key1:=.Columns(1), Order1:=xlAscending, _
Orientation:=xlTopToBottom, Header:=xlYes
End With
.Columns(1).Delete
End With
Debug.Print Timer
End Sub
tbh, ~2000 rows of data isn't that much to be worried about but 10× or 100× that amount of data will start to lag significantly when inserting rows individually or in a bulk non-contiguous orientation. A 'helper' column populated with a Range.DataSeries method (fastest way I know of populating a sequence) can be readily discarded once its purpose has been fulfilled.
Running the above against 2500 rows of random data typical of the image took ⁸⁄₁₀₀ of a second. That time might be moderately improved with disabling the Application.ScreenUpdating property and similar overhead.
I need to read the data from an Excel spreadsheet like so using Visual Basic.
v|123|t
t|123|t
g|123|t
I want to read the first column of the spreadsheet and check if it is a V or not. I'm looking to build a script that will delete everything that is not a V, but I am stuck on this.
A quick method using AutoFilter. This filters out anything from the first column that isn't "v" then deletes it and removes the filter.
Sub vFilter()
With ActiveSheet
.AutoFilterMode = False
With Range("A1", Range("A" & Rows.Count).End(xlUp))
.AutoFilter 1, "<>v"
On Error Resume Next
.EntireRow.Delete
End With
.AutoFilterMode = False
End With
End Sub
Autofilter is very useful when working with data in tables.
You can select a range of cells (ie the whole table), then click the Filter button found on the Excel Ribbon>Data>Sort&Filter.
This will add drop down lists to each of the top cells in your selection.
You can use these to reduce the list to only show those with a V in the first column.
You can then select all the rows and delete them.
This what the VBA code posted by KFichter is doing.
If you need to just do it once, use autofilters manually.
Harvey
I have this piece of code which finds the excel row of an item from a list and deletes the items from a list. What I want... is to delete the Excel row as well.
The code is here
Private Sub imperecheaza_Click()
Dim ws As Worksheet
Dim Rand As Long
Set ws = Worksheets("BD_IR")
Rand = 3
Do While ws.Cells(Rand, 4).Value <> "" And Rand < 65000
If ws.Cells(Rand, 4).Value = gksluri.Value * 1 And ws.Cells(Rand, 5).Value = gksluri.List(gksluri.ListIndex, 1) * 1 Then
ws.Range(Rand, 1).EntireRow.Delete '(here I want to delete the entire row that meets the criteria from the If statement)
gksluri.RemoveItem gksluri.ListIndex
Exit Do
End If
Rand = Rand + 1
Loop
End Sub
Where I added ws.Range(Rand,1).EntireRow.Delete is where I want to delete the entire row but I don't know how to do it. What I want... if it finds the same value in a cell like in some selected item of my list to be able to remove both the entire row in excel and the item from the listbox. It works to remove the item from the listbox but I don't know how to remove the row as well
Chris Nielsen's solution is simple and will work well. A slightly shorter option would be...
ws.Rows(Rand).Delete
...note there is no need to specify a Shift when deleting a row as, by definition, it's not possible to shift left
Incidentally, my preferred method for deleting rows is to use...
ws.Rows(Rand) = ""
...in the initial loop. I then use a Sort function to push these rows to the bottom of the data. The main reason for this is because deleting single rows can be a very slow procedure (if you are deleting >100). It also ensures nothing gets missed as per Robert Ilbrink's comment
You can learn the code for sorting by recording a macro and reducing the code as demonstrated in this expert Excel video. I have a suspicion that the neatest method (Range("A1:Z10").Sort Key1:=Range("A1"), Order1:=xlSortAscending/Descending, Header:=xlYes/No) can only be discovered on pre-2007 versions of Excel...but you can always reduce the 2007/2010 equivalent code
Couple more points...if your list is not already sorted by a column and you wish to retain the order, you can stick the row number 'Rand' in a spare column to the right of each row as you loop through. You would then sort by that comment and eliminate it
If your data rows contain formatting, you may wish to find the end of the new data range and delete the rows that you cleared earlier. That's to keep the file size down. Note that a single large delete at the end of the procedure will not impair your code's performance in the same way that deleting single rows does
Change your line
ws.Range(Rand, 1).EntireRow.Delete
to
ws.Cells(Rand, 1).EntireRow.Delete
Better yet, use union to grab all the rows you want to delete, then delete them all at once. The rows need not be continuous.
dim rng as range
dim rDel as range
for each rng in {the range you're searching}
if {Conditions to be met} = true then
if not rDel is nothing then
set rDel = union(rng,rDel)
else
set rDel = rng
end if
end if
next
rDel.entirerow.delete
That way you don't have to worry about sorting or things being at the bottom.
Something like this will do it:
Rows("12:12").Select
Selection.Delete
So in your code it would look like something like this:
Rows(CStr(rand) & ":" & CStr(rand)).Select
Selection.Delete