I have a table that ranges from "A:EV".
I want to find the last row of only range "A:DD".
The columns might have blank cells, so I need to go through all and find the furthest row of columns A to DD.
How can I code it?
Modified from HERE
Sub foo()
With Sheets("Sheet9") 'Change to your sheet
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lastrow = .Range("A:DD").Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
'Used 1000 to prove that it was not defaulting to this.
'Change to 1 when using in actual code.
lastrow = 1000 'Change to 1 when using.
End If
MsgBox lastrow
End With
End Sub
And to adjust the range a bit, change the two column letters in these two lines.
This one searches over columns A:DD.
lastrow = .Range("A:DD").Find(What:="*", _
After:=.Range("A1"), _
This version narrows the search range to Y:DD
lastrow = .Range("Y:DD").Find(What:="*", _
After:=.Range("Y1"), _
And with a little voodoo, if you are interested in also getting the column where the last row was found but don't want to extract it from .Address, use this.
sub voodoo()
Dim theresult As Variant
With Sheets("Sheet9") 'Change to your sheet
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
Set theresult = .Range("Y:DD").Find(What:="*", _
After:=.Range("Y1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False)
Else
'Used 1000 to prove that it was not defaulting to this.
'Change to 1 when using in actual code.
lastrow = 1000 'Change to 1 when using.
End If
MsgBox ("LastRow " & theresult.Row & " column " & theresult.Column)
End With
End Sub
Related
I need to find the last cell that contains data in a row that has blank cells. I have tried:
Dim rowCell as Integer
rowCell = Cells.Find(what:="*", _
after:=Range("A1"), _
lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
matchCase:=False).Column
Debug.Print rowCell
But it returns "5" and the columns go up to HE, which is supposed to be Column 213. How can I get it to return a value for one row?
EDIT:
I was able to get this to work on one row with 158 columns, but when I try it on the line below it, by incrementing the after:=Range("A2"), it gives me 6. It's supposed to be 213. Line 58 goes up to FB, which is supposed to be 158, but the script reports 213.
Figured it out.
Dim rowCell as Integer
For i = 5 To 54
With ActiveSheet
If .Rows(i).EntireRow.Hidden Then
Else
.Rows(i).Select
rowCell = ActiveSheet.Rows(i).Find(what:="*", _
lookat:=xlPart, _
LookIn:=xlFormulas, _
searchorder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
Debug.Print "Row " & i; " Column " & rowCell
End If
End With
Next i
Print Last Columns Using the Find Method
Option Explicit
Sub PrintLastColumns()
Dim LastCell As Range
Dim LastColumn As Long
Dim i As Long
For i = 5 To 54
With ActiveSheet.Rows(i)
' Not needed in the Find method (in this case):
' After - refers to the first cell by default.
' LookAt - 'xlWhole' or 'xlPart' is not relevant
' since you search for anything ('*').
' SearchOrder - not relevant when in one row or one column.
' MatchCase - 'False' by default; not relevant ('*').
'Set LastCell = .Find(What:="*", LookIn:=xlFormulas, _
SearchDirection:=xlPrevious)
' or simply:
Set LastCell = .Find("*", , xlFormulas, , , xlPrevious)
End With
If LastCell Is Nothing Then ' no last cell hence no last column
Debug.Print "Row " & i & " is empty."
Else
LastColumn = LastCell.Column
Debug.Print "Row: " & i, "Last Column: " & LastColumn, _
"Last Cell Address: " & LastCell.Address(0, 0)
End If
Next i
End Sub
I am attempting to have a macro insert a column on sheet "Runs", and then paste information from sheet "Templates" onto the newly inserted column on a specific Row. I have named the range for row four as "Eight", however, info from templates is pasted onto column A, Row 4, and not the newly inserted column.
Set myWorksheet = Worksheets("Runs")
myFirstColumnT = myWorksheet.Cells.Find( _
What:="TS", _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious).Column
myLastColumnT = myWorksheet.Cells.Find( _
What:="TE", _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious).Column
For iCounter = myLastColumnT To (myFirstColumnT + 1) Step -100000000
myWorksheet.Columns(iCounter).Insert
Sheets("Templates").Select
Range("B2:B16").Copy
Sheets("Runs").Select
With Columns(iCounter).Select
Range("eight").PasteSpecial
End With
Next iCounter
The issue is your With doesn't actually do anything and if it did your Range doesn't reference it.
I've removed your loop, it has such a massive step it isn't actually looping anything. Also you don't need a loop for this.
I removed the .column from your .finds because that will cause an error if it fails, I also added in some error checking for if (when) it doesn't find anything.
I removed all instances of .Select because they aren't necessary.
Dim myworksheet As Worksheet
Dim myfirstcolumnt As Range
Dim mylastcolumnt As Range
Dim newcol As Long
Set myworksheet = Worksheets("Runs")
'I'm assuming you need this for a reason other than the loop, otherwise you can remove it
Set myfirstcolumnt = myworksheet.Cells.Find( _
What:="TS", _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious)
If myfirstcolumnt Is Nothing Then
MsgBox "TS not found"
Exit Sub
End If
Set mylastcolumnt = myworksheet.Cells.Find( _
What:="TE", _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious)
If mylastcolumnt Is Nothing Then 'Avoiding errors
MsgBox "TE not found"
Exit Sub
End If
newcol = mylastcolumnt.Column + 1 'No need to loop to find the column you're making
myworksheet.Columns(newcol).Insert 'use the new column index to add the column
Sheets("Templates").Range("b2:b16").Copy
myworksheet.Cells(4, newcol).PasteSpecial 'We know it's going in row 4 and we have the new column index now
If you want to use your named range you can do myworksheet.Cells(myworksheet.range("Eight").Row, newcol)... Though I suggest changing the name, a range called "Eight" pointing to Row 4 isn't very clear.
Trying to copy data from one Excel spreadsheet to another (from New_data to report).
In the New_data spreadsheet I find the second time System (hence why I start the search below the first one at N21) appears then I need to copy all data below it from columns b - k until I hit blank cells. How do I get the amount of rows to only capture filled cells?
Range("B584:K641") needs to be dynamic.
Sub CopyWorkbook()
Range("N21").Select
Cells.Find(What:="system", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
Range("B584:K641").Select
Selection.Copy
Application.WindowState = xlNormal
Windows("report.xlsx").Activate
Range("A2").Select
ActiveSheet.Paste
Windows("new_data.csv"). _
Activate
End Sub
Try the next code please. It should be very fast (if I correctly understood where to be searched for 'system', starting with what...). The code assumes that "new_data.csv" is the csv workbook name. If not, you must use its real name when defining shCSV sheet:
Sub CopyWorkbook()
Dim shR As Worksheet, shCSV As Worksheet, lastRow As Long, systCell As Range, arr
Set shR = Workbooks("report.xlsx").ActiveSheet 'use here the sheet you need to paste
'it should be better to use the sheet name.
'No need to have the respective sheet activated at the beginning
Set shCSV = Workbooks("new_data.csv").Sheets(1) 'csv file has a single sheet, anyhow
lastRow = shCSV.Range("B" & rows.count).End(xlUp).row
Set systCell = shCSV.Range("B21:B" & lastRow).Find(What:="system", _
After:=shCSV.Range("B21"), LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False)
If systCell Is Nothing Then MsgBox "No 'sytem' cell has been found...": Exit Sub
arr = shCSV.Range(systCell, shCSV.Range("K" & lastRow)).Value
shR.Range("A2").Resize(UBound(arr), UBound(arr, 2)).Value = arr
End Sub
Try:
Sub test()
Dim LR As Long
Dim Ini As Long
LR = Range("B" & Rows.Count).End(xlUp).Row 'last non empty row in column B
Ini = Application.WorksheetFunction.Match("system", Range("N21:N" & LR), 0) + 20 'position of system after n21
Range("B" & Ini & ":K" & LR).Copy
'''rest of your code to paste
End Sub
Note that this code is searching word system only in column N. If it's somewhere else, you'll need to adapt the MATCH function
I set a range to equal the filtered range and start a loop to count how many none empty cells occur until the first empty cell in column B.
Sub CopyWorkbook()
ThisWorkbook.Sheets("new_data").Activate
Range("N21").Select
Dim rng As Range
Set rng = Cells.Find(What:="system", After:=ActiveCell, _
LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, _
SearchFormat:=False)
Dim i As Double
i = rng.Row
Do Until ThisWorkbook.Sheets("new_data").Range("B" & i) = vbNullString
i = i + 1
Loop
i = i - 1
Range("B" & rng.Row & ":K" & i).Select
Selection.Copy
Application.WindowState = xlNormal
Windows("report.xlsx").Activate
Range("A2").Select
ActiveSheet.Paste
Windows("new_data.csv").Activate
End Sub
I found a Stack Overflow question that was helpful in finding an answer. Find cell address
Microsoft Excel 2010:
From month to month, the number of lines of data can be variable. When I paste new data into the ILS_IMPORT tab, there may be 3,500 records and the next month could be 2,500. When I go to import the data into Access, and extra 1,000 lines will appear unless I delete all records from line 2,501 on. I would like to have Excel VBA to do this and have made attempts, but nothing has worked thus far. I know that Column O will always have data to the end because it is the quarter indicator (ex. Q2).
However, this code keeps deleting the last row and I don't know if it is truly deleting all the way to the end. Can someone point me in the right direction?
Sub test()
Dim rng As Range
Dim lastRow As Long
With ThisWorkbook.Sheets("ILS_IMPORT")
'Find anything in the cells
Set rng = .Cells.Find(What:="*", _
After:=.Range("O1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False)
'if data is 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("O1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lastRow = 1
End If
'I use lastRow + 1 to prevent deletion data above when it is on lastrow
.Range(rng.Row + 2 & ":" & lastRow + 2).Delete Shift:=xlUp
End With
End Sub
Could you clear/delete the blank range before you paste data in?
range(cells(2,1),cells(2,1).end(xldown)).EntireRow.Clear
endofrow = excelWorksheet.get_Range("X3", "Y3").get_End(XlDirection.xlDown).Row.ToString();
//endofrow value must be 5 but it comes as 8 and null rows appear
this function must read only 2 rows as only two rows of data are present ,but it reads extra rows and null rows are appearing during insertion.
I use this code to return last row. hope this might help you
Sub GetLastRow()
Dim ws As Worksheet
Dim lRow As Long
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lRow = 1
End If
End With
MsgBox "The last row in Sheet1 which has data is " & lRow
End Sub
you can change it according to your need.