Dim mRange As Range
Columns("B:B").Select
i = 0
Set mRange = Range("B:B")
mRange.Find(What:="TRUE", After:=ActiveCell, LookIn:=xlValues, LookAt _
:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:= _
False).Activate
Rows(ActiveCell.Row).Select
Selection.Delete Shift:=xlUp
For i = 0 To 1
Columns("B:B").Select
Set mRange = Range("B:B")
mRange.Find(What:="TRUE", After:=ActiveCell, LookIn:=xlValues, LookAt _
:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:= _
False).Activate
Rows(ActiveCell.Row).Select
Selection.Delete Shift:=xlUp
Do While Not mRange Is Nothing
Set mRange = Range("B:B")
mRange.Select
mRange.Find(What:="TRUE", After:=ActiveCell, LookIn:=xlValues, LookAt _
:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:= _
False).Activate
Rows(ActiveCell.Row).Select
Selection.Delete Shift:=xlUp
Loop
Next i
The above code correctly deletes out the rows where a cell has the word "TRUE" in it, but receives this error when it can no longer find "TRUE". It does not jump out of the loop, but hangs at the final mRange.Find method. What have I done wrong? Thx.
"Run-time error 91, Object variable or With block variable not set"
As the comments suggest, get rid of .Select.
This code should be all that's needed.
Do
Dim sAdd as String
sAdd = vbNullString
Dim rFound as Range
Set rFound = Range("B:B").Find(What:="TRUE", After:=Cells(Rows.Count,Columns.Count), LookIn:=xlValues, LookAt _
:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:= _
False)
If Not rFound is Nothing Then
sAdd = rFound.Address
rFound.EntireRow.Delete Shift:=xlUp
End If
Loop Until sAdd = vbNullString
This will also work and may be faster if the rowset isn't extremely large.
Dim lRow as Long
lRow = Range("B" & Rows.Count).End(xlUp).Row
With Range("B1:B" & lRow)
.AutoFilter 1, TRUE
.Offset(1).SpecialCells(xlCellTypeVisible).EntireRow.Delete
.AutoFilter
End With
Application.ScreenUpdating = False
Dim rFound As Range
Dim mRange As Range
Set mRange = Range("B:B")
Do
Set rFound = mRange.Find(What:="TRUE", After:=ActiveCell, LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False)
If Not rFound Is Nothing Then rFound.EntireRow.Delete
Loop Until rFound Is Nothing
Application.ScreenUpdating = True
Related
I want to create a range from a cell containing, for example, the word "alex" to lastrow, in the first column.
Let's call this cell-alex.
The idea is to make:
range(cell-alex, cells(lastrow, 1)).
I know how to get lastrow, but not cell-alex. Excel always selects the range from A1 to the lastrow.
Cells.Find(What:="alex", after:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True _
, SearchFormat:=True).Select
Set sht = Worksheets(sheetbr)
lastrow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
Range(ActiveCell, Cells(lastrow, 13)).Select
if you know for sure that "Alex" is in column 1, then use this:
With Worksheets(sheetbr)
.Range(.Columns(1).Find(What:="alex", after:=.Cells(.Rows.Count, 1), LookIn:=xlFormulas, LookAt:=xlPart, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True, _
SearchFormat:=True), _
.Cells(.Rows.Count, "A").End(xlUp)).Select
End With
otherwise use this:
Dim f As Range
With Worksheets(sheetbr)
Set f = .Columns(1).Find(What:="alex", after:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True _
, SearchFormat:=True)
If Not f Is Nothing Then .Range(f, .Cells(.Rows.Count, "A").End(xlUp)).Select
End With
I think the problem is LookIn:=xlFormulas. Try changing to LookIn:=xlValues
All right, I have figured out this.
I did not tell you everything.
I start my code with importing another document.
While I was working on my code, the moment you mention ActiveCell it starts working with the other book.
I resolved it by copying data from my imported spreadsheet to the original (book1).
The rest was easy. Here it goes:
Set sht = ThisWorkbook.Worksheets(1)
lastrow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row 'to find the lastRow
Cells.Find(What:="GuV 7", after:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=True).Activate
Range(ActiveCell, Cells(lastrow, 13)).Select 'I need columns 1-13
Once again, thanks guys.
I have a worksheet that has a header row, and I want to group the rows using VBA. I have attempted this syntax
Sub GroupItTogether()
Dim rLastCell As Range
Set rLastCell = ActiveSheet.Cells.Find(What:="*", After:=.Cells(1, 1), _
LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False)
Range("A2" & rLastCell).Select
Selection.Rows.Group
ActiveSheet.Outline.ShowLevels RowLevels:=1
End Sub
However, this will produce an error of:
Invalid or unqualified reference
Highlighting the line of code: After:=.Cells(1, 1)
What must I do to group all rows (sans the header) with VBA?
EDIT
Per comments, I edited my syntax to the below, which removes the error but this does not group all rows (excluding header). How should this be updated to group by the used range?
Sub GroupItTogether()
Dim rLastCell As Range
Set rLastCell = ActiveSheet.Cells.Find(What:="*", After:=Cells(1, 1), _
LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False)
Range("A2" & rLastCell).Select
Selection.Rows.Group
ActiveSheet.Outline.ShowLevels RowLevels:=1
End Sub
You don't need to use Select and Selection. Once you find the Range for rLastCell , you can read the last row property from your range with rLastCell.Row, and then just group them.
Option Explicit
Sub GroupItTogether()
Dim rLastCell As Range
Set rLastCell = ActiveSheet.Cells.Find(What:="*", After:=Cells(1, 1), _
LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False)
Range("A2:A" & rLastCell.Row).Rows.Group
ActiveSheet.Outline.ShowLevels RowLevels:=1
End Sub
Note: you can get the last row that has data in Column A with :
lastrow = Cells(Rows.Count, "A").End(xlUp).Row
(no need to use the .Find method)
Would it be possible to use the find method to search for back-up options?
Here's my code right now:
Set foundCell = Cells.Find(What:="RCP 1", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False)
If Not foundCell Is Nothing Then
foundCell.Activate
foundCell.Rows("1:1").EntireRow.Select
Selection.Copy
Range("A" & (PLcount + 8)).Select
ActiveSheet.Paste
Else
Set foundCell = Cells.Find(What:="RCP- 1", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False)
If Not foundCell Is Nothing Then
foundCell.Activate
foundCell.Rows("1:1").EntireRow.Select
Selection.Copy
Range("A" & (PLcount + 8)).Select
ActiveSheet.Paste
End If
End If
I would like to be able to do something like below. Note the text after .Find(What:=)
Set foundCell = Cells.Find(What:="RCP 1" "RCP- 1" "RCP 1", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False)
If Not foundCell Is Nothing Then
foundCell.Activate
foundCell.Rows("1:1").EntireRow.Select
Selection.Copy
Range("A" & (PLcount + 8)).Select
ActiveSheet.Paste
End If
Where the first term is the first priority, the second term is the second priority, the third term is the third priority, etc.
EDIT - there is only limited support for wildcards in Find() - you would probably not class it as "regex-level" functionality:
* - zero or more characters
? - single character
~ - escapes * or ? if you want to find those literal characters
Alternatively can put the Find into a separate function:
Sub Tester()
Dim foundCell, PLCount As Long
PLCount = 3
Set foundCell = FindFirst(Cells, Array("RCP 1", "RCP- 1"))
If Not foundCell Is Nothing Then
'no need for any select/activate
foundCell.EntireRow.Copy Destination:=Range("A" & (PLCount + 8))
End If
End Sub
'return the first match to a value in the array "arrWhat"
' Returns Nothing if no match
Function FindFirst(rngWhere, arrWhat) As Range
Dim v, f As Range
For Each v In arrWhat
Set f = rngWhere.Find(what:=v, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not f Is Nothing Then Exit For
Next v
Set FindFirst = f
End Function
I have a spreadsheet with a varying number of rows in it. At the bottom of the useful information on the spreadsheet is a row called "Terminations", followed by a varying number of rows none of which I'm interested in.
How can I write a VBA script to search for "Terminations" and delete ALL rows after it?
I can search for "Terminations" like so:
Cells.Find(What:="Terminations", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
And I can delete rows like so:
Rows("245:246").Select
Selection.Delete Shift:=xlUp
However, my attempts thus far to combine these two has been fruitless.
Try this one:
Sub test()
Dim rng As Range
Dim lastRow As Long
'change Sheet1 to suit
With ThisWorkbook.Sheets("Sheet1")
'find Terminations
Set rng = .Cells.Find(What:="Terminations", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False)
'if Terminations NOT found - exit from sub
If rng Is Nothing Then Exit Sub
'find last row
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lastRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lastRow = 1
End If
'I use lastRow + 1 to prevent deletion "Terminations" when it is on lastrow
.Range(rng.Row + 1 & ":" & lastRow + 1).Delete Shift:=xlUp
End With
End Sub
How to determine lastRow from here
I'd like to delete all columns in a worksheet which meet the following criteria:
row 1 = "foobar"
rows 2-1000 are empty
It sounds simple enough but I haven't managed to get it working fully. Any help would be massively appreciated.
Thanks!
Fastest way to delete rows as per your requirement.
I am assuming that Row1 Has Column Headers
Option Explicit
Sub Sample()
Dim aCell As Range, rng As Range
Dim LastCol As Long, LastRow As Long, i As Long
With Sheets("Sheet1")
Set aCell = .Rows(2).Find(What:="foobar", LookIn:=xlValues, _
Lookat:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not aCell Is Nothing Then .Rows(2).Delete
LastRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
LastCol = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
Set rng = Range("A1:" & Split(Cells(, LastCol).Address, "$")(1) _
& LastRow)
ActiveSheet.AutoFilterMode = False
For i = 1 To LastCol
rng.AutoFilter Field:=i, Criteria1:=""
Next i
rng.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
ActiveSheet.AutoFilterMode = False
End With
End Sub
How about
dim col as Long, lastCol as Long, r as range
lastCol = ActiveSheet.Usedrange.columns(Activesheet.Usedrange.columns.count).column
for c=lastCol to 1 Step -1
set r = Range(Cells(1, c), Cells(1000, c))
if r.Rows(1) = "foobar" Then
if WorksheetFunction.CountA(Range(r.Rows(2), r.Rows(r.Rows.Count))) = 0 then
Columns(c).delete
end if
end If
next
[edit by OP: added a missing space]