This question already has answers here:
Find last used cell in Excel VBA
(14 answers)
Closed last year.
In column A I have several values. As values are added or removed, in excel vba I want to extract all values from column A down to the last value
How can i create this?
Werte = Sheets("Messauswertung").Range("A1:A100").Value
This is not a the optimal way
Thanks!
On way is
dim lastRow as Long
With Sheets("Messauswertung")
lastRow = .Cells(rows.Count, 1).End(xlUp).Row 'last used row
Werte = .Range("A1:A" & lastRow).Value
End With
By the way, each sheet has a .Name but also a .CodeName (Sheet1).
I find it much better to (eventually change the CodeName and) use that one.
Easier to read, to write, and protected from name changes by users.
Related
This question already has answers here:
lastrow and excel table.
(6 answers)
Closed 6 months ago.
I have a worksheet with a table that is constantly being updated, so the number of rows it has is variable. I am interested in retrieving the last value in column B. However, the tricky part is that not all rows in this column of the table have a value. Sometimes the next cell with an actual value could be just below the previous one, and sometimes there could be many empty spaces in between.
I tried to use the following code to do so:
LastValue = Cells(Rows.Count, "B").End(xlUp).Value
The issue I am experiencing happens in a very specific scenario. If we suppose the last cell with a value in the column is B6, but the last cell of the table corresponding to this column is B10, the value retrieved is empty (the one in B10). What I would need to find is cell B6 and give that value to the variable LastValue. Is there any way to do this? I could only find code examples to find the last row of the entire worksheet, ignoring individual columns.
This code works below based on your worksheet being titled Sheet1 and the table as Table 1.
Sub FindLastRowInExcelTable()
Dim lastrow As Long
Dim ws As Worksheet
Set ws = Sheets("Sheet1")
lastrow = ws.ListObjects("Table1").Range.Columns(2).Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
End Sub
You can modify Columns(2) to change the column you are looking to count.
Need a little help here.
In the "Data" Tab I want to copy values in column "c2:c1000" and paste in column "a1" of another Tab.
This is what i have so far,
Dim x As Long
Dim lastRow As Long
lastRow = Worksheet("Data").Cells(3, Columns.Count).End(xlUp).Column
For x = 1 To lastRow
If Worksheets("Sheet2").Cells(2, "A") = "" Then
Worksheets("Data").Range("c2:c1000").Copy Destination:=Worksheets("Sheet2").Range(1, "A")
Sheets("Sheet2").Range("A1").Value = Format(Now, "mm/dd/yyyy HH:mm:ss")
Else
Worksheets("Data").Range("c2:c1000").Copy Destination:=Worksheets("Sheet2").Cells(2,
Columns.Count).End(xlToLeft).Offset(, 1)
'Sheets("Sheet2").Range("A1").Value = Format(Now, "mm/dd/yyyy HH:mm:ss") --> can't figure how to increment this as this will need to be on the subsequent empty column
End If
Next
End Sub
Your help will be greatly appreciated!
Thank you.
Pasting values first into range A1 and down and then next time to cell B1 and so on, leaves no space for the timestamp to A1, B1 etc. So, I assume that you would like to paste the random values to row 2. So cells A1, B1, ... are left for the timestamp.
Inside the With statements we can refer to properties of the wsAudit so we can replace the "Worksheets("Audit")." reference with just "."
The column.count expression just checks the amount of columns in the worksheet.
The expression .Cells(2, Columns.Count) just points to last cell in the row 2.
The .End(xlToLeft).Column then looks from this column to left and is supposed to find the last not empty cell on this row. It's basically the same idea that in Excel's sheet you would go to cell XDF2 and hit CTRL+Arrow Left from keyboard.
But instead of activating the cell we just want to get the columns index number and then add 1 (the new column) and save it into variable. Now the new column is known.
The expression Range(.Cells(2, newColAudit), .Cells(1000, newColAudit)).Value is really the same as e.g. Range("B2:B1000"), but with this we can use the row and column index numbers instead. This is useful as the column number varies.
And as Samuel pointed out the copy paste operation can be avoided by setting the areas equal.
Dim wsAudit As Worksheet
Dim newColAudit As Long
Set wsAudit = Worksheets("Audit")
With wsAudit
newColAudit = .Cells(2, Columns.Count).End(xlToLeft).Column + 1
Range(.Cells(2, newColAudit), .Cells(1000, newColAudit)).Value = Worksheets("Data").Range("C2:C1000").Value
.Cells(1, newColAudit).Value = Format(Now, "mm/dd/yyyy HH:mm:ss")
End With
Much like your LastRow* variable for your source sheet, create a LastColumn variable for your destination sheet, which will find the last used column the same way you are finding your last used row.
Like so:
Dim LastColumn As Long
LastColumn = Sheets("Audit").Cells(1, Columns.Count).End(xlToLeft).Column
Then use the variable like so:
Destination:= Worksheets("Audit").Cells(1, LastColumn)
It seems that your code contradicts your question too, in your question you explained the data will be written to the Audit sheet in row 1, using the next column each time but your code looks for values in row 2 in your If statement:
If Worksheets("Audit").Cells(2, "A") = "" Then is the same as If Worksheets("Audit").Range("A2") = "" Then.
If you mean to check the first row, change the 2 to 1.
To help improve your codes efficiency:
(Also see the link to 'how to avoid select' in that question):
You can achieve 'copy/paste' without actually using the 'copy' and 'paste' methods by assigning the value of one range to the other, as example, like so:
Worksheets("Audit").Cells(1, LastColumn).Resize(999, 1) = Worksheets("Data").Range("c2:c1000").Value
Note: Change the Resize Property rows to suit the source range (in this case you are wanting to move values from C2:C1000).
*The LastRow variable is a bit confusing, as it is looking for the last used column in row 3.
If it's meant to find a column, consider renaming it to avoid confusion later on in debugging.
If it's meant to find the last row, try like this:
LastRow = Worksheet("Data").Cells(Rows.Count, 1).End(xlUp).Row
I have a table with column A containing incrementing numerical values, and column B being a bunch of names. I need to filter the table according the names, and have column C update with the difference between the value in column A in the current row and the cell above..
For example, I'd like to have something like this
which,
when filtered according to the Name column, should update the difference like so
I have tried to use SUBTOTAL function in a few different ways but to no avail. Ideally it'd update once the filter in the table is changed. I tried to do this in VBA but so far I've gotten macro that only filters with the hard-coded filter criteria.
Solutions in either excel formulas/python/vba are all welcomed and greatly appreciated!
I apologise in advance if this question isn't up to standards as Im new here :) Thank you in advance!
#JvdV: This is the outcome of me trying to implement your formula, This is after filtering.
REVISED ANSWER
So after your explenation I have looked into a formula that will give you the difference of the current row B-value minus the B-value of occurance of the A-value before that.
=IFERROR(B2-LOOKUP(2,1/($A$1:A1=A2),$B$1:B2),0)
Taking your sample data, it would look like this:
Then when you apply the filter, it would look like this:
So with this workaround you dont have the correct value when no filter is applied, but in this case I assumed you are interested in the difference when it IS filtered!
The formula is entered in cell C2 and dragged down.
EDIT
If this is not the answer you'r after and you DO need the values when it is not filtered, make use of a UDF like below:
Public Function LastVisibleCell(CL As Range) As Long
Dim RW As Long, X As Long
RW = CL.Row - 1
On Error GoTo 1
If RW > 1 Then
For X = RW To 1 Step -1
If ActiveSheet.Rows(X).EntireRow.Hidden Then
Else
LastVisibleCell = Cells(CL.Row, 2).Value - Cells(X, 2).Value
Exit For
End If
Next X
Else
1: LastVisibleCell = 0
End If
End Function
Call it from cell C2 like: =LastVisibleCell(A2) and drag down. When you apply your filter, the cells will update.
Beware, this will take ages to update on large datasets!
After 3 days of intense (albeit ineffective) Google-ing, I finally came across this answer also on stack overflow.
However, as I'm working on a large set of data (>150,000 rows), the method in the question uses too much memory. Using VBA to paste the formulas into visible cells only does not seem to alleviate the problem.
Sub CopyPasteFormula()
Dim Ws As Worksheet
Dim LRow As Long
Dim PasteRng As Range
Set Ws = Worksheets("Translated Data")
Ws.Range("$D$2:$D$200000").AutoFilter Field:=4, Criteria1:="<>-", Operator:=xlFilterValues
LRow = Ws.Range("D" & Rows.Count).End(xlUp).Row
Set PasteRng = Ws.Range("A3:A" & LRow).SpecialCells(xlCellTypeVisible)
Ws.Range("A3").Copy
PasteRng.PasteSpecial xlPasteFormulas
Application.CutCopyMode = False
End Sub
Above is my macro code to attempt reduce the memory use... Appreciate any feedback!
This question already has answers here:
Finding the Last Row and using it in a formula
(2 answers)
Closed 5 years ago.
I would like this Code to count the number of incidents in a column starting at Cell A3 and then go the last cell in the column without me having to define it.
ActiveCell.FormulaR1C1 = _
"=COUNTIF(Data!R[-2]C[-3]:R[647]C[-3],Data!R[-2]C[-3])"
Still new to VBA and learning.
Here's a simple way to locate the last used cell in column C. There are several variations to finding lastRow, this is just one of them. Add your code accordingly.
Dim LastRow As Long
Dim lastCell As Long
lastCell = Range("C65536").End(xlUp).Cell '<<--for finding last active cell reference
lastRow = Range("C65536").End(xlUp).Row '<<--for finding last row number
This question already has answers here:
Find last used cell in Excel VBA
(14 answers)
Closed 6 years ago.
Follow on from earlier question. I am trying to count the number of rows in a table which contain data (not counting number of rows which are part of the table).
For example, my table is:
My code is:
With ThisWorkbook.Worksheets(1)
Set ATB = .ListObjects("Table1")
.Activate
numberRows = .Cells(.Rows.Count, "A").End(xlUp).Row
End With`
This returns the wrong number (trust me that column A has the same data count)
Likewise, I want to use VBA to resize the table nicely but need this row count for that.
Try this
Sub check()
With ThisWorkbook.Worksheets("Sheet1")
Set ATB = .ListObjects("Table1")
.Activate
numberRows = Application.CountA(.Range("A:A"))
End With
End Sub
Try this excel formula
=COUNTA(Table1[A1])