Find the last cell address using vba excel - excel

I have searched this site and it seems like all the answers just point to finding the row number of the cell.
I am trying to set a range so that it will go from A1 to the end of the data in the A column. This spreadsheet will be updated weekly so there will be data added to it every week.
I was wondering what code would work so that I can either find the row number and somehow tie it in with my range code so that it will equal "A" + lastrownumber? OR if there is code that will provide the column and row number together? If I have missed the link to the correct answer a simple link will do as well and I apologize for the post and your time.
Here is my code:
Sub NamedRange()
Dim Rng1 As Range
Dim newDate As Integer
Dim NumberOfRows As Range
Dim MyRange As Range
Dim lastRow2 As Range
lastRow2 = Range("A65536").End(xlUp).Row
'lastRow2 = LastRow
Set Rng1 = Sheets("Sheet1").Range(lastRow2)
ActiveWorkbook.Names.Add Name:="MyRange", RefersTo:=Rng1
Dim date1 As String
Dim dat As Date
Dim newPrice As Double
Set RgSales = Range("MyRange")

This will return the range object corresponding to the last filled in cell in column A
Range("A:A").Find("*",Range("A1"),SearchDirection:=xlprevious)
If you want the row number, use the following:
Range("A:A").Find("*",Range("A1"),SearchDirection:=xlprevious).row

This will give the last row in a given column
= Cells(Activesheet.Rows.Count, ColumnNumber).End(xlUp).Row (Fixed per #Gimp)
you then have a reference you can use to add to the data - e.g if you want to look in column "A", then that would be columnnumber 1. feed that into the function, then you can use Cells(NumberReturnedFromFunction,ColumnNumber) to address that cell, and add .Address if you want the A1 style of address

Try using something like this:
Activesheet.Cells(Activesheet.Rows.Count, "A").End(xlUp).Row
You can replace Activesheet with references to a sheet's index # like Sheets(1) or the sheet name like Sheets("Sheet1")
By using the Rows.Count it will check to see what the max rows are and be compatible across all versions of Excel.
In the end you can use this within your range reference like this:
Msgbox Sheets(1).Range("A" & Sheets(1).Cells(Sheets(1).Rows.Count, "A").End(xlUp).row).value
But I'd probably rewrite that as
With Sheets(1)
Msgbox .Range("A" & .Cells(.Rows.Count, "A").End(xlUp).row).value
End With

In case there are gaps in the data I'd avoid using xlDown so something like the following is fine. Try it in the immediate window:
Activesheet.range("A1:A" & Activesheet.Cells(Excel.Rows.Count, 1).End(Excel.xlUp).Row).select

Related

Assigning cell value based to vlookup result - VBA

After failing to figure out how to do that for a while, I'll try my luck here:
I'm essentially trying to compare two situations using VBA.
A similar (and a lot simpler) example:
F2, for example, calculate 152+D2, while F3 calculates 185+D3.
I wish to run a macro that would check the effect of one person getting a different amount of points. For example, if A2 = Max the macro should assign the value of A3 (18) to D3. If A2 = Lewis, 18 would become the new value of D2.
Tried using vlookup and match+index in order to find the cell that I want to change. When using vlookup, the code looked similar to this:
First I copied F2:F4 to I2:I4, so the results would be comparable. Then tried to replace the value of D2:D4 according to A2&A3:
name = Range("A2").value
newvalue = Range("A3").value
Find = Application.VLookup(name, Range("C2:D4"), 2, False)
Find.value = newvalue
Perhaps I should be looking for the cell itself, and not the value, and then it would work (maybe using offset, or offset+match? couldn't make it work)?
Would appreciate any help!
Not really sure what the intention is but this seems like a fun challenge.
So logic is this. We look for the name in column C. If we get a match we will get a row back as an answer, then we replace the value from "A3" and add it to the row we got but to the column D.
Maybe something like this :D?
Option Explicit
Sub something_test()
Dim lookup_val As String
Dim lrow As Long
Dim lookup_rng As Range
Dim match_row As Long
Dim ws As Worksheet
Set ws = Worksheets("Sheet1") 'Name the worksheet
lrow = ws.Cells(Rows.Count, "C").End(xlUp).Row 'Find last row in Sheet1
lookup_val = ws.Cells(2, "A").Value 'Set the lookup value
Set lookup_rng = ws.Range("C2:C" & lrow) 'set the lookup range
match_row = Application.Match(lookup_val, lookup_rng, 0) + 1 'Find the name in column C. Add +1 since the range starts at row 2. We will get the row number back
ws.Cells(match_row, "D").Value = ws.Cells(3, "A").Value 'Take the value from "A3" and replace the existing value at the row we found, but for column D
End Sub

Convert range to array

I have the following worksheet:
I want to convert the range from C15 to last row/column to array.
I have tried the following code but is not working:
Sub rangeToArray()
Dim arr() As Variant
arr = Range("C15", Range("C15").End(xlDown).End(xlToRight))
End Sub
I get this:
Could someone help me please with this? I would like to get the range from C15 to last row/column and based on different criteria to sort it and copy rows to a different spreadsheet with the same format. I want to convert the range into an array as I have over 30k rows and will work faster.
Thank you!
arr = Range("C15", Range("C15").End(xlDown).End(xlToRight)) is just another way of saying arr = Range("C15").CurrentRegion
On top of that this would currently refer to the ActiveSheet, therefor you might want to try the following:
Sub rangeToArray()
Dim arr() As Variant
With Sheet1 'Change to whichever CodeName your sheet has
arr = .Range("C15").CurrentRegion
End With
End Sub
Note: As said in my comment, CurrentRegion will not work correctly once you start having gaps in your data. Therefor you might want to rework the code to check for the last used row in column C:C and the last used column in row 15:
Sub rangeToArray()
Dim arr() As Variant
Dim lr As Long, lc As Long
With Sheet1 'Change to whichever CodeName your sheet has
lr = .Cells(.Rows.Count, 3).End(xlUp).Row
lc = .Cells(15, .Columns.Count).End(xlToLeft).Column
arr = .Range(.Cells(15, 3), .Cells(lr, lc))
End With
End Sub
Based on this answer with the most reliable way to find the last row and column, the following range is possibly the most reliable way to select all your data to last row and column:
Arr = Range(Cells(15, 3), Cells(Range("A" & Rows.Count).End(xlUp).Row, _
Cells(1, Columns.Count).End(xlToLeft).Column))
Please note, it would be best to specify the sheet for every Cell and Range statement.

How to concatenate text from a column into a new column? VBA Excel

I'm new to vba programming and I would like to work on a function to fix salutations in an excel file.
To start, I would just like to append a Dear " to a name in the first column, and put this value in the next column, so that I would end up with the name in the first column and "Dear name" in the next column.
The function I have so far, is putting "Dear " in the next column, but it is not appending that to the text in the first column. Could someone help me correct my code?
Sub letterSalutationFixer()
Dim letterSalutationColumn As Range
Set letterSalutationColumn = Columns(1)
For Each Cell In letterSalutationColumn
Cell.Offset(, 1).Value = "Dear " & Cell.Text
Next
End Sub
PS. I do realise that I don't necessarily need to do this programmatically since it doesn't take that long to do with the functions already available, but I eventually want to expand this to fix other data with more complexity - and just thought I could start with something simple.
Many thanks in advance!
The reason it's blank is that Cell is equivalent to the whole column. You're close though. If you did...
For Each Cell In letterSalutationColumn.Cells
..l it would cycle through each cell.
However, the way it's written, it would cycle through each cell in the whole column, which could crash Excel, or at least slow things way down.
Here's a reworked version of what you're trying to do. It only acts on the cells in column A with content:
Sub Salutation()
Dim ws As Excel.Worksheet
Dim LastRow As Long
Dim NameRange As Excel.Range
Dim cell As Excel.Range
Set ws = ActiveSheet
With ws
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
Set NameRange = .Range("A2:A" & LastRow)
For Each cell In NameRange
cell.Offset(, 1) = "Dear " & cell.Text
Next cell
End With
End Sub
It also declares all variables, something you want to get in the habit of doing. Do a search on Option Explicit to learn how to force yourself to.
It also uses a With statement to fully qualify Object references, so that instead of just referring to Column(1) or Range(something) you're specifying that it's in ws, which has been set to the ActiveSheet.
Another way is the VBA alternative of
Using a formula in column B that runs the concatenation against the used part of column A (ie in B1 ="Dear " &A1 etc)
The formula then is copied over itself as a value to remove the formula
code
Sub QuickCon()
Dim rng1 As Range
Set rng1 = Range([a1], Cells(Rows.Count, "A").End(xlUp))
With rng1.Offset(0, 1)
.FormulaR1C1 = "=""Dear "" &RC[-1]"
.Value = .Value
End With
End Sub

How do I compare dates in one column to a cell in the same row in another column?

I feel like this should be a simple enough task, but I'm not experienced enough with Excel VBA to know how to approach it. Basically I want to look at two cells in a row and do something if they both both have specific dates in them. The two cells will always be in one of two specific columns.
For example, if the date in D2 and I2 both are both earlier than November, then I want to do something to that row and move to the next row. Then, if the date in D3 and I3 both are both earlier than November, then I want to do something to that row and move to the next row. And so on, and so on...
My problem isn't so much about how to do all the steps. It's really about how to go about doing this compare. I know how to select just the cells in those two columns by doing the following:
Union(Range(Cells(2, 4), Cells(Rows.Count, 4).End(xlUp)), _
Range(Cells(2, 9), Cells(Rows.Count, 9).End(xlUp))).Select
But then it occurred to me that I don't know how I would go about comparing the respective cells of both columns. I only know how to loop through each cell of one column.
Any help would be greatly appreciated.
How about just looping through 1 column, then using the Offset method to compare.
Check this:
Option Explicit
Sub CheckTwoCols()
Dim wks As Worksheet, lastrow As Long, rng As Range, cel as Range
Set wks = Sheets(1) 'change sheet reference to suit your needs
With wks
lastrow = .Range("D" & .Rows.Count).End(xlup).Row
Set rng = .Range("D2:D" & lastrow)
For each cel in rng
'column I is 5 columns to the right of column D
If cel < "11/1/2012" and cel.offset(,5) < "11/1/2012" Then
'process code
End If
Next
End With
End Sub

Excel VBA - select a dynamic cell range

I want to be able to dynamically select a range of cells (the heading row), where the row is 1 but the columns with be for 1 to last column, where "A" is the first Column and where "M" is the last column. I know how to find the last column, but I don't know how to modified the below range to input the first and last column as "A" and "M".
Range("A1:M1").Select
If you want to select a variable range containing all headers cells:
Dim sht as WorkSheet
Set sht = This Workbook.Sheets("Data")
'Range(Cells(1,1),Cells(1,Columns.Count).End(xlToLeft)).Select '<<< NOT ROBUST
sht.Range(sht.Cells(1,1),sht.Cells(1,Columns.Count).End(xlToLeft)).Select
...as long as there's no other content on that row.
EDIT: updated to stress that when using Range(Cells(...), Cells(...)) it's good practice to qualify both Range and Cells with a worksheet reference.
sub selectVar ()
dim x,y as integer
let srange = "A" & x & ":" & "m" & y
range(srange).select
end sub
I think this is the simplest way.
So it depends on how you want to pick the incrementer, but this should work:
Range("A1:" & Cells(1, i).Address).Select
Where i is the variable that represents the column you want to select (1=A, 2=B, etc.). Do you want to do this by column letter instead? We can adjust if so :)
If you want the beginning to be dynamic as well, you can try this:
Sub SelectCols()
Dim Col1 As Integer
Dim Col2 As Integer
Col1 = 2
Col2 = 4
Range(Cells(1, Col1), Cells(1, Col2)).Select
End Sub
I like to used this method the most, it will auto select the first column to the last column being used. However, if the last cell in the first row or the last cell in the first column are empty, this code will not calculate properly. Check the link for other methods to dynamically select cell range.
Sub DynamicRange()
'Best used when first column has value on last row and first row has a value in the last column
Dim sht As Worksheet
Dim LastRow As Long
Dim LastColumn As Long
Dim StartCell As Range
Set sht = Worksheets("Sheet1")
Set StartCell = Range("A1")
'Find Last Row and Column
LastRow = sht.Cells(sht.Rows.Count, StartCell.Column).End(xlUp).Row
LastColumn = sht.Cells(StartCell.Row, sht.Columns.Count).End(xlToLeft).Column
'Select Range
sht.Range(StartCell, sht.Cells(LastRow, LastColumn)).Select
End Sub

Resources