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)
Related
I want to copy the content of one sheet at the end of the other, i have tried this vba code and it works,
Private Sub CommandButton1_Click()
Sheets("B").Select
Range("A1:H14").Select
Range("A1:H14").Copy
Sheets("A").Select
' Find the last row of data
Range("B48:I48").Select
ActiveSheet.Paste
Sheets("A").Select
End Sub
but what i want is to copy without having to specify the range of the data, because i have many files and many data and it's gonna be hard to do all of that manually and change the range a each time.
Below will copy entire content in Sheet B to Sheet A
Sheets("B").Cells.Copy Destination:=Sheets("A").Range("A1")
You do not need to select cells while copying.
There's no need to use so many Select, which slows down the code, you can use the 1 line below will copy the entire contents of Sheet("B") to the first empty row at Column "A" in Sheet("A").
Dim Rng As Range
Dim lRow As Long
Dim lCol As Long
Dim lPasteRow As Long
With Sheets("B")
lRow = .Cells.Find(What:="*", _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
lCol = .Cells.Find(What:="*", _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
lPasteRow = Sheets("A").Cells.Find(What:="*", _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
.Range(.Cells(1, 1), .Cells(lRow, lCol)).Copy Destination:=Sheets("A").Range("A" & lPasteRow + 1)
End With
I usually do something like this, assuming sheet1 is the sheet to be updated by data from sheet2;
dim destLen as Long 'rows used in sheet 1
dim sourceLen as Long 'rows used in sheet 2
Open directory with source files and loop through each file and do the following
destLen = Sheet1.Range("A"&Rows.Count).End(xlUp).Row
sourceLen = Sheet2.Range("A"&Rows.Count).End(xlUp).Row
Sheet2.Range("B1" & ":I" & sourceLen).copy
Sheet1.Range("A" & destLen + 1).pasteSpecial xlValues
Application.CutCopyMode = False
I am trying to select from A9 to the lastrow & lastcolumn.
I have this to select the last cell, but it doesn't select from A9 to Last it just selects the lastrow/lastcolumn. Also this is not ideal because if I have blanks in the future.
I have searched and could not find anything for selecting from a cell to the lastrow & lastcolumn
Sub FindLast()
Application.ScreenUpdating = False
Range("A9").End(xlToRight).End(xlDown).Select
Application.ScreenUpdating = True
End Sub
Search order in my file would be Column A & Row 8 if that helps at all.
Code Below is what I am using to work on active sheets
Sub SelectAll()
Application.ScreenUpdating = False
Dim lastRow As Long, lastCol As Long
Dim Rng As Range
Dim WholeRng As Range
With ActiveWorksheet
Set Rng = Cells
'last row
lastRow = Rng.Find(What:="*", After:=Rng.Cells(1), Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False).Row
'last column
lastCol = Rng.Find(What:="*", After:=Rng.Cells(1), Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False).Column
Set WholeRng = Range(Cells(9, "A"), Cells(lastRow, lastCol))
WholeRng.Select
End With
Application.ScreenUpdating = True
End Sub
Or you could exploit UsedRange
Sub FindLast()
With Activesheet
.Range(.Range("A9"), .UsedRange.Cells(.UsedRange.Rows.Count, .UsedRange.Columns.Count)).Select
End With
End Sub
The safest way is use the Find function:
Option Explicit
Sub LastRow_Col_Find()
' Safest way to ensure you got the last row:
Dim lastRow As Long, lastCol As Long
Dim Rng As Range
Dim WholeRng As Range
With Worksheets("report")
Set Rng = .Cells
' Safest way to ensure you got the last row
lastRow = Rng.Find(What:="*", After:=Rng.Cells(1), Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False).Row
'MsgBox lastRow ' <-- for DEBUG
' Safest way to ensure you got the last column
lastCol = Rng.Find(What:="*", After:=Rng.Cells(1), Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False).Column
'MsgBox lastColumn ' <-- for DEBUG
' set the Range for the entire UsedRange in "YourSheetName" sheet
Set WholeRng = .Range(.Cells(9, "A"), .Cells(lastRow, lastCol))
WholeRng.Select '<-- ONLY IF YOU MUST
End With
End Sub
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 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]